コード例 #1
0
def test_brentq_spr_e20_327():
    """test pvsystem.singlediode with Brent method on SPR-E20-327"""
    spr_e20_327 = CECMOD.SunPower_SPR_E20_327
    x = pvsystem.calcparams_desoto(
        effective_irradiance=POA, temp_cell=TCELL,
        alpha_sc=spr_e20_327.alpha_sc, a_ref=spr_e20_327.a_ref,
        I_L_ref=spr_e20_327.I_L_ref, I_o_ref=spr_e20_327.I_o_ref,
        R_sh_ref=spr_e20_327.R_sh_ref, R_s=spr_e20_327.R_s,
        EgRef=1.121, dEgdT=-0.0002677)
    il, io, rs, rsh, nnsvt = x
    pvs = pvsystem.singlediode(*x, method='lambertw')
    out = pvsystem.singlediode(*x, method='brentq')
    isc, voc, imp, vmp, pmp, ix, ixx = out.values()
    assert np.isclose(pvs['i_sc'], isc)
    assert np.isclose(pvs['v_oc'], voc)
    # the singlediode method doesn't actually get the MPP correct
    pvs_imp = pvsystem.i_from_v(rsh, rs, nnsvt, vmp, io, il, method='lambertw')
    pvs_vmp = pvsystem.v_from_i(rsh, rs, nnsvt, imp, io, il, method='lambertw')
    assert np.isclose(pvs_imp, imp)
    assert np.isclose(pvs_vmp, vmp)
    assert np.isclose(pvs['p_mp'], pmp)
    assert np.isclose(pvs['i_x'], ix)
    pvs_ixx = pvsystem.i_from_v(rsh, rs, nnsvt, (voc + vmp)/2, io, il,
                                method='lambertw')
    assert np.isclose(pvs_ixx, ixx)
    return isc, voc, imp, vmp, pmp, pvs
コード例 #2
0
def test_newton_fs_495():
    """test pvsystem.singlediode with Newton method on FS495"""
    fs_495 = CECMOD.First_Solar_FS_495
    x = pvsystem.calcparams_desoto(
        effective_irradiance=POA, temp_cell=TCELL,
        alpha_sc=fs_495.alpha_sc, a_ref=fs_495.a_ref, I_L_ref=fs_495.I_L_ref,
        I_o_ref=fs_495.I_o_ref, R_sh_ref=fs_495.R_sh_ref, R_s=fs_495.R_s,
        EgRef=1.475, dEgdT=-0.0003)
    il, io, rs, rsh, nnsvt = x
    x += (101, )
    pvs = pvsystem.singlediode(*x, method='lambertw')
    out = pvsystem.singlediode(*x, method='newton')
    isc, voc, imp, vmp, pmp, ix, ixx, i, v = out.values()
    assert np.isclose(pvs['i_sc'], isc)
    assert np.isclose(pvs['v_oc'], voc)
    # the singlediode method doesn't actually get the MPP correct
    pvs_imp = pvsystem.i_from_v(rsh, rs, nnsvt, vmp, io, il, method='lambertw')
    pvs_vmp = pvsystem.v_from_i(rsh, rs, nnsvt, imp, io, il, method='lambertw')
    assert np.isclose(pvs_imp, imp)
    assert np.isclose(pvs_vmp, vmp)
    assert np.isclose(pvs['p_mp'], pmp)
    assert np.isclose(pvs['i_x'], ix)
    pvs_ixx = pvsystem.i_from_v(rsh, rs, nnsvt, (voc + vmp)/2, io, il,
                                method='lambertw')
    assert np.isclose(pvs_ixx, ixx)
    return isc, voc, imp, vmp, pmp, i, v, pvs
コード例 #3
0
def test_newton_fs_495():
    """test pvsystem.singlediode with Newton method on FS495"""
    fs_495 = CECMOD.First_Solar_FS_495
    x = pvsystem.calcparams_desoto(effective_irradiance=POA,
                                   temp_cell=TCELL,
                                   alpha_sc=fs_495.alpha_sc,
                                   a_ref=fs_495.a_ref,
                                   I_L_ref=fs_495.I_L_ref,
                                   I_o_ref=fs_495.I_o_ref,
                                   R_sh_ref=fs_495.R_sh_ref,
                                   R_s=fs_495.R_s,
                                   EgRef=1.475,
                                   dEgdT=-0.0003)
    il, io, rs, rsh, nnsvt = x
    x += (101, )
    pvs = pvsystem.singlediode(*x, method='lambertw')
    out = pvsystem.singlediode(*x, method='newton')
    isc, voc, imp, vmp, pmp, ix, ixx, i, v = out.values()
    assert np.isclose(pvs['i_sc'], isc)
    assert np.isclose(pvs['v_oc'], voc)
    # the singlediode method doesn't actually get the MPP correct
    pvs_imp = pvsystem.i_from_v(rsh, rs, nnsvt, vmp, io, il, method='lambertw')
    pvs_vmp = pvsystem.v_from_i(rsh, rs, nnsvt, imp, io, il, method='lambertw')
    assert np.isclose(pvs_imp, imp)
    assert np.isclose(pvs_vmp, vmp)
    assert np.isclose(pvs['p_mp'], pmp)
    assert np.isclose(pvs['i_x'], ix)
    pvs_ixx = pvsystem.i_from_v(rsh,
                                rs,
                                nnsvt, (voc + vmp) / 2,
                                io,
                                il,
                                method='lambertw')
    assert np.isclose(pvs_ixx, ixx)
    return isc, voc, imp, vmp, pmp, i, v, pvs
コード例 #4
0
def test_brentq_spr_e20_327():
    """test pvsystem.singlediode with Brent method on SPR-E20-327"""
    spr_e20_327 = CECMOD.SunPower_SPR_E20_327
    x = pvsystem.calcparams_desoto(effective_irradiance=POA,
                                   temp_cell=TCELL,
                                   alpha_sc=spr_e20_327.alpha_sc,
                                   a_ref=spr_e20_327.a_ref,
                                   I_L_ref=spr_e20_327.I_L_ref,
                                   I_o_ref=spr_e20_327.I_o_ref,
                                   R_sh_ref=spr_e20_327.R_sh_ref,
                                   R_s=spr_e20_327.R_s,
                                   EgRef=1.121,
                                   dEgdT=-0.0002677)
    il, io, rs, rsh, nnsvt = x
    pvs = pvsystem.singlediode(*x, method='lambertw')
    out = pvsystem.singlediode(*x, method='brentq')
    isc, voc, imp, vmp, pmp, ix, ixx = out.values()
    assert np.isclose(pvs['i_sc'], isc)
    assert np.isclose(pvs['v_oc'], voc)
    # the singlediode method doesn't actually get the MPP correct
    pvs_imp = pvsystem.i_from_v(rsh, rs, nnsvt, vmp, io, il, method='lambertw')
    pvs_vmp = pvsystem.v_from_i(rsh, rs, nnsvt, imp, io, il, method='lambertw')
    assert np.isclose(pvs_imp, imp)
    assert np.isclose(pvs_vmp, vmp)
    assert np.isclose(pvs['p_mp'], pmp)
    assert np.isclose(pvs['i_x'], ix)
    pvs_ixx = pvsystem.i_from_v(rsh,
                                rs,
                                nnsvt, (voc + vmp) / 2,
                                io,
                                il,
                                method='lambertw')
    assert np.isclose(pvs_ixx, ixx)
    return isc, voc, imp, vmp, pmp, pvs
コード例 #5
0
def test_method_spr_e20_327(method, cec_module_spr_e20_327):
    """test pvsystem.singlediode with different methods on SPR-E20-327"""
    spr_e20_327 = cec_module_spr_e20_327
    x = pvsystem.calcparams_desoto(
        effective_irradiance=POA, temp_cell=TCELL,
        alpha_sc=spr_e20_327['alpha_sc'], a_ref=spr_e20_327['a_ref'],
        I_L_ref=spr_e20_327['I_L_ref'], I_o_ref=spr_e20_327['I_o_ref'],
        R_sh_ref=spr_e20_327['R_sh_ref'], R_s=spr_e20_327['R_s'],
        EgRef=1.121, dEgdT=-0.0002677)
    il, io, rs, rsh, nnsvt = x
    pvs = pvsystem.singlediode(*x, method='lambertw')
    out = pvsystem.singlediode(*x, method=method)
    isc, voc, imp, vmp, pmp, ix, ixx = out.values()
    assert np.isclose(pvs['i_sc'], isc)
    assert np.isclose(pvs['v_oc'], voc)
    # the singlediode method doesn't actually get the MPP correct
    pvs_imp = pvsystem.i_from_v(rsh, rs, nnsvt, vmp, io, il, method='lambertw')
    pvs_vmp = pvsystem.v_from_i(rsh, rs, nnsvt, imp, io, il, method='lambertw')
    assert np.isclose(pvs_imp, imp)
    assert np.isclose(pvs_vmp, vmp)
    assert np.isclose(pvs['p_mp'], pmp)
    assert np.isclose(pvs['i_x'], ix)
    pvs_ixx = pvsystem.i_from_v(rsh, rs, nnsvt, (voc + vmp)/2, io, il,
                                method='lambertw')
    assert np.isclose(pvs_ixx, ixx)
コード例 #6
0
def test_newton_fs_495(method, cec_module_fs_495):
    """test pvsystem.singlediode with different methods on FS495"""
    fs_495 = cec_module_fs_495
    x = pvsystem.calcparams_desoto(
        effective_irradiance=POA, temp_cell=TCELL,
        alpha_sc=fs_495['alpha_sc'], a_ref=fs_495['a_ref'],
        I_L_ref=fs_495['I_L_ref'], I_o_ref=fs_495['I_o_ref'],
        R_sh_ref=fs_495['R_sh_ref'], R_s=fs_495['R_s'],
        EgRef=1.475, dEgdT=-0.0003)
    il, io, rs, rsh, nnsvt = x
    x += (101, )
    pvs = pvsystem.singlediode(*x, method='lambertw')
    out = pvsystem.singlediode(*x, method=method)
    isc, voc, imp, vmp, pmp, ix, ixx, i, v = out.values()
    assert np.isclose(pvs['i_sc'], isc)
    assert np.isclose(pvs['v_oc'], voc)
    # the singlediode method doesn't actually get the MPP correct
    pvs_imp = pvsystem.i_from_v(rsh, rs, nnsvt, vmp, io, il, method='lambertw')
    pvs_vmp = pvsystem.v_from_i(rsh, rs, nnsvt, imp, io, il, method='lambertw')
    assert np.isclose(pvs_imp, imp)
    assert np.isclose(pvs_vmp, vmp)
    assert np.isclose(pvs['p_mp'], pmp)
    assert np.isclose(pvs['i_x'], ix)
    pvs_ixx = pvsystem.i_from_v(rsh, rs, nnsvt, (voc + vmp)/2, io, il,
                                method='lambertw')
    assert np.isclose(pvs_ixx, ixx)
コード例 #7
0
def test_singlediode_array():
    # github issue 221
    photocurrent = np.linspace(0, 10, 11)
    resistance_shunt = 16
    resistance_series = 0.094
    nNsVth = 0.473
    saturation_current = 1.943e-09

    sd = pvsystem.singlediode(photocurrent,
                              saturation_current,
                              resistance_series,
                              resistance_shunt,
                              nNsVth,
                              method='lambertw')

    expected = np.array([
        0., 0.54538398, 1.43273966, 2.36328163, 3.29255606, 4.23101358,
        5.16177031, 6.09368251, 7.02197553, 7.96846051, 8.88220557
    ])

    assert_allclose(sd['i_mp'], expected, atol=0.01)

    sd = pvsystem.singlediode(photocurrent, saturation_current,
                              resistance_series, resistance_shunt, nNsVth)

    expected = pvsystem.i_from_v(resistance_shunt,
                                 resistance_series,
                                 nNsVth,
                                 sd['v_mp'],
                                 saturation_current,
                                 photocurrent,
                                 method='lambertw')

    assert_allclose(sd['i_mp'], expected, atol=0.01)
コード例 #8
0
ファイル: test_pvsystem.py プロジェクト: edresch/pvlib-python
def test_singlediode():  
    cecmodule = sam_data['cecmod'].Example_Module 
    IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto(S=irrad_data.GHI,
                                         temp_cell=25,
                                         alpha_isc=cecmodule['Alpha_sc'],
                                         module_parameters=cecmodule,
                                         EgRef=1.121,
                                         dEgdT=-0.0002677)                       
    pvsystem.singlediode(module=cecmodule, IL=IL, I0=I0, Rs=Rs, Rsh=Rsh,
                         nNsVth=nNsVth)
コード例 #9
0
def test_fit_sandia_simple(get_test_iv_params, get_bad_iv_curves):
    test_params = get_test_iv_params
    testcurve = pvsystem.singlediode(photocurrent=test_params['IL'],
                                     saturation_current=test_params['I0'],
                                     resistance_shunt=test_params['Rsh'],
                                     resistance_series=test_params['Rs'],
                                     nNsVth=test_params['nNsVth'],
                                     ivcurve_pnts=300)
    expected = tuple(test_params[k]
                     for k in ['IL', 'I0', 'Rs', 'Rsh', 'nNsVth'])
    result = sde.fit_sandia_simple(voltage=testcurve['v'],
                                   current=testcurve['i'])
    assert np.allclose(result, expected, rtol=5e-5)
    result = sde.fit_sandia_simple(voltage=testcurve['v'],
                                   current=testcurve['i'],
                                   v_oc=testcurve['v_oc'],
                                   i_sc=testcurve['i_sc'])
    assert np.allclose(result, expected, rtol=5e-5)
    result = sde.fit_sandia_simple(voltage=testcurve['v'],
                                   current=testcurve['i'],
                                   v_oc=testcurve['v_oc'],
                                   i_sc=testcurve['i_sc'],
                                   v_mp_i_mp=(testcurve['v_mp'],
                                              testcurve['i_mp']))
    assert np.allclose(result, expected, rtol=5e-5)
    result = sde.fit_sandia_simple(voltage=testcurve['v'],
                                   current=testcurve['i'],
                                   vlim=0.1)
    assert np.allclose(result, expected, rtol=5e-5)
コード例 #10
0
def test_singlediode_series_ivcurve(cec_module_params):
    times = pd.DatetimeIndex(start='2015-06-01', periods=3, freq='6H')
    poa_data = pd.Series([0, 400, 800], index=times)
    IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto(
                                         poa_data,
                                         temp_cell=25,
                                         alpha_isc=cec_module_params['alpha_sc'],
                                         module_parameters=cec_module_params,
                                         EgRef=1.121,
                                         dEgdT=-0.0002677)

    out = pvsystem.singlediode(IL, I0, Rs, Rsh, nNsVth, ivcurve_pnts=3)

    expected = OrderedDict([('i_sc', array([        nan,  3.01054475,  6.00675648])),
             ('v_oc', array([         nan,   9.96886962,  10.29530483])),
             ('i_mp', array([        nan,  2.65191983,  5.28594672])),
             ('v_mp', array([        nan,  8.33392491,  8.4159707 ])),
             ('p_mp', array([         nan,  22.10090078,  44.48637274])),
             ('i_x', array([        nan,  2.88414114,  5.74622046])),
             ('i_xx', array([        nan,  2.04340914,  3.90007956])),
             ('v',
              array([[         nan,          nan,          nan],
       [  0.        ,   4.98443481,   9.96886962],
       [  0.        ,   5.14765242,  10.29530483]])),
             ('i',
              array([[             nan,              nan,              nan],
       [  3.01079860e+00,   2.88414114e+00,   3.10862447e-14],
       [  6.00726296e+00,   5.74622046e+00,   0.00000000e+00]]))])

    for k, v in out.items():
        assert_allclose(expected[k], v, atol=1e-2)
コード例 #11
0
def test_fit_desoto_sandia(cec_params_cansol_cs5p_220p):
    # this test computes a set of IV curves for the input fixture, fits
    # the De Soto model to the calculated IV curves, and compares the fitted
    # parameters to the starting values
    params = cec_params_cansol_cs5p_220p['params']
    params.pop('Adjust')
    specs = cec_params_cansol_cs5p_220p['specs']
    effective_irradiance = np.array([400., 500., 600., 700., 800., 900.,
                                     1000.])
    temp_cell = np.array([15., 25., 35., 45.])
    ee = np.tile(effective_irradiance, len(temp_cell))
    tc = np.repeat(temp_cell, len(effective_irradiance))
    iph, io, rs, rsh, nnsvth = pvsystem.calcparams_desoto(
        ee, tc, alpha_sc=specs['alpha_sc'], **params)
    sim_ivcurves = pvsystem.singlediode(iph, io, rs, rsh, nnsvth, 300)
    sim_ivcurves['ee'] = ee
    sim_ivcurves['tc'] = tc

    result = sdm.fit_desoto_sandia(sim_ivcurves, specs)
    modeled = pd.Series(index=params.keys(), data=np.nan)
    modeled['a_ref'] = result['a_ref']
    modeled['I_L_ref'] = result['I_L_ref']
    modeled['I_o_ref'] = result['I_o_ref']
    modeled['R_s'] = result['R_s']
    modeled['R_sh_ref'] = result['R_sh_ref']
    expected = pd.Series(params)
    assert np.allclose(modeled[params.keys()].values,
                       expected[params.keys()].values, rtol=5e-2)
コード例 #12
0
def test_singlediode_series_ivcurve(cec_module_params):
    times = pd.DatetimeIndex(start='2015-06-01', periods=3, freq='6H')
    poa_data = pd.Series([0, 400, 800], index=times)
    IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto(
                                  poa_data, temp_cell=25,
                                  alpha_isc=cec_module_params['alpha_sc'],
                                  module_parameters=cec_module_params,
                                  EgRef=1.121, dEgdT=-0.0002677)

    out = pvsystem.singlediode(IL, I0, Rs, Rsh, nNsVth, ivcurve_pnts=3)

    expected = OrderedDict([('i_sc', array([0., 3.01054475, 6.00675648])),
                            ('v_oc', array([0., 9.96886962, 10.29530483])),
                            ('i_mp', array([0., 2.65191983, 5.28594672])),
                            ('v_mp', array([0., 8.33392491, 8.4159707])),
                            ('p_mp', array([0., 22.10090078, 44.48637274])),
                            ('i_x', array([0., 2.88414114, 5.74622046])),
                            ('i_xx', array([0., 2.04340914, 3.90007956])),
                            ('v', array([[0., 0., 0.],
                                         [0., 4.98443481, 9.96886962],
                                         [0., 5.14765242, 10.29530483]])),
                            ('i', array([[0., 0., 0.],
                                         [3.01079860e+00, 2.88414114e+00,
                                          3.10862447e-14],
                                         [6.00726296e+00, 5.74622046e+00,
                                          0.00000000e+00]]))])

    for k, v in out.items():
        assert_allclose(v, expected[k], atol=1e-2)
コード例 #13
0
ファイル: sdm.py プロジェクト: kanderso-nrel/pvlib-python
def _update_iv_params(voc, isc, vmp, imp, ee, iph, io, rs, rsh, nnsvth, u,
                      maxiter, eps1):
    # Refine Rsh, Rs, Io and Iph in that order.
    # Helper function for fit_<model>_sandia.
    counter = 1.  # counter variable for parameter updating while loop,
    # counts iterations
    prevconvergeparams = {}
    prevconvergeparams['state'] = 0.0

    not_converged = np.array([True])

    while not_converged.any() and counter <= maxiter:
        # update rsh to match max power point using a fixed point method.
        rsh[u] = _update_rsh_fixed_pt(vmp[u], imp[u], iph[u], io[u], rs[u],
                                      rsh[u], nnsvth[u])

        # Calculate Rs to be consistent with Rsh and maximum power point
        _, phi = _calc_theta_phi_exact(vmp[u], imp[u], iph[u], io[u],
                                       rs[u], rsh[u], nnsvth[u])
        rs[u] = (iph[u] + io[u] - imp[u]) * rsh[u] / imp[u] - \
            nnsvth[u] * phi / imp[u] - vmp[u] / imp[u]

        # Update filter for good parameters
        u = _filter_params(ee, isc, io, rs, rsh)

        # Update value for io to match voc
        io[u] = _update_io(voc[u], iph[u], io[u], rs[u], rsh[u], nnsvth[u])

        # Calculate Iph to be consistent with Isc and other parameters
        iph = isc + io * np.expm1(rs * isc / nnsvth) + isc * rs / rsh

        # update filter for good parameters
        u = _filter_params(ee, isc, io, rs, rsh)

        # compute the IV curve from the current parameter values
        result = singlediode(iph[u], io[u], rs[u], rsh[u], nnsvth[u])

        # check convergence criteria
        # [5] Step 3d
        convergeparams = _check_converge(
            prevconvergeparams, result, vmp[u], imp[u], counter)

        prevconvergeparams = convergeparams
        counter += 1.
        t5 = prevconvergeparams['vmperrmeanchange'] >= eps1
        t6 = prevconvergeparams['imperrmeanchange'] >= eps1
        t7 = prevconvergeparams['pmperrmeanchange'] >= eps1
        t8 = prevconvergeparams['vmperrstdchange'] >= eps1
        t9 = prevconvergeparams['imperrstdchange'] >= eps1
        t10 = prevconvergeparams['pmperrstdchange'] >= eps1
        t11 = prevconvergeparams['vmperrabsmaxchange'] >= eps1
        t12 = prevconvergeparams['imperrabsmaxchange'] >= eps1
        t13 = prevconvergeparams['pmperrabsmaxchange'] >= eps1
        not_converged = np.logical_or.reduce(np.array([t5, t6, t7, t8, t9,
                                                       t10, t11, t12, t13]))

    return iph, io, rs, rsh, u
コード例 #14
0
 def pv_fit_loss_func(params):
     """Loss function for physical pv-cell parameters."""
     I_ph, I_0, R_s, R_sh, v_th = params
     pv = pvsystem.singlediode(I_ph, I_0, R_s, R_sh, v_th)
     return np.sum(np.abs(
         np.asarray([
             pv['i_sc'] - i_sc, pv['v_oc'] - v_oc, pv['i_mp'] - i_mp,
             pv['v_mp'] - v_mp
         ])),
                   axis=0)
コード例 #15
0
ファイル: test_pvsystem.py プロジェクト: wukunna/pvlib-python
def test_singlediode_series():
    cecmodule = sam_data['cecmod'].Example_Module
    IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto(
        irrad_data['ghi'],
        temp_cell=25,
        alpha_isc=cecmodule['alpha_sc'],
        module_parameters=cecmodule,
        EgRef=1.121,
        dEgdT=-0.0002677)
    out = pvsystem.singlediode(cecmodule, IL, I0, Rs, Rsh, nNsVth)
    assert isinstance(out, pd.DataFrame)
コード例 #16
0
def test_singlediode_series():  
    cecmodule = sam_data['cecmod'].Example_Module 
    IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto(
                                         irrad_data['ghi'],
                                         temp_cell=25,
                                         alpha_isc=cecmodule['alpha_sc'],
                                         module_parameters=cecmodule,
                                         EgRef=1.121,
                                         dEgdT=-0.0002677)                       
    out = pvsystem.singlediode(cecmodule, IL, I0, Rs, Rsh, nNsVth)
    assert isinstance(out, pd.DataFrame)
コード例 #17
0
def test_singlediode_series(cec_module_params):
    times = pd.DatetimeIndex(start='2015-01-01', periods=2, freq='12H')
    poa_data = pd.Series([0, 800], index=times)
    IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto(
                                         poa_data,
                                         temp_cell=25,
                                         alpha_isc=cec_module_params['alpha_sc'],
                                         module_parameters=cec_module_params,
                                         EgRef=1.121,
                                         dEgdT=-0.0002677)
    out = pvsystem.singlediode(IL, I0, Rs, Rsh, nNsVth)
    assert isinstance(out, pd.DataFrame)
コード例 #18
0
def test_singlediode_series(cec_module_params):
    times = pd.DatetimeIndex(start='2015-01-01', periods=2, freq='12H')
    poa_data = pd.Series([0, 800], index=times)
    IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto(
                                         poa_data,
                                         temp_cell=25,
                                         alpha_isc=cec_module_params['alpha_sc'],
                                         module_parameters=cec_module_params,
                                         EgRef=1.121,
                                         dEgdT=-0.0002677)
    out = pvsystem.singlediode(IL, I0, Rs, Rsh, nNsVth)
    assert isinstance(out, pd.DataFrame)
コード例 #19
0
def test_singlediode_series():  
    cecmodule = sam_data['cecmod'].Example_Module                       
    out = pvsystem.singlediode(cecmodule, 7, 6e-7, .1, 20, .5)
    expected = {'i_xx': 4.2549732697234193,
                'i_mp': 6.1390251797935704,
                'v_oc': 8.1147298764528042,
                'p_mp': 38.194165464983037,
                'i_x': 6.7556075876880621,
                'i_sc': 6.9646747613963198,
                'v_mp': 6.221535886625464}
    assert isinstance(out, dict)
    for k, v in out.items():
        assert_almost_equals(expected[k], v, 5)
コード例 #20
0
ファイル: test_pvsystem.py プロジェクト: caskeep/pvlib-python
def test_singlediode_floats(sam_data):
    module = 'Example_Module'
    module_parameters = sam_data['cecmod'][module]
    out = pvsystem.singlediode(7, 6e-7, .1, 20, .5)
    expected = {'i_xx': 4.2685798754011426,
                'i_mp': 6.1390251797935704,
                'v_oc': 8.1063001465863085,
                'p_mp': 38.194165464983037,
                'i_x': 6.7556075876880621,
                'i_sc': 6.9646747613963198,
                'v_mp': 6.221535886625464}
    assert isinstance(out, dict)
    for k, v in out.items():
        assert_allclose(expected[k], v, atol=3)
コード例 #21
0
def test_singlediode_floats_ivcurve():
    out = pvsystem.singlediode(7, 6e-7, .1, 20, .5, ivcurve_pnts=3)
    expected = {'i_xx': 4.2685798754011426,
                'i_mp': 6.1390251797935704,
                'v_oc': 8.1063001465863085,
                'p_mp': 38.194165464983037,
                'i_x': 6.7556075876880621,
                'i_sc': 6.9646747613963198,
                'v_mp': 6.221535886625464,
                'i': np.array([6.965172e+00,   6.755882e+00,   2.575717e-14]),
                'v': np.array([0.     ,  4.05315,  8.1063])}
    assert isinstance(out, dict)
    for k, v in out.items():
        assert_allclose(expected[k], v, atol=3)
コード例 #22
0
def test_singlediode_floats():
    module = 'Example_Module'
    module_parameters = sam_data['cecmod'][module]
    out = pvsystem.singlediode(module_parameters, 7, 6e-7, .1, 20, .5)
    expected = {'i_xx': 4.2549732697234193,
                'i_mp': 6.1390251797935704,
                'v_oc': 8.1147298764528042,
                'p_mp': 38.194165464983037,
                'i_x': 6.7556075876880621,
                'i_sc': 6.9646747613963198,
                'v_mp': 6.221535886625464}
    assert isinstance(out, dict)
    for k, v in out.items():
        assert_almost_equals(expected[k], v, 5)
コード例 #23
0
def test_singlediode_floats_ivcurve():
    out = pvsystem.singlediode(7, 6e-7, .1, 20, .5, ivcurve_pnts=3)
    expected = {'i_xx': 4.2498,
                'i_mp': 6.1275,
                'v_oc': 8.1063,
                'p_mp': 38.1937,
                'i_x': 6.7558,
                'i_sc': 6.9651,
                'v_mp': 6.2331,
                'i': np.array([6.965172e+00, 6.755882e+00, 2.575717e-14]),
                'v': np.array([0., 4.05315, 8.1063])}
    assert isinstance(out, dict)
    for k, v in out.items():
        assert_allclose(v, expected[k], atol=1e-3)
コード例 #24
0
def test_singlediode_floats_ivcurve():
    out = pvsystem.singlediode(7, 6e-7, .1, 20, .5, ivcurve_pnts=3)
    expected = {'i_xx': 4.2685798754011426,
                'i_mp': 6.1390251797935704,
                'v_oc': 8.1063001465863085,
                'p_mp': 38.194165464983037,
                'i_x': 6.7556075876880621,
                'i_sc': 6.9646747613963198,
                'v_mp': 6.221535886625464,
                'i': np.array([6.965172e+00,   6.755882e+00,   2.575717e-14]),
                'v': np.array([0.     ,  4.05315,  8.1063])}
    assert isinstance(out, dict)
    for k, v in out.items():
        assert_allclose(expected[k], v, atol=3)
コード例 #25
0
def cec_module_detail(request, cec_module_id):
    cec_mod = get_object_or_404(CEC_Module, pk=cec_module_id)
    fieldnames = CEC_Module._meta.get_fields()
    cec_mod_dict = {k.name: getattr(cec_mod, k.name) for k in fieldnames}
    # for k in ['IXO', 'IXXO', 'C4', 'C5', 'C6', 'C7']:
    #     if cec_mod_dict[k] is None:
    #         cec_mod_dict[k] = 0.
    celltemps = [0.0, 25.0, 50.0, 75.0, 100.0]
    effirrad = 1000
    results = []
    for tc in celltemps:
        params = calcparams_cec(
            effective_irradiance=effirrad, temp_cell=tc,
            alpha_sc=cec_mod_dict['alpha_sc'],
            a_ref=cec_mod_dict['a_ref'],
            I_L_ref=cec_mod_dict['I_L_ref'],
            I_o_ref=cec_mod_dict['I_o_ref'],
            R_sh_ref=cec_mod_dict['R_sh_ref'],
            R_s=cec_mod_dict['R_s'],
            Adjust=cec_mod_dict['Adjust'])
        results.append(singlediode(*params, ivcurve_pnts=100, method='newton'))
    current = np.concatenate([r['i'].reshape(1, 100) for r in results], axis=0)
    voltage = np.concatenate([r['v'].reshape(1, 100) for r in results], axis=0)
    # eff = results['p_mp'] / effirrad / cec_mod.Area * 100 / 1000
    fig = figure(
        x_axis_label='voltage, V [V]',
        y_axis_label='current, I [A]',
        title=cec_mod.Name,
        plot_width=800, plot_height=600, sizing_mode='scale_width'
    )
    plot = fig.multi_line(
        voltage.tolist(), current.tolist(), color=cmap, line_width=4)
    legend = Legend(items=[
        LegendItem(label='{:d} [C]'.format(int(ct)), renderers=[plot], index=n)
        for n, ct in enumerate(celltemps)])
    fig.scatter(
        0, [r['i_sc'] for r in results], size=15, color=cmap, marker='square')
    fig.scatter(
        [r['v_oc'] for r in results], 0, size=15, color=cmap)
    fig.scatter(
        [r['v_mp'] for r in results], [r['i_mp'] for r in results], size=15,
        color=cmap, marker='triangle')
    fig.add_layout(legend)
    plot_script, plot_div = components(fig)
    return render(
        request, 'cec_module_detail.html', {
            'path': request.path, 'cec_mod': cec_mod,
            'plot_script': plot_script, 'plot_div': plot_div,
            'cec_mod_dict': cec_mod_dict,
            'cec_mod_tech': dict(CEC_Module.TECH)})
コード例 #26
0
def test_singlediode_series():
    cecmodule = sam_data["cecmod"].Example_Module
    out = pvsystem.singlediode(cecmodule, 7, 6e-7, 0.1, 20, 0.5)
    expected = {
        "i_xx": 4.2549732697234193,
        "i_mp": 6.1390251797935704,
        "v_oc": 8.1147298764528042,
        "p_mp": 38.194165464983037,
        "i_x": 6.7556075876880621,
        "i_sc": 6.9646747613963198,
        "v_mp": 6.221535886625464,
    }
    assert isinstance(out, dict)
    for k, v in out.items():
        assert_almost_equals(expected[k], v, 5)
コード例 #27
0
def test_singlediode_floats():
    module = 'Example_Module'
    module_parameters = sam_data['cecmod'][module]
    out = pvsystem.singlediode(module_parameters, 7, 6e-7, .1, 20, .5)
    expected = {
        'i_xx': 4.2685798754011426,
        'i_mp': 6.1390251797935704,
        'v_oc': 8.1063001465863085,
        'p_mp': 38.194165464983037,
        'i_x': 6.7556075876880621,
        'i_sc': 6.9646747613963198,
        'v_mp': 6.221535886625464
    }
    assert isinstance(out, dict)
    for k, v in out.items():
        yield assert_almost_equals, expected[k], v, 3
コード例 #28
0
def test_singlediode_series(cec_module_params):
    times = pd.date_range(start='2015-01-01', periods=2, freq='12H')
    effective_irradiance = pd.Series([0.0, 800.0], index=times)
    IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto(
        effective_irradiance,
        temp_cell=25,
        alpha_sc=cec_module_params['alpha_sc'],
        a_ref=cec_module_params['a_ref'],
        I_L_ref=cec_module_params['I_L_ref'],
        I_o_ref=cec_module_params['I_o_ref'],
        R_sh_ref=cec_module_params['R_sh_ref'],
        R_s=cec_module_params['R_s'],
        EgRef=1.121,
        dEgdT=-0.0002677)
    out = pvsystem.singlediode(IL, I0, Rs, Rsh, nNsVth)
    assert isinstance(out, pd.DataFrame)
コード例 #29
0
def test_singlediode_array():
    # github issue 221
    photocurrent = np.linspace(0, 10, 11)
    resistance_shunt = 16
    resistance_series = 0.094
    nNsVth = 0.473
    saturation_current = 1.943e-09

    sd = pvsystem.singlediode(photocurrent, saturation_current,
                              resistance_series, resistance_shunt, nNsVth)

    expected = np.array([
        0.        ,  0.54538398,  1.43273966,  2.36328163,  3.29255606,
        4.23101358,  5.16177031,  6.09368251,  7.02197553,  7.96846051,
        8.88220557])

    assert_allclose(sd['i_mp'], expected, atol=0.01)
コード例 #30
0
ファイル: pan_solver.py プロジェクト: jhfatehi/pv
def singlediodePVSYST(G, T, I0_ref, IL_ref, n_ref, Ns, u_sc, u_n, Rs, Rsh_ref,
                      Rsh_0, Rsh_exp):
    '''
	reference conditions assumed to be STC (1000 W/m^2, 25 C)

	G = module irradiance under test
	T = cell temperature under test
	I0_ref = diode saturation current at STC (from calc_ref_vals)
	IL_ref = cell photo current at STC (from calc_ref_vals)
	n_ref = diode ideality factor at STC (from calc_ref_vals)
	Nsc = number of cells in series (datasheet)
	u_sc = short circuit current temperature coefficient at 1000W/M^2 (datasheet)
	u_n = diode ideality factor temperature coefficient (solving for)
	Rs = series resistance (solving for)
	Rsh_ref = shunt resistance at 1000 W/m^2 (solving for)
	Rsh_0 = shunt resistance at 0 W/m^2 (solving for)
	Rsh_exp = shunt resistance exponential factor (solving for)
	'''

    IL, I0, Rs, Rsh, nNsVth = calcparams_pvsyst(G,
                                                T,
                                                u_sc,
                                                n_ref,
                                                u_n,
                                                IL_ref,
                                                I0_ref,
                                                Rsh_ref,
                                                Rsh_0,
                                                Rs,
                                                Ns,
                                                Rsh_exp,
                                                EgRef=1.121,
                                                irrad_ref=1000,
                                                temp_ref=25)

    out = singlediode(IL,
                      I0,
                      Rs,
                      Rsh,
                      nNsVth,
                      ivcurve_pnts=None,
                      method='lambertw')

    return (out['p_mp'])
コード例 #31
0
def test_singlediode_floats(sam_data):
    module = 'Example_Module'
    module_parameters = sam_data['cecmod'][module]
    out = pvsystem.singlediode(7, 6e-7, .1, 20, .5)
    expected = {'i_xx': 4.2498,
                'i_mp': 6.1275,
                'v_oc': 8.1063,
                'p_mp': 38.1937,
                'i_x': 6.7558,
                'i_sc': 6.9651,
                'v_mp': 6.2331,
                'i': None,
                'v': None}
    assert isinstance(out, dict)
    for k, v in out.items():
        if k in ['i', 'v']:
            assert v is None
        else:
            assert_allclose(v, expected[k], atol=1e-3)
コード例 #32
0
def test_singlediode_floats():
    out = pvsystem.singlediode(7, 6e-7, .1, 20, .5, method='lambertw')
    expected = {
        'i_xx': 4.2498,
        'i_mp': 6.1275,
        'v_oc': 8.1063,
        'p_mp': 38.1937,
        'i_x': 6.7558,
        'i_sc': 6.9651,
        'v_mp': 6.2331,
        'i': None,
        'v': None
    }
    assert isinstance(out, dict)
    for k, v in out.items():
        if k in ['i', 'v']:
            assert v is None
        else:
            assert_allclose(v, expected[k], atol=1e-3)
コード例 #33
0
def test_singlediode_floats(sam_data):
    module = 'Example_Module'
    module_parameters = sam_data['cecmod'][module]
    out = pvsystem.singlediode(7, 6e-7, .1, 20, .5)
    expected = {'i_xx': 4.2685798754011426,
                'i_mp': 6.1390251797935704,
                'v_oc': 8.1063001465863085,
                'p_mp': 38.194165464983037,
                'i_x': 6.7556075876880621,
                'i_sc': 6.9646747613963198,
                'v_mp': 6.221535886625464,
                'i': None,
                'v': None}
    assert isinstance(out, dict)
    for k, v in out.items():
        if k in ['i', 'v']:
            assert v is None
        else:
            assert_allclose(expected[k], v, atol=3)
コード例 #34
0
def _add_single_diode_iv_curve(sys_df, sys_params):
    """Add IV curve generated by single diode model.

    Args:
        sys_df (pd.DataFrame): time-series data that must contain 'g_poa' and 'temp_air' parameters
        sys_params (dict): organized like so:
            {'mod': pvlib.pvsystem.retrieve_same(...).SYSTEM_NAME, 'n_mod': int}

    Returns:
        pd.DataFrame with new columns (voltage_array_single_diode and current_array_single_diode)
    """
    new_df = []
    if 'temp_cell' not in sys_df.keys():
        sys_df = _add_cell_module_temp(sys_df, sys_params['celltemp_model'])
    for i in range(len(sys_df)):
        ser = sys_df.iloc[i]
        # final two args are the band gap (assumed Si) and temperature dependence of bandgap at SRC
        il, i0, rs, rsh, nnsvth = pvsystem.calcparams_desoto(
            ser['g_poa'], ser['temp_cell'], sys_params['mod']['alpha_sc'],
            sys_params['mod'], 1.121, -0.0002677)
        params = pvsystem.singlediode(il,
                                      i0,
                                      rs,
                                      rsh,
                                      nnsvth,
                                      ivcurve_pnts=250)
        new_df.append({
            'voltage_array_single_diode':
            params['v'] * sys_params['n_mod'],
            'current_array_single_diode':
            params['i']
        })

    new_df = pd.DataFrame(new_df, index=sys_df.index)

    sys_df['voltage_array_single_diode'] = new_df['voltage_array_single_diode']
    sys_df['current_array_single_diode'] = new_df['current_array_single_diode']

    return sys_df.copy()
コード例 #35
0
ファイル: cpvsystem.py プロジェクト: marcosnomore/CPV
    def singlediode(self,
                    photocurrent,
                    saturation_current,
                    resistance_series,
                    resistance_shunt,
                    nNsVth,
                    ivcurve_pnts=None):
        """Wrapper around the :py:func:`pvsystem.singlediode` function.

        Parameters
        ----------
        See pvsystem.singlediode for details

        Returns
        -------
        See pvsystem.singlediode for details
        """

        return pvsystem.singlediode(photocurrent,
                                    saturation_current,
                                    resistance_series,
                                    resistance_shunt,
                                    nNsVth,
                                    ivcurve_pnts=ivcurve_pnts)
コード例 #36
0
def test_singlediode_series_ivcurve(cec_module_params):
    times = pd.date_range(start='2015-06-01', periods=3, freq='6H')
    effective_irradiance = pd.Series([0.0, 400.0, 800.0], index=times)
    IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto(
        effective_irradiance,
        temp_cell=25,
        alpha_sc=cec_module_params['alpha_sc'],
        a_ref=cec_module_params['a_ref'],
        I_L_ref=cec_module_params['I_L_ref'],
        I_o_ref=cec_module_params['I_o_ref'],
        R_sh_ref=cec_module_params['R_sh_ref'],
        R_s=cec_module_params['R_s'],
        EgRef=1.121,
        dEgdT=-0.0002677)

    out = pvsystem.singlediode(IL,
                               I0,
                               Rs,
                               Rsh,
                               nNsVth,
                               ivcurve_pnts=3,
                               method='lambertw')

    expected = OrderedDict([
        ('i_sc', array([0., 3.01054475, 6.00675648])),
        ('v_oc', array([0., 9.96886962, 10.29530483])),
        ('i_mp', array([0., 2.65191983, 5.28594672])),
        ('v_mp', array([0., 8.33392491, 8.4159707])),
        ('p_mp', array([0., 22.10090078, 44.48637274])),
        ('i_x', array([0., 2.88414114, 5.74622046])),
        ('i_xx', array([0., 2.04340914, 3.90007956])),
        ('v',
         array([[0., 0., 0.], [0., 4.98443481, 9.96886962],
                [0., 5.14765242, 10.29530483]])),
        ('i',
         array([[0., 0., 0.], [3.01079860e+00, 2.88414114e+00, 3.10862447e-14],
                [6.00726296e+00, 5.74622046e+00, 0.00000000e+00]]))
    ])

    for k, v in out.items():
        assert_allclose(v, expected[k], atol=1e-2)

    out = pvsystem.singlediode(IL, I0, Rs, Rsh, nNsVth, ivcurve_pnts=3)

    expected['i_mp'] = pvsystem.i_from_v(Rsh,
                                         Rs,
                                         nNsVth,
                                         out['v_mp'],
                                         I0,
                                         IL,
                                         method='lambertw')
    expected['v_mp'] = pvsystem.v_from_i(Rsh,
                                         Rs,
                                         nNsVth,
                                         out['i_mp'],
                                         I0,
                                         IL,
                                         method='lambertw')
    expected['i'] = pvsystem.i_from_v(Rsh,
                                      Rs,
                                      nNsVth,
                                      out['v'].T,
                                      I0,
                                      IL,
                                      method='lambertw').T
    expected['v'] = pvsystem.v_from_i(Rsh,
                                      Rs,
                                      nNsVth,
                                      out['i'].T,
                                      I0,
                                      IL,
                                      method='lambertw').T

    for k, v in out.items():
        assert_allclose(v, expected[k], atol=1e-2)
コード例 #37
0
def _add_single_diode_params(sys_df, sys_params, extracted_params=True):
    """Compute expected IV parameters using single-diode equation.

    Single-diode parameters will be added to the self.df_dict dataframes using the following columns:
        isc_single_diode, voc_single_diode, ipmax_single_diode, vpmax_single_diode, pmax_single_diode,
        ix_single_diode, ixx_single_diode

    The measured values will also be normalized by single-diode parameters and stored in columns with names:
        isc_norm_single_diode, voc_norm_single_diode, ipmax_norm_single_diode, vpmax_norm_single_diode,
        pmax_norm_single_diode, ix_norm_single_diode, ixx_norm_single_diode

    Args:
        sys_df (pd.DataFrame): time-series data that must contain IV curves
        sys_params (dict): parameters needed for single-diode calculation from PVLIB; organized as follows:
            {'mod': pvlib.pvsystem.retrieve_same(...).SYSTEM_NAME, 'n_mod': int}

    Returns:
        pd.DataFrame with additional columns added
    """
    diode_params = []
    if 'temp_cell' not in sys_df.keys():
        sys_df = _add_cell_module_temp(sys_df, sys_params['celltemp_model'])
    for i in range(len(sys_df)):
        ser = sys_df.iloc[i]
        # final two args are the band gap (assumed Si) and temperature dependence of bandgap at SRC
        il, i0, rs, rsh, nnsvth = pvsystem.calcparams_desoto(
            ser['g_poa'], ser['temp_cell'], sys_params['mod']['alpha_sc'],
            sys_params['mod'], 1.121, -0.0002677)
        params = pvsystem.singlediode(il, i0, rs, rsh, nnsvth)
        diode_params.append({
            'isc_single_diode':
            params['i_sc'],
            'voc_single_diode':
            params['v_oc'] * sys_params['n_mod'],
            'ipmax_single_diode':
            params['i_mp'],
            'vpmax_single_diode':
            params['v_mp'] * sys_params['n_mod'],
            'pmax_single_diode':
            params['p_mp'] * sys_params['n_mod'],
            'ix_single_diode':
            params['i_x'],
            'ixx_single_diode':
            params['i_xx']
        })

    param_df = pd.DataFrame(diode_params, index=sys_df.index)
    for key in param_df:
        sys_df[key] = param_df[key]

    if extracted_params:
        try:
            sys_df['isc_norm_single_diode'] = sys_df['isc_extracted'] / sys_df[
                'isc_single_diode']
            sys_df['voc_norm_single_diode'] = sys_df['voc_extracted'] / sys_df[
                'voc_single_diode']
            sys_df['ipmax_norm_single_diode'] = sys_df[
                'ipmax_extracted'] / sys_df['ipmax_single_diode']
            sys_df['vpmax_norm_single_diode'] = sys_df[
                'vpmax_extracted'] / sys_df['vpmax_single_diode']
            sys_df['pmax_norm_single_diode'] = sys_df[
                'pmax_extracted'] / sys_df['pmax_single_diode']
            sys_df['ix_norm_single_diode'] = sys_df['ix_extracted'] / sys_df[
                'ix_single_diode']
            sys_df['ixx_norm_single_diode'] = sys_df['ixx_extracted'] / sys_df[
                'ixx_single_diode']
        except KeyError:
            raise KeyError(
                'Call param_extraction() if extracted_params = True.')
    else:
        sys_df['isc_norm_single_diode'] = sys_df['isc'] / sys_df[
            'isc_single_diode']
        sys_df['voc_norm_single_diode'] = sys_df['voc'] / sys_df[
            'voc_single_diode']
        sys_df['ipmax_norm_single_diode'] = sys_df['ipmax'] / sys_df[
            'ipmax_single_diode']
        sys_df['vpmax_norm_single_diode'] = sys_df['vpmax'] / sys_df[
            'vpmax_single_diode']
        sys_df['pmax_norm_single_diode'] = sys_df['pmax'] / sys_df[
            'pmax_single_diode']
        # data doesn't usually contain ix, ixx
        try:
            sys_df['ix_norm_single_diode'] = sys_df['ix'] / sys_df[
                'ix_single_diode']
        except KeyError:
            pass
        try:
            sys_df['ixx_norm_single_diode'] = sys_df['ixx'] / sys_df[
                'ixx_single_diode']
        except KeyError:
            pass

    return sys_df.copy()
コード例 #38
0
ファイル: singlediode.py プロジェクト: mikofski/pvpro
def pvlib_single_diode(
        effective_irradiance,
        temperature_cell,
        resistance_shunt_ref,
        resistance_series_ref,
        diode_factor,
        cells_in_series,
        alpha_isc,
        photocurrent_ref,
        saturation_current_ref,
        Eg_ref=1.121,
        dEgdT=-0.0002677,
        conductance_shunt_extra=0,
        irradiance_ref=1000,
        temperature_ref=25,
        method='newton',
        ivcurve_pnts=None,
        output_all_params=False
):
    """
    Find points of interest on the IV curve given module parameters and
    operating conditions.

    method 'newton is about twice as fast as method 'lambertw

    Parameters
    ----------
    effective_irradiance : numeric
        effective irradiance in W/m^2

    temp_cell : numeric
        Cell temperature in C

    resistance_shunt : numeric

    resistance_series : numeric

    diode_ideality_factor : numeric

    number_cells_in_series : numeric

    alpha_isc :
        in amps/c

    reference_photocurrent : numeric
        photocurrent at standard test conditions, in A.

    reference_saturation_current : numeric

    reference_Eg : numeric
        band gap in eV.

    reference_irradiance : numeric
        reference irradiance in W/m^2. Default is 1000.

    reference_temperature : numeric
        reference temperature in C. Default is 25.

    verbose : bool
        Whether to print information.

    Returns
    -------
    OrderedDict or DataFrame

        The returned dict-like object always contains the keys/columns:

            * i_sc - short circuit current in amperes.
            * v_oc - open circuit voltage in volts.
            * i_mp - current at maximum power point in amperes.
            * v_mp - voltage at maximum power point in volts.
            * p_mp - power at maximum power point in watts.
            * i_x - current, in amperes, at ``v = 0.5*v_oc``.
            * i_xx - current, in amperes, at ``V = 0.5*(v_oc+v_mp)``.

        If ivcurve_pnts is greater than 0, the output dictionary will also
        include the keys:

            * i - IV curve current in amperes.
            * v - IV curve voltage in volts.

        The output will be an OrderedDict if photocurrent is a scalar,
        array, or ivcurve_pnts is not None.

        The output will be a DataFrame if photocurrent is a Series and
        ivcurve_pnts is None.

    """

    kB = 1.381e-23
    q = 1.602e-19
    nNsVth_ref = diode_factor * cells_in_series * kB / q * (
            273.15 + temperature_ref)

    iph, io, rs, rsh, nNsVth = calcparams_pvpro(effective_irradiance,
                                                temperature_cell,
                                                alpha_isc,
                                                nNsVth_ref,
                                                photocurrent_ref,
                                                saturation_current_ref,
                                                resistance_shunt_ref,
                                                resistance_series_ref,
                                                conductance_shunt_extra,
                                                Eg_ref=Eg_ref, dEgdT=dEgdT,
                                                irradiance_ref=irradiance_ref,
                                                temperature_ref=temperature_ref)

    out = singlediode(iph,
                      io,
                      rs,
                      rsh,
                      nNsVth,
                      method=method,
                      ivcurve_pnts=ivcurve_pnts,
                      )
    # out = rename(out)

    if output_all_params:

        params = {'photocurrent': iph,
                  'saturation_current': io,
                  'resistance_series': rs,
                  'resistace_shunt': rsh,
                  'nNsVth': nNsVth}

        for p in params:
            out[p] = params[p]

    return out
コード例 #39
0
    conditions['Geff'],
    conditions['Tcell'],
    alpha_sc=parameters['alpha_sc'],
    a_ref=parameters['a_ref'],
    I_L_ref=parameters['I_L_ref'],
    I_o_ref=parameters['I_o_ref'],
    R_sh_ref=parameters['R_sh_ref'],
    R_s=parameters['R_s'],
    EgRef=1.121,
    dEgdT=-0.0002677)

# plug the parameters into the SDE and solve for IV curves:
curve_info = pvsystem.singlediode(photocurrent=IL,
                                  saturation_current=I0,
                                  resistance_series=Rs,
                                  resistance_shunt=Rsh,
                                  nNsVth=nNsVth,
                                  ivcurve_pnts=100,
                                  method='lambertw')

# plot the calculated curves:
plt.figure()
for i, case in conditions.iterrows():
    label = ("$G_{eff}$ " + f"{case['Geff']} $W/m^2$\n"
             "$T_{cell}$ " + f"{case['Tcell']} $C$")
    plt.plot(curve_info['v'][i], curve_info['i'][i], label=label)
    v_mp = curve_info['v_mp'][i]
    i_mp = curve_info['i_mp'][i]
    # mark the MPP
    plt.plot([v_mp], [i_mp], ls='', marker='o', c='k')
コード例 #40
0
def test_fit_pvsyst_sandia(npts=3000):

    # get IV curve data
    iv_specs, ivcurves = _read_iv_curves_for_test('PVsyst_demo.csv', npts)

    # get known Pvsyst model parameters and five parameters from each fitted
    # IV curve
    pvsyst_specs, pvsyst = _read_pvsyst_expected('PVsyst_demo_model.csv')

    modeled = sdm.fit_pvsyst_sandia(ivcurves, iv_specs)

    # calculate IV curves using the fitted model, for comparison with input
    # IV curves
    param_res = pvsystem.calcparams_pvsyst(
        effective_irradiance=ivcurves['ee'], temp_cell=ivcurves['tc'],
        alpha_sc=iv_specs['alpha_sc'], gamma_ref=modeled['gamma_ref'],
        mu_gamma=modeled['mu_gamma'], I_L_ref=modeled['I_L_ref'],
        I_o_ref=modeled['I_o_ref'], R_sh_ref=modeled['R_sh_ref'],
        R_sh_0=modeled['R_sh_0'], R_s=modeled['R_s'],
        cells_in_series=iv_specs['cells_in_series'], EgRef=modeled['EgRef'])
    iv_res = pvsystem.singlediode(*param_res)

    # assertions
    assert np.allclose(
        ivcurves['p_mp'], iv_res['p_mp'], equal_nan=True, rtol=0.038)
    assert np.allclose(
        ivcurves['v_mp'], iv_res['v_mp'], equal_nan=True, rtol=0.029)
    assert np.allclose(
        ivcurves['i_mp'], iv_res['i_mp'], equal_nan=True, rtol=0.021)
    assert np.allclose(
        ivcurves['i_sc'], iv_res['i_sc'], equal_nan=True, rtol=0.003)
    assert np.allclose(
        ivcurves['v_oc'], iv_res['v_oc'], equal_nan=True, rtol=0.019)
    # cells_in_series, alpha_sc, beta_voc, descr
    assert all((iv_specs[k] == pvsyst_specs[k]) for k in iv_specs.keys())
    # I_L_ref, I_o_ref, EgRef, R_sh_ref, R_sh_0, R_sh_exp, R_s, gamma_ref,
    # mu_gamma
    assert np.isclose(modeled['I_L_ref'], pvsyst['I_L_ref'], rtol=6.5e-5)
    assert np.isclose(modeled['I_o_ref'], pvsyst['I_o_ref'], rtol=0.15)
    assert np.isclose(modeled['R_s'], pvsyst['R_s'], rtol=0.0035)
    assert np.isclose(modeled['R_sh_ref'], pvsyst['R_sh_ref'], rtol=0.091)
    assert np.isclose(modeled['R_sh_0'], pvsyst['R_sh_0'], rtol=0.013)
    assert np.isclose(modeled['EgRef'], pvsyst['EgRef'], rtol=0.037)
    assert np.isclose(modeled['gamma_ref'], pvsyst['gamma_ref'], rtol=0.0045)
    assert np.isclose(modeled['mu_gamma'], pvsyst['mu_gamma'], rtol=0.064)

    # Iph, Io, Rsh, Rs, u
    mask = np.ones(modeled['u'].shape, dtype=bool)
    # exclude one curve with different convergence
    umask = mask.copy()
    umask[2540] = False
    assert all(modeled['u'][umask] == pvsyst['u'][:npts][umask])
    assert np.allclose(
        modeled['iph'][modeled['u']], pvsyst['iph'][:npts][modeled['u']],
        equal_nan=True, rtol=0.0009)
    assert np.allclose(
        modeled['io'][modeled['u']], pvsyst['io'][:npts][modeled['u']],
        equal_nan=True, rtol=0.096)
    assert np.allclose(
        modeled['rs'][modeled['u']], pvsyst['rs'][:npts][modeled['u']],
        equal_nan=True, rtol=0.035)
    # exclude one curve with Rsh outside 63% tolerance
    rshmask = modeled['u'].copy()
    rshmask[2545] = False
    assert np.allclose(
        modeled['rsh'][rshmask], pvsyst['rsh'][:npts][rshmask],
        equal_nan=True, rtol=0.63)
コード例 #41
0
def pvsyst_parameter_estimation(ivcurves, specs, const=const_default,
                                maxiter=5, eps1=1.e-3, graphic=False):
    """
    pvsyst_parameter_estimation estimates parameters fro the PVsyst module
    performance model

    Syntax
    ------
    PVsyst, oflag = pvsyst_paramter_estimation(ivcurves, specs, const, maxiter,
                                               eps1, graphic)

    Description
    -----------
    pvsyst_paramter_estimation estimates parameters for the PVsyst module
    performance model [2,3,4]. Estimation methods are documented in [5,6,7].

    Parameters
    ----------
    ivcurves: a dict containing IV curve data in the following fields where j
    denotes the jth data set
        ivcurves['i'][j] - a numpy array of current (A) (same length as v)
        ivcurves['v'][j] - a numpy array of voltage (V) (same length as i)
        ivcurves['ee'][j] - effective irradiance (W / m^2), i.e., POA broadband
                            irradiance adjusted by solar spectrum modifier
        ivcurves['tc'][j] - cell temperature (C)
        ivcurves['isc'][j] - short circuit current of IV curve (A)
        ivcurves['voc'][j] - open circuit voltage of IV curve (V)
        ivcurves['imp'][j] - current at max power point of IV curve (A)
        ivcurves['vmp'][j] - voltage at max power point of IV curve (V)

    specs: a dict containing module-level values
        specs['ns'] - number of cells in series
        specs['aisc'] - temperature coefficeint of isc (A/C)

    const: an optional OrderedDict containing physical and other constants
        const['E0'] - effective irradiance at STC, normally 1000 W/m2
        constp['T0'] - cell temperature at STC, normally 25 C
        const['k'] - 1.38066E-23 J/K (Boltzmann's constant)
        const['q'] - 1.60218E-19 Coulomb (elementary charge)

    maxiter: an optional numpy array input that sets the maximum number of
             iterations for the parameter updating part of the algorithm.
             Default value is 5.

    eps1: the desired tolerance for the IV curve fitting. The iterative
          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. Default value is 1e-3 (.0001%).

    graphic: a boolean, if true then plots are produced during the parameter
             estimation process. Default is false

    Returns
    -------
    pvsyst: a OrderedDict containing the model parameters
        pvsyst['IL_ref'] - light current (A) at STC
        pvsyst['Io_ref'] - dark current (A) at STC
        pvsyst['eG'] - effective band gap (eV) at STC
        pvsyst['Rsh_ref'] - shunt resistance (ohms) at STC
        pvsyst['Rsh0'] - shunt resistance (ohms) at zero irradiance
        pvsyst['Rshexp'] - exponential factor defining decrease in rsh with
                           increasing effective irradiance
        pvsyst['Rs_ref'] - series resistance (ohms) at STC
        pvsyst['gamma_ref'] - diode (ideality) factor at STC
        pvsyst['mugamma'] - temperature coefficient for diode (ideality) factor
        pvsyst['Iph'] - numpy array of values of light current Iph estimated
                        for each IV curve
        pvsyst['Io'] - numpy array of values of dark current Io estimated for
                       each IV curve
        pvsyst['Rsh'] - numpy array of values of shunt resistance Rsh estimated
                        for each IV curve
        pvsyst['Rs'] - numpy array of values of series resistance Rs estimated
                       for each IV curve
        pvsyst.u - filter indicating IV curves with parameter values deemed
                   reasonable by the private function filter_params

    oflag: Boolean indicating success or failure of estimation of the diode
           (ideality) factor parameter. If failure, then no parameter values
           are returned

    References
    ----------
    [1] PVLib MATLAB
    [2] 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.
    [3] A. Mermoud, PV Modules modeling, Presentation at the 2nd PV Performance
        Modeling Workshop, Santa Clara, CA, May 2013
    [4] 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
    [5] C. Hansen, Estimating Parameters for the PVsyst Version 6 Photovoltaic
        Module Performance Model, Sandia National Laboratories Report
        SAND2015-8598
    [6] C. Hansen, Parameter Estimation for Single Diode Models of Photovoltaic
        Modules, Sandia National Laboratories Report SAND2015-2065
    [7] C. Hansen, Estimation of Parameters for Single Diode Models using
        Measured IV Curves, Proc. of the 39th IEEE PVSC, June 2013.
    """
    ee = ivcurves['ee']
    tc = ivcurves['tc']
    tck = tc + 273.15
    isc = ivcurves['isc']
    voc = ivcurves['voc']
    imp = ivcurves['imp']
    vmp = ivcurves['vmp']

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

    n = len(ivcurves['voc'])

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

    pio = np.ones(n)
    piph = np.ones(n)
    prsh = np.ones(n)
    prs = np.ones(n)
    pn = np.ones(n)

    for j in range(n):
        current, voltage = rectify_iv_curve(ivcurves['i'][j], ivcurves['v'][j],
                                            voc[j], isc[j])
        # initial estimate of Rsh, from integral over voltage regression
        # [5] Step 3a; [6] Step 3a
        pio[j], piph[j], prs[j], prsh[j], pn[j] = \
            est_single_diode_param(current, voltage, vth[j] * specs['ns'])

    # Estimate the diode factor gamma from Isc-Voc data. Method incorporates
    # temperature dependence by means of the equation for Io

    y = np.log(isc - voc / prsh) - 3. * np.log(tck / (const['T0'] + 273.15))
    x1 = const['q'] / const['k'] * (1. / (const['T0'] + 273.15) - 1. / tck)
    x2 = voc / (vth * specs['ns'])
    t0 = np.isnan(y)
    t1 = np.isnan(x1)
    t2 = np.isnan(x2)
    uu = np.logical_or(t0, t1)
    uu = np.logical_or(uu, t2)

    x = np.vstack((np.ones(len(x1[~uu])), x1[~uu], -x1[~uu] *
                   (tck[~uu] - (const['T0'] + 273.15)), x2[~uu],
                   -x2[~uu] * (tck[~uu] - (const['T0'] + 273.15)))).T
    alpha = np.linalg.lstsq(x, y[~uu])[0]

    gamma_ref = 1. / alpha[3]
    mugamma = alpha[4] / alpha[3] ** 2

    if np.isnan(gamma_ref) or np.isnan(mugamma) or not np.isreal(gamma_ref) \
            or not np.isreal(mugamma):
        badgamma = True
    else:
        badgamma = False

    pvsyst = OrderedDict()

    if ~badgamma:
        gamma = gamma_ref + mugamma * (tc - const['T0'])

        if graphic:
            f1 = plt.figure()
            ax10 = f1.add_subplot(111)
            ax10.plot(x2, y, 'b+', x2, x * alpha, 'r.')
            ax10.set_xlabel('X = Voc / Ns * Vth')
            ax10.set_ylabel('Y = log(Isc - Voc/Rsh)')
            ax10.legend(['I-V Data', 'Regression Model'], loc=2)
            ax10.text(np.min(x2) + 0.85 * (np.max(x2) - np.min(x2)), 1.05 *
                      np.max(y), ['\gamma_0 = %s' % gamma_ref])
            ax10.text(np.min(x2) + 0.85 * (np.max(x2) - np.min(x2)), 0.98 *
                      np.max(y), ['\mu_\gamma = %s' % mugamma])
            plt.show()

        nnsvth = gamma * (vth * specs['ns'])

        # For each IV curve, sequentially determine initial values for Io, Rs,
        # and Iph [5] Step 3a; [6] Step 3

        io = np.ones(n)
        iph = np.ones(n)
        rs = np.ones(n)
        rsh = prsh

        for j in range(n):
            curr, volt = rectify_iv_curve(ivcurves['i'][j], ivcurves['v'][j],
                                          voc[j], isc[j])

            if rsh[j] > 0:
                # 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]
                u = np.logical_and(t3, t4)
                tmp = -rsh[j] * didv - 1.
                v = np.logical_and(u, tmp > 0)
                if np.sum(v) > 0:
                    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] + io[j] * np.exp(isc[j] / nnsvth[j]) \
                    + isc[j] * rs[j] / rsh[j]
            else:
                io[j] = float("Nan")
                rs[j] = float("Nan")
                iph[j] = float("Nan")

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

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

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

        # Refine Rsh, Rs, Io and Iph in that order.
        counter = 1.  # counter variable for parameter updating while loop,
        # counts iterations
        prevconvergeparams = OrderedDict()
        prevconvergeparams['state'] = 0.

        if graphic:
            h = plt.figure()
        if graphic:
            # create a new handle for the converge parameter figure
            convergeparamsfig = plt.figure()

        t14 = np.array([True])

        while t14.any() and counter <= maxiter:
            # update rsh to match max power point using a fixed point method.
            tmprsh = update_rsh_fixed_pt(rsh[u], rs[u], io[u], iph[u],
                                         nnsvth[u], imp[u], vmp[u])

            if graphic:
                ax11 = h.add_subplot(111)
                ax11.plot(counter, np.mean(np.abs(tmprsh - rsh[u])), 'k')
                ax11.hold(True)
                ax11.set_xlabel('Iteration')
                ax11.set_ylabel('mean(abs(tmprsh[u] - rsh[u]))')
                ax11.set_title('Update Rsh')
                plt.show()

            rsh[u] = tmprsh

            # Calculate Rs to be consistent with Rsh and maximum power point
            [a, phi] = calc_theta_phi_exact(imp[u], iph[u], vmp[u], io[u],
                                            nnsvth[u], rs[u], rsh[u])
            rs[u] = (iph[u] + io[u] - imp[u]) * rsh[u] / imp[u] - \
                nnsvth[u] * phi / imp[u] - vmp[u] / imp[u]

            # Update filter for good parameters
            u = filter_params(io, rsh, rs, ee, isc)

            # Update value for io to match voc
            tmpio = update_io_known_n(rsh[u], rs[u], nnsvth[u], io[u], iph[u],
                                      voc[u])
            io[u] = tmpio

            # Calculate Iph to be consistent with Isc and other parameters
            iph = isc - io + io * np.exp(rs * isc / nnsvth) + isc * rs / rsh

            # update filter for good parameters
            u = filter_params(io, rsh, rs, ee, isc)

            # compute the IV curve from the current parameter values
            result = singlediode(iph[u], io[u], rs[u], rsh[u], nnsvth[u])

            # check convergence criteria
            # [5] Step 3d
            if graphic:
                convergeparams = check_converge(prevconvergeparams, result,
                                                vmp[u], imp[u], graphic,
                                                convergeparamsfig, counter)
            else:
                convergeparams = check_converge(prevconvergeparams, result,
                                                vmp[u], imp[u], graphic, 0.,
                                                counter)

            prevconvergeparams = convergeparams
            counter += 1.
            t5 = prevconvergeparams['vmperrmeanchange'] >= eps1
            t6 = prevconvergeparams['imperrmeanchange'] >= eps1
            t7 = prevconvergeparams['pmperrmeanchange'] >= eps1
            t8 = prevconvergeparams['vmperrstdchange'] >= eps1
            t9 = prevconvergeparams['imperrstdchange'] >= eps1
            t10 = prevconvergeparams['pmperrstdchange'] >= eps1
            t11 = prevconvergeparams['vmperrabsmaxchange'] >= eps1
            t12 = prevconvergeparams['imperrabsmaxchange'] >= eps1
            t13 = prevconvergeparams['pmperrabsmaxchange'] >= eps1
            t14 = np.logical_or(t5, t6)
            t14 = np.logical_or(t14, t7)
            t14 = np.logical_or(t14, t8)
            t14 = np.logical_or(t14, t9)
            t14 = np.logical_or(t14, t10)
            t14 = np.logical_or(t14, t11)
            t14 = np.logical_or(t14, t12)
            t14 = np.logical_or(t14, t13)

        # Extract coefficients for auxillary equations
        # Estimate Io0 and eG
        tok = const['T0'] + 273.15  # convert to to K
        x = const['q'] / const['k'] * (1. / tok - 1. / tck[u]) / gamma[u]
        y = np.log(io[u]) - 3. * np.log(tck[u] / tok)
        new_x = sm.add_constant(x)
        res = sm.RLM(y, new_x).fit()
        beta = res.params
        io0 = np.exp(beta[0])
        eg = beta[1]

        if graphic:
            # Predict Io and Eg
            pio = io0 * ((tc[u] + 273.15) / const['T0'] + 273.15) ** 3. * \
                  np.exp((const['q'] / const['k']) * (eg / gamma[u]) *
                         (1. / (const['T0'] + 273.15) - 1. / (tc[u] + 273.15)))

            iofig = plt.figure()
            ax12 = iofig.add_subplot(311)
            ax13 = iofig.add_subplot(312)
            ax14 = iofig.add_subplot(313)
            ax12.hold(True)
            ax12.plot(tc[u], y, 'r+', tc[u], beta[0] + x * beta[1], 'b.')
            ax12.set_xlabel('Cell temp. (C)')
            ax12.set_ylabel('log(Io)-3log(T_C/T_0)')
            ax12.legend(['Data', 'Model'], loc=2)
            ax13.hold(True)
            ax13.plot(tc[u], io[u], 'r+', tc[u], pio, '.')
            ax13.set_xlabel('Cell temp. (C)')
            ax13.set_ylabel('I_O (A)')
            ax13.legend(['Extracted', 'Predicted'], loc=2)
            ax14.hold(True)
            ax14.plot(tc[u], (pio - io[u]) / io[u] * 100., 'x')
            ax14.set_xlabel('Cell temp. (C)')
            ax14.set_ylabel('Percent Deviation in I_O')

            iofig1 = plt.figure()
            ax15 = iofig1.add_subplot(111)
            ax15.hold(True)
            ax15.plot(tc[u], y + 3. * (tc[u] / const['T0']), 'k.', tc[u],
                      beta[0] + x * beta[1] + 3 * (tc[u] / const['T0']), 'g.')
            ax15.set_xlabel('Cell temp. (C)')
            ax15.set_ylabel('log(Io)-3log(T_C/T_0)')
            ax15.legend(['Data', 'Regression Model'], loc=2)

            iofig2 = plt.figure()
            ax16 = iofig2.add_subplot(111)
            ax16.hold(True)
            ax16.plot(tc[u], io[u], 'b+', tc[u], pio, 'r.')
            ax16.set_xlabel('Cell temp. (C)')
            ax16.set_ylabel('I_O (A)')
            ax16.legend(['Extracted from IV Curves', 'Predicted by Eq. 3'],
                        loc=2)
            ax16.text(np.min(tc[u]), np.min(io[u]) + .83 *
                      (np.max(io[u]) - np.min(io[u])), ['I_{O0} = %s' % io0])
            ax16.text(np.min(tc[u]), np.min(io[u]) + .83 *
                      (np.max(io[u]) - np.min(io[u])), ['eG = %s' % eg])

        # Estimate Iph0
        x = tc[u] - const['T0']
        y = iph[u] * (const['E0'] / ee[u])
        # average over non-NaN values of Y and X
        nans = np.isnan(y - specs['aisc'] * x)
        iph0 = np.mean(y[~nans] - specs['aisc'] * x[~nans])

        if graphic:
            # Predict Iph
            piph = (ee[u] / const['E0']) * (iph0 + specs['aisc'] *
                                            (tc[u] - const['T0']))

            iphfig = plt.figure()
            ax17 = iphfig.add_subplot(311)
            ax18 = iphfig.add_subplot(312)
            ax19 = iphfig.add_subplot(313)
            ax17.hold(True)
            ax17.plot(ee[u], piph, 'r+', [0., np.max(ee[u])], [iph0, iph0])
            ax17.set_xlabel('Irradiance (W/m^2)')
            ax17.set_ylabel('I_L')
            ax17.legend(['Data', 'I_L at STC'], loc=4)
            ax18.hold(True)
            ax18.plot(ee[u], iph[u], 'r+', ee[u], piph, '.')
            ax18.set_xlabel('Irradiance (W/m^2)')
            ax18.set_ylabel('I_L (A)')
            ax18.legend(['Extracted', 'Predicted'], loc=2)
            ax19.hold(True)
            ax19.plot(ee[u], (piph - iph[u]) / iph[u] * 100., 'x',
                      [np.min(ee[u]), np.max(ee[u])], [0., 0.])
            ax19.set_xlabel('Irradiance (W/m^2)')
            ax19.set_ylabel('Percent Deviation from I_L')

            iphfig1 = plt.figure()
            ax20 = iphfig1.add_subplot(111)
            ax20.hold(True)
            ax20.plot(tc[u], iph[u], 'b+', tc[u], piph, 'r.', [0., 80.],
                      [iph0, iph0])
            ax20.set_xlabel('Cell temp. (C)')
            ax20.set_ylabel('I_L (W/m^2)')
            ax20.legend(['Extracted from IV Curves', 'Predicted by Eq. 2',
                         'I_L at STC'], loc=2)
            ax20.text(1.1 * np.min(tc[u]), 1.05 * iph0, ['I_{L0} = %s' % iph0])

        # Additional filter for Rsh and Rs; Restrict effective irradiance to be
        # greater than 400 W/m^2
        vfil = ee > 400

        # Estimate Rsh0, Rsh_ref and Rshexp

        # Initial Guesses. Rsh0 is value at Ee=0.
        nans = np.isnan(rsh)
        if any(ee < 400):
            grsh0 = np.mean(rsh[np.logical_and(~nans, ee < 400)])
        else:
            grsh0 = np.max(rsh)

        # Rsh_ref is value at Ee = 1000
        if any(vfil):
            grshref = np.mean(rsh[np.logical_and(~nans, vfil)])
        else:
            grshref = np.min(rsh)

        # PVsyst default for Rshexp is 5.5
        rshexp = 5.5

        # Here we use a nonlinear least squares technique. Lsqnonlin minimizes
        # the sum of squares of the objective function (here, tf).
        x0 = np.array([grsh0, grshref])
        beta = optimize.least_squares(fun_rsh, x0, args=(rshexp, ee[u],
                                                         const['E0'], rsh[u]),
                                      bounds=np.array([[1., 1.], [1.e7, 1.e6]])
                                      )

        # Extract PVsyst parameter values
        rsh0 = beta.x[0]
        rshref = beta.x[1]

        if graphic:
            # Predict Rsh
            prsh = estrsh(beta, rshexp, ee, const['E0'])

            rshfig = plt.figure()
            ax21 = rshfig.add_subplot(211)
            ax22 = rshfig.add_subplot(212)
            ax21.hold(True)
            ax21.plot(ee[u], np.log10(rsh[u]), 'r.', ee[u], np.log10(prsh[u]),
                      'b.')
            ax21.set_xlabel('Irradiance (W/m^2)')
            ax21.set_ylabel('log_{10}(R_{sh})')
            ax21.legend(['Extracted', 'Predicted'], loc=2)
            ax22.hold(True)
            ax22.plot(ee[u], (np.log10(prsh[u]) - np.log10(rsh[u])) /
                      np.log10(rsh[u]) * 100., 'x',
                      [np.min(ee[u]), np.max(ee[u])], [0., 0.])
            ax22.set_xlabel('Irradiance (W/m^2)')
            ax22.set_ylabel('Percent Deviation in log_{10}(R_{sh})')

            rshfig1 = plt.figure()
            ax23 = rshfig1.add_subplot(111)
            ax23.hold(True)
            ax23.plot(ee[u], np.log10(rsh[u]), 'b.', ee[u], np.log10(prsh[u]),
                      'r.')
            ax23.set_xlabel('Irradiance (W/m^2)')
            ax23.set_ylabel('log_{10}(R_{sh})')
            ax23.legend(['Extracted from IV Curves', 'Predicted by Eq. 5'],
                        loc=3)
            ax23.text(150, 3.65, ['R_{SH0} = %s' % rsh0])
            ax23.text(150, 3.5, ['R_{SH,ref} = %s' % rshref])
            ax23.text(150, 3.35, ['R_{SHexp} = %s' % rshexp])

        # Estimate Rs0
        t15 = np.logical_and(u, vfil)
        rs0 = np.mean(rs[t15])

        if graphic:
            rsfig = plt.figure()
            ax24 = rsfig.add_subplot(211)
            ax25 = rsfig.add_subplot(212)
            ax24.hold(True)
            ax24.plot(ee[t15], rs[t15], 'r.', ee[t15],
                      rs0 * np.ones(len(ee[t15])), 'b.')
            ax24.set_xlabel('Irradiance (W/m^2)')
            ax24.set_ylabel('R_S')
            ax24.legend(['R_S values', 'Model'])
            ax24.set_xlim([0, 1])
            ax24.set_ylin([0, 1200])
            ax25.hold(True)
            ax25.plot(ee[u], (rs0 - rs[u]) / rs[u] * 100., 'x',
                      [np.min(ee[u]), np.max(ee[u])], [0., 0.])
            ax25.set_xlabel('Irradiance (W/m^2)')
            ax25.set_ylabel('Percent Deviation in R_S')

            rsfig1 = plt.figure()
            ax26 = rsfig1.add_subplot(111)
            ax26.hold(True)
            ax26.plot(ee[t15], rs[t15], 'b.', [0., np.max(ee[u])], [rs0, rs0],
                      'r')
            ax26.set_xlabel('Irradiance (W/m^2)')
            ax26.set_ylabel('R_S')
            ax26.legend(['Extracted from IV Curves', 'Predicted by Eq. 7'],
                        loc=3)
            ax26.text(800, 1.2 * rs0, ['R_{S0} = %s' % rs0])

        # Save parameter estimates in output structure
        pvsyst['IL_ref'] = iph0
        pvsyst['Io_ref'] = io0
        pvsyst['eG'] = eg
        pvsyst['Rs_ref'] = rs0
        pvsyst['gamma_ref'] = gamma_ref
        pvsyst['mugamma'] = mugamma
        pvsyst['Iph'] = iph
        pvsyst['Io'] = io
        pvsyst['Rsh0'] = rsh0
        pvsyst['Rsh_ref'] = rshref
        pvsyst['Rshexp'] = rshexp
        pvsyst['Rs'] = rs
        pvsyst['Rsh'] = rsh
        pvsyst['Ns'] = specs['ns']
        pvsyst['u'] = u

        oflag = True
    else:
        oflag = False

        pvsyst['IL_ref'] = float("Nan")
        pvsyst['Io_ref'] = float("Nan")
        pvsyst['eG'] = float("Nan")
        pvsyst['Rs_ref'] = float("Nan")
        pvsyst['gamma_ref'] = float("Nan")
        pvsyst['mugamma'] = float("Nan")
        pvsyst['Iph'] = float("Nan")
        pvsyst['Io'] = float("Nan")
        pvsyst['Rsh0'] = float("Nan")
        pvsyst['Rsh_ref'] = float("Nan")
        pvsyst['Rshexp'] = float("Nan")
        pvsyst['Rs'] = float("Nan")
        pvsyst['Rsh'] = float("Nan")
        pvsyst['Ns'] = specs['ns']
        pvsyst['u'] = np.zeros(n)
    return pvsyst, oflag