예제 #1
0
def test_rectify_iv_curve(ivcurve):
    voltage, current = ivcurve

    vexp_no_dec = np.array([0., 1.,  5., 10., 25., 25.00001, 28., 30., 47.,
                            51.])
    iexp_no_dec = np.array([7., 6., 6., 5., 4., 3., 2.5, 2.7, 0.5, 0.])
    v, i = rectify_iv_curve(voltage, current)
    np.testing.assert_allclose(v, vexp_no_dec, atol=.0001)
    np.testing.assert_allclose(i, iexp_no_dec, atol=.0001)

    vexp = np.array([0., 1., 5., 10., 25., 28., 30., 47., 51.])
    iexp = np.array([7., 6., 6., 5., 3.5, 2.5, 2.7, 0.5, 0.])
    v, i = rectify_iv_curve(voltage, current, decimals=4)
    np.testing.assert_allclose(v, vexp, atol=.0001)
    np.testing.assert_allclose(i, iexp, atol=.0001)
예제 #2
0
def _initial_iv_params(ivcurves, ee, voc, isc, rsh, nnsvth):
    # sets initial values for iph, io, rs and quality filter u.
    # Helper function for fit_<model>_sandia.
    n = len(ivcurves['v_oc'])
    io = np.ones(n)
    iph = np.ones(n)
    rs = np.ones(n)

    for j in range(n):

        if rsh[j] > 0:
            volt, curr = rectify_iv_curve(ivcurves['v'][j],
                                          ivcurves['i'][j])
            # Initial estimate of Io, evaluate the single diode model at
            # voc and approximate Iph + Io = Isc [5] Step 3a; [6] Step 3b
            io[j] = (isc[j] - voc[j] / rsh[j]) * np.exp(-voc[j] /
                                                        nnsvth[j])

            # initial estimate of rs from dI/dV near Voc
            # [5] Step 3a; [6] Step 3c
            [didv, d2id2v] = _numdiff(volt, curr)
            t3 = volt > .5 * voc[j]
            t4 = volt < .9 * voc[j]
            tmp = -rsh[j] * didv - 1.
            with np.errstate(invalid="ignore"):  # expect nan in didv
                v = np.logical_and.reduce(np.array([t3, t4, ~np.isnan(tmp),
                                                    np.greater(tmp, 0)]))
            if np.any(v):
                vtrs = (nnsvth[j] / isc[j] * (
                    np.log(tmp[v] * nnsvth[j] / (rsh[j] * io[j]))
                    - volt[v] / nnsvth[j]))
                rs[j] = np.mean(vtrs[vtrs > 0], axis=0)
            else:
                rs[j] = 0.

            # Initial estimate of Iph, evaluate the single diode model at
            # Isc [5] Step 3a; [6] Step 3d
            iph[j] = isc[j] + io[j] * np.expm1(isc[j] / nnsvth[j]) \
                + isc[j] * rs[j] / rsh[j]

        else:
            io[j] = np.nan
            rs[j] = np.nan
            iph[j] = np.nan

        # Filter IV curves for good initial values
        # [5] Step 3b
        u = _filter_params(ee, isc, io, rs, rsh)

        # [5] Step 3c
        # Refine Io to match Voc
        io[u] = _update_io(voc[u], iph[u], io[u], rs[u], rsh[u], nnsvth[u])

        # parameters [6], Step 3c
        # Calculate Iph to be consistent with Isc and current values of other
        iph = isc + io * np.expm1(rs * isc / nnsvth) + isc * rs / rsh

    return iph, io, rs, u
예제 #3
0
def fit_desoto_sandia(ivcurves, specs, const=None, maxiter=5, eps1=1.e-3):
    """
    Estimate parameters for the De Soto module performance model.

    Parameters
    ----------
    ivcurves : dict
        i : array
            One array element for each IV curve. The jth element is itself an
            array of current for jth IV curve (same length as v[j]) [A]
        v : array
            One array element for each IV curve. The jth element is itself an
            array of voltage for jth IV curve  (same length as i[j]) [V]
        ee : array
            effective irradiance for each IV curve, i.e., POA broadband
            irradiance adjusted by solar spectrum modifier [W / m^2]
        tc : array
            cell temperature for each IV curve [C]
        i_sc : array
            short circuit current for each IV curve [A]
        v_oc : array
            open circuit voltage for each IV curve [V]
        i_mp : array
            current at max power point for each IV curve [A]
        v_mp : array
            voltage at max power point for each IV curve [V]

    specs : dict
        cells_in_series : int
            number of cells in series
        alpha_sc : float
            temperature coefficient of Isc [A/C]
        beta_voc : float
            temperature coefficient of Voc [V/C]

    const : dict
        E0 : float
            effective irradiance at STC, default 1000 [W/m^2]
        T0 : float
            cell temperature at STC, default 25 [C]
        k : float
            1.38066E-23 J/K (Boltzmann's constant)
        q : float
            1.60218E-19 Coulomb (elementary charge)

    maxiter : int, default 5
        input that sets the maximum number of iterations for the parameter
        updating part of the algorithm.

    eps1: float, default 1e-3
        Tolerance for the IV curve fitting. The parameter updating stops when
        absolute values of the percent change in mean, max and standard
        deviation of Imp, Vmp and Pmp between iterations are all less than
        eps1, or when the number of iterations exceeds maxiter.

    Returns
    -------
    dict
        I_L_ref : float
            light current at STC [A]
        I_o_ref : float
            dark current at STC [A]
        EgRef : float
            effective band gap at STC [eV]
        R_s : float
            series resistance at STC [ohm]
        R_sh_ref : float
            shunt resistance at STC [ohm]
        cells_in_series : int
            number of cells in series
        iph : array
            light current for each IV curve [A]
        io : array
            dark current for each IV curve [A]
        rs : array
            series resistance for each IV curve [ohm]
        rsh : array
            shunt resistance for each IV curve [ohm]
        u : array
            boolean for each IV curve indicating that the parameter values
            are deemed reasonable by the private function ``_filter_params``

    Notes
    -----
    The De Soto module performance model is described in [1]_. The fitting
    method is documented in [2]_, [3]_. Ported from PVLib Matlab [4]_.

    References
    ----------
    .. [1] W. De Soto et al., "Improvement and validation of a model for
       photovoltaic array performance", Solar Energy, vol 80, pp. 78-88,
       2006.
    .. [2] C. Hansen, Parameter Estimation for Single Diode Models of
       Photovoltaic Modules, Sandia National Laboratories Report SAND2015-2065
    .. [3] C. Hansen, Estimation of Parameters for Single Diode Models using
        Measured IV Curves, Proc. of the 39th IEEE PVSC, June 2013.
    .. [4] PVLib MATLAB https://github.com/sandialabs/MATLAB_PV_LIB
    """

    if const is None:
        const = {'E0': 1000.0, 'T0': 25.0, 'k': 1.38066e-23, 'q': 1.60218e-19}

    ee = ivcurves['ee']
    tc = ivcurves['tc']
    tck = tc + 273.15
    isc = ivcurves['i_sc']
    voc = ivcurves['v_oc']
    imp = ivcurves['i_mp']
    vmp = ivcurves['v_mp']

    # Cell Thermal Voltage
    vth = const['k'] / const['q'] * tck

    n = len(voc)

    # Initial estimate of Rsh used to obtain the diode factor gamma0 and diode
    # temperature coefficient mu_gamma. Rsh is estimated using the co-content
    # integral method.

    rsh = np.ones(n)
    for j in range(n):
        voltage, current = rectify_iv_curve(ivcurves['v'][j], ivcurves['i'][j])
        # initial estimate of Rsh, from integral over voltage regression
        # [5] Step 3a; [6] Step 3a
        _, _, _, rsh[j], _ = _fit_sandia_cocontent(
            voltage, current, vth[j] * specs['cells_in_series'])

    n0 = _fit_desoto_sandia_diode(ee, voc, vth, tc, specs, const)

    bad_n = np.isnan(n0) or not np.isreal(n0)

    if bad_n:
        raise RuntimeError(
            "Failed to estimate the diode (ideality) factor parameter;"
            " aborting parameter estimation.")

    nnsvth = n0 * specs['cells_in_series'] * vth

    # For each IV curve, sequentially determine initial values for Io, Rs,
    # and Iph [5] Step 3a; [6] Step 3
    iph, io, rs, u = _initial_iv_params(ivcurves, ee, voc, isc, rsh,
                                        nnsvth)

    # Update values for each IV curve to converge at vmp, imp, voc and isc
    iph, io, rs, rsh, u = _update_iv_params(voc, isc, vmp, imp, ee,
                                            iph, io, rs, rsh, nnsvth, u,
                                            maxiter, eps1)

    # get single diode models from converged values for each IV curve
    desoto = _extract_sdm_params(ee, tc, iph, io, rs, rsh, n0, u,
                                 specs, const, model='desoto')
    # Add parameters estimated in this function
    desoto['a_ref'] = n0 * specs['cells_in_series'] * const['k'] / \
        const['q'] * (const['T0'] + 273.15)
    desoto['cells_in_series'] = specs['cells_in_series']

    return desoto
예제 #4
0
def fit_pvsyst_sandia(ivcurves, specs, const=None, maxiter=5, eps1=1.e-3):
    """
    Estimate parameters for the PVsyst module performance model.

    Parameters
    ----------
    ivcurves : dict
        i : array
            One array element for each IV curve. The jth element is itself an
            array of current for jth IV curve (same length as v[j]) [A]
        v : array
            One array element for each IV curve. The jth element is itself an
            array of voltage for jth IV curve  (same length as i[j]) [V]
        ee : array
            effective irradiance for each IV curve, i.e., POA broadband
            irradiance adjusted by solar spectrum modifier [W / m^2]
        tc : array
            cell temperature for each IV curve [C]
        i_sc : array
            short circuit current for each IV curve [A]
        v_oc : array
            open circuit voltage for each IV curve [V]
        i_mp : array
            current at max power point for each IV curve [A]
        v_mp : array
            voltage at max power point for each IV curve [V]

    specs : dict
        cells_in_series : int
            number of cells in series
        alpha_sc : float
            temperature coefficient of isc [A/C]

    const : dict
        E0 : float
            effective irradiance at STC, default 1000 [W/m^2]
        T0 : float
            cell temperature at STC, default 25 [C]
        k : float
            1.38066E-23 J/K (Boltzmann's constant)
        q : float
            1.60218E-19 Coulomb (elementary charge)

    maxiter : int, default 5
        input that sets the maximum number of iterations for the parameter
        updating part of the algorithm.

    eps1: float, default 1e-3
        Tolerance for the IV curve fitting. The parameter updating stops when
        absolute values of the percent change in mean, max and standard
        deviation of Imp, Vmp and Pmp between iterations are all less than
        eps1, or when the number of iterations exceeds maxiter.

    Returns
    -------
    dict
        I_L_ref : float
            light current at STC [A]
        I_o_ref : float
            dark current at STC [A]
        EgRef : float
            effective band gap at STC [eV]
        R_s : float
            series resistance at STC [ohm]
        R_sh_ref : float
            shunt resistance at STC [ohm]
        R_sh_0 : float
            shunt resistance at zero irradiance [ohm]
        R_sh_exp : float
            exponential factor defining decrease in shunt resistance with
            increasing effective irradiance
        gamma_ref : float
            diode (ideality) factor at STC [unitless]
        mu_gamma : float
            temperature coefficient for diode (ideality) factor [1/K]
        cells_in_series : int
            number of cells in series
        iph : array
            light current for each IV curve [A]
        io : array
            dark current for each IV curve [A]
        rs : array
            series resistance for each IV curve [ohm]
        rsh : array
            shunt resistance for each IV curve [ohm]
        u : array
            boolean for each IV curve indicating that the parameter values
            are deemed reasonable by the private function ``_filter_params``

    Notes
    -----
    The PVsyst module performance model is described in [1]_, [2]_, and [3]_.
    The fitting method is documented in [4]_, [5]_, and [6]_.
    Ported from PVLib Matlab [7]_.

    References
    ----------
    .. [1] K. Sauer, T. Roessler, C. W. Hansen, Modeling the Irradiance and
       Temperature Dependence of Photovoltaic Modules in PVsyst, IEEE Journal
       of Photovoltaics v5(1), January 2015.
    .. [2] A. Mermoud, PV Modules modeling, Presentation at the 2nd PV
       Performance Modeling Workshop, Santa Clara, CA, May 2013
    .. [3] A. Mermoud, T. Lejeuene, Performance Assessment of a Simulation
       Model for PV modules of any available technology, 25th European
       Photovoltaic Solar Energy Conference, Valencia, Spain, Sept. 2010
    .. [4] C. Hansen, Estimating Parameters for the PVsyst Version 6
       Photovoltaic Module Performance Model, Sandia National Laboratories
       Report SAND2015-8598
    .. [5] C. Hansen, Parameter Estimation for Single Diode Models of
       Photovoltaic Modules, Sandia National Laboratories Report SAND2015-2065
    .. [6] C. Hansen, Estimation of Parameters for Single Diode Models using
        Measured IV Curves, Proc. of the 39th IEEE PVSC, June 2013.
    .. [7] PVLib MATLAB https://github.com/sandialabs/MATLAB_PV_LIB
    """

    if const is None:
        const = {'E0': 1000.0, 'T0': 25.0, 'k': 1.38066e-23, 'q': 1.60218e-19}

    ee = ivcurves['ee']
    tc = ivcurves['tc']
    tck = tc + 273.15
    isc = ivcurves['i_sc']
    voc = ivcurves['v_oc']
    imp = ivcurves['i_mp']
    vmp = ivcurves['v_mp']

    # Cell Thermal Voltage
    vth = const['k'] / const['q'] * tck

    n = len(ivcurves['v_oc'])

    # Initial estimate of Rsh used to obtain the diode factor gamma0 and diode
    # temperature coefficient mu_gamma. Rsh is estimated using the co-content
    # integral method.

    rsh = np.ones(n)
    for j in range(n):
        voltage, current = rectify_iv_curve(ivcurves['v'][j], ivcurves['i'][j])
        # initial estimate of Rsh, from integral over voltage regression
        # [5] Step 3a; [6] Step 3a
        _, _, _, rsh[j], _ = _fit_sandia_cocontent(
            voltage, current, vth[j] * specs['cells_in_series'])

    gamma_ref, mu_gamma = _fit_pvsyst_sandia_gamma(voc, isc, rsh, vth, tck,
                                                   specs, const)

    badgamma = np.isnan(gamma_ref) or np.isnan(mu_gamma) \
        or not np.isreal(gamma_ref) or not np.isreal(mu_gamma)

    if badgamma:
        raise RuntimeError(
            "Failed to estimate the diode (ideality) factor parameter;"
            " aborting parameter estimation.")

    gamma = gamma_ref + mu_gamma * (tc - const['T0'])
    nnsvth = gamma * (vth * specs['cells_in_series'])

    # For each IV curve, sequentially determine initial values for Io, Rs,
    # and Iph [5] Step 3a; [6] Step 3
    iph, io, rs, u = _initial_iv_params(ivcurves, ee, voc, isc, rsh,
                                        nnsvth)

    # Update values for each IV curve to converge at vmp, imp, voc and isc
    iph, io, rs, rsh, u = _update_iv_params(voc, isc, vmp, imp, ee,
                                            iph, io, rs, rsh, nnsvth, u,
                                            maxiter, eps1)

    # get single diode models from converged values for each IV curve
    pvsyst = _extract_sdm_params(ee, tc, iph, io, rs, rsh, gamma, u,
                                 specs, const, model='pvsyst')
    # Add parameters estimated in this function
    pvsyst['gamma_ref'] = gamma_ref
    pvsyst['mu_gamma'] = mu_gamma
    pvsyst['cells_in_series'] = specs['cells_in_series']

    return pvsyst