electrical.pnjunction のソースコード

import numpy as np
import math
import argparse
import matplotlib.pyplot as plt

"""
pnjunction.py

PN接合ダイオードの電流-電圧 (IV) 特性を計算し、プロットするスクリプト。

このスクリプトは、ユーザーが指定した半導体材料のパラメータと環境条件(温度)に基づき、
PN接合ダイオードの重要な電気的特性である逆方向飽和電流 (Js) と内部電位 (Vbi) を計算します。
その後、指定された印加電圧範囲におけるダイオードの電流-電圧 (IV) 特性を、
ニュートン法を用いた数値計算によりシミュレーションします。
計算されたIV特性はmatplotlibライブラリを使用してグラフとして視覚的に表示され、
主要な計算結果はコンソールに出力されます。

関連リンク:
:doc:`pnjunction_usage`
"""

# 物理定数
KB = 1.380649e-23
QE = 1.60217663e-19

[ドキュメント] def calculate_material_params(args): """ PN接合ダイオードの材料パラメータ(逆方向飽和電流、内部電位)を計算します。 半導体の特性(キャリア有効質量、ドーピング濃度、移動度、寿命など)と温度に基づき、 伝導帯・価電子帯有効状態密度、フェルミ準位、内部電位 (Vbi)、キャリア拡散係数、拡散長を計算し、 最終的にダイオードの逆方向飽和電流 Js を決定します。 :param args: コマンドライン引数を格納したargparse.Namespaceオブジェクト。 以下の属性を持つことが期待されます。 :param args.temp: float 温度 (K) :param args.men: float 電子の有効質量比 (無次元) :param args.mhp: float 正孔の有効質量比 (無次元) :param args.ecn: float N側伝導帯端エネルギー (eV) :param args.ndn: float N側ドーピング濃度 (/cm^3) :param args.evp: float P側価電子帯端エネルギー (eV) :param args.nap: float P側ドーピング濃度 (/cm^3) :param args.mun: float 電子移動度 (cm^2/Vs) :param args.taun: float 電子寿命 (s) :param args.mup: float 正孔移動度 (cm^2/Vs) :param args.taup: float 正孔寿命 (s) :returns: :returns js: float 逆方向飽和電流 (A/cm^2) :returns v_bi: float 内部電位 (V) """ T = args.temp nc = 2.51e19 * (args.men**1.5) * ((T/300)**1.5) nv = 2.51e19 * (args.mhp**1.5) * ((T/300)**1.5) efn = args.ecn - (KB * T / QE) * math.log(args.ndn / nc) efp = args.evp + (KB * T / QE) * math.log(args.nap / nv) v_bi = efp - efn dn = args.mun * (KB * T / QE) dp = args.mup * (KB * T / QE) ln, lp = math.sqrt(dn * args.taun), math.sqrt(dp * args.taup) term_exp = math.exp(-QE * v_bi / (KB * T)) js = QE * (dn / (ln)) * args.ndn * term_exp + QE * (dp / (lp)) * args.nap * term_exp return js, v_bi
[ドキュメント] def calculate_diode_current(v_target, temp, js, n_diode, rs, area, v_initial): """ 指定された印加電圧におけるPN接合ダイオードの電流をニュートン法を用いて計算します。 理想ダイオードモデルに直列抵抗 (Rs) を加味した方程式 (V_total = V_diode + I_diode * R_s) を ニュートン法を用いて数値的に解きます。これにより、目標の印加電圧 V_target における ダイオードにかかる電圧 V_diode と、それに対応する電流 I_diode を高精度で求めます。 ニュートン法の初期値として前回の計算結果を使用することで、収束性を向上させています。 :param v_target: float 目標とする印加電圧 (V)。 :param temp: float 温度 (K)。 :param js: float 逆方向飽和電流 (A/cm^2)。 :param n_diode: float ダイオード理想係数 (無次元)。 :param rs: float 直列抵抗 (ohm)。 :param area: float ダイオードの面積 (cm^2)。 :param v_initial: float ニュートン法の初期値として使用するダイオード電圧 (V)。 通常は前回の計算結果や予測値が用いられます。 :returns: :returns v_diode: float ダイオードにかかる最終的な電圧 (V)。 :returns current: float ダイオードに流れる最終的な電流 (A)。 """ if v_target == 0: return 0.0, 0.0 v_diode = v_initial dv, eps, max_iter = 1e-4, 1e-7, 100 vt = (n_diode * KB * temp) / QE for _ in range(max_iter): get_i = lambda vd: js * (math.exp(vd / vt) - 1.0) * area im, ip = get_i(v_diode - dv), get_i(v_diode + dv) v_total = 0.5 * ((v_diode - dv + im * rs) + (v_diode + dv + ip * rs)) if abs(v_total - v_target) < eps: return v_diode, 0.5 * (im + ip) dv_dv = ((v_diode + dv + ip * rs) - (v_diode - dv + im * rs)) / (2.0 * dv) v_diode += (v_target - v_total) / dv_dv return v_diode, js * (math.exp(v_diode / vt) - 1.0) * area
[ドキュメント] def main(): """ PN接合ダイオードのIV特性シミュレーションのメイン処理を実行します。 コマンドライン引数から半導体材料のパラメータ、シミュレーションの電圧範囲、 プロットの表示オプションなどを受け取ります。 `calculate_material_params` 関数でダイオードの基本パラメータ (Js, Vbi) を計算し、 その後、`calculate_diode_current` 関数を繰り返し呼び出して、 指定された電圧範囲におけるダイオード電流を計算します。 計算された電流-電圧特性はmatplotlibでプロットされ、コンソールに主要な計算結果が出力されます。 :returns: なし :rtype: None """ parser = argparse.ArgumentParser(description='PN Junction IV Characteristics Simulator') parser.add_argument('--temp', type=float, default=300.0, help='Temperature [K]') parser.add_argument('--area', type=float, default=0.01, help='Diode Area [cm^2]') parser.add_argument('--rs', type=float, default=10.0, help='Series Resistance [ohm]') parser.add_argument('--ndn', type=float, default=1.0e16, help='N-side doping concentration [/cm^3]') parser.add_argument('--ecn', type=float, default=4.05, help='N-side conduction band edge energy [eV]') parser.add_argument('--men', type=float, default=0.19, help='Effective mass ratio of electron (N-side)') parser.add_argument('--mun', type=float, default=1500.0, help='Electron mobility (N-side) [cm^2/Vs]') parser.add_argument('--taun', type=float, default=1e-5, help='Electron lifetime (N-side) [s]') parser.add_argument('--nap', type=float, default=1.0e16, help='P-side doping concentration [/cm^3]') parser.add_argument('--evp', type=float, default=5.17, help='P-side valence band edge energy [eV]') parser.add_argument('--mhp', type=float, default=0.16, help='Effective mass ratio of hole (P-side)') parser.add_argument('--mup', type=float, default=500.0, help='Hole mobility (P-side) [cm^2/Vs]') parser.add_argument('--taup', type=float, default=1e-5, help='Hole lifetime (P-side) [s]') parser.add_argument('--v0', type=float, default=-1.0, help='Start voltage for simulation [V]') parser.add_argument('--v1', type=float, default=1.0, help='End voltage for simulation [V]') parser.add_argument('--step', type=float, default=0.02, help='Voltage step for simulation [V]') parser.add_argument('--noplot', action='store_true', help='Disable plot display') args = parser.parse_args() js, v_bi = calculate_material_params(args) v_apps = np.arange(args.v0, args.v1 + args.step, args.step) currents = [] v_prev = args.v0 * 0.2 for v_app in v_apps: _, i = calculate_diode_current(v_app, args.temp, js, 1.0, args.rs, args.area, v_prev) currents.append(i) v_prev = _ abs_currents = np.abs(currents) # グラフ描画 if not args.noplot: plt.figure(figsize=(8, 6)) plt.semilogy(v_apps, abs_currents, 'b-', label=f'Rs = {args.rs} ohm') plt.title("PN Junction IV Characteristics") plt.xlabel("Applied Voltage (V)") plt.ylabel("|Current| (A)") plt.grid(True, which="both", ls="-", alpha=0.5) plt.legend() # 0Vの線を表示 plt.axvline(0, color='black', lw=1) print(f"Calculated Vbi: {v_bi:.4f} V") print(f"Calculated Js : {js:.6e} A/cm2") plt.show()
if __name__ == "__main__": main()