pvfit.py 技術ドキュメント

プログラムの動作

pvfit.py は、太陽電池のI-V (電流-電圧) 特性データを解析し、単一ダイオードモデル (SDM) のパラメータにフィッティングするためのPythonプログラムです。これにより、太陽電池の電気的特性を物理モデルに基づいて定量的に評価できます。

主な機能は以下の通りです。

  • データ読み込み: CSV形式のI-V特性データを読み込みます。データは電圧の昇順にソートされ、指定された電圧範囲でフィルタリングできます。

  • 初期パラメータ推定: フィッティングのためのSDMパラメータ(逆飽和電流 \(I_0\)、ダイオード品質因子 \(n\)、光生成電流 \(I_{PV}\)、直列抵抗 \(R_s\)、並列抵抗 \(R_{sh}\))の初期値を自動的に推定します。

  • SDMパラメータフィッティング: 非線形最小二乗法を用いて、測定されたI-VデータにSDMをフィッティングし、最適なSDMパラメータを決定します。フィッティング中には、プロットとコンソール出力で進捗をリアルタイムで確認できます。

  • 誤差推定: フィッティングされたパラメータの標準誤差およびモデル曲線の信頼区間を線形近似に基づき推定します。

  • 特性値算出: フィッティング結果から、開回路電圧 (\(V_{OC}\)) と短絡電流 (\(I_{SC}\)) を推定します。

  • 結果保存: フィッティングされたパラメータ、推定誤差、\(V_{OC}\)\(I_{SC}\)、残差二乗和 (RSS) をCSVファイルに保存します。

  • 結果プロット: 測定データとフィッティングされたモデル曲線、およびその信頼区間を、線形および対数スケールで表示します。

  • シミュレーションモード: 既存のパラメータ、またはコマンドラインで指定されたパラメータを用いてSDM曲線をシミュレーションし、プロットを表示します。

このプログラムは、実験データから太陽電池の物理パラメータを抽出し、その動作を理解・予測する課題を解決するために役立ちます。

原理

単一ダイオードモデル (Single Diode Model, SDM)

pvfit.py で使用される単一ダイオードモデルは、太陽電池の電流-電圧特性を記述する物理モデルです。モデルのパラメータは以下の通りです。

  • \(I_0\): 逆飽和電流 (Reverse Saturation Current)

  • \(n\): ダイオード品質因子 (Diode Ideality Factor)

  • \(I_{PV}\): 光生成電流 (Photo-generated Current)

  • \(R_s\): 直列抵抗 (Series Resistance)

  • \(R_{sh}\): 並列抵抗 (Shunt Resistance)

  • \(T\): 温度 (Temperature)

  • \(k_B\): ボルツマン定数 (\(1.380649 \times 10^{-23}\) J/K)

  • \(q\): 素電荷 (\(1.602176634 \times 10^{-19}\) C)

  • \(V_t = n k_B T / q\): 熱電圧 (Thermal Voltage)

プログラムで用いられているモデルは、以下の非線形方程式を解くことで電流 \(I\) を算出します。

\[I = I_0 \left( \exp \left( \frac{V - I_D' R_s}{n k_B T / q} \right) - 1 \right) + \frac{V - I_D' R_s}{R_{sh}} - I_{PV}\]

ここで、\(I_D'\) はダイオードとシャント抵抗に流れる電流の合計であり、以下の式を満たします。

\[I_D' = I_0 \left( \exp \left( \frac{V - I_D' R_s}{n k_B T / q} \right) - 1 \right) + \frac{V - I_D' R_s}{R_{sh}}\]

プログラム内の model 関数では、\(I_D'\)Idark として scipy.optimize.brentq を用いて数値的に解き、\(I = I_D' - I_{PV}\) として最終的な電流値 (\(I_{final}\)) を計算しています。これは、測定電流 \(I_{meas}\) が通常負の値を取る(発電モード)ことに合わせて符号が調整された形式です。

フィッティングアルゴリズム

フィッティングは、scipy.optimize.minimize 関数を用いて行われます。目的関数 (objective) は、測定電流 \(I_{meas}\) とモデル電流 \(I_{calc}\) の対数スケールでの残差二乗和 (RSS) を最小化するように定義されています。

\[RSS = \sum \left( \log_{10}(|I_{meas}| + \epsilon_I) - \log_{10}(|I_{calc}| + \epsilon_I) \right)^2\]

ここで、\(\epsilon_I\) (EPS_I) はゼロ除算を回避するための非常に小さな正の定数 (\(1.0 \times 10^{-15}\)) です。対数スケールでの最適化は、特に低電流領域や広範囲の電流値にわたるフィッティングの精度を向上させるのに有効です。 SDMパラメータのうち、\(I_0, I_{PV}, R_s, R_{sh}\) は非負の値であるため、最適化の際には対数変換 (\(10^x\)) された値が使われ、ndiode はそのまま最適化されます。

誤差推定

フィッティングされたパラメータの誤差とモデル曲線の信頼区間は、線形近似に基づいた誤差伝播の原理を用いて算出されます。 まず、フィッティングされた最適なパラメータ \(p_{opt}\) における、目的関数の各パラメータに対するヤコビ行列 \(J\) が数値的に計算されます。

\[J_{ij} = \frac{\partial \log_{10}(|I_{calc}(V_i, p)| + \epsilon_I)}{\partial p_j}\]

その後、残差の分散 \(\hat{\sigma}^2 = RSS / (N-P)\) (\(N\): データ点数, \(P\): 最適化されたパラメータ数) とヤコビ行列を用いて、パラメータの共分散行列 \(C = \hat{\sigma}^2 (J^T J)^{-1}\) を計算します。パラメータの標準誤差は、共分散行列の対角要素の平方根から得られます。モデル曲線の標準偏差は、\(\sqrt{\text{diag}(J C J^T)}\) から推定されます。

\(V_{OC}\)\(I_{SC}\) の推定

  • \(I_{SC}\) (短絡電流): SDMモデルにおいて電圧 \(V=0\) の時の電流として計算されます。

  • \(V_{OC}\) (開回路電圧): SDMモデルにおいて電流 \(I=0\) となる電圧として、電圧-電流特性の多項式近似 (solve_root_poly) を用いて数値的に求められます。

必要な非標準ライブラリとインストール方法

pvfit.py の実行には、以下のPython非標準ライブラリが必要です。

  • numpy: 数値計算を効率的に行うためのライブラリ。

  • matplotlib: データのプロットを行うためのライブラリ。

  • scipy: 科学技術計算ライブラリで、特に最適化とルート探索機能を使用します。

これらのライブラリは、Pythonのパッケージマネージャ pip を使用してインストールできます。コマンドラインまたはターミナルで以下のコマンドを実行してください。

pip install numpy matplotlib scipy

必要な入力ファイル

プログラムは、I-V特性データを含むCSVファイルを入力として受け取ります。

  • ファイル名: コマンドライン引数 --infile で指定します。デフォルトは input.csv です。

  • 形式: テキストベースのCSV (Comma Separated Values) 形式です。

  • エンコーディング: UTF-8 (または BOM 付き UTF-8) を推奨します。

  • データ構造:

    • メタデータ行 (オプション): MetaData,TestRecord.RecordTime,YYYY-MM-DD HH:MM:SS の形式で、試験の記録時間などの情報を読み込むことができます。

    • データ開始行: DataName という文字列を含む行は、データ値のヘッダーとして扱われ、その次の行からデータ値が始まります。

    • データ値行: DataValue,電圧値,電流値 の形式で、実際のI-Vデータが記述されます。電圧値と電流値は浮動小数点数として解釈されます。

入力ファイル例 (example_input.csv):

MetaData,TestRecord.RecordTime,2023-10-27 10:00:00
DataName,Voltage(V),Current(A)
DataValue,-0.100,-1.000
DataValue,0.000,-0.998
DataValue,0.100,-0.995
DataValue,0.200,-0.980
DataValue,0.300,-0.900
DataValue,0.400,-0.650
DataValue,0.500,-0.200
DataValue,0.550,0.005
DataValue,0.600,0.010
DataValue,0.700,0.012

生成される出力ファイル

プログラムは、実行モードに応じて以下のファイルを生成または更新します。

  • [infile_stem]-parameters.csv:

    • ファイル名: 入力ファイル名(例: input.csv)から拡張子を除いたものに -parameters.csv を付けた名前(例: input-parameters.csv)で保存されます。

    • 内容: SDMのパラメータ、推定誤差、およびその他の関連情報が含まれます。

      • varname: パラメータ名 (I0, ndiode, IPV, Rs, Rsh, VOC_est, ISC_est, RSS_logy)。

      • value: 各パラメータのフィッティング結果、または推定された \(V_{OC}\)\(I_{SC}\)、RSS の値。

      • optid: そのパラメータが最適化された場合は 1、固定された場合は 0

      • error: 最適化されたパラメータの標準誤差。固定されたパラメータや推定値の場合は 0

    • 用途: フィッティング結果の永続的な保存、および次回の実行時の初期パラメータや固定パラメータの読み込みに使用されます。

プログラム実行時には、I-V特性のプロットウィンドウも表示されますが、これは画像ファイルとして自動的に保存されません。

コマンドラインでの使用例 (Usage)

pvfit.py は、コマンドライン引数で動作モードとパラメータを指定して実行します。

python pvfit.py --mode <mode> --infile <input_file.csv> [options]
  • --mode <mode>: プログラムの実行モードを指定します。以下のいずれかを選択します。

    • init: 入力データからSDMパラメータの初期値を自動推定し、[infile_stem]-parameters.csv に保存して終了します。

    • fit: SDMパラメータをI-Vデータにフィッティングし、結果を [infile_stem]-parameters.csv に保存し、プロットを表示します。

    • sim: 既存のパラメータを読み込むか、コマンドラインで指定されたパラメータでSDMをシミュレーションし、プロットを表示します。

  • --infile <input_file.csv>: 解析対象のI-VデータCSVファイルのパスを指定します。デフォルトは input.csv です。

  • --temperature <float>: シミュレーションまたはフィッティングに使用する温度をケルビン (K) で指定します。デフォルトは 300.0 です。

  • --xmin <float>, --xmax <float>: 入力データを読み込む際に、電圧の最小値および最大値を指定してデータをフィルタリングします。

  • --I0 <float>, --ndiode <float>, --IPV <float>, --Rs <float>, --Rsh <float>: 各SDMパラメータの値を直接指定します。

    • init モードでは、これらの値は初期推定値を上書きします。

    • fit モードでは、これらの値はフィッティングの初期値として使用されます。--fix と組み合わせることで、値を固定することもできます。

    • sim モードでは、これらの値がシミュレーションに使用されます。

  • --fix <param_name> [<param_name>...]: fit モードで、フィッティング中に値を固定するSDMパラメータの名前をスペース区切りで複数指定します (例: --fix I0 Rs)。この指定は、[infile_stem]-parameters.csv に保存されている optid=0 の設定と結合されます。

  • --method <method_name>: scipy.optimize.minimize で使用する最適化手法を指定します。デフォルトは Nelder-Mead です。

  • --ninterval_print <int>: fit モードで、フィッティング中にコンソールに進捗情報を表示するイテレーション間隔を指定します。デフォルトは 10 です。

  • --ninterval_plot <int>: fit モードで、フィッティング中にプロットを更新するイテレーション間隔を指定します。デフォルトは 10 です。

コマンドラインでの具体的な使用例

以下の例では、前のセクションで示した example_input.csv ファイルが存在することを前提とします。

例1: 初期パラメータの推定と保存

入力データからSDMパラメータの初期値を自動推定し、結果をCSVファイルに保存します。このモードではプロットは表示されません。

コマンド:

python pvfit.py --mode init --infile example_input.csv

想定される出力 (コンソール):

File Name: example_input.csv
Record Time: 2023-10-27 10:00:00
Voltage range: -0.1000 to 0.7000 V

--- Initial Parameters Saved ---

生成されるファイル (example_input-parameters.csv の内容例): (値は入力データにより変動します)

varname,value,optid,error
I0,1.000000e-10,1,0
ndiode,1.500000e+00,1,0
IPV,1.000000e+00,1,0
Rs,1.000000e+01,1,0
Rsh,1.000000e+06,1,0
VOC_est,5.500000e-01,0,0
ISC_est,-9.980000e-01,0,0

例2: SDMパラメータのフィッティング

example_input.csv のデータと、例1で生成された初期パラメータを用いて、SDMパラメータをフィッティングします。フィッティングの進捗がコンソールとプロットウィンドウにリアルタイムで表示され、最終結果が example_input-parameters.csv に保存されます。

コマンド:

python pvfit.py --mode fit --infile example_input.csv

想定される出力 (コンソール):

File Name: example_input.csv
Record Time: 2023-10-27 10:00:00
Voltage range: -0.1000 to 0.7000 V
Iter   10 | RSS: 1.2345e+00 | I0: 1.23e-10 | ndiode: 1.51e+00 | IPV: 1.01e+00 | Rs: 9.87e+00 | Rsh: 9.99e+05
Iter   20 | RSS: 0.8765e+00 | I0: 1.30e-10 | ndiode: 1.50e+00 | IPV: 1.00e+00 | Rs: 9.50e+00 | Rsh: 1.10e+06
...
Final Results (RSS: 0.1234e+00)
  I0      : 1.500000e-10 +/- 1.00e-11
  ndiode  : 1.450000e+00 +/- 5.00e-02
  IPV     : 9.900000e-01 +/- 2.00e-03
  Rs      : 8.500000e+00 +/- 1.00e+00
  Rsh     : 1.200000e+06 +/- 5.00e+05

(同時に、測定データとフィッティングモデル曲線を示すI-Vプロットが表示されます。)

生成されるファイル (example_input-parameters.csv の内容例、更新後): (値はフィッティング結果により変動します)

varname,value,optid,error
I0,1.500000e-10,1,1.000000e-11
ndiode,1.450000e+00,1,5.000000e-02
IPV,9.900000e-01,1,2.000000e-03
Rs,8.500000e+00,1,1.000000e+00
Rsh,1.200000e+06,1,5.000000e+05
VOC_est,5.900000e-01,0,0
ISC_est,-9.900000e-01,0,0
RSS_logy,1.234000e-01,0,0

例3: 特定のパラメータを固定してフィッティング

fit モードで、特定のパラメータ(例: Rs)を固定値でフィッティングを行います。ここでは Rs10.0 に固定します。

コマンド:

python pvfit.py --mode fit --infile example_input.csv --fix Rs --Rs 10.0

想定される出力 (コンソール):

File Name: example_input.csv
Record Time: 2023-10-27 10:00:00
Voltage range: -0.1000 to 0.7000 V
Iter   10 | RSS: 1.5000e+00 | I0: 1.30e-10 | ndiode: 1.60e+00 | IPV: 1.05e+00 | Rs: 1.00e+01(F) | Rsh: 1.10e+06
...
Final Results (RSS: 0.1400e+00)
  I0      : 1.800000e-10 +/- 1.20e-11
  ndiode  : 1.650000e+00 +/- 6.00e-02
  IPV     : 1.020000e+00 +/- 2.50e-03
  Rs      : 1.000000e+01 (Fixed)
  Rsh     : 1.300000e+06 +/- 6.00e+05

Rs が固定値として扱われ、エラー表示がないことが確認できます。I-Vプロットも表示されます。)

例4: シミュレーションモード

既存のパラメータファイル、またはコマンドラインで指定されたSDMパラメータを用いてI-V曲線をシミュレーションし、プロットのみを表示します。ここでは特定のパラメータを直接指定します。

コマンド:

python pvfit.py --mode sim --infile example_input.csv --I0 1e-10 --ndiode 1.5 --IPV 1.0 --Rs 5.0 --Rsh 1e6

想定される出力 (コンソール):

File Name: example_input.csv
Record Time: 2023-10-27 10:00:00
Voltage range: -0.1000 to 0.7000 V

--- Simulation Mode ---
  I0      : 1.000000e-10
  ndiode  : 1.500000e+00
  IPV     : 1.000000e+00
  Rs      : 5.000000e+00
  Rsh     : 1.000000e+06

(指定されたパラメータに基づくモデル曲線が測定データと共にプロットされます。)