pnjunction.py ダウンロード/コピー

pnjunction.py をダウンロード

pnjunction.py
pnjunction.py
  1import numpy as np
  2import math
  3import argparse
  4import matplotlib.pyplot as plt
  5
  6"""
  7PN接合ダイオードの電流-電圧 (IV) 特性を計算し、プロットするスクリプト。
  8
  9概要:
 10    PN接合ダイオードの電流-電圧 (IV) 特性を計算し、プロットします。
 11詳細説明:
 12    このスクリプトは、ユーザーが指定した半導体材料のパラメータと環境条件(温度)に基づき、
 13    PN接合ダイオードの重要な電気的特性である逆方向飽和電流 Js と内部電位 Vbi を計算します。
 14    その後、指定された印加電圧範囲におけるダイオードの電流-電圧 (IV) 特性を、
 15    ニュートン法を用いた数値計算によりシミュレーションします。
 16    計算されたIV特性はmatplotlibライブラリを使用してグラフとして視覚的に表示され、
 17    主要な計算結果はコンソールに出力されます。
 18関連リンク:
 19    pnjunction_usage
 20"""
 21
 22# 物理定数
 23KB = 1.380649e-23
 24QE = 1.60217663e-19
 25
 26def calculate_material_params(args):
 27    """
 28    概要:
 29        PN接合ダイオードの材料パラメータを計算します。
 30    詳細説明:
 31        半導体の特性(キャリア有効質量、ドーピング濃度、移動度、寿命など)と温度に基づき、
 32        伝導帯・価電子帯有効状態密度、フェルミ準位、内部電位 Vbi、キャリア拡散係数、
 33        拡散長を計算し、最終的にダイオードの逆方向飽和電流 Js を決定します。
 34    引数:
 35        :param args: コマンドライン引数を格納したargparse.Namespaceオブジェクト。
 36                     このオブジェクトには、以下の属性が含まれている必要があります。
 37                     temp: 温度 (K)。
 38                     men: 電子の有効質量比 (無次元)。
 39                     mhp: 正孔の有効質量比 (無次元)。
 40                     ecn: N側伝導帯端エネルギー (eV)。
 41                     ndn: N側ドーピング濃度 (/cm^3)。
 42                     evp: P側価電子帯端エネルギー (eV)。
 43                     nap: P側ドーピング濃度 (/cm^3)。
 44                     mun: 電子移動度 (cm^2/Vs)。
 45                     taun: 電子寿命 (s)。
 46                     mup: 正孔移動度 (cm^2/Vs)。
 47                     taup: 正孔寿命 (s)。
 48        :type args: argparse.Namespace
 49    戻り値:
 50        :returns js: 逆方向飽和電流 (A/cm^2)。
 51        :rtype js: float
 52        :returns v_bi: 内部電位 (V)。
 53        :rtype v_bi: float
 54    """
 55    T = args.temp
 56    nc = 2.51e19 * (args.men**1.5) * ((T/300)**1.5)
 57    nv = 2.51e19 * (args.mhp**1.5) * ((T/300)**1.5)
 58    
 59    efn = args.ecn - (KB * T / QE) * math.log(args.ndn / nc)
 60    efp = args.evp + (KB * T / QE) * math.log(args.nap / nv)
 61    v_bi = efp - efn
 62
 63    dn = args.mun * (KB * T / QE)
 64    dp = args.mup * (KB * T / QE)
 65    ln, lp = math.sqrt(dn * args.taun), math.sqrt(dp * args.taup)
 66
 67    term_exp = math.exp(-QE * v_bi / (KB * T))
 68    js = QE * (dn / (ln)) * args.ndn * term_exp + QE * (dp / (lp)) * args.nap * term_exp
 69    return js, v_bi
 70
 71def calculate_diode_current(v_target, temp, js, n_diode, rs, area, v_initial):
 72    """
 73    概要:
 74        指定された印加電圧におけるPN接合ダイオードの電流をニュートン法を用いて計算します。
 75    詳細説明:
 76        理想ダイオードモデルに直列抵抗 Rs を加味した方程式、
 77        V_total = V_diode + I_diode * Rs、をニュートン法を用いて数値的に解きます。
 78        これにより、目標の印加電圧 v_target におけるダイオードにかかる電圧 v_diode と、
 79        それに対応する電流 I_diode を高精度で求めます。
 80        ニュートン法の初期値として前回の計算結果を使用することで、収束性を向上させています。
 81    引数:
 82        :param v_target: 目標とする印加電圧 (V)。
 83        :type v_target: float
 84        :param temp: 温度 (K)。
 85        :type temp: float
 86        :param js: 逆方向飽和電流 (A/cm^2)。
 87        :type js: float
 88        :param n_diode: ダイオード理想係数 (無次元)。
 89        :type n_diode: float
 90        :param rs: 直列抵抗 (ohm)。
 91        :type rs: float
 92        :param area: ダイオードの面積 (cm^2)。
 93        :type area: float
 94        :param v_initial: ニュートン法の初期値として使用するダイオード電圧 (V)。
 95                          通常は前回の計算結果や予測値が用いられます。
 96        :type v_initial: float
 97    戻り値:
 98        :returns v_diode: ダイオードにかかる最終的な電圧 (V)。
 99        :rtype v_diode: float
100        :returns current: ダイオードに流れる最終的な電流 (A)。
101        :rtype current: float
102    """
103    if v_target == 0: return 0.0, 0.0
104    v_diode = v_initial
105    dv, eps, max_iter = 1e-4, 1e-7, 100
106    vt = (n_diode * KB * temp) / QE
107
108    for _ in range(max_iter):
109        get_i = lambda vd: js * (math.exp(vd / vt) - 1.0) * area
110        im, ip = get_i(v_diode - dv), get_i(v_diode + dv)
111        v_total = 0.5 * ((v_diode - dv + im * rs) + (v_diode + dv + ip * rs))
112        
113        if abs(v_total - v_target) < eps:
114            return v_diode, 0.5 * (im + ip)
115        
116        dv_dv = ((v_diode + dv + ip * rs) - (v_diode - dv + im * rs)) / (2.0 * dv)
117        v_diode += (v_target - v_total) / dv_dv
118    return v_diode, js * (math.exp(v_diode / vt) - 1.0) * area
119
120def main():
121    """
122    概要:
123        PN接合ダイオードのIV特性シミュレーションのメイン処理を実行します。
124    詳細説明:
125        コマンドライン引数から半導体材料のパラメータ、シミュレーションの電圧範囲、
126        プロットの表示オプションなどを受け取ります。
127        calculate_material_params 関数でダイオードの基本パラメータ Js と Vbi を計算し、
128        その後、calculate_diode_current 関数を繰り返し呼び出して、
129        指定された電圧範囲におけるダイオード電流を計算します。
130        計算された電流-電圧特性はmatplotlibでプロットされ、コンソールに主要な計算結果が出力されます。
131    戻り値:
132        :returns: なし
133        :rtype: None
134    """
135    parser = argparse.ArgumentParser(description='PN Junction IV Characteristics Simulator')
136    parser.add_argument('--temp', type=float, default=300.0, help='Temperature [K]')
137    parser.add_argument('--area', type=float, default=0.01, help='Diode Area [cm^2]')
138    parser.add_argument('--rs', type=float, default=10.0, help='Series Resistance [ohm]')
139    parser.add_argument('--ndn', type=float, default=1.0e16, help='N-side doping concentration [/cm^3]')
140    parser.add_argument('--ecn', type=float, default=4.05, help='N-side conduction band edge energy [eV]')
141    parser.add_argument('--men', type=float, default=0.19, help='Effective mass ratio of electron (N-side)')
142    parser.add_argument('--mun', type=float, default=1500.0, help='Electron mobility (N-side) [cm^2/Vs]')
143    parser.add_argument('--taun', type=float, default=1e-5, help='Electron lifetime (N-side) [s]')
144    parser.add_argument('--nap', type=float, default=1.0e16, help='P-side doping concentration [/cm^3]')
145    parser.add_argument('--evp', type=float, default=5.17, help='P-side valence band edge energy [eV]')
146    parser.add_argument('--mhp', type=float, default=0.16, help='Effective mass ratio of hole (P-side)')
147    parser.add_argument('--mup', type=float, default=500.0, help='Hole mobility (P-side) [cm^2/Vs]')
148    parser.add_argument('--taup', type=float, default=1e-5, help='Hole lifetime (P-side) [s]')
149    parser.add_argument('--v0', type=float, default=-1.0, help='Start voltage for simulation [V]')
150    parser.add_argument('--v1', type=float, default=1.0, help='End voltage for simulation [V]')
151    parser.add_argument('--step', type=float, default=0.02, help='Voltage step for simulation [V]')
152    parser.add_argument('--noplot', action='store_true', help='Disable plot display')
153    args = parser.parse_args()
154
155    js, v_bi = calculate_material_params(args)
156    
157    v_apps = np.arange(args.v0, args.v1 + args.step, args.step)
158    currents = []
159    
160    v_prev = args.v0 * 0.2
161    for v_app in v_apps:
162        _, i = calculate_diode_current(v_app, args.temp, js, 1.0, args.rs, args.area, v_prev)
163        currents.append(i)
164        v_prev = _
165
166    abs_currents = np.abs(currents)
167
168    # グラフ描画
169    if not args.noplot:
170        plt.figure(figsize=(8, 6))
171        plt.semilogy(v_apps, abs_currents, 'b-', label=f'Rs = {args.rs} ohm')
172        plt.title("PN Junction IV Characteristics")
173        plt.xlabel("Applied Voltage (V)")
174        plt.ylabel("|Current| (A)")
175        plt.grid(True, which="both", ls="-", alpha=0.5)
176        plt.legend()
177        
178        # 0Vの線を表示
179        plt.axvline(0, color='black', lw=1)
180        
181        print(f"Calculated Vbi: {v_bi:.4f} V")
182        print(f"Calculated Js : {js:.6e} A/cm2")
183        plt.show()
184
185if __name__ == "__main__":
186    main()