Scripting em Python
1. Introdução
No OghmaNano, o scripting em Python funciona editando diretamente os arquivos de configuração da simulação em disco
e então invocando o mecanismo de simulação (oghma_core.exe) para executar o modelo.
Esta seção descreve esse fluxo de trabalho em detalhe.
2. Executando arquivos de simulação com Python
Uma simulação do OghmaNano é definida inteiramente por um único arquivo de configuração JSON,
sim.json.
Esse arquivo contém o estado completo da simulação, incluindo a estrutura do dispositivo,
os parâmetros de material, as configurações numéricas e a configuração de saída.
Em muitos casos, sim.json já existe como um arquivo normal dentro do diretório da simulação.
Ao controlar o OghmaNano a partir de Python, o script lê sim.json na memória usando a
biblioteca padrão json do Python, modifica um ou mais parâmetros e grava o JSON atualizado
de volta em disco.
Crucialmente, o script Python deve ser executado com seu diretório de trabalho definido como o
diretório da simulação — isto é, o diretório que contém sim.json (e
sim.oghma).
Esse é o diretório a partir do qual oghma_core.exe é iniciado.
Uma vez que o arquivo JSON tenha sido atualizado, o script inicia oghma_core.exe
a partir desse mesmo diretório.
O mecanismo de simulação sempre lê seus arquivos de entrada a partir do diretório de trabalho atual,
portanto, se o diretório de trabalho estiver incorreto, a simulação falhará ou executará o modelo errado.
Essa separação de responsabilidades é intencional e explícita: Python é responsável por definir o que muda na simulação, enquanto o OghmaNano é responsável por executar a física usando os arquivos presentes no diretório atual.
O exemplo abaixo demonstra esse processo carregando sim.json, modificando a mobilidade de
portadores da primeira camada do dispositivo, gravando a configuração atualizada de volta em disco e então
executando a simulação a partir do diretório da simulação.
import json
import os
import sys
f=open('sim.json') #abrir o arquivo sim.json
lines=f.readlines()
f.close()
lines="".join(lines) #converter o texto em um objeto json do python
data = json.loads(lines)
#Editar um valor (use o firefox como visualizador json
# para ajudar a descobrir qual valor editar)
# desta vez estamos editando a mobilidade da camada 1
data['epitaxy']['segment1']['shape_dos']['mue_y']=1.0
#converter o objeto json de volta em string
jstr = json.dumps(data, sort_keys=False, indent='\t')
#gravá-lo de volta em disco
f=open('sim.json',"w")
f.write(jstr)
f.close()
#executar a simulação usando oghma_core
os.system("oghma_core.exe")
Se a simulação em sim.json estiver configurada para executar uma curva J–V, o OghmaNano gravará arquivos de saída no
diretório da simulação contendo quantidades como PCE, fator de preenchimento, \(J_{sc}\) e
\(V_{oc}\).
O exemplo abaixo mostra como ler um arquivo de saída JSON e anexar o valor de \(V_{oc}\) a um arquivo de texto separado.
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. Simulações mais complexas
Em muitos fluxos de trabalho com scripting, você desejará executar a mesma simulação base várias vezes com diferentes valores de parâmetro e manter cada execução isolada em seu próprio diretório. Essa é a forma mais simples de manter as saídas organizadas e evitar sobrescrever acidentalmente os resultados.
O exemplo abaixo cria um conjunto de diretórios correspondentes a quatro mobilidades
(1e-5, 1e-6, 1e-7, 1e-8). Para cada diretório ele:
- Cria o diretório (se ele ainda não existir).
- Copia o
sim.jsonatual para esse diretório. - Edita o
sim.jsoncopiado para definir a mobilidade alvo. - Muda o diretório de trabalho para esse diretório.
- Executa o solver nesse diretório, produzindo saídas locais para essa execução.
Esse padrão é a base do scripting em lote no OghmaNano: um diretório por execução, um arquivo de configuração por execução e uma pasta de saída limpa para cada valor de parâmetro.
import json
import os
import shutil
# O script deve ser iniciado no diretório base da simulação
# (ou seja, o diretório que contém o sim.json de referência).
base_dir = os.getcwd()
mobilities = [1e-5, 1e-6, 1e-7, 1e-8]
for mu in mobilities:
# Criar um nome de diretório fácil de ler e que ordene bem
run_dir = os.path.join(base_dir, f"mu_{mu:.0e}")
os.makedirs(run_dir, exist_ok=True)
# Copiar o sim.json base para o diretório da execução
src_sim = os.path.join(base_dir, "sim.json")
dst_sim = os.path.join(run_dir, "sim.json")
shutil.copyfile(src_sim, dst_sim)
# Carregar o sim.json copiado e editar a mobilidade NESSA cópia
f = open(dst_sim)
lines = f.readlines()
f.close()
lines = "".join(lines)
data = json.loads(lines)
# Editar um valor: definir a mobilidade da primeira camada do dispositivo
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()
# Mudar para o diretório da execução e executar o solver lá
os.chdir(run_dir)
# Se o seu comando for "augment.nano" em vez disso, substitua a string abaixo.
os.system("oghma_core.exe")
# Voltar ao diretório base para a próxima execução
os.chdir(base_dir)
Após a execução, cada diretório conterá as saídas correspondentes àquele valor de mobilidade. Na próxima seção, estenderemos esse script para coletar resultados-chave de cada execução e agregá-los em um único arquivo de resumo.
Plotando \(V_{oc}\) contra a mobilidade inversa
Depois de executar um lote de simulações em diretórios separados, o próximo passo normalmente é extrair uma figura de
mérito chave de cada execução e visualizar a tendência. Um exemplo comum é ler a tensão de circuito aberto
\(V_{oc}\) a partir do arquivo de saída JSON (sim_info.dat) e plotá-la contra
a mobilidade inversa \(1/\mu\).
O script abaixo varre um conjunto de diretórios de execução (por exemplo mu_1e-05, mu_1e-06, ...)
e, para cada diretório:
- Carrega
sim_info.datcomo JSON. - Extrai
Voc. - Calcula \(1/\mu\) usando a mobilidade associada àquele diretório.
- Grava um pequeno arquivo de resumo (
voc_vs_inv_mobility.dat). - Plota \(V_{oc}\) vs \(1/\mu\).
import json
import os
# Opcional: plotagem (requer matplotlib)
import matplotlib.pyplot as plt
base_dir = os.getcwd()
# As mobilidades devem corresponder aos diretórios de execução gerados anteriormente
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")
# Ler o arquivo de saída JSON e extrair 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)
# Gravar uma pequena tabela de resumo em disco
out = open("voc_vs_inv_mobility.dat", "w")
out.write("# mobilidade_inversa(1/mu) Voc(V)\n")
for x, y in zip(inv_mu, vocs):
out.write(f"{x:.6e} {y}\n")
out.close()
# Plotar Voc contra a mobilidade inversa
plt.plot(inv_mu, vocs, "o-")
plt.xlabel("Mobilidade inversa (1/μ)")
plt.ylabel("Tensão de circuito aberto Voc (V)")
plt.title("Voc vs mobilidade inversa")
plt.grid(True)
plt.tight_layout()
plt.show()
📺 Vídeo relacionado
O vídeo abaixo demonstra como o OghmaNano pode ser controlado usando scripting em Python.
Nota: A API e a interface interna de scripting mostradas no vídeo agora estão obsoletas e não são mais
distribuídas, pois provaram ser difíceis de manter. O fluxo de trabalho atual e recomendado é usar um script Python
externo para editar diretamente os arquivos JSON da simulação e então invocar oghma_core.exe. Essa abordagem é
mais simples, mais robusta e mais fácil de manter. Você ainda pode achar o vídeo útil para entender o fluxo de trabalho geral e os casos de uso típicos, mas para o
método atualizado siga as etapas descritas acima.