首页 示例 截图 用户手册 Bluesky logo YouTube
OghmaNano 模拟有机/钙钛矿太阳能电池、OFET 和 OLED 下载

MATLAB 脚本

1. 介绍

在 OghmaNano 中,MATLAB 脚本通过直接编辑磁盘上的仿真配置文件, 然后调用仿真引擎(oghma_core.exe)来运行模型。 本节将详细说明这一工作流程。

2. 使用 MATLAB 运行仿真文件

一个 OghmaNano 仿真完全由单个 JSON 配置文件 sim.json 定义。 该文件包含仿真的完整状态,包括器件结构、 材料参数、数值设置和输出配置。 在许多情况下,sim.json 已经作为普通文件存在于仿真目录中。

使用 MATLAB 驱动 OghmaNano 时,脚本会使用 MATLAB 的 JSON 支持将 sim.json 读入内存,修改一个或多个参数,然后将更新后的 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 将把输出文件写入 仿真目录,其中包含诸如 PCE、填充因子、\(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-51e-61e-71e-8)。对于每个目录,它会:

  1. 创建该目录(如果它尚不存在)。
  2. 将当前的 sim.json 复制到该目录中。
  3. 编辑复制后的 sim.json 以设置目标迁移率。
  4. 将工作目录切换到该目录。
  5. 在该目录中运行求解器,从而生成该次运行本地的输出。

这种模式是 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-05mu_1e-06、...),下一步是从每次运行中提取一个关键性能指标并将趋势可视化。 一个常见示例是从每个目录中的 sim_info.dat 读取开路电压 \(V_{oc}\), 并将其相对于反迁移率 \(1/\mu\) 作图。

下面的脚本扫描一组固定的运行目录,这些目录对应的迁移率为 1e-51e-61e-71e-8,并对每个目录执行:

  1. sim_info.dat 作为 JSON 读取。
  2. 提取 Voc
  3. 使用与该目录关联的迁移率计算 \(1/\mu\)
  4. 写出一个简要汇总文件(voc_vs_inv_mobility.dat)。
  5. 绘制 \(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;