8000 Add desoto and pvsyst as dc_model options to ModelChain (#555) · shirubana/pvlib-python@cba621b · GitHub
[go: up one dir, main page]

Skip to content

Commit cba621b

Browse files
authored
Add desoto and pvsyst as dc_model options to ModelChain (pvlib#555)
* Add desoto and pvsyst as dc_model options to ModelChain * Add desoto to DC_MODEL_PARAMS * Change to pvlibDeprecationWarning, add v0.7 test for singlediode keyword * Fix model function reference in test_infer_dc_model * Change function object to strings * Add pvsyst_dc_snl_ac_system to test_infer_dc_models argument list * Add sam_data argument to pvsyst_dc_snl_ac_system * Update whatsnew, api.rst * Add deprecated to ModelChain.singlediode docstring * Revert "Add deprecated to ModelChain.singlediode docstring" This reverts commit 7bf8a30. * Add deprecated to ModelChain.singlediode docstring * Fix indents, remove ModelChain.singlediode from api.rst
1 parent 7166fb0 commit cba621b

File tree

5 files changed

+111
-15
lines changed

5 files changed

+111
-15
lines changed

docs/sphinx/source/api.rst

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,10 @@ AOI modifiers
204204
pvsystem.ashraeiam
205205
pvsystem.sapm_aoi_loss
206206

207-
Single diode model
208-
------------------
207+
Single diode models
208+
-------------------
209209

210-
Functions relevant for the single diode model.
210+
Functions relevant for single diode models.
211211

212212
.. autosummary::
213213
:toctree: generated/
@@ -419,7 +419,8 @@ ModelChain model definitions.
419419
:toctree: generated/
420420

421421
modelchain.ModelChain.sapm
422-
modelchain.ModelChain.singlediode
422+
modelchain.ModelChain.desoto
423+
modelchain.ModelChain.pvsyst
423424
modelchain.ModelChain.pvwatts_dc
424425
modelchain.ModelChain.snlinverter
425426
modelchain.ModelChain.adrinverter

docs/sphinx/source/whatsnew/v0.6.0.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ API Changes
5353
dirindex functions. (:issue:`311`, :issue:`396`)
5454
* Method ModelChain.infer_dc_model now returns a tuple (function handle, model name string)
5555
instead of only the function handle (:issue:`417`)
56+
* Add DC model methods desoto and pvsyst to ModelChain, and deprecates DC model method singlediode
57+
(singlediode defaults to desoto until v0.7.0) (:issue:`487`)
5658

5759

5860
Enhancements
@@ -104,6 +106,7 @@ Enhancements
104106
* Add irradiance.clearness_index function. (:issue:`396`)
105107
* Add irradiance.clearness_index_zenith_independent function. (:issue:`396`)
106108
* Add checking for consistency between module_parameters and dc_model. (:issue:`417`)
109+
* Add DC model methods desoto and pvsyst to ModelChain (:issue:`487`)
107110

108111

109112
Bug fixes

pvlib/modelchain.py

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from pvlib.tracking import SingleAxisTracker
1515
import pvlib.irradiance # avoid name conflict with full import
1616
from pvlib.pvsystem import DC_MODEL_PARAMS
17+
from pvlib._deprecation import pvlibDeprecationWarning
1718

1819

1920
def basic_chain(times, latitude, longitude,
@@ -251,8 +252,8 @@ class ModelChain(object):
251252
dc_model: None, str, or function, default None
252253
If None, the model will be inferred from the contents of
253254
system.module_parameters. Valid strings are 'sapm',
254-
'singlediode', 'pvwatts'. The ModelChain instance will be passed
255-
as the first argument to a user-defined function.
255+
'desoto', 'pvsyst', 'pvwatts'. The ModelChain instance will
256+
be passed as the first argument to a user-defined function.
256257
257258
ac_model: None, str, or function, default None
258259
If None, the model will be inferred from the contents of
@@ -379,10 +380,19 @@ def dc_model(self, model):
379380
str(missing_params))
380381
if model == 'sapm':
381382
self._dc_model = self.sapm
382-
elif model == 'singlediode':
383-
self._dc_model = self.singlediode
383+
elif model == 'desoto':
384+
self._dc_model = self.desoto
385+
elif model == 'pvsyst':
386+
self._dc_model = self.pvsyst
384387
elif model == 'pvwatts':
385388
self._dc_model = self.pvwatts_dc
389+
elif model == 'singlediode':
390+
warnings.warn('DC model keyword singlediode used for '
391+
'ModelChain object. singlediode is '
392+
'ambiguous, use desoto instead. singlediode '
393+
'keyword will be removed in v0.7.0 and '
394+
'later', pvlibDeprecationWarning)
395+
self._dc_model = self.desoto
386396
else:
387397
raise ValueError(model + ' is not a valid DC power model')
388398
else:
@@ -393,7 +403,10 @@ def infer_dc_model(self):
393403
if set(['A0', 'A1', 'C7']) <= params:
394 F438 404
return self.sapm, 'sapm'
395405
elif set(['a_ref', 'I_L_ref', 'I_o_ref', 'R_sh_ref', 'R_s']) <= params:
396-
return self.singlediode, 'singlediode'
406+
return self.desoto, 'desoto'
407+
elif set(['gamma_ref', 'mu_gamma', 'I_L_ref', 'I_o_ref',
408+
'R_sh_ref', 'R_sh_0', 'R_sh_exp', 'R_s']) <= params:
409+
return self.pvsyst, 'pvsyst'
397410
elif set(['pdc0', 'gamma_pdc']) <= params:
398411
return self.pvwatts_dc, 'pvwatts'
399412
else:
@@ -408,7 +421,44 @@ def sapm(self):
408421

409422
return self
410423

424+
def desoto(self):
425+
(photocurrent, saturation_current, resistance_series,
426+
resistance_shunt, nNsVth) = (
427+
self.system.calcparams_desoto(self.effective_irradiance,
428+
self.temps['temp_cell']))
429+
430+
self.diode_params = (photocurrent, saturation_current,
431+
resistance_series,
432+
resistance_shunt, nNsVth)
433+
434+
self.dc = self.system.singlediode(
435+
photocurrent, saturation_current, resistance_series,
436+
resistance_shunt, nNsVth)
437+
438+
self.dc = self.system.scale_voltage_current_power(self.dc).fillna(0)
439+
440+
return self
441+
442+
def pvsyst(self):
443+
(photocurrent, saturation_current, resistance_series,
444+
resistance_shunt, nNsVth) = (
445+
self.system.calcparams_pvsyst(self.effective_irradiance,
446+
self.temps['temp_cell']))
447+
448+
self.diode_params = (photocurrent, saturation_current,
449+
resistance_series,
450+
resistance_shunt, nNsVth)
451+
452+
self.dc = self.system.singlediode(
453+
photocurrent, saturation_current, resistance_series,
454+
resistance_shunt, nNsVth)
455+
456+
self.dc = self.system.scale_voltage_current_power(self.dc).fillna(0)
457+
458+
return self
459+
411460
def singlediode(self):
461+
"""Deprecated"""
412462
(photocurrent, saturation_current, resistance_series,
413463
resistance_shunt, nNsVth) = (
414464
self.system.calcparams_desoto(self.effective_irradiance,

pvlib/pvsystem.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@
3131
'C7', 'Isco', 'Impo', 'Aisc', 'Aimp', 'Bvoco',
3232
'Mbvoc', 'Bvmpo', 'Mbvmp', 'N', 'Cells_in_Series',
3333
'IXO', 'IXXO', 'FD']),
34+
'desoto' :
35+
set(['alpha_sc', 'a_ref', 'I_L_ref', 'I_o_ref',
36+
'R_sh_ref', 'R_s']),
37+
'pvsyst' :
38+
set(['gamma_ref', 'mu_gamma', 'I_L_ref', 'I_o_ref',
39+
'R_sh_ref', 'R_sh_0', 'R_s', 'alpha_sc', 'EgRef',
40+
'cells_in_series']),
3441
'singlediode' :
3542
set(['alpha_sc', 'a_ref', 'I_L_ref', 'I_o_ref',
3643
'R_sh_ref', 'R_s']),

pvlib/test/test_modelchain.py

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@
1414
from pvlib.pvsystem import PVSystem
1515
from pvlib.tracking import SingleAxisTracker
1616
from pvlib.location import Location
17+
from pvlib._deprecation import pvlibDeprecationWarning
1718

1819
from pandas.util.testing import assert_series_equal, assert_frame_equal
1920
import pytest
2021
21-
from test_pvsystem import sam_data
22-
from conftest import requires_scipy
22+
from test_pvsystem import sam_data, pvsyst_module_params
23+
from conftest import fail_on_pvlib_version, requires_scipy
2324

2425

2526
@pytest.fixture
@@ -53,6 +54,20 @@ def cec_dc_snl_ac_system(sam_data):
5354
return system
5455

5556

57+
@pytest.fixture
58+
def pvsyst_dc_snl_ac_system(sam_data):
59+
module = 'PVsyst test module'
60+
module_parameters = pvsyst_module_params()
61+
module_parameters['b'] = 0.05
62+
inverters = sam_data['cecinverter']
63+
inverter = inverters['ABB__MICRO_0_25_I_OUTD_US_208_208V__CEC_2014_'].copy()
64+
system = PVSystem(surface_tilt=32.2, surface_azimuth=180,
65+
module=module,
66+
module_parameters=module_parameters,
67+
inverter_parameters=inverter)
68+
return system
69+
70+
5671
@pytest.fixture
5772
def cec_dc_adr_ac_system(sam_data):
5873
modules = sam_data['cecmod']
@@ -203,14 +218,26 @@ def poadc(mc):
203218

204219

205220
@pytest.mark.parametrize('dc_model', [
206-
'sapm', pytest.param('singlediode', marks=requires_scipy), 'pvwatts_dc'])
207-
def test_infer_dc_model(system, cec_dc_snl_ac_system,
221+
'sapm',
222+
pytest.param('desoto', marks=requires_scipy),
223+
pytest.param('pvsyst', marks=requires_scipy),
224+
pytest.param('singlediode', marks=requires_scipy),
225+
'pvwatts_dc'])
226+
def test_infer_dc_model(system, cec_dc_snl_ac_system, pvsyst_dc_snl_ac_system,
208227
pvwatts_dc_pvwatts_ac_system, location, dc_model,
209228
weather, mocker):
210-
dc_systems = {'sapm': system, 'singlediode': cec_dc_snl_ac_system,
229+
dc_systems = {'sapm': system,
230+
'desoto': cec_dc_snl_ac_system,
231+
'pvsyst': pvsyst_dc_snl_ac_system,
232+
'singlediode': cec_dc_snl_ac_system,
211233
'pvwatts_dc': pvwatts_dc_pvwatts_ac_system}
234+
dc_model_function = {'sapm': 'sapm',
235+
'desoto': 'calcparams_desoto',
236+
'pvsyst': 'calcparams_pvsyst',
237+
'singlediode': 'calcparams_desoto',
238+
'pvwatts_dc': 'pvwatts_dc'}
212239
system = dc_systems[dc_model]
213-
m = mocker.spy(system, dc_model)
240+
m = mocker.spy(system, dc_model_function[dc_model])
214241
mc = ModelChain(system, location,
215242
aoi_model='no_loss', spectral_model='no_loss')
216243
mc.run_model(weather.index, weather=weather)
@@ -410,6 +437,14 @@ def test_bad_get_orientation():
410437
modelchain.get_orientation('bad value')
411438

412439

440+
@fail_on_pvlib_version('0.7')
441+
def test_deprecated_07():
442+
with pytest.warns(pvlibDeprecationWarning):
443+
mc = ModelChain(cec_dc_snl_ac_system, location,
444+
dc_model='singlediode', # this should fail after 0.7
445+
aoi_model='no_loss', spectral_model='no_loss')
446+
447+
413448
@requires_scipy
414449
def test_basic_chain_required(sam_data):
415450
times = pd.DatetimeIndex(start='20160101 1200-0700',

0 commit comments

Comments
 (0)
0