Source code for psc_sim.iv
from __future__ import annotations
import math
import numpy as np
from psc_sim.parameters import EXP_CLIP, CellParameters
def voc_from_iv(V: np.ndarray, I_a: np.ndarray) -> float | None:
"""Estimate Voc by linearly interpolating the I=0 crossing."""
Vf = np.asarray(V, dtype=float)
If = np.asarray(I_a, dtype=float) * 1000.0
if Vf.size < 2:
return None
for k in range(Vf.size - 1):
a, b = If[k], If[k + 1]
if a == 0.0:
return float(Vf[k])
if a < 0.0 <= b or a > 0.0 >= b:
if b == a:
return float(0.5 * (Vf[k] + Vf[k + 1]))
t = -a / (b - a)
t = max(0.0, min(1.0, t))
return float(Vf[k] + t * (Vf[k + 1] - Vf[k]))
return None
[docs]
def residual_iv_implicit(I: float, V: float, p: CellParameters, rs: float) -> float:
"""f(I)=0 for the implicit one-diode equation."""
vt = p.vt()
Vd = V + I * rs
ev = min(Vd / vt, EXP_CLIP)
expv = math.exp(ev)
return p.I0 * (expv - 1.0) + Vd / p.Rsh - p.Iph - I
def simple_diode_current(V: float, I0: float, Iph: float, vt: float) -> float:
"""Rs=0, Rsh=inf limit of the implicit form."""
ev = min(V / vt, EXP_CLIP)
return I0 * (math.exp(ev) - 1.0) - Iph