OghmaNanoにおける電気的ニュートンソルバーのLuaスクリプト制御
1. はじめに
OghmaNanoには組み込みのLuaスクリプトインターフェースが備わっており、実行時において内部の数値計算ソルバーを変更することが可能である。これにより、各種方程式の有効化/無効化、3次元ニュートンソルバーの調整、過渡状態やJ–Vスキャン時における特定の物理モデルの固定化、さらには独自の反復計算戦略の実装といった高度な制御が行える。
これは外部スクリプト処理とは異なる。Pythonのような言語はsim.jsonを変更した上でソルバーを起動することで機能するため、パラメータスイープやバッチ処理、後処理に適している。
一方、Luaはソルバー内部で動作し、基盤となるC言語コードを変更することなく数値計算の流れに直接介入することが可能である。
2. Luaとは何か?
Luaは軽量かつ高性能なスクリプト言語であり、大規模なアプリケーション内に組み込むことを目的として設計されている。ゲームエンジンや科学計算用ソフトウェアなど、コアコードを再コンパイルすることなく内部動作を変更する必要がある分野で広く利用されている。Pythonと比較してLuaはメモリ消費量がはるかに少なく、実行時のオーバーヘッドも低いため、性能が極めて重要となるループ処理においても適している。C言語と比較しても記述や修正がはるかに容易でありながら、プログラムの振る舞いを細かく制御することも可能だ。こうした特性からLuaはOghmaNanoに最適な言語であり、実行時において数値計算用ソルバーの挙動を直接制御するために用いられている。
Luaに馴染みがない方のために、典型的なバブルソートの実装例を紹介します。
a = {5, 3, 8, 1, 2}
n = #a
for i = 1, n do
for j = 1, n - i do
if a[j] > a[j+1] then
a[j], a[j+1] = a[j+1], a[j]
end
end
end
2. Luaスクリプトエディタへのアクセス方法
OghmaNanoのLuaスクリプトエディタは、メインウィンドウの電気系リボンからアクセス可能であり、その様子は??に示されている。ドリフト拡散ソルバー制御機能の隣にある小さなドロップダウン矢印をクリックするとメニューが開き、??にその様子が示されている。続いて「マイクロコードを編集」をクリックするとLuaエディタが起動し、??にその画面が表示される。
Ctrl+Sキーを押すか、エディタツールバーにある保存ボタンを使用してスクリプトを保存します。マイクロコードを有効化するには、??に示すように有効化ボタンを押下する必要があります。
3. 簡単な例として、可動イオンが凍結されたペロブスカイト太陽電池のシミュレーションを挙げる。
Luaスクリプトを用いる簡単な例として、ペロブスカイトデバイスのシミュレーションが挙げられる。この場合、J–Vスキャン中に可動イオンを凍結させたいケースもある。ペロブスカイトには比較的ゆっくりとドリフトする可動イオンが存在する。実験上は、まずデバイスに負バイアスを印加してイオンを特定の配置状態へ移動させ、その後イオンが大きく反応する時間がないうちに極めて高速なJ–Vスキャンを実施するのが一般的である。
OghmaNanoにおいて、ペロブスカイトのイオンモデルが有効化されている場合、電気ソルバーは通常各電圧ステップごとにイオンが緩和することを許容する。これは極めて低速な、あるいは準定常状態におけるJ–Vスキャンに相当する。この挙動は場合によっては有用だが、電圧がはるかに速く変化する実験環境を再現することはできない。このような測定状況を模倣するため、以下のLuaスクリプトを用いて主電気ループの開始時点でイオンを固定することが可能だ。シミュレーションでは通常通り所定の初期電圧まで電圧を上昇させることで準備段階でイオンが移動することも可能だが、主ループに入るとイオンに関する方程式は無効化される。
-- Initialise solver
a = dd_solver()
a.verbose = false -- Suppress solver output
-- Apply logic only in the main electrical loop
if (a.problem_type & ELEC_PROB_MAIN_LOOP) ~= 0 then
a.solve_nion = false -- Disable ion equation (freeze ions)
print("ion solver off")
else
print("ion solver on") -- Keep ions active during initialisation
end
a:run() -- Execute solver step
この例では、まずソルバーオブジェクトが生成され、診断出力が抑制される。次にスクリプトは、現在のソルバー処理段階が主な電気的ループに対応しているかどうかを判定する。該当する場合、solve_nion=falseの設定を変更することで可動イオンに関する方程式が無効化され、修正後の方程式セットを用いてソルバーが実行される。このようなシミュレーション例は、OghmaNanoのサンプルモデル内にある「ペロブスカイトセル/ペロブスカイト太陽電池-凍結されたイオン(MAPI)」という項目に含まれている。
5. 例:ADI走査法(交互方向非明示法)
Luaスクリプトを用いたより高度な応用例として、複雑な三次元問題を解くための交互方向非明示法(ADI)に基づく解法の実装が挙げられる。この手法は、多次元問題をより低次元な問題の連続解決へと分解する点で、交互方向非明示法と密接に関連している。
OghmaNanoにおいては、この手法をソルバーレベルで直接実装することが可能であり、方向性結合を選択的に有効化または無効化することで実現される。完全に結合した3次元系を一度に解くのではなく、領域を交互の方向に沿って走査することで、極めて難易度の高い3次元ドリフト拡散問題においても安定性および収束性が大幅に向上する。
ここで用いられる戦略は、3次元問題を複数の方向別パスに分割することである。第1パスでは、ソルバーはx方向の結合を除外した状態でy方向およびz方向全体にわたって計算を行う。第2パスでは、ソルバーはz方向のスライス単位で動作し、同様の処理を実施する。得られた誤差の合計値が蓄積され、独自の収束判定基準として用いられる。
以下の例は、Luaを用いてこのような交互方向非明示法に基づく計算処理を構築する方法を示している。
-- Initialise solver and control variables
a = dd_solver()
cont = true
count = 0
-- Main ADI-style iteration loop
while cont == true do
-- ===== X-slice pass =====
a.set_newton_state("x") -- Use/store Newton state for x-pass
tot_error = 0.0
a.step_z = -1 -- Full domain in z
a.step_x = 1 -- Slice-by-slice in x
a.step_y = -1 -- Full domain in y
a.solve_pos_x = false -- Disable x-direction Poisson coupling
a.solve_pos_y = true
a.solve_pos_z = true
a.solve_je_x = 0 -- Disable x-direction electron current
a.solve_jh_x = 0 -- Disable x-direction hole current
a.solve_je_y = true
a.solve_jh_y = true
a.solve_je_z = true
a.solve_jh_z = true
a.solve_srh_e = true -- Keep SRH recombination active
a.solve_srh_h = true
a.solve_nion = 0 -- Disable ions
a.solve_singlet = false -- Disable excited-state physics
error = a:run() -- Execute x-slice solve
tot_error = tot_error + error
-- ===== Z-slice pass =====
a.set_newton_state("z") -- Switch to z-pass Newton state
a.step_z = 1 -- Slice-by-slice in z
a.step_x = -1 -- Full domain in x
a.step_y = -1 -- Full domain in y
a.solve_pos_x = true
a.solve_pos_y = true
a.solve_pos_z = false -- Disable z-direction Poisson coupling
a.solve_je_y = true
a.solve_jh_y = true
a.solve_je_x = true
a.solve_jh_x = true
a.solve_je_z = false -- Disable z-direction transport
a.solve_jh_z = false
a.solve_srh_e = true
a.solve_srh_h = true
a.solve_nion = false
a.solve_singlet = false
error = a:run() -- Execute z-slice solve
tot_error = tot_error + error
-- ===== Convergence logic =====
if (error < 1e-3) then -- Local convergence check
if (count > 2) then -- Ensure minimum iterations
cont = false
end
end
print("count", count, "tot error:", error)
count = count + 1
if (tot_error < 1e-7) then -- Global convergence criterion
cont = false
end
if (count > 10) then -- Safety iteration limit
cont = false
end
end
この実装では、各反復計算において2回の方向別処理が行われる。第1回処理ではx方向のポアソン方程式およびキャリア輸送項が無効化され、結果として系がx方向に沿ってスライス単位で解かれる。第2回処理では同様にz方向の項が無効化され、これにより補完的な走査が実現される。
各方向処理ごとに個別のニュートン状態が set_newton_state() を用いて維持されるため、ソルバーは静電ポテンシャル、キャリア密度、トラップ占有状態といった内部変数をそれぞれ独立して保持することが可能となる。
収束状態の制御はLuaスクリプト内で明示的に行われる。各方向処理における誤差および反復回数が閾値条件を満たすか、累積誤差が所定の許容値を下回るか、あるいは最大反復回数に達した時点でループは終了する。
この例では、Luaスクリプトを用いて完全にカスタマイズ可能な数値計算ワークフローを構築する方法を説明する。固定された数値計算法に頼るのではなく、多次元系の分解方法、中間状態の管理手法、および収束性の判定基準をユーザー自身が直接定義できるのである。この機能は、完全結合型の計算手法が不安定または計算効率が悪くなる可能性のある複雑な3次元シミュレーションにおいて特に有用である。
3. dd_solver()オブジェクト
OghmaNanoにおける電気的ソルバーのLua制御の開始点となるのがdd_solver()オブジェクトです。このオブジェクトを通じて内部のドリフト拡散/ニュートンソルバーに直接アクセスでき、実行時において方程式群や求解戦略の両方を変更することが可能となります。
実際の利用において、このソルバーオブジェクトにより3つの主要な操作が可能となる。
- 現在のソルバーコンテキスト(問題の種類や印加バイアスなど)を確認してください。
- 個々の方程式や方向性結合の有効化/無効化が可能である。
- ソルバーの計算ステップを実行し、収束状態や誤差の指標を取得する。
最も一般的に使用される場は表??にまとめられている。
| フィールド | 意味 | 一般的な利用例 |
|---|---|---|
step_x、step_y、step_z |
各方向における計算領域の範囲を制御する。-1では全領域を一度に解くが、1ではスライスごとに計算を進める。 |
方向別分解処理およびスライス単位のソルバー |
solve_pos_x、solve_pos_y、solve_pos_z |
各方向におけるポアソン結合の有効化または無効化が可能。 | 選択した軸方向における静電結合の解除。 |
solve_je_x、solve_je_y、solve_je_z |
各方向における電子連続性方程式を制御する。 | 方向別輸送制御 |
solve_jh_x、solve_jh_y、solve_jh_z |
各方向における正孔の連続性方程式を制御する。 | 方向別輸送制御 |
solve_srh_e、solve_srh_h |
電子および正孔に対してショックレー・リード・ホールトラップ現象を実現可能にする。 | 簡略化された系においてもトラップの動的挙動を維持する。 |
solve_nion |
可動イオンに関する方程式を有効化または無効化する。 | ペロブスカイト太陽電池のシミュレーションにおける可動イオンの動きの固定化 |
solve_singlet |
励起状態(一重項)用のソルバーを制御する。 | 電気解析時における励起子およびOLED物理モデルの無効化。 |
verbose |
ソルバーの診断出力を制御する。 | デバッグ実行またはサイレント実行。 |
problem_type |
現在のソルバー処理段階を示します。 | 論理処理を選択的に適用する(例えば、メインループのみに適用する)。 |
Vapplied |
印加された端子電圧を返します。 | バイアス依存型制御ロジック |
scale_dphi_for_Bfree |
内部電位更新用のスケーリングパラメータ。 | 高度な数値調整手法。 |
フィールドへのアクセスに加え、このソルバーにはいくつかの重要なメソッドが用意されている:
| メソッド | 役割 |
|---|---|
a:run() |
設定されたソルバー処理を実行し、誤差指標を返す。 |
a.set_newton_state("x") |
保存済みのニュートン状態を選択または作成する。これにより、異なる方向の計算パスごとに解変数(電位、キャリア密度、トラップ占有率)の独立したコピーを維持することが可能となる。 |
8. まとめ
OghmaNanoにおけるLuaスクリプト機能により、内部のドリフト拡散ソルバーを直接制御でき、実行時において解くべき数式体系を変更することが可能となる。外部スクリプトが入力ファイルを操作するのとは異なり、Luaはソルバーループ内で動作するため、各計算ステップごとに数式群や方向性結合、収束挙動を変更できるのである。この機能は、標準的な完全結合型定式化が物理的にも数値的にも適切でない場合に特に有用である。例えば、可動イオンといった緩和が遅い自由度を固定したり、ADI方式を用いて複雑な3次元問題を方向別計算ステップに分解したりする場合がこれに該当する。
ここで示す例は2つの主要な利用ケースを表している。1つ目は最小限の介入例であり、実験における高速走査条件を再現するために、主な電気回路ループ内でのみ可動イオンに関する方程式を無効化している。2つ目は、Luaを用いて方向別スライス間を交互に切り替えつつ、ユーザー定義の収束基準を適用することで独自のソルバー処理手順を構築する方法を示している。
より一般的に言えば、LuaはOghmaNanoにおける数値計算手法開発用のフレームワークと見なすべきである。これによりユーザーは既定のソルバー設定に縛られることなく、問題の物理的側面や対象システムの数値的特性に合わせた独自の解法戦略を定義できるのである。