Startseite Beispiele Screenshots Benutzerhandbuch Bluesky-Logo YouTube ☰
OghmaNano Simulation von organischen/Perowskit-Solarzellen, OFETs und OLEDs DOWNLOAD Quick Start guide

MATLAB-Skriptprogrammierung

1. Einleitung

In OghmaNano funktioniert die MATLAB-Skripterstellung, indem die Konfigurationsdateien der Simulation direkt auf der Festplatte bearbeitet und anschließend die Simulations-Engine (oghma_core.exe) aufgerufen wird, um das Modell auszuführen. In diesem Abschnitt wird dieser Arbeitsablauf detailliert beschrieben.

2. Simulationsdateien mit MATLAB ausführen

Eine OghmaNano-Simulation wird vollständig durch eine einzige JSON-Konfigurationsdatei sim.json definiert. Diese Datei enthält den vollständigen Zustand der Simulation, einschließlich der Gerätearchitektur, der Materialparameter, der numerischen Einstellungen und der Ausgabekonfiguration. In vielen Fällen sim.json existiert diese Datei bereits als normale Datei innerhalb des Simulationsverzeichnisses.

Wenn OghmaNano über MATLAB gesteuert wird, liest das Skript sim.json mithilfe der JSON-Funktionalität von MATLAB in den Speicher, ändert einen oder mehrere Parameter und speichert die aktualisierte JSON-Datei wieder auf der Festplatte.

Entscheidend ist, dass MATLAB oghma_core.exe mit dem Simulationsverzeichnis als aktuellem Arbeitsverzeichnis ausgeführt werden muss – also dem Verzeichnis, das sim.json (und sim.oghma) enthält. Die Simulationssoftware liest ihre Eingabedateien immer aus dem aktuellen Arbeitsverzeichnis. Wenn das Arbeitsverzeichnis falsch ist, schlägt die Simulation fehl oder es wird das falsche Modell ausgeführt.

Diese Aufteilung der Verantwortlichkeiten ist bewusst und explizit: MATLAB ist dafür zuständig, festzulegen, welche Änderungen in der Simulation vorgenommen werden, während OghmaNano die physikalische Berechnung unter Verwendung der in dem aktuellen Verzeichnis vorhandenen Dateien durchführt.

Das folgende Beispiel veranschaulicht diesen Prozess, indem es sim.json lädt, die Trägermobilität der ersten Geräteschicht modifiziert, die aktualisierte Konfiguration auf der Festplatte speichert und anschließend die Simulation aus dem Simulationsverzeichnis ausführt.


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

Wenn die Simulation in sim.json so eingerichtet ist, dass eine J–V-Kurve berechnet wird, erstellt OghmaNano Ausgabedateien im Simulationsverzeichnis, die Größen wie den Wirkungsgrad, den Füllfaktor, \(J_{sc}\) und \(V_{oc}\) enthalten.

3. Ergebnisse extrahieren

Viele der von OghmaNano erstellten Ausgabedateien sind im JSON-Format gespeichert. Ein gängiges Verfahren besteht darin, sim_info.dat auszulesen, einen einzelnen, aussagekräftigen Wert zu extrahieren (zum Beispiel Voc) und diesen einer Textdatei hinzuzufügen, um ihn später zu analysieren.

Das folgende Beispiel liest sim_info.dat und fügt den Wert von \(V_{oc}\) einer separaten Textdatei hinzu.


% 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. Komplexere Simulationen

In vielen Skript-basierten Arbeitsabläufen möchten Sie möglicherweise die gleiche Basissimulation mehrmals mit unterschiedlichen Parameterwerten ausführen und jede Ausführung in einem eigenen Verzeichnis isoliert speichern. Dies ist die einfachste Methode, um übersichtliche Ergebnisse zu erzielen und zu verhindern, dass Ergebnisse versehentlich überschrieben werden.

Das folgende Beispiel erstellt eine Reihe von Verzeichnissen, die den vier Mobilitätsarten (1e-5, 1e-6, 1e-7, 1e-8) entsprechen. Für jedes Verzeichnis werden folgende Schritte ausgeführt:

  1. Erstellt das Verzeichnis (falls es noch nicht vorhanden ist).
  2. Kopiert die aktuelle sim.json-Datei in dieses Verzeichnis.
  3. Bearbeitet die kopierte sim.json-Datei, um die gewünschte Mobilität einzustellen.
  4. Ändert das aktuelle Arbeitsverzeichnis in das angegebene Verzeichnis.
  5. Führt den Solver in diesem Verzeichnis aus und erzeugt Ausgabedateien, die für diese Ausführung spezifisch sind.

Dieses Muster bildet die Grundlage für die Batch-Skripterstellung in OghmaNano: Für jeden Durchlauf wird ein eigenes Verzeichnis, eine eigene Konfigurationsdatei und ein eigener, leerer Ausgabeordner für jeden Parametersatz verwendet.


% 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. Ergebnisse extrahieren

Nachdem eine Reihe von Simulationen in separaten Verzeichnissen durchgeführt wurden (z. B. mu_1e-05, mu_1e-06, ...), besteht der nächste Schritt darin, eine wichtige Kennzahl aus jeder Simulation zu extrahieren und den Trend grafisch darzustellen. Ein gängiges Beispiel ist das Auslesen der Leerlaufspannung \(V_{oc}\) aus sim_info.dat in jedem Verzeichnis und das anschließende Aufzeichnen dieser Werte in Abhängigkeit von der inversen Beweglichkeit \(1/\mu\).

Das folgende Skript durchsucht eine vordefinierte Menge von Verzeichnissen, die den Mobilitätswerten 1e-5, 1e-6, 1e-7, 1e-8 entsprechen, und führt für jedes Verzeichnis Folgendes aus:

  1. Lädt sim_info.dat als JSON-Datei.
  2. Auszüge Voc.
  3. Berechnet \(1/\mu\) anhand der Mobilität, die dem jeweiligen Verzeichnis zugeordnet ist.
  4. Erstellt eine kleine Zusammenfassungsdatei (voc_vs_inv_mobility.dat).
  5. Diagramme \(V_{oc}\) im Vergleich zu \(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;