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