Створення сценаріїв на Python.
1. Вступ
У OghmaNano сценарії Python виконуються шляхом безпосередньої зміни файлів конфігурації моделювання, що зберігаються на диску, а потім запуску рушія моделювання (oghma_core.exe) для виконання моделі. У цьому розділі детально описано цей процес.
2. Запуск файлів моделювання за допомогою Python.
Моделювання в OghmaNano повністю визначається одним файлом конфігурації у форматі JSON, sim.json. Цей файл містить повний стан моделювання, включно зі структурою пристрою, параметрами матеріалів, числовими налаштуваннями та конфігурацією вихідних даних. У багатьох випадках sim.json вже існує як звичайний файл у каталозі моделювання.
Під час керування OghmaNano з використанням Python, скрипт зчитує дані sim.json в пам’ять за допомогою стандартної бібліотеки Python json, змінює один або кілька параметрів і записує оновлений JSON-файл на диск.
Найважливіше, що скрипт Python має бути запущений із правильно вказаною робочою директорією, яка має відповідати директорії моделювання, тобто директорії, що містить sim.json (і sim.oghma). Саме з цієї директорії запускається oghma_core.exe.
Після оновлення файлу JSON, скрипт запускає oghma_core.exe з тієї ж самої директорії. Механізм моделювання завжди зчитує вхідні файли з поточної робочої директорії, тому, якщо робоча директорія вказана неправильно, моделювання не вдасться або буде запущено не той варіант моделі.
Такий розподіл обов’язків є навмисним і чітко визначеним: Python відповідає за визначення того, які зміни відбуваються в моделюванні, а OghmaNano відповідає за виконання фізичних розрахунків на основі файлів, що містяться в поточній директорії.
Наведений нижче приклад демонструє цей процес шляхом завантаження sim.json, зміни рухливості носіїв заряду в першому шарі пристрою, збереження оновленої конфігурації на диск, а потім запуску моделювання з каталогу моделювання.
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")
Якщо в симуляції sim.json налаштовано отримання кривої залежності струму від напруги (J–V), OghmaNano створить вихідні файли в каталозі симуляції, які міститимуть такі параметри, як ККД, коефіцієнт заповнення, \(J_{sc}\) і \(V_{oc}\).
На прикладі нижче показано, як зчитати файл у форматі JSON і додати значення \(V_{oc}\) до окремого текстового файлу.
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. Складніші моделювання.
У багатьох сценаріях автоматизації процесів вам знадобиться кілька разів запускати одну й ту саму базову симуляцію з різними значеннями параметрів і зберігати результати кожного запуску в окремій папці. Це найпростіший спосіб забезпечити охайність результатів і запобігти випадковому перезапису даних.
Наведений нижче приклад створює набір каталогів, що відповідають чотирьом типам мобільності (1e-5, 1e-6, 1e-7, 1e-8). Для кожного каталогу він:
- Створює каталог (якщо він ще не існує).
- Копіює поточний файл
sim.jsonдо вказаної директорії. - Редагує скопійований
sim.json, щоб задати цільову швидкість переміщення. - Змінює поточну робочу директорію на вказану.
- Запускає програму для розв’язання задач у вказаній директорії, генеруючи результати, які зберігаються локально для цього конкретного запуску.
Ця схема є основою для пакетного скриптингу в OghmaNano: для кожного запуску використовується окрема директорія, окремий файл конфігурації та окрема папка для виводу результатів для кожного значення параметра.
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)
Після виконання кожної ітерації, у відповідній папці будуть міститися результати, що відповідають заданому значенню параметра рухливості. У наступному розділі ми розширимо цей скрипт, щоб зібрати основні результати з кожної ітерації та об’єднати їх в один зведений файл.
Побудова графіка \(V_{oc}\) у залежності від оберненої величини рухливості.
Після того, як ви запустили серію симуляцій в окремих папках, наступним кроком зазвичай є отримання ключового показника ефективності для кожної симуляції та візуалізація отриманої тенденції. Типовим прикладом є зчитування значення напруги розімкнутого контуру \(V_{oc}\) з файлу JSON (sim_info.dat) і відображення його у вигляді графіка залежності від оберненої рухливості \(1/\mu\).
Наведений нижче скрипт перевіряє набір каталогів, що використовуються для виконання програм (наприклад, mu_1e-05, mu_1e-06...) і для кожного каталогу:
- Завантажити
sim_info.datу форматі JSON. - Уривки
Voc. - Обчислює \(1/\mu\) на основі показника мобільності, пов’язаного з цією директорією.
- Створює невеликий файл із підсумковою інформацією (
voc_vs_inv_mobility.dat). - Порівняння графіків \(V_{oc}\) та \(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()
📺 Пов’язане відео
У наведеному нижче відео демонструється, як можна керувати OghmaNano за допомогою сценаріїв, написаних мовою Python.
Примітка: API та внутрішній інтерфейс сценаріїв, показані у відео, зараз застаріли та більше не використовуються, оскільки виявилося, що їх важко підтримувати. Наразі рекомендується використовувати зовнішній скрипт Python для безпосередньої зміни файлів JSON, що використовуються для моделювання, а потім викликати oghma_core.exe. Цей підхід простіший, надійніший і легший у підтримці. Ви все ще можете знайти відео корисним для розуміння загального процесу та типових сценаріїв використання, але для отримання інформації про сучасний метод, будь ласка, дотримуйтеся описаних вище інструкцій.