Σπίτι Παραδείγματα Στιγμιότυπα οθόνης Εγχειρίδιο χρήστη Λογότυπο της Bluesky YouTube ☰
OghmaNano Πλατφόρμα προσομοίωσης πολλαπλών φυσικών πεδίων για οπτοηλεκτρονικές συσκευές και φωτονικά συστήματα. Λήψη Οδηγός γρήγορης εκκίνησης

Δημιουργία σεναρίων MATLAB

1. Εισαγωγή

Στο OghmaNano, η δημιουργία σεναρίων MATLAB γίνεται μέσω της άμεσης επεξεργασίας των αρχείων διαμόρφωσης προσομοίωσης στον δίσκο και στη συνέχεια της ενεργοποίησης της μηχανής προσομοίωσης (oghma_core.exe) για την εκτέλεση του μοντέλου. Αυτή η ενότητα περιγράφει λεπτομερώς αυτή τη διαδικασία.

2. Εκτέλεση αρχείων προσομοίωσης με το MATLAB.

Μια προσομοίωση OghmaNano ορίζεται εξ ολοκλήρου από ένα μόνο αρχείο διαμόρφωσης JSON, sim.json. Αυτό το αρχείο περιέχει την πλήρη κατάσταση της προσομοίωσης, συμπεριλαμβανομένης της δομής της συσκευής, των παραμέτρων των υλικών, των αριθμητικών ρυθμίσεων και της διαμόρφωσης εξόδου. Σε πολλές περιπτώσεις, sim.json υπάρχει ήδη ως ένα κανονικό αρχείο μέσα στον κατάλογο της προσομοίωσης.

Όταν χρησιμοποιείτε το OghmaNano μέσω του MATLAB, το σενάριο διαβάζει το αρχείο sim.json στη μνήμη χρησιμοποιώντας τις δυνατότητες JSON του MATLAB, τροποποιεί μία ή περισσότερες παραμέτρους και αποθηκεύει την ενημερωμένη έκδοση του αρχείου 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-5, 1e-6, 1e-7, 1e-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-05, mu_1e-06, ...), το επόμενο βήμα είναι να εξαχθεί μια βασική παράμετρος απόδοσης από κάθε εκτέλεση και να απεικονιστεί η τάση. Ένα κοινό παράδειγμα είναι η ανάγνωση της τάσης ανοιχτού κυκλώματος \(V_{oc}\) από το αρχείο sim_info.dat σε κάθε κατάλογο και η γραφική της παράσταση σε σχέση με την αντίστροφη κινητικότητα \(1/\mu\).

Το παρακάτω σενάριο σαρώνει ένα καθορισμένο σύνολο καταλόγων, τα οποία αντιστοιχούν στις κινητικότητες 1e-5, 1e-6, 1e-7, 1e-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;