Home Examples Screenshots User manual Bluesky logo YouTube ☰
OghmaNano Multiphysics simulation platform for optoelectronic devices and photonic systems DOWNLOAD Quick Start guide

Programmation en langage de script MATLAB

1. Introduction

Dans OghmaNano, les scripts MATLAB fonctionnent en modifiant directement les fichiers de configuration de la simulation sur le disque, puis en lançant le moteur de simulation (oghma_core.exe) pour exécuter le modèle. Cette section décrit ce processus en détail.

2. Exécution de fichiers de simulation avec MATLAB.

Une simulation OghmaNano est entièrement définie par un seul fichier de configuration au format JSON, sim.json. Ce fichier contient l’état complet de la simulation, y compris la structure du dispositif, les paramètres des matériaux, les paramètres numériques et la configuration de la sortie. Dans de nombreux cas, sim.json existe déjà sous la forme d’un fichier normal dans le répertoire de la simulation.

Lorsque vous exécutez OghmaNano à partir de MATLAB, le script lit le fichier sim.json et l’enregistre en mémoire à l’aide de la fonction JSON de MATLAB, modifie un ou plusieurs paramètres, puis enregistre le fichier JSON mis à jour sur le disque.

Il est essentiel que MATLAB s’exécute oghma_core.exe avec son répertoire de travail défini sur le répertoire de simulation, c’est-à-dire le répertoire contenant sim.json (et sim.oghma). Le moteur de simulation lit toujours ses fichiers d’entrée à partir du répertoire de travail actuel. Par conséquent, si le répertoire de travail est incorrect, la simulation échouera ou exécutera le mauvais modèle.

Cette répartition des responsabilités est délibérée et clairement définie : MATLAB est chargé de déterminer les modifications à apporter à la simulation, tandis qu’OghmaNano est chargé d’exécuter les calculs physiques en utilisant les fichiers présents dans le répertoire courant.

L’exemple ci-dessous illustre ce processus en chargeant sim.json, en modifiant la mobilité des porteurs de la première couche du dispositif, en enregistrant la configuration mise à jour sur le disque, puis en exécutant la simulation à partir du répertoire de simulation.


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

Si la simulation dans sim.json est configurée pour générer une courbe J–V, OghmaNano créera des fichiers de sortie dans le répertoire de la simulation, qui contiendront des données telles que le rendement de conversion de puissance (PCE), le facteur de remplissage, \(J_{sc}\) et \(V_{oc}\).

3. Extraction des résultats.

De nombreux fichiers de sortie d’OghmaNano sont écrits au format JSON. Une pratique courante consiste à lire le fichier sim_info.dat, à extraire une valeur numérique représentative (par exemple, Voc) et à l’ajouter à un fichier texte en vue d’une analyse ultérieure.

L’exemple ci-dessous lit la valeur de sim_info.dat et ajoute la valeur de \(V_{oc}\) à un fichier texte distinct.


% 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. Simulations plus complexes.

Dans de nombreux processus d’exécution de scripts, vous voudrez exécuter la même simulation de base plusieurs fois, en utilisant différentes valeurs de paramètres, et conserver chaque exécution dans un répertoire distinct. C’est la méthode la plus simple pour obtenir des résultats clairs et éviter d’écraser accidentellement des données.

L’exemple ci-dessous crée un ensemble de répertoires correspondant à quatre types de mobilité (1e-5, 1e-6, 1e-7, 1e-8). Pour chaque répertoire, il effectue les opérations suivantes :

  1. Crée le répertoire (s’il n’existe pas déjà).
  2. Copie le fichier sim.json actuel dans ce répertoire.
  3. Modifie la copie de sim.json pour définir la mobilité cible.
  4. Modifie le répertoire de travail pour qu’il corresponde au répertoire spécifié.
  5. Exécute le programme de résolution dans ce répertoire, ce qui génère des résultats spécifiques à cette exécution.

Ce modèle constitue la base du script en mode batch dans OghmaNano : un répertoire par exécution, un fichier de configuration par exécution et un dossier de résultats propre pour chaque valeur de paramètre.


% 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. Extraction des résultats

Après avoir exécuté une série de simulations dans des répertoires distincts (par exemple, mu_1e-05, mu_1e-06, ...), l’étape suivante consiste à extraire une valeur clé de chaque simulation et à visualiser la tendance. Un exemple courant consiste à lire la tension en circuit ouvert \(V_{oc}\) à partir de sim_info.dat dans chaque répertoire et à la représenter graphiquement en fonction de la mobilité inverse \(1/\mu\).

Le script ci-dessous analyse un ensemble prédéfini de répertoires correspondant aux valeurs de mobilité 1e-5, 1e-6, 1e-7, 1e-8, et pour chaque répertoire :

  1. Charge les données sim_info.dat au format JSON.
  2. Extrait(s) Voc.
  3. Calcule \(1/\mu\) en utilisant la mobilité associée à ce répertoire.
  4. Crée un petit fichier récapitulatif (voc_vs_inv_mobility.dat).
  5. Comparaison des graphiques \(V_{oc}\) et \(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;