Scripting in MATLABScripting in MATLAB
1. Introduzione1. Introduzione
In OghmaNano, gli script MATLAB funzionano modificando direttamente i file di configurazione della simulazione presenti sul disco e quindi avviando il motore di simulazione (oghma_core.exe) per eseguire il modello. In questa sezione viene descritto nel dettaglio questo processo.In OghmaNano, gli script MATLAB funzionano modificando direttamente i file di configurazione della simulazione presenti sul disco e quindi avviando il motore di simulazione (oghma_core.exe) per eseguire il modello. In questa sezione viene descritto nel dettaglio questo processo.
2. Esecuzione di file di simulazione con MATLAB2. Esecuzione di file di simulazione con MATLAB
Una simulazione OghmaNano è definita interamente da un singolo file di configurazione in formato JSON, sim.json. Questo file contiene lo stato completo della simulazione, inclusa la struttura del dispositivo, i parametri dei materiali, le impostazioni numeriche e la configurazione dell’output. In molti casi, sim.json esiste già come file normale all’interno della directory della simulazione.Una simulazione OghmaNano è definita interamente da un singolo file di configurazione in formato JSON, sim.json. Questo file contiene lo stato completo della simulazione, inclusa la struttura del dispositivo, i parametri dei materiali, le impostazioni numeriche e la configurazione dell’output. In molti casi, sim.json esiste già come file normale all’interno della directory della simulazione.
Quando si esegue OghmaNano da MATLAB, lo script legge il file sim.json e lo carica in memoria utilizzando le funzionalità JSON di MATLAB, modifica uno o più parametri e quindi salva il file JSON aggiornato su disco.Quando si esegue OghmaNano da MATLAB, lo script legge il file sim.json e lo carica in memoria utilizzando le funzionalità JSON di MATLAB, modifica uno o più parametri e quindi salva il file JSON aggiornato su disco.
Fondamentalmente, MATLAB deve essere eseguito oghma_core.exe con la directory di lavoro impostata sulla directory di simulazione, ovvero la directory che contiene sim.json (e sim.oghma). Il motore di simulazione legge sempre i file di input dalla directory di lavoro corrente, quindi, se la directory di lavoro è errata, la simulazione fallirà o eseguirà il modello sbagliato.Fondamentalmente, MATLAB deve essere eseguito oghma_core.exe con la directory di lavoro impostata sulla directory di simulazione, ovvero la directory che contiene sim.json (e sim.oghma). Il motore di simulazione legge sempre i file di input dalla directory di lavoro corrente, quindi, se la directory di lavoro è errata, la simulazione fallirà o eseguirà il modello sbagliato.
Questa suddivisione delle responsabilità è intenzionale e ben definita: MATLAB è responsabile della definizione delle modifiche apportate alla simulazione, mentre OghmaNano è responsabile dell’esecuzione delle simulazioni fisiche utilizzando i file presenti nella directory corrente.Questa suddivisione delle responsabilità è intenzionale e ben definita: MATLAB è responsabile della definizione delle modifiche apportate alla simulazione, mentre OghmaNano è responsabile dell’esecuzione delle simulazioni fisiche utilizzando i file presenti nella directory corrente.
L’esempio riportato di seguito illustra questo processo caricando sim.json, modificando la mobilità dei portatori di carica del primo strato del dispositivo, salvando la configurazione aggiornata su disco e quindi eseguendo la simulazione dalla directory di simulazione.L’esempio riportato di seguito illustra questo processo caricando sim.json, modificando la mobilità dei portatori di carica del primo strato del dispositivo, salvando la configurazione aggiornata su disco e quindi eseguendo la simulazione dalla directory di simulazione.
% 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);
Se la simulazione in sim.json è configurata per generare una curva corrente-tensione (J–V), OghmaNano creerà dei file di output nella directory della simulazione, contenenti dati quali l’efficienza di conversione della potenza (PCE), il fattore di riempimento e i valori di \(J_{sc}\) e \(V_{oc}\).Se la simulazione in sim.json è configurata per generare una curva corrente-tensione (J–V), OghmaNano creerà dei file di output nella directory della simulazione, contenenti dati quali l’efficienza di conversione della potenza (PCE), il fattore di riempimento e i valori di \(J_{sc}\) e \(V_{oc}\).
3. Estrazione dei risultati3. Estrazione dei risultati
Molti dei file di output di OghmaNano sono scritti in formato JSON. Un metodo comune consiste nel leggere il file sim_info.dat, estrarre un valore scalare che rappresenta una metrica di qualità (ad esempio Voc) e aggiungerlo a un file di testo per un’analisi successiva.Molti dei file di output di OghmaNano sono scritti in formato JSON. Un metodo comune consiste nel leggere il file sim_info.dat, estrarre un valore scalare che rappresenta una metrica di qualità (ad esempio Voc) e aggiungerlo a un file di testo per un’analisi successiva.
L’esempio riportato di seguito legge il contenuto di sim_info.dat e aggiunge il valore di \(V_{oc}\) a un file di testo separato.L’esempio riportato di seguito legge il contenuto di sim_info.dat e aggiunge il valore di \(V_{oc}\) a un file di testo separato.
% 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. Simulazioni più complesse3. Simulazioni più complesse
In molti processi di scripting, potrebbe essere necessario eseguire la stessa simulazione di base più volte, utilizzando valori di parametri diversi, e mantenere ogni esecuzione isolata in una directory dedicata. Questo è il metodo più semplice per mantenere i risultati organizzati e per evitare di sovrascriverli accidentalmente.In molti processi di scripting, potrebbe essere necessario eseguire la stessa simulazione di base più volte, utilizzando valori di parametri diversi, e mantenere ogni esecuzione isolata in una directory dedicata. Questo è il metodo più semplice per mantenere i risultati organizzati e per evitare di sovrascriverli accidentalmente.
L’esempio riportato di seguito crea una serie di directory corrispondenti a quattro modalità di movimento (1e-5, 1e-6, 1e-7, 1e-8). Per ciascuna directory, vengono eseguite le seguenti operazioni:L’esempio riportato di seguito crea una serie di directory corrispondenti a quattro modalità di movimento (1e-5, 1e-6, 1e-7, 1e-8). Per ciascuna directory, vengono eseguite le seguenti operazioni:
- Crea la directory (se questa non esiste già).Crea la directory (se questa non esiste già).
- Copia il file
sim.jsoncorrente nella directory specificata.Copia il filesim.jsoncorrente nella directory specificata. - Modifica la copia di
sim.jsonper impostare la mobilità desiderata.Modifica la copia disim.jsonper impostare la mobilità desiderata. - Modifica la directory di lavoro impostandola sulla directory specificata.Modifica la directory di lavoro impostandola sulla directory specificata.
- Esegue il programma di risoluzione nella directory specificata, generando i risultati relativi a tale esecuzione.Esegue il programma di risoluzione nella directory specificata, generando i risultati relativi a tale esecuzione.
Questo schema costituisce la base per la creazione di script batch in OghmaNano: una directory per ogni esecuzione, un file di configurazione per ogni esecuzione e una cartella di output dedicata per ogni valore di parametro.Questo schema costituisce la base per la creazione di script batch in OghmaNano: una directory per ogni esecuzione, un file di configurazione per ogni esecuzione e una cartella di output dedicata per ogni valore di parametro.
% 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. Estrazione dei risultati4. Estrazione dei risultati
Dopo aver eseguito una serie di simulazioni in cartelle separate (ad esempio mu_1e-05, mu_1e-06, ...), il passo successivo consiste nell’estrarre un parametro chiave da ciascuna simulazione e visualizzare l’andamento. Un esempio comune è quello di leggere la tensione a circuito aperto \(V_{oc}\) da sim_info.dat in ciascuna cartella e rappresentarla graficamente in relazione alla mobilità inversa \(1/\mu\).Dopo aver eseguito una serie di simulazioni in cartelle separate (ad esempio mu_1e-05, mu_1e-06, ...), il passo successivo consiste nell’estrarre un parametro chiave da ciascuna simulazione e visualizzare l’andamento. Un esempio comune è quello di leggere la tensione a circuito aperto \(V_{oc}\) da sim_info.dat in ciascuna cartella e rappresentarla graficamente in relazione alla mobilità inversa \(1/\mu\).
Lo script riportato di seguito analizza una serie predefinita di directory, corrispondenti alle diverse modalità di funzionamento 1e-5, 1e-6, 1e-7, 1e-8, ed esegue le seguenti operazioni per ciascuna directory:Lo script riportato di seguito analizza una serie predefinita di directory, corrispondenti alle diverse modalità di funzionamento 1e-5, 1e-6, 1e-7, 1e-8, ed esegue le seguenti operazioni per ciascuna directory:
- Carica
sim_info.datin formato JSON.Caricasim_info.datin formato JSON. - Estratti
Voc.EstrattiVoc. - Calcola \(1/\mu\) utilizzando la mobilità associata a tale directory.Calcola \(1/\mu\) utilizzando la mobilità associata a tale directory.
- Crea un piccolo file di riepilogo (
voc_vs_inv_mobility.dat).Crea un piccolo file di riepilogo (voc_vs_inv_mobility.dat). - Confronto tra i grafici \(V_{oc}\) e \(1/\mu\).Confronto tra i grafici \(V_{oc}\) e \(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;