Python 스크립팅
1. 소개
OghmaNano에서 Python 스크립팅은 디스크에 있는 시뮬레이션 구성 파일을 직접 편집한 뒤
시뮬레이션 엔진(oghma_core.exe)을 호출하여 모델을 실행하는 방식으로 동작합니다.
이 절에서는 이 워크플로를 자세히 설명합니다.
2. Python으로 시뮬레이션 파일 실행하기
OghmaNano 시뮬레이션은 단일 JSON 구성 파일
sim.json으로 완전히 정의됩니다.
이 파일에는 소자 구조,
재료 파라미터, 수치 설정, 출력 구성을 포함한
시뮬레이션의 전체 상태가 들어 있습니다.
많은 경우 sim.json은 이미 시뮬레이션 디렉터리 내부에 일반 파일로 존재합니다.
Python에서 OghmaNano를 구동할 때 스크립트는 Python의 표준
json 라이브러리를 사용하여 sim.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') #sim.json 파일 열기
lines=f.readlines()
f.close()
lines="".join(lines) #텍스트를 Python JSON 객체로 변환
data = json.loads(lines)
#값 편집하기(Firefox를 JSON 뷰어로 사용하면
# 어떤 값을 편집해야 하는지 파악하는 데 도움이 됩니다)
# 여기서는 layer 1의 이동도를 편집합니다
data['epitaxy']['segment1']['shape_dos']['mue_y']=1.0
#JSON 객체를 다시 문자열로 변환
jstr = json.dumps(data, sort_keys=False, indent='\t')
#다시 디스크에 쓰기
f=open('sim.json',"w")
f.write(jstr)
f.close()
#oghma_core를 사용해 시뮬레이션 실행
os.system("oghma_core.exe")
sim.json의 시뮬레이션이 J–V 곡선을 실행하도록 설정되어 있다면, OghmaNano는
시뮬레이션 디렉터리에 PCE, 충전율, \(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
# 스크립트는 기준 시뮬레이션 디렉터리에서 시작되어야 합니다
# (즉, 기준 sim.json이 들어 있는 디렉터리).
base_dir = os.getcwd()
mobilities = [1e-5, 1e-6, 1e-7, 1e-8]
for mu in mobilities:
# 읽기 쉽고 정렬도 잘 되는 디렉터리 이름 생성
run_dir = os.path.join(base_dir, f"mu_{mu:.0e}")
os.makedirs(run_dir, exist_ok=True)
# 기준 sim.json을 실행 디렉터리로 복사
src_sim = os.path.join(base_dir, "sim.json")
dst_sim = os.path.join(run_dir, "sim.json")
shutil.copyfile(src_sim, dst_sim)
# 복사된 sim.json을 불러와 THAT copy에서 이동도 편집
f = open(dst_sim)
lines = f.readlines()
f.close()
lines = "".join(lines)
data = json.loads(lines)
# 값 편집: 첫 번째 소자 층의 이동도 설정
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()
# 실행 디렉터리로 이동하여 այնտեղ서 해석기 실행
os.chdir(run_dir)
# 명령이 "augment.nano"인 경우 아래 문자열을 바꾸십시오.
os.system("oghma_core.exe")
# 다음 실행을 위해 기준 디렉터리로 복귀
os.chdir(base_dir)
실행 후에는 각 디렉터리에 해당 이동도 값에 대응하는 출력이 포함됩니다. 다음 절에서는 이 스크립트를 확장하여 각 실행의 핵심 결과를 수집하고 하나의 요약 파일로 집계할 것입니다.
\(V_{oc}\)를 역이동도에 대해 플로팅하기
분리된 디렉터리에서 시뮬레이션 배치를 실행한 뒤 다음 단계는 보통
각 실행에서 핵심 성능 지표 하나를 추출하여 추세를 시각화하는 것입니다.
흔한 예는 JSON 출력 파일(sim_info.dat)에서 개방회로 전압
\(V_{oc}\)를 읽고 이를
역이동도 \(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
# 선택 사항: 플로팅(matplotlib 필요)
import matplotlib.pyplot as plt
base_dir = os.getcwd()
# 이동도 값은 앞서 생성한 실행 디렉터리와 일치해야 합니다
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")
# JSON 출력 파일을 읽고 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)
# 작은 요약 표를 디스크에 기록
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()
# 역이동도에 대해 Voc 플로팅
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()
📺 관련 동영상
아래 동영상은 Python 스크립팅을 사용하여 OghmaNano를 구동하는 방법을 보여줍니다.
참고: 동영상에 나오는 API 및 내부 스크립팅 인터페이스는 현재 폐기되었으며 더 이상
제공되지 않습니다. 유지보수가 어렵다는 점이 확인되었기 때문입니다. 현재 권장되는 워크플로는 외부 Python
스크립트를 사용하여 JSON 시뮬레이션 파일을 직접 편집한 다음 oghma_core.exe를 호출하는 것입니다. 이 방식은
더 단순하고, 더 견고하며, 유지보수가 더 쉽습니다. 동영상은 전체적인 워크플로와 일반적인 사용 사례를 이해하는 데에는 여전히 도움이 될 수 있지만, 최신 방법은
위에 설명된 절차를 따르십시오.