예제 #1
0
def test_fish():
    """
    test shunt current.
    """
    # make sympy symbols
    ish, vd, rsh = sympy.symbols(['ish', 'vd', 'rsh'])
    # shunt current
    ish = vd / rsh
    d_vd = sympy.diff(ish, vd)
    d_rsh = sympy.diff(ish, rsh)
    # evaluate
    test_data = {'vd': VD_1, 'rsh': RSH_1}
    fish_test, jish_test = diode.fish(**test_data)
    fish_expected = np.float(ish.evalf(subs=test_data))
    jish_expected = np.array(
        [d_vd.evalf(subs=test_data),
         d_rsh.evalf(subs=test_data)],
        dtype=np.float)
    LOGGER.debug('test: %g = expected: %g', fish_test, fish_expected)
    assert np.isclose(fish_test, fish_expected)
    assert np.allclose(jish_test, jish_expected.reshape(-1, 1))
예제 #2
0
def residual_two_diode(x, isc, voc, imp, vmp, tc):
    """
    Objective function to solve 2-diode model.
    :param x: parameters isat1, isat2, rs and rsh
    :param isc: short circuit current [A] at tc [C]
    :param voc: open circuit voltage [V] at tc [C]
    :param imp: max power current [A] at tc [C]
    :param vmp: max power voltage [V] at tc [C]
    :param tc: cell temperature [C]
    :return: norm of the residuals its sensitivity
    """
    # Constants
    q = diode.QE  # [C/electron] elementary electric charge
    # (n.b. 1 Coulomb = 1 A * s)
    kb = diode.KB  # [J/K/molecule] Boltzmann's constant
    tck = tc + 273.15  # [K] reference temperature
    # Governing Equation
    vt = kb * tck / q  # [V] thermal voltage
    # Rescale Variables
    isat1_t0 = np.exp(x[0])
    isat2 = np.exp(x[1])
    rs = x[2]**2.0
    rsh = x[3]**2.0
    # first diode saturation current
    isat1 = diode.isat_t(tc, isat1_t0)
    # Short Circuit
    vd_isc, _ = diode.fvd(vc=0.0, ic=isc, rs=rs)
    id1_isc, _ = diode.fid(isat=isat1, vd=vd_isc, m=1.0, vt=vt)
    id2_isc, _ = diode.fid(isat=isat2, vd=vd_isc, m=2.0, vt=vt)
    ish_isc, _ = diode.fish(vd=vd_isc, rsh=rsh)
    # Photo-generated Current
    iph = isc + id1_isc + id2_isc + ish_isc  # [A]
    # Open Circuit
    vd_voc, jvd_voc = diode.fvd(vc=voc, ic=0.0, rs=rs)
    id1_voc, jid1_voc = diode.fid(isat=isat1, vd=vd_voc, m=1.0, vt=vt)
    id2_voc, jid2_voc = diode.fid(isat=isat2, vd=vd_voc, m=2.0, vt=vt)
    ish_voc, jish_voc = diode.fish(vd=vd_voc, rsh=rsh)
    # Max Power Point
    vd_mpp, jvd_mpp = diode.fvd(vc=vmp, ic=imp, rs=rs)
    id1_mpp, jid1_mpp = diode.fid(isat=isat1, vd=vd_mpp, m=1.0, vt=vt)
    id2_mpp, jid2_mpp = diode.fid(isat=isat2, vd=vd_mpp, m=2.0, vt=vt)
    ish_mpp, jish_mpp = diode.fish(vd=vd_mpp, rsh=rsh)
    # Slope at Max Power Point
    dpdv, jdpdv = two_diode.fdpdv(isat1=isat1,
                                  isat2=isat2,
                                  rs=rs,
                                  rsh=rsh,
                                  ic=imp,
                                  vc=vmp,
                                  vt=vt)
    # Shunt Resistance
    frsh, jrsh = two_diode.fjrsh(isat1=isat1,
                                 isat2=isat2,
                                 rs=rs,
                                 rsh=rsh,
                                 vt=vt,
                                 isc=isc)
    # Residual
    # should be (M, ) array with M residual equations (constraints)
    f2 = np.stack(
        [
            (iph - id1_voc - id2_voc - ish_voc).T,  # Open Circuit
            (iph - id1_mpp - id2_mpp - ish_mpp - imp).T,  # Max Power Point
            dpdv.T,  # Slope at Max Power Point
            frsh.T  # Shunt Resistance
        ],
        axis=0).flatten()
    # Jacobian
    # should be (M, N) array with M residuals and N variables
    # [[df1/dx1, df1/dx2, ...], [df2/dx1, df2/dx2, ...]]
    jvoc = np.stack(
        (
            -jid1_voc[0],  # d/disat1
            -jid2_voc[0],  # d/disat2
            -jvd_voc[2] * (jid1_voc[1] + jid2_voc[1] + jish_voc[0]),  # d/drs
            -jish_voc[1]  # d/drsh
        ),
        axis=0).T.reshape(-1, 4)
    jmpp = np.stack(
        (
            -jid1_mpp[0],  # d/disat1
            -jid2_mpp[0],  # d/disat2
            -jvd_mpp[2] * (jid1_mpp[1] + jid2_mpp[1] + jish_mpp[0]),  # d/drs
            -jish_mpp[1]  # d.drsh
        ),
        axis=0).T.reshape(-1, 4)
    # Scaling Factors
    scale_fx = np.array([np.exp(x[0]), np.exp(x[1]), 2 * x[2], 2 * x[3]])
    # scales each column by the corresponding element
    j2 = np.concatenate(
        (jvoc, jmpp, jdpdv[:4].T.reshape(-1, 4), jrsh[:4].T.reshape(-1, 4)),
        axis=0) * scale_fx
    return f2, j2