Skip to content

Commit

Permalink
split test_sdm.py accordingly
Browse files Browse the repository at this point in the history
  • Loading branch information
kandersolar committed Oct 11, 2024
1 parent 0d45f54 commit 11ec899
Show file tree
Hide file tree
Showing 7 changed files with 425 additions and 407 deletions.
Empty file.
12 changes: 12 additions & 0 deletions pvlib/tests/ivtools/sdm/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import pytest


@pytest.fixture
def cec_params_cansol_cs5p_220p():
return {'ivcurve': {'V_mp_ref': 46.6, 'I_mp_ref': 4.73, 'V_oc_ref': 58.3,
'I_sc_ref': 5.05},
'specs': {'alpha_sc': 0.0025, 'beta_voc': -0.19659,
'gamma_pmp': -0.43, 'cells_in_series': 96},
'params': {'I_L_ref': 5.056, 'I_o_ref': 1.01e-10,
'R_sh_ref': 837.51, 'R_s': 1.004, 'a_ref': 2.3674,
'Adjust': 2.3}}
102 changes: 102 additions & 0 deletions pvlib/tests/ivtools/sdm/test__fit_desoto_pvsyst_sandia.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import numpy as np

import pytest
from numpy.testing import assert_allclose

from pvlib.ivtools.sdm._fit_desoto_pvsyst_sandia import (
_calc_theta_phi_exact,
_update_rsh_fixed_pt,
_update_io
)


@pytest.mark.parametrize('vmp, imp, iph, io, rs, rsh, nnsvth, expected', [
(2., 2., 2., 2., 2., 2., 2., np.nan),
(2., 2., 0., 2., 2., 2., 2., np.nan),
(2., 2., 2., 0., 2., 2., 2., np.nan),
(2., 2., 2., 2., 0., 2., 2., np.nan),
(2., 2., 2., 2., 2., 0., 2., np.nan),
(2., 2., 2., 2., 2., 2., 0., np.nan)])
def test__update_rsh_fixed_pt_nans(vmp, imp, iph, io, rs, rsh, nnsvth,
expected):
outrsh = _update_rsh_fixed_pt(vmp, imp, iph, io, rs, rsh, nnsvth)
assert np.all(np.isnan(outrsh))


def test__update_rsh_fixed_pt_vmp0():
outrsh = _update_rsh_fixed_pt(vmp=0., imp=2., iph=2., io=2., rs=2.,
rsh=2., nnsvth=2.)
assert_allclose(outrsh, np.array([502.]), atol=.0001)


def test__update_rsh_fixed_pt_vector():
outrsh = _update_rsh_fixed_pt(rsh=np.array([-1., 3, .5, 2.]),
rs=np.array([1., -.5, 2., 2.]),
io=np.array([.2, .3, -.4, 2.]),
iph=np.array([-.1, 1, 3., 2.]),
nnsvth=np.array([4., -.2, .1, 2.]),
imp=np.array([.2, .2, -1., 2.]),
vmp=np.array([0., -1, 0., 0.]))
assert np.all(np.isnan(outrsh[0:3]))
assert_allclose(outrsh[3], np.array([502.]), atol=.0001)


@pytest.mark.parametrize('voc, iph, io, rs, rsh, nnsvth, expected', [
(2., 2., 2., 2., 2., 2., 0.5911),
(2., 2., 2., 0., 2., 2., 0.5911),
(2., 2., 0., 2., 2., 2., 0.),
(2., 0., 2., 2., 2., 2., 1.0161e-4),
(0., 2., 2., 2., 2., 2., 17.9436)])
def test__update_io(voc, iph, io, rs, rsh, nnsvth, expected):
outio = _update_io(voc, iph, io, rs, rsh, nnsvth)
assert_allclose(outio, expected, atol=.0001)


@pytest.mark.parametrize('voc, iph, io, rs, rsh, nnsvth', [
(2., 2., 2., 2., 2., 0.),
(-1., -1., -1., -1., -1., -1.)])
def test__update_io_nan(voc, iph, io, rs, rsh, nnsvth):
outio = _update_io(voc, iph, io, rs, rsh, nnsvth)
assert np.isnan(outio)


@pytest.mark.parametrize('vmp, imp, iph, io, rs, rsh, nnsvth, expected', [
(2., 2., 2., 2., 2., 2., 2., (1.8726, 2.)),
(2., 0., 2., 2., 2., 2., 2., (1.8726, 3.4537)),
(2., 2., 0., 2., 2., 2., 2., (1.2650, 0.8526)),
(0., 2., 2., 2., 2., 2., 2., (1.5571, 2.))])
def test__calc_theta_phi_exact(vmp, imp, iph, io, rs, rsh, nnsvth, expected):
theta, phi = _calc_theta_phi_exact(vmp, imp, iph, io, rs, rsh, nnsvth)
assert_allclose(theta, expected[0], atol=.0001)
assert_allclose(phi, expected[1], atol=.0001)


@pytest.mark.parametrize('vmp, imp, iph, io, rs, rsh, nnsvth', [
(2., 2., 2., 0., 2., 2., 2.),
(2., 2., 2., 2., 2., 2., 0.),
(2., 0., 2., 2., 2., 0., 2.)])
def test__calc_theta_phi_exact_both_nan(vmp, imp, iph, io, rs, rsh, nnsvth):
theta, phi = _calc_theta_phi_exact(vmp, imp, iph, io, rs, rsh, nnsvth)
assert np.isnan(theta)
assert np.isnan(phi)


def test__calc_theta_phi_exact_one_nan():
theta, phi = _calc_theta_phi_exact(imp=2., iph=2., vmp=2., io=2.,
nnsvth=2., rs=0., rsh=2.)
assert np.isnan(theta)
assert_allclose(phi, 2., atol=.0001)


def test__calc_theta_phi_exact_vector():
theta, phi = _calc_theta_phi_exact(imp=np.array([1., -1.]),
iph=np.array([-1., 1.]),
vmp=np.array([1., -1.]),
io=np.array([-1., 1.]),
nnsvth=np.array([1., -1.]),
rs=np.array([-1., 1.]),
rsh=np.array([1., -1.]))
assert np.isnan(theta[0])
assert np.isnan(theta[1])
assert np.isnan(phi[0])
assert_allclose(phi[1], 2.2079, atol=.0001)
41 changes: 41 additions & 0 deletions pvlib/tests/ivtools/sdm/test_cec.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import numpy as np
import pandas as pd

import pytest

from pvlib.ivtools import sdm

from pvlib.tests.conftest import requires_pysam


@requires_pysam
def test_fit_cec_sam(cec_params_cansol_cs5p_220p):
input_data = cec_params_cansol_cs5p_220p['ivcurve']
specs = cec_params_cansol_cs5p_220p['specs']
I_L_ref, I_o_ref, R_s, R_sh_ref, a_ref, Adjust = \
sdm.fit_cec_sam(
celltype='polySi', v_mp=input_data['V_mp_ref'],
i_mp=input_data['I_mp_ref'], v_oc=input_data['V_oc_ref'],
i_sc=input_data['I_sc_ref'], alpha_sc=specs['alpha_sc'],
beta_voc=specs['beta_voc'],
gamma_pmp=specs['gamma_pmp'],
cells_in_series=specs['cells_in_series'])
expected = pd.Series(cec_params_cansol_cs5p_220p['params'])
modeled = pd.Series(index=expected.index, data=np.nan)
modeled['a_ref'] = a_ref
modeled['I_L_ref'] = I_L_ref
modeled['I_o_ref'] = I_o_ref
modeled['R_s'] = R_s
modeled['R_sh_ref'] = R_sh_ref
modeled['Adjust'] = Adjust
assert np.allclose(modeled.values, expected.values, rtol=5e-2)


@requires_pysam
def test_fit_cec_sam_estimation_failure(cec_params_cansol_cs5p_220p):
# Failing to estimate the parameters for the CEC SDM model should raise an
# exception.
with pytest.raises(RuntimeError):
sdm.fit_cec_sam(celltype='polySi', v_mp=0.45, i_mp=5.25, v_oc=0.55,
i_sc=5.5, alpha_sc=0.00275, beta_voc=0.00275,
gamma_pmp=0.0055, cells_in_series=1, temp_ref=25)
70 changes: 70 additions & 0 deletions pvlib/tests/ivtools/sdm/test_desoto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import numpy as np
import pandas as pd

import pytest

from pvlib.ivtools import sdm
from pvlib import pvsystem

from pvlib.tests.conftest import requires_statsmodels


def test_fit_desoto():
result, _ = sdm.fit_desoto(v_mp=31.0, i_mp=8.71, v_oc=38.3, i_sc=9.43,
alpha_sc=0.005658, beta_voc=-0.13788,
cells_in_series=60)
result_expected = {'I_L_ref': 9.45232,
'I_o_ref': 3.22460e-10,
'R_s': 0.297814,
'R_sh_ref': 125.798,
'a_ref': 1.59128,
'alpha_sc': 0.005658,
'EgRef': 1.121,
'dEgdT': -0.0002677,
'irrad_ref': 1000,
'temp_ref': 25}
assert np.allclose(pd.Series(result), pd.Series(result_expected),
rtol=1e-4)


def test_fit_desoto_failure():
with pytest.raises(RuntimeError) as exc:
sdm.fit_desoto(v_mp=31.0, i_mp=8.71, v_oc=38.3, i_sc=9.43,
alpha_sc=0.005658, beta_voc=-0.13788,
cells_in_series=10)
assert ('Parameter estimation failed') in str(exc.value)


@requires_statsmodels
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))
IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto(
ee, tc, alpha_sc=specs['alpha_sc'], **params)
ivcurve_params = dict(photocurrent=IL, saturation_current=I0,
resistance_series=Rs, resistance_shunt=Rsh,
nNsVth=nNsVth)
sim_ivcurves = pvsystem.singlediode(**ivcurve_params).to_dict('series')
v = np.linspace(0., sim_ivcurves['v_oc'], 300)
i = pvsystem.i_from_v(voltage=v, **ivcurve_params)
sim_ivcurves.update(v=v.T, i=i.T, ee=ee, 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)
Loading

0 comments on commit 11ec899

Please sign in to comment.