Шаг 4. Серии и очереди расчётов¶
Один расчёт из Шаг 1. Первый скрипт — частный случай. Обычно интересно посмотреть, как результат меняется при варьировании параметра (или сразу нескольких).
ParameterSeries.Expand¶
Берёт базовую конфигурацию и словарь «какое поле → какие значения», возвращает массив независимых конфигураций:
baseCfg = CalculationConfig( ...
'Representation', "EnergyBased", 'Material', "Aluminum", ...
'Length_nm', 50, 'Temperature', 0.5, 'SelfConsistencySteps', 15);
baseCfg.Grid = GridConfig('zN', 40, 'eN', 200, 'eStart', -74, 'eEnd', 74);
varying = containers.Map();
varying('SpinMixingAngle') = [0, 0.05, 0.1];
cfgs = ParameterSeries.Expand(baseCfg, varying); % 3 конфигурации
varying — containers.Map, а не обычная struct, потому что ключ
может быть составным путём с точкой, например "Grid.zN" (struct так не
умеет — точка в имени поля недопустима). Значение — вектор (или
string-массив/cell-массив) значений для перебора.
Несколько параметров сразу¶
varying = containers.Map();
varying('SpinMixingAngle') = [0, 0.1];
varying('MisorientationAngle_Degrees') = [0, 45, 90];
cfgs = ParameterSeries.Expand(baseCfg, varying, "grid"); % 2*3 = 6
Число варьируемых параметров не ограничено — практическое ограничение
только комбинаторное: в режиме "grid" (декартово произведение, по
умолчанию) число конфигураций — произведение длин всех векторов.
Если декартово произведение не нужно, а нужен параллельный перебор (i-е
значение первого параметра вместе с i-м значением второго) — режим
"zip"; все векторы тогда должны быть одинаковой длины:
cfgsZip = ParameterSeries.Expand(baseCfg, varying, "zip"); % 2 конфигурации, не 6
Имя каждой конфигурации (cfg.TaskName) собирается автоматически из
варьируемых значений: EnergyBased_Aluminum_50nm_SpinMixingAngle=0.1_MisorientationAngle_Degrees=45
— это же имя станет именем папки результата (Шаг 5. Сохранение и загрузка результатов).
Запуск серии¶
Два варианта, в зависимости от того, нужна ли persistent-очередь.
Просто прогнать всё и получить результаты в памяти:
results = CalculationRunner.RunMany(cfgs);
% results(i).Config, results(i).Calculation, results(i).Error
Одна упавшая конфигурация не останавливает остальные — ошибка попадает в
results(i).Error, расчёт продолжается со следующей.
Через очередь (когда хочется явно видеть прогресс, сохранить очередь и продолжить в другой сессии MATLAB):
q = CalculationQueue();
q.AddMany(cfgs);
q.Save('queue.mat'); % можно закрыть MATLAB прямо сейчас
% ... позже, в новой сессии:
q2 = CalculationQueue.Load('queue.mat');
q2.RunAll();
q2.Summary();
CalculationQueue — единственный handle-класс в скрипточном слое (в
отличие от конфигураций): это осознанно, очередь по своей природе общее
изменяемое состояние. RunNext() выполняет только следующий
pending-элемент — удобно для пошагового прогона.
И в CalculationRunner.RunMany, и в CalculationQueue после каждого
запуска автоматически обновляется текстовый manifest.txt в папке серии
(если задан SaveOptions — см. Шаг 5. Сохранение и загрузка результатов).
Дальше¶
Как результаты серии раскладываются по папкам на диске и как загрузить их обратно — Шаг 5. Сохранение и загрузка результатов.