Python-Skripting
1. Einleitung
In OghmaNano funktioniert die Verwendung von Python-Skripten, 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 Python 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 Python gesteuert wird, liest das Skript sim.json mithilfe der Standardbibliothek json von Python in den Speicher, ändert einen oder mehrere Parameter und schreibt die aktualisierte JSON-Datei wieder auf die Festplatte.
Entscheidend ist, dass das Python-Skript mit dem Simulationsverzeichnis als Arbeitsverzeichnis ausgeführt werden muss – also dem Verzeichnis, das sim.json (und sim.oghma) enthält. Von diesem Verzeichnis aus wird oghma_core.exe gestartet.
Sobald die JSON-Datei aktualisiert wurde, startet das Skript oghma_core.exe aus demselben Verzeichnis. Die Simulations-Engine 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: Python 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.
import json
import os
import sys
f=open('sim.json') #open the sim.json file
lines=f.readlines()
f.close()
lines="".join(lines) #convert the text to a python json object
data = json.loads(lines)
#Edit a value (use firefox as a json viewer
# to help you figure out which value to edit)
# this time we are editing the mobility of layer 1
data['epitaxy']['segment1']['shape_dos']['mue_y']=1.0
#convert the json object back to a string
jstr = json.dumps(data, sort_keys=False, indent='\t')
#write it back to disk
f=open('sim.json',"w")
f.write(jstr)
f.close()
#run the simulation using oghma_core
os.system("oghma_core.exe")
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.
Das folgende Beispiel zeigt, wie man eine JSON-Ausgabedatei liest und den Wert von \(V_{oc}\) an eine separate Textdatei anhängt.
f=open('sim_info.dat')
lines=f.readlines()
f.close()
lines="".join(lines)
data = json.loads(lines)
f=open('out.dat',"a")
f.write(str(data["Voc"])+"\n");
f.close()
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:
- Erstellt das Verzeichnis (falls es noch nicht vorhanden ist).
- Kopiert die aktuelle
sim.json-Datei in dieses Verzeichnis. - Bearbeitet die kopierte
sim.json-Datei, um die gewünschte Mobilität einzustellen. - Ändert das aktuelle Arbeitsverzeichnis in das angegebene Verzeichnis.
- 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.
import json
import os
import shutil
# The script must be started in the base simulation directory
# (i.e. the directory containing the reference sim.json).
base_dir = os.getcwd()
mobilities = [1e-5, 1e-6, 1e-7, 1e-8]
for mu in mobilities:
# Create a directory name that is easy to read and sorts nicely
run_dir = os.path.join(base_dir, f"mu_{mu:.0e}")
os.makedirs(run_dir, exist_ok=True)
# Copy the base sim.json into the run directory
src_sim = os.path.join(base_dir, "sim.json")
dst_sim = os.path.join(run_dir, "sim.json")
shutil.copyfile(src_sim, dst_sim)
# Load the copied sim.json and edit the mobility in THAT copy
f = open(dst_sim)
lines = f.readlines()
f.close()
lines = "".join(lines)
data = json.loads(lines)
# Edit a value: set the mobility for the first device layer
data['epitaxy']['segment1']['shape_dos']['mue_y'] = mu
jstr = json.dumps(data, sort_keys=False, indent='\t')
f = open(dst_sim, "w")
f.write(jstr)
f.close()
# Change into the run directory and execute the solver there
os.chdir(run_dir)
# If your command is "augment.nano" instead, replace the string below.
os.system("oghma_core.exe")
# Return to the base directory for the next run
os.chdir(base_dir)
Nach der Ausführung enthält jedes Verzeichnis die Ausgaben, die dem jeweiligen Mobilitätswert entsprechen. Im nächsten Abschnitt werden wir dieses Skript erweitern, um die wichtigsten Ergebnisse jeder Ausführung zu sammeln und in einer einzigen zusammenfassenden Datei zusammenzuführen.
Darstellung von \(V_{oc}\) in Abhängigkeit vom Kehrwert der Beweglichkeit.
Sobald Sie eine Reihe von Simulationen in separaten Verzeichnissen durchgeführt haben, besteht der nächste Schritt in der Regel 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 der JSON-Ausgabedatei (sim_info.dat) und das Darstellen dieser in einem Diagramm in Abhängigkeit von der inversen Beweglichkeit \(1/\mu\).
Das folgende Skript durchsucht eine Reihe von Verzeichnissen (z. B. mu_1e-05, mu_1e-06, ...) und führt für jedes Verzeichnis Folgendes aus:
- Lädt
sim_info.datals JSON-Datei. - Auszüge
Voc. - Berechnet \(1/\mu\) anhand der Mobilität, die dem jeweiligen Verzeichnis zugeordnet ist.
- Erstellt eine kleine Zusammenfassungsdatei (
voc_vs_inv_mobility.dat). - Diagramme \(V_{oc}\) im Vergleich zu \(1/\mu\).
import json
import os
# Optional: plotting (requires matplotlib)
import matplotlib.pyplot as plt
base_dir = os.getcwd()
# Mobilities must match the run directories you generated earlier
mobilities = [1e-5, 1e-6, 1e-7, 1e-8]
inv_mu = []
vocs = []
for mu in mobilities:
run_dir = os.path.join(base_dir, f"mu_{mu:.0e}")
info_path = os.path.join(run_dir, "sim_info.dat")
# Read the JSON output file and extract Voc
f = open(info_path)
lines = f.readlines()
f.close()
lines = "".join(lines)
data = json.loads(lines)
voc = data["Voc"]
inv_mu.append(1.0 / mu)
vocs.append(voc)
# Write a small summary table to disk
out = open("voc_vs_inv_mobility.dat", "w")
out.write("# inv_mobility(1/mu) Voc(V)\n")
for x, y in zip(inv_mu, vocs):
out.write(f"{x:.6e} {y}\n")
out.close()
# Plot Voc against inverse mobility
plt.plot(inv_mu, vocs, "o-")
plt.xlabel("Inverse mobility (1/μ)")
plt.ylabel("Open-circuit voltage Voc (V)")
plt.title("Voc vs inverse mobility")
plt.grid(True)
plt.tight_layout()
plt.show()
📺 Verwandtes Video
Das folgende Video zeigt, wie OghmaNano mithilfe von Python-Skripten gesteuert werden kann.
Hinweis: Die im Video gezeigte API und die interne Skriptschnittstelle sind veraltet und werden nicht mehr bereitgestellt, da sich ihre Wartung als schwierig erwiesen hat. Der aktuelle und empfohlene Arbeitsablauf besteht darin, ein externes Python-Skript zu verwenden, um die JSON-Simulationsdateien direkt zu bearbeiten und anschließend oghma_core.exe aufzurufen. Dieser Ansatz ist einfacher, robuster und lässt sich leichter warten. Das Video kann weiterhin nützlich sein, um den allgemeinen Arbeitsablauf und typische Anwendungsfälle zu verstehen, aber für die aktuelle Methode befolgen Sie bitte die oben beschriebenen Schritte.