Створення сценаріїв у MATLAB.
1. Вступ
У OghmaNano сценарії MATLAB виконуються шляхом безпосередньої зміни файлів конфігурації моделювання, що зберігаються на диску, а потім запуску рушія моделювання (oghma_core.exe) для виконання моделі. У цьому розділі детально описано цей процес.
2. Запуск файлів моделювання за допомогою MATLAB.
Моделювання в OghmaNano повністю визначається одним файлом конфігурації у форматі JSON, sim.json. Цей файл містить повний стан моделювання, включно зі структурою пристрою, параметрами матеріалів, числовими налаштуваннями та конфігурацією вихідних даних. У багатьох випадках sim.json вже існує як звичайний файл у каталозі моделювання.
Під час керування OghmaNano з MATLAB, скрипт зчитує дані sim.json в пам’ять, використовуючи підтримку JSON у MATLAB, змінює один або кілька параметрів і записує оновлені дані JSON назад на диск.
Найважливіше, що MATLAB має запускатися oghma_core.exe із налаштованою робочою директорією, яка вказує на директорію моделювання, тобто на директорію, що містить sim.json (та sim.oghma). Механізм моделювання завжди зчитує вхідні файли з поточної робочої директорії, тому, якщо робоча директорія вказана неправильно, моделювання не вдасться або буде запущено не ту модель.
Такий розподіл обов’язків є навмисним і чітко визначеним: MATLAB відповідає за визначення того, які зміни відбуваються в моделюванні, а OghmaNano відповідає за виконання фізичних розрахунків на основі файлів, що містяться в поточній директорії.
Наведений нижче приклад демонструє цей процес шляхом завантаження sim.json, зміни рухливості носіїв заряду в першому шарі пристрою, збереження оновленої конфігурації на диск, а потім запуску моделювання з каталогу моделювання.
% Set this to your simulation folder (must contain sim.json / sim.oghma)
sim_dir = "C:\path\to\your\simulation";
% Read sim.json
sim_path = fullfile(sim_dir, "sim.json");
txt = fileread(sim_path);
data = jsondecode(txt);
% Edit a value: mobility of segment1 (same JSON path as the Python page)
data.epitaxy.segment1.shape_dos.mue_y = 1.0;
% Write sim.json back to disk
out = jsonencode(data);
fid = fopen(sim_path, "w");
fprintf(fid, "%s", out);
fclose(fid);
% Run the simulation (working directory must be the simulation folder)
orig_dir = pwd;
cd(sim_dir);
system("oghma_core.exe");
cd(orig_dir);
Якщо в симуляції sim.json налаштовано отримання кривої залежності струму від напруги (J–V), OghmaNano створить вихідні файли в каталозі симуляції, які міститимуть такі параметри, як ККД, коефіцієнт заповнення, \(J_{sc}\) і \(V_{oc}\).
3. Отримання результатів
Багато вихідних файлів OghmaNano створено у форматі JSON. Зазвичай процес передбачає зчитування sim_info.dat, вилучення скалярного значення, що характеризує якість результату (наприклад, Voc), і додавання цього значення до текстового файлу для подальшого аналізу.
Наведений нижче приклад містить sim_info.dat і додає значення \(V_{oc}\) до окремого текстового файлу.
% Must be run from (or pointed at) a completed simulation directory
sim_dir = "C:\path\to\your\simulation";
info_path = fullfile(sim_dir, "sim_info.dat");
txt = fileread(info_path);
info = jsondecode(txt);
voc = info.Voc;
% Append to a text file (one Voc per line)
out_path = fullfile(sim_dir, "out.dat");
fid = fopen(out_path, "a");
fprintf(fid, "%g\n", voc);
fclose(fid);
3. Складніші моделювання.
У багатьох сценаріях автоматизації процесів вам знадобиться кілька разів запускати одну й ту саму базову симуляцію з різними значеннями параметрів і зберігати результати кожного запуску в окремій папці. Це найпростіший спосіб забезпечити охайність результатів і запобігти випадковому перезапису даних.
Наведений нижче приклад створює набір каталогів, що відповідають чотирьом типам мобільності (1e-5, 1e-6, 1e-7, 1e-8). Для кожного каталогу він:
- Створює каталог (якщо він ще не існує).
- Копіює поточний файл
sim.jsonдо вказаної директорії. - Редагує скопійований
sim.json, щоб задати цільову швидкість переміщення. - Змінює поточну робочу директорію на вказану.
- Запускає програму для розв’язання задач у вказаній директорії, генеруючи результати, які зберігаються локально для цього конкретного запуску.
Ця схема є основою для пакетного скриптингу в OghmaNano: для кожного запуску використовується окрема директорія, окремий файл конфігурації та окрема папка для виводу результатів для кожного значення параметра.
% The script should be started in the base simulation directory
% (i.e. the directory containing the reference sim.json).
base_dir = pwd;
mobilities = [1e-5, 1e-6, 1e-7, 1e-8];
src_sim = fullfile(base_dir, "sim.json");
for k = 1:numel(mobilities)
mu = mobilities(k);
run_name = sprintf("mu_%.0e", mu);
run_dir = fullfile(base_dir, run_name);
if ~exist(run_dir, "dir")
mkdir(run_dir);
end
% Copy the base sim.json into the run directory
dst_sim = fullfile(run_dir, "sim.json");
copyfile(src_sim, dst_sim);
% Load the copied sim.json and edit the mobility in THAT copy
txt = fileread(dst_sim);
data = jsondecode(txt);
data.epitaxy.segment1.shape_dos.mue_y = mu;
out = jsonencode(data);
fid = fopen(dst_sim, "w");
fprintf(fid, "%s", out);
fclose(fid);
% Change into the run directory and execute the solver there
cd(run_dir);
system("oghma_core.exe");
cd(base_dir);
end
4. Отримання результатів
Після виконання серії симуляцій в окремих папках (наприклад, mu_1e-05, mu_1e-06, ...), наступним кроком є отримання ключового показника ефективності для кожної симуляції та візуалізація отриманої тенденції. Типовим прикладом є зчитування значення напруги розімкнутого контуру \(V_{oc}\) з файлу sim_info.dat в кожній папці та побудова графіку залежності цього значення від оберненої рухливості \(1/\mu\).
Наведений нижче скрипт перевіряє заздалегідь визначений набір каталогів, що відповідають показникам рухливості 1e-5, 1e-6, 1e-7, 1e-8, і для кожного каталогу виконує наступне:
- Завантажити
sim_info.datу форматі JSON. - Уривки
Voc. - Обчислює \(1/\mu\) на основі показника мобільності, пов’язаного з цією директорією.
- Створює невеликий файл із підсумковою інформацією (
voc_vs_inv_mobility.dat). - Порівняння графіків \(V_{oc}\) та \(1/\mu\).
% Run this from the BASE directory that contains the run folders
% (mu_1e-05, mu_1e-06, ...). If not, set base_dir explicitly.
base_dir = pwd;
% Mobilities must match the run directories you generated earlier
mobilities = [1e-5, 1e-6, 1e-7, 1e-8];
inv_mu = zeros(size(mobilities));
vocs = zeros(size(mobilities));
for k = 1:numel(mobilities)
mu = mobilities(k);
run_dir = fullfile(base_dir, sprintf("mu_%.0e", mu));
info_path = fullfile(run_dir, "sim_info.dat");
if ~exist(info_path, "file")
error("Missing sim_info.dat in: %s", run_dir);
end
txt = fileread(info_path);
info = jsondecode(txt);
vocs(k) = info.Voc;
inv_mu(k) = 1.0 / mu;
end
% Write a small summary table to disk
out_path = fullfile(base_dir, "voc_vs_inv_mobility.dat");
fid = fopen(out_path, "w");
fprintf(fid, "# inv_mobility(1/mu) Voc(V)\n");
for k = 1:numel(inv_mu)
fprintf(fid, "%.6e %g\n", inv_mu(k), vocs(k));
end
fclose(fid);
% Plot Voc against inverse mobility
figure;
plot(inv_mu, vocs, "o-");
xlabel("Inverse mobility (1/\mu)");
ylabel("Open-circuit voltage V_{oc} (V)");
title("V_{oc} vs inverse mobility");
grid on;