Strona główna Przykłady Zrzuty ekranu Instrukcja obsługi Logo Bluesky. YouTube ☰
OghmaNano Platforma do symulacji wielofizycznych procesów zachodzących w optoelektronicznych urządzeniach i systemach fotonicznych. POBIERZ Przewodnik szybkiego uruchomienia

Tworzenie skryptów w MATLABie

1. Wprowadzenie

W OghmaNano skrypty MATLAB działają poprzez bezpośrednią edycję plików konfiguracyjnych symulacji na dysku, a następnie uruchamianie silnika symulacyjnego (oghma_core.exe) w celu uruchomienia modelu. W tej sekcji szczegółowo opisano ten proces.

2. Uruchamianie plików symulacyjnych za pomocą programu MATLAB.

Symulacja OghmaNano jest w pełni definiowana przez pojedynczy plik konfiguracyjny w formacie JSON, sim.json. Plik ten zawiera kompletny stan symulacji, w tym strukturę urządzenia, parametry materiałowe, ustawienia numeryczne i konfigurację wyjściową. W wielu przypadkach sim.json już istnieje jako zwykły plik w katalogu symulacji.

Podczas uruchamiania programu OghmaNano z poziomu MATLAB, skrypt odczytuje dane sim.json do pamięci, wykorzystując funkcje obsługi formatu JSON w MATLAB, modyfikuje jeden lub więcej parametrów, a następnie zapisuje zaktualizowane dane JSON na dysku.

Co najważniejsze, program MATLAB musi być uruchomiony oghma_core.exe z ustawionym katalogiem roboczym na katalog symulacji – czyli katalog, w którym znajdują się sim.json (oraz sim.oghma). Silnik symulacyjny zawsze odczytuje pliki wejściowe z aktualnego katalogu roboczego, więc jeśli katalog roboczy jest nieprawidłowy, symulacja zakończy się niepowodzeniem lub uruchomi nieprawidłowy model.

To rozdzielenie zakresów odpowiedzialności jest celowe i wyraźnie określone: MATLAB odpowiada za definiowanie zmian wprowadzanych w symulacji, natomiast OghmaNano odpowiada za uruchamianie obliczeń fizycznych na podstawie plików znajdujących się w bieżącym katalogu.

Poniższy przykład ilustruje ten proces poprzez załadowanie sim.json, zmodyfikowanie mobilności nośników w pierwszej warstwie urządzenia, zapisanie zaktualizowanej konfiguracji na dysku, a następnie uruchomienie symulacji z katalogu symulacji.


% 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);

Jeśli w programie sim.json ustawiono symulację mającą na celu wygenerowanie krzywej J–V, OghmaNano zapisze pliki wynikowe w katalogu symulacji, zawierające takie parametry, jak PCE, współczynnik wypełnienia, \(J_{sc}\) i \(V_{oc}\).

3. Pobieranie wyników

Wiele plików wyjściowych programu OghmaNano zapisywanych jest w formacie JSON. Typowym rozwiązaniem jest odczytanie danych sim_info.dat, wyodrębnienie pojedynczej wartości określającej jakość (na przykład Voc) i dołączenie jej do pliku tekstowego w celu późniejszej analizy.

Poniższy przykład odczytuje wartość sim_info.dat i zapisuje wartość \(V_{oc}\) do oddzielnego pliku tekstowego.


% 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. Bardziej zaawansowane symulacje.

W wielu procesach tworzenia skryptów będziesz chciał uruchamiać tę samą podstawową symulację wielokrotnie, używając różnych wartości parametrów, i przechowywać wyniki każdego uruchomienia w oddzielnym folderze. Jest to najprostszy sposób na zachowanie porządku w wynikach i uniknięcie przypadkowego nadpisywania danych.

Poniższy przykład tworzy zestaw katalogów odpowiadających czterem różnym typom mobilności (1e-5, 1e-6, 1e-7, 1e-8). Dla każdego katalogu wykonuje następujące czynności:

  1. Tworzy katalog (jeśli taki katalog jeszcze nie istnieje).
  2. Kopiuje aktualną wersję sim.json do tego katalogu.
  3. Modyfikuje skopiowany element sim.json, aby ustawić docelową wartość mobilności.
  4. Zmienia bieżący katalog roboczy na wskazany katalog.
  5. Uruchamia program rozwiązujący w danym katalogu, generując wyniki, które są zapisywane lokalnie w tym katalogu.

Ten schemat stanowi podstawę skryptów wsadowych w OghmaNano: dla każdego uruchomienia tworzony jest oddzielny katalog, oddzielny plik konfiguracyjny oraz czysty folder wyjściowy dla każdej wartości parametru.


% 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. Pobieranie wyników

Po przeprowadzeniu serii symulacji w oddzielnych katalogach (np. mu_1e-05, mu_1e-06, ...), kolejnym krokiem jest wyodrębnienie kluczowego wskaźnika z każdej symulacji i przedstawienie go w formie graficznej, aby zilustrować tendencję. Typowym przykładem jest odczytanie napięcia w obwodzie otwartym \(V_{oc}\) z pliku sim_info.dat w każdym katalogu i przedstawienie go na wykresie w zależności od odwrotności ruchliwości \(1/\mu\).

Poniższy skrypt przeszukuje zdefiniowany zestaw katalogów, odpowiadających wartościom mobilności 1e-5, 1e-6, 1e-7, 1e-8, a dla każdego katalogu wykonuje następujące czynności:

  1. Wczytuje dane sim_info.dat w formacie JSON.
  2. Fragmenty Voc.
  3. Oblicza wartość \(1/\mu\) na podstawie mobilności powiązanej z danym katalogiem.
  4. Tworzy mały plik podsumowujący (voc_vs_inv_mobility.dat).
  5. Porównanie fabuł \(V_{oc}\) i \(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;