Skip to content

Commit 9cb218c

Browse files
committed
add tests
1 parent 6a11969 commit 9cb218c

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed

tests/ivtools/sdm/test_pvsyst.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
from tests.conftest import requires_statsmodels, TESTS_DATA_DIR
99

10+
import pytest
11+
1012

1113
def _read_iv_curves_for_test(datafile, npts):
1214
""" read constants and npts IV curves from datafile """
@@ -198,3 +200,107 @@ def test_pvsyst_temperature_coeff():
198200
params['I_L_ref'], params['I_o_ref'], params['R_sh_ref'],
199201
params['R_sh_0'], params['R_s'], params['cells_in_series'])
200202
assert_allclose(gamma_pdc, expected, rtol=0.0005)
203+
204+
205+
@pytest.fixture
206+
def pvsyst_iec61853_table3():
207+
# test cases in Table 3 of https://doi.org/10.1109/JPHOTOV.2025.3554338
208+
parameters = ['alpha_sc', 'I_L_ref', 'I_o_ref', 'gamma_ref', 'mu_gamma',
209+
'R_sh_ref', 'R_sh_0', 'R_sh_exp', 'R_s', 'cells_in_series',
210+
'EgRef']
211+
high_current = {
212+
'true': [1e-3, 10, 1e-11, 1.0, -1e-4, 300, 1500, 5.5, 0.2, 60, 1.121],
213+
'estimated': [9.993e-4, 9.997, 1.408e-10, 1.109, -1.666e-5, 543.7,
214+
6130, 5.5, 0.176, 60, 1.121]
215+
}
216+
high_voltage = {
217+
'true': [1e-3, 1.8, 1e-9, 1.5, 1e-4, 3000, 10000, 5.5, 5.0, 108, 1.4],
218+
'estimated': [9.983e-4, 1.799, 1.225e-8, 1.706, 2.662e-4, 4288, 47560,
219+
5.5, 4.292, 108, 1.4],
220+
}
221+
for d in [high_current, high_voltage]:
222+
for key in d:
223+
d[key] = dict(zip(parameters, np.array(d[key])))
224+
225+
return {
226+
'high current': high_current, 'high voltage': high_voltage
227+
}
228+
229+
230+
@pytest.fixture
231+
def iec61853_conditions():
232+
ee = np.array([100, 100, 200, 200, 400, 400, 400, 600, 600, 600, 600,
233+
800, 800, 800, 800, 1000, 1000, 1000, 1000, 1100, 1100,
234+
1100], dtype=np.float64)
235+
tc = np.array([15, 25, 15, 25, 15, 25, 50, 15, 25, 50, 75,
236+
15, 25, 50, 75, 15, 25, 50, 75, 25, 50, 75],
237+
dtype=np.float64)
238+
return ee, tc
239+
240+
241+
@requires_statsmodels
242+
def test_fit_pvsyst_iec61853_sandia(pvsyst_iec61853_table3,
243+
iec61853_conditions):
244+
ee, tc = iec61853_conditions
245+
for _, case in pvsyst_iec61853_table3.items():
246+
true_params = case['true']
247+
expected_params = case['estimated']
248+
249+
sde_params = pvsystem.calcparams_pvsyst(ee, tc, **true_params)
250+
iv = pvsystem.singlediode(*sde_params)
251+
252+
fitted_params = sdm.fit_pvsyst_iec61853_sandia(
253+
ee, tc, iv['i_sc'], iv['v_oc'], iv['i_mp'], iv['v_mp'],
254+
true_params['cells_in_series'], EgRef=true_params['EgRef'],
255+
)
256+
for key in expected_params.keys():
257+
assert np.isclose(fitted_params[key], expected_params[key],
258+
atol=0, rtol=1e-3)
259+
260+
261+
@requires_statsmodels
262+
def test_fit_pvsyst_iec61853_sandia_optional(pvsyst_iec61853_table3,
263+
iec61853_conditions):
264+
# verify that modifying each optional parameter results in different output
265+
ee, tc = iec61853_conditions
266+
case = pvsyst_iec61853_table3['high current']
267+
true_params = case['true']
268+
expected = case['estimated']
269+
sde_params = pvsystem.calcparams_pvsyst(ee, tc, **true_params)
270+
iv = pvsystem.singlediode(*sde_params)
271+
272+
main_inputs = dict(
273+
effective_irradiance=ee, temp_cell=tc, i_sc=iv['i_sc'],
274+
v_oc=iv['v_oc'], i_mp=iv['i_mp'], v_mp=iv['v_mp'],
275+
cells_in_series=true_params['cells_in_series']
276+
)
277+
278+
fitted_params = sdm.fit_pvsyst_iec61853_sandia(**main_inputs,
279+
EgRef=1.0)
280+
assert not np.isclose(fitted_params['I_o_ref'], expected['I_o_ref'],
281+
atol=0, rtol=1e-3)
282+
283+
fitted_params = sdm.fit_pvsyst_iec61853_sandia(**main_inputs,
284+
alpha_sc=0.5e-3)
285+
assert not np.isclose(fitted_params['alpha_sc'], expected['alpha_sc'],
286+
atol=0, rtol=1e-3)
287+
288+
fitted_params = sdm.fit_pvsyst_iec61853_sandia(**main_inputs,
289+
beta_mp=-1e-4)
290+
assert not np.isclose(fitted_params['R_sh_ref'], expected['R_sh_ref'],
291+
atol=0, rtol=1e-3)
292+
293+
fitted_params = sdm.fit_pvsyst_iec61853_sandia(**main_inputs,
294+
r_sh_coeff=0.3)
295+
assert not np.isclose(fitted_params['R_sh_ref'], expected['R_sh_ref'],
296+
atol=0, rtol=1e-3)
297+
298+
fitted_params = sdm.fit_pvsyst_iec61853_sandia(**main_inputs,
299+
R_s=0.5)
300+
assert not np.isclose(fitted_params['R_s'], expected['R_s'],
301+
atol=0, rtol=1e-3)
302+
303+
fitted_params = sdm.fit_pvsyst_iec61853_sandia(**main_inputs,
304+
min_Rsh_irradiance=500)
305+
assert not np.isclose(fitted_params['R_sh_ref'], expected['R_sh_ref'],
306+
atol=0, rtol=1e-3)

0 commit comments

Comments
 (0)