Skip to content

Commit 11ec899

Browse files
committed
split test_sdm.py accordingly
1 parent 0d45f54 commit 11ec899

File tree

7 files changed

+425
-407
lines changed

7 files changed

+425
-407
lines changed

pvlib/tests/ivtools/sdm/__init__.py

Whitespace-only changes.

pvlib/tests/ivtools/sdm/conftest.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import pytest
2+
3+
4+
@pytest.fixture
5+
def cec_params_cansol_cs5p_220p():
6+
return {'ivcurve': {'V_mp_ref': 46.6, 'I_mp_ref': 4.73, 'V_oc_ref': 58.3,
7+
'I_sc_ref': 5.05},
8+
'specs': {'alpha_sc': 0.0025, 'beta_voc': -0.19659,
9+
'gamma_pmp': -0.43, 'cells_in_series': 96},
10+
'params': {'I_L_ref': 5.056, 'I_o_ref': 1.01e-10,
11+
'R_sh_ref': 837.51, 'R_s': 1.004, 'a_ref': 2.3674,
12+
'Adjust': 2.3}}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import numpy as np
2+
3+
import pytest
4+
from numpy.testing import assert_allclose
5+
6+
from pvlib.ivtools.sdm._fit_desoto_pvsyst_sandia import (
7+
_calc_theta_phi_exact,
8+
_update_rsh_fixed_pt,
9+
_update_io
10+
)
11+
12+
13+
@pytest.mark.parametrize('vmp, imp, iph, io, rs, rsh, nnsvth, expected', [
14+
(2., 2., 2., 2., 2., 2., 2., np.nan),
15+
(2., 2., 0., 2., 2., 2., 2., np.nan),
16+
(2., 2., 2., 0., 2., 2., 2., np.nan),
17+
(2., 2., 2., 2., 0., 2., 2., np.nan),
18+
(2., 2., 2., 2., 2., 0., 2., np.nan),
19+
(2., 2., 2., 2., 2., 2., 0., np.nan)])
20+
def test__update_rsh_fixed_pt_nans(vmp, imp, iph, io, rs, rsh, nnsvth,
21+
expected):
22+
outrsh = _update_rsh_fixed_pt(vmp, imp, iph, io, rs, rsh, nnsvth)
23+
assert np.all(np.isnan(outrsh))
24+
25+
26+
def test__update_rsh_fixed_pt_vmp0():
27+
outrsh = _update_rsh_fixed_pt(vmp=0., imp=2., iph=2., io=2., rs=2.,
28+
rsh=2., nnsvth=2.)
29+
assert_allclose(outrsh, np.array([502.]), atol=.0001)
30+
31+
32+
def test__update_rsh_fixed_pt_vector():
33+
outrsh = _update_rsh_fixed_pt(rsh=np.array([-1., 3, .5, 2.]),
34+
rs=np.array([1., -.5, 2., 2.]),
35+
io=np.array([.2, .3, -.4, 2.]),
36+
iph=np.array([-.1, 1, 3., 2.]),
37+
nnsvth=np.array([4., -.2, .1, 2.]),
38+
imp=np.array([.2, .2, -1., 2.]),
39+
vmp=np.array([0., -1, 0., 0.]))
40+
assert np.all(np.isnan(outrsh[0:3]))
41+
assert_allclose(outrsh[3], np.array([502.]), atol=.0001)
42+
43+
44+
@pytest.mark.parametrize('voc, iph, io, rs, rsh, nnsvth, expected', [
45+
(2., 2., 2., 2., 2., 2., 0.5911),
46+
(2., 2., 2., 0., 2., 2., 0.5911),
47+
(2., 2., 0., 2., 2., 2., 0.),
48+
(2., 0., 2., 2., 2., 2., 1.0161e-4),
49+
(0., 2., 2., 2., 2., 2., 17.9436)])
50+
def test__update_io(voc, iph, io, rs, rsh, nnsvth, expected):
51+
outio = _update_io(voc, iph, io, rs, rsh, nnsvth)
52+
assert_allclose(outio, expected, atol=.0001)
53+
54+
55+
@pytest.mark.parametrize('voc, iph, io, rs, rsh, nnsvth', [
56+
(2., 2., 2., 2., 2., 0.),
57+
(-1., -1., -1., -1., -1., -1.)])
58+
def test__update_io_nan(voc, iph, io, rs, rsh, nnsvth):
59+
outio = _update_io(voc, iph, io, rs, rsh, nnsvth)
60+
assert np.isnan(outio)
61+
62+
63+
@pytest.mark.parametrize('vmp, imp, iph, io, rs, rsh, nnsvth, expected', [
64+
(2., 2., 2., 2., 2., 2., 2., (1.8726, 2.)),
65+
(2., 0., 2., 2., 2., 2., 2., (1.8726, 3.4537)),
66+
(2., 2., 0., 2., 2., 2., 2., (1.2650, 0.8526)),
67+
(0., 2., 2., 2., 2., 2., 2., (1.5571, 2.))])
68+
def test__calc_theta_phi_exact(vmp, imp, iph, io, rs, rsh, nnsvth, expected):
69+
theta, phi = _calc_theta_phi_exact(vmp, imp, iph, io, rs, rsh, nnsvth)
70+
assert_allclose(theta, expected[0], atol=.0001)
71+
assert_allclose(phi, expected[1], atol=.0001)
72+
73+
74+
@pytest.mark.parametrize('vmp, imp, iph, io, rs, rsh, nnsvth', [
75+
(2., 2., 2., 0., 2., 2., 2.),
76+
(2., 2., 2., 2., 2., 2., 0.),
77+
(2., 0., 2., 2., 2., 0., 2.)])
78+
def test__calc_theta_phi_exact_both_nan(vmp, imp, iph, io, rs, rsh, nnsvth):
79+
theta, phi = _calc_theta_phi_exact(vmp, imp, iph, io, rs, rsh, nnsvth)
80+
assert np.isnan(theta)
81+
assert np.isnan(phi)
82+
83+
84+
def test__calc_theta_phi_exact_one_nan():
85+
theta, phi = _calc_theta_phi_exact(imp=2., iph=2., vmp=2., io=2.,
86+
nnsvth=2., rs=0., rsh=2.)
87+
assert np.isnan(theta)
88+
assert_allclose(phi, 2., atol=.0001)
89+
90+
91+
def test__calc_theta_phi_exact_vector():
92+
theta, phi = _calc_theta_phi_exact(imp=np.array([1., -1.]),
93+
iph=np.array([-1., 1.]),
94+
vmp=np.array([1., -1.]),
95+
io=np.array([-1., 1.]),
96+
nnsvth=np.array([1., -1.]),
97+
rs=np.array([-1., 1.]),
98+
rsh=np.array([1., -1.]))
99+
assert np.isnan(theta[0])
100+
assert np.isnan(theta[1])
101+
assert np.isnan(phi[0])
102+
assert_allclose(phi[1], 2.2079, atol=.0001)

pvlib/tests/ivtools/sdm/test_cec.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import numpy as np
2+
import pandas as pd
3+
4+
import pytest
5+
6+
from pvlib.ivtools import sdm
7+
8+
from pvlib.tests.conftest import requires_pysam
9+
10+
11+
@requires_pysam
12+
def test_fit_cec_sam(cec_params_cansol_cs5p_220p):
13+
input_data = cec_params_cansol_cs5p_220p['ivcurve']
14+
specs = cec_params_cansol_cs5p_220p['specs']
15+
I_L_ref, I_o_ref, R_s, R_sh_ref, a_ref, Adjust = \
16+
sdm.fit_cec_sam(
17+
celltype='polySi', v_mp=input_data['V_mp_ref'],
18+
i_mp=input_data['I_mp_ref'], v_oc=input_data['V_oc_ref'],
19+
i_sc=input_data['I_sc_ref'], alpha_sc=specs['alpha_sc'],
20+
beta_voc=specs['beta_voc'],
21+
gamma_pmp=specs['gamma_pmp'],
22+
cells_in_series=specs['cells_in_series'])
23+
expected = pd.Series(cec_params_cansol_cs5p_220p['params'])
24+
modeled = pd.Series(index=expected.index, data=np.nan)
25+
modeled['a_ref'] = a_ref
26+
modeled['I_L_ref'] = I_L_ref
27+
modeled['I_o_ref'] = I_o_ref
28+
modeled['R_s'] = R_s
29+
modeled['R_sh_ref'] = R_sh_ref
30+
modeled['Adjust'] = Adjust
31+
assert np.allclose(modeled.values, expected.values, rtol=5e-2)
32+
33+
34+
@requires_pysam
35+
def test_fit_cec_sam_estimation_failure(cec_params_cansol_cs5p_220p):
36+
# Failing to estimate the parameters for the CEC SDM model should raise an
37+
# exception.
38+
with pytest.raises(RuntimeError):
39+
sdm.fit_cec_sam(celltype='polySi', v_mp=0.45, i_mp=5.25, v_oc=0.55,
40+
i_sc=5.5, alpha_sc=0.00275, beta_voc=0.00275,
41+
gamma_pmp=0.0055, cells_in_series=1, temp_ref=25)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import numpy as np
2+
import pandas as pd
3+
4+
import pytest
5+
6+
from pvlib.ivtools import sdm
7+
from pvlib import pvsystem
8+
9+
from pvlib.tests.conftest import requires_statsmodels
10+
11+
12+
def test_fit_desoto():
13+
result, _ = sdm.fit_desoto(v_mp=31.0, i_mp=8.71, v_oc=38.3, i_sc=9.43,
14+
alpha_sc=0.005658, beta_voc=-0.13788,
15+
cells_in_series=60)
16+
result_expected = {'I_L_ref': 9.45232,
17+
'I_o_ref': 3.22460e-10,
18+
'R_s': 0.297814,
19+
'R_sh_ref': 125.798,
20+
'a_ref': 1.59128,
21+
'alpha_sc': 0.005658,
22+
'EgRef': 1.121,
23+
'dEgdT': -0.0002677,
24+
'irrad_ref': 1000,
25+
'temp_ref': 25}
26+
assert np.allclose(pd.Series(result), pd.Series(result_expected),
27+
rtol=1e-4)
28+
29+
30+
def test_fit_desoto_failure():
31+
with pytest.raises(RuntimeError) as exc:
32+
sdm.fit_desoto(v_mp=31.0, i_mp=8.71, v_oc=38.3, i_sc=9.43,
33+
alpha_sc=0.005658, beta_voc=-0.13788,
34+
cells_in_series=10)
35+
assert ('Parameter estimation failed') in str(exc.value)
36+
37+
38+
@requires_statsmodels
39+
def test_fit_desoto_sandia(cec_params_cansol_cs5p_220p):
40+
# this test computes a set of IV curves for the input fixture, fits
41+
# the De Soto model to the calculated IV curves, and compares the fitted
42+
# parameters to the starting values
43+
params = cec_params_cansol_cs5p_220p['params']
44+
params.pop('Adjust')
45+
specs = cec_params_cansol_cs5p_220p['specs']
46+
effective_irradiance = np.array([400., 500., 600., 700., 800., 900.,
47+
1000.])
48+
temp_cell = np.array([15., 25., 35., 45.])
49+
ee = np.tile(effective_irradiance, len(temp_cell))
50+
tc = np.repeat(temp_cell, len(effective_irradiance))
51+
IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto(
52+
ee, tc, alpha_sc=specs['alpha_sc'], **params)
53+
ivcurve_params = dict(photocurrent=IL, saturation_current=I0,
54+
resistance_series=Rs, resistance_shunt=Rsh,
55+
nNsVth=nNsVth)
56+
sim_ivcurves = pvsystem.singlediode(**ivcurve_params).to_dict('series')
57+
v = np.linspace(0., sim_ivcurves['v_oc'], 300)
58+
i = pvsystem.i_from_v(voltage=v, **ivcurve_params)
59+
sim_ivcurves.update(v=v.T, i=i.T, ee=ee, tc=tc)
60+
61+
result = sdm.fit_desoto_sandia(sim_ivcurves, specs)
62+
modeled = pd.Series(index=params.keys(), data=np.nan)
63+
modeled['a_ref'] = result['a_ref']
64+
modeled['I_L_ref'] = result['I_L_ref']
65+
modeled['I_o_ref'] = result['I_o_ref']
66+
modeled['R_s'] = result['R_s']
67+
modeled['R_sh_ref'] = result['R_sh_ref']
68+
expected = pd.Series(params)
69+
assert np.allclose(modeled[params.keys()].values,
70+
expected[params.keys()].values, rtol=5e-2)

0 commit comments

Comments
 (0)