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

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:

  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.


       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:

  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\).

       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.

Erstellung eines Python-Skripts zur Simulation einer Perowskit-Solarzelle in OghmaNano.