Skip to content

Commit

Permalink
preconfigured ModelChain for pvwatts, sapm (#1022)
Browse files Browse the repository at this point in the history
* PVWatts(ModelChain)

* make_chain_pvwatts classmethod

* sapm

* method names, comment

* remove class, add pvsyst stub

* fix dict update, a couple of tests

* documentation

* remove incomplete with_pvsyst

* fix temperature model issues

* fix temp model kwarg. run_model in test

* complicated code is bad

* remove with_pvsyst from docs
  • Loading branch information
wholmgren committed Aug 25, 2020
1 parent 87d1bf2 commit a7edb8b
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 0 deletions.
2 changes: 2 additions & 0 deletions docs/sphinx/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,8 @@ Creating a ModelChain object.
:toctree: generated/

modelchain.ModelChain
modelchain.ModelChain.with_pvwatts
modelchain.ModelChain.with_sapm

Running
-------
Expand Down
5 changes: 5 additions & 0 deletions docs/sphinx/source/whatsnew/v0.8.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ Enhancements
(:pull:`1017`)
* Add :py:func:`pvlib.inverter.fit_sandia` that fits the Sandia inverter model
to a set of inverter efficiency curves. (:pull:`1011`)
* Add factory methods :py:meth:`~pvlib.modelchain.ModelChain.with_pvwatts`
:py:meth:`~pvlib.modelchain.ModelChain.with_sapm` to create ``ModelChain``
objects configured for the respective modeling paradigms. The
configurations are defined in ``modelchain.PVWATTS_CONFIG``, and
``modelchain.SAPM_CONFIG``. (:issue:`1013`, :pull:`1022`)
* Added *racking_model*, *module_type*, and *temperature_model_parameters* to
PVSystem, LocalizedPVSystem, SingleAxisTracker, and
LocalizedSingleAxisTracker repr methods. (:issue:`1027`)
Expand Down
189 changes: 189 additions & 0 deletions pvlib/modelchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,30 @@
from pvlib._deprecation import pvlibDeprecationWarning
from pvlib.tools import _build_kwargs


# these dictionaries contain the default configuration for following
# established modeling sequences. They can be used in combination with
# basic_chain and ModelChain. They are used by the ModelChain methods
# ModelChain.with_pvwatts, ModelChain.with_sapm, etc.

# pvwatts documentation states that it uses the following reference for
# a temperature model: Fuentes, M. K. (1987). A Simplified Thermal Model
# for Flat-Plate Photovoltaic Arrays. SAND85-0330. Albuquerque, NM:
# Sandia National Laboratories. Accessed September 3, 2013:
# http://prod.sandia.gov/techlib/access-control.cgi/1985/850330.pdf
# pvlib python does not implement that model, so use the SAPM instead.
PVWATTS_CONFIG = dict(
dc_model='pvwatts', ac_model='pvwatts', losses_model='pvwatts',
transposition_model='perez', aoi_model='physical',
spectral_model='no_loss', temperature_model='sapm'
)

SAPM_CONFIG = dict(
dc_model='sapm', ac_model='sandia', losses_model='no_loss',
aoi_model='sapm', spectral_model='sapm', temperature_model='sapm'
)


def basic_chain(times, latitude, longitude,
module_parameters, temperature_model_parameters,
inverter_parameters,
Expand Down Expand Up @@ -349,6 +373,171 @@ def __init__(self, system, location,
self.times = None
self.solar_position = None

@classmethod
def with_pvwatts(cls, system, location,
orientation_strategy=None,
clearsky_model='ineichen',
airmass_model='kastenyoung1989',
name=None,
**kwargs):
"""
ModelChain that follows the PVWatts methods.
Parameters
----------
system : PVSystem
A :py:class:`~pvlib.pvsystem.PVSystem` object that represents
the connected set of modules, inverters, etc.
location : Location
A :py:class:`~pvlib.location.Location` object that represents
the physical location at which to evaluate the model.
orientation_strategy : None or str, default None
The strategy for aligning the modules. If not None, sets the
``surface_azimuth`` and ``surface_tilt`` properties of the
``system``. Allowed strategies include 'flat',
'south_at_latitude_tilt'. Ignored for SingleAxisTracker systems.
clearsky_model : str, default 'ineichen'
Passed to location.get_clearsky.
airmass_model : str, default 'kastenyoung1989'
Passed to location.get_airmass.
name: None or str, default None
Name of ModelChain instance.
**kwargs
Parameters supplied here are passed to the ModelChain
constructor and take precedence over the default
configuration.
Examples
--------
>>> module_parameters = dict(gamma_pdc=-0.003, pdc0=4500)
>>> inverter_parameters = dict(pac0=4000)
>>> tparams = TEMPERATURE_MODEL_PARAMETERS['sapm']['open_rack_glass_glass']
>>> system = PVSystem(surface_tilt=30, surface_azimuth=180,
... module_parameters=module_parameters,
... inverter_parameters=inverter_parameters,
... temperature_model_parameters=tparams)
>>> location = Location(32.2, -110.9)
>>> ModelChain.with_pvwatts(system, location)
ModelChain:
name: None
orientation_strategy: None
clearsky_model: ineichen
transposition_model: perez
solar_position_method: nrel_numpy
airmass_model: kastenyoung1989
dc_model: pvwatts_dc
ac_model: pvwatts_inverter
aoi_model: physical_aoi_loss
spectral_model: no_spectral_loss
temperature_model: sapm_temp
losses_model: pvwatts_losses
""" # noqa: E501
config = PVWATTS_CONFIG.copy()
config.update(kwargs)
return ModelChain(
system, location,
orientation_strategy=orientation_strategy,
clearsky_model=clearsky_model,
airmass_model=airmass_model,
name=name,
**config
)

@classmethod
def with_sapm(cls, system, location,
orientation_strategy=None,
clearsky_model='ineichen',
transposition_model='haydavies',
solar_position_method='nrel_numpy',
airmass_model='kastenyoung1989',
name=None,
**kwargs):
"""
ModelChain that follows the Sandia Array Performance Model
(SAPM) methods.
Parameters
----------
system : PVSystem
A :py:class:`~pvlib.pvsystem.PVSystem` object that represents
the connected set of modules, inverters, etc.
location : Location
A :py:class:`~pvlib.location.Location` object that represents
the physical location at which to evaluate the model.
orientation_strategy : None or str, default None
The strategy for aligning the modules. If not None, sets the
``surface_azimuth`` and ``surface_tilt`` properties of the
``system``. Allowed strategies include 'flat',
'south_at_latitude_tilt'. Ignored for SingleAxisTracker systems.
clearsky_model : str, default 'ineichen'
Passed to location.get_clearsky.
transposition_model : str, default 'haydavies'
Passed to system.get_irradiance.
solar_position_method : str, default 'nrel_numpy'
Passed to location.get_solarposition.
airmass_model : str, default 'kastenyoung1989'
Passed to location.get_airmass.
name: None or str, default None
Name of ModelChain instance.
**kwargs
Parameters supplied here are passed to the ModelChain
constructor and take precedence over the default
configuration.
Examples
--------
>>> mods = pvlib.pvsystem.retrieve_sam('sandiamod')
>>> invs = pvlib.pvsystem.retrieve_sam('cecinverter')
>>> module_parameters = mods['Canadian_Solar_CS5P_220M___2009_']
>>> inverter_parameters = invs['ABB__MICRO_0_25_I_OUTD_US_240__240V_']
>>> tparams = TEMPERATURE_MODEL_PARAMETERS['sapm']['open_rack_glass_glass']
>>> system = PVSystem(surface_tilt=30, surface_azimuth=180,
... module_parameters=module_parameters,
... inverter_parameters=inverter_parameters,
... temperature_model_parameters=tparams)
>>> location = Location(32.2, -110.9)
>>> ModelChain.with_sapm(system, location)
ModelChain:
name: None
orientation_strategy: None
clearsky_model: ineichen
transposition_model: haydavies
solar_position_method: nrel_numpy
airmass_model: kastenyoung1989
dc_model: sapm
ac_model: snlinverter
aoi_model: sapm_aoi_loss
spectral_model: sapm_spectral_loss
temperature_model: sapm_temp
losses_model: no_extra_losses
""" # noqa: E501
config = SAPM_CONFIG.copy()
config.update(kwargs)
return ModelChain(
system, location,
orientation_strategy=orientation_strategy,
clearsky_model=clearsky_model,
transposition_model=transposition_model,
solar_position_method=solar_position_method,
airmass_model=airmass_model,
name=name,
**config
)

def __repr__(self):
attrs = [
'name', 'orientation_strategy', 'clearsky_model',
Expand Down
13 changes: 13 additions & 0 deletions pvlib/tests/test_modelchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,19 @@ def test_ModelChain_creation(sapm_dc_snl_ac_system, location):
ModelChain(sapm_dc_snl_ac_system, location)


def test_with_sapm(sapm_dc_snl_ac_system, location, weather):
mc = ModelChain.with_sapm(sapm_dc_snl_ac_system, location)
assert mc.dc_model == mc.sapm
mc.run_model(weather)


def test_with_pvwatts(pvwatts_dc_pvwatts_ac_system, location, weather):
mc = ModelChain.with_pvwatts(pvwatts_dc_pvwatts_ac_system, location)
assert mc.dc_model == mc.pvwatts_dc
assert mc.temperature_model == mc.sapm_temp
mc.run_model(weather)


@pytest.mark.parametrize('strategy, expected', [
(None, (32.2, 180)), ('None', (32.2, 180)), ('flat', (0, 180)),
('south_at_latitude_tilt', (32.2, 180))
Expand Down

0 comments on commit a7edb8b

Please sign in to comment.