8000 Add scale_voltage_current_power to ModelChain.pvwatts_dc by cwhanse · Pull Request #1138 · pvlib/pvlib-python · GitHub
[go: up one dir, main page]

Skip to content

Add scale_voltage_current_power to ModelChain.pvwatts_dc #1138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jan 21, 2021
Next Next commit
add scale_voltage_current_power to ModelChain.pvwatts_dc, docstring e…
…dits, whatsnew
  • Loading branch information
cwhanse committed Jan 20, 2021
commit d210be90b48b886c44277d4b3abdfb508fae1360
4 changes: 4 additions & 0 deletions docs/sphinx/source/whatsnew/v0.9.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ Enhancements
automatically switch to using ``'effective_irradiance'`` (if available) for
cell temperature models, when ``'poa_global'`` is not provided in input
weather or calculated from input weather data.
* :py:meth:`~pvlib.modelchain.ModelChain.pvwatts_dc` now scales the DC power
by `pvsystem.PVSystem.modules_per_strings` and
`pvsystem.PVSystem.strings_per_inverter`. Note that both attributes still
default to 1. (:pull:`XXXX`)

Bug fixes
~~~~~~~~~
Expand Down
19 changes: 19 additions & 0 deletions pvlib/modelchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -730,8 +730,27 @@ def pvsyst(self):
return self._singlediode(self.system.calcparams_pvsyst)

def pvwatts_dc(self):
"""Calculate DC power using the PVWatts model.

Results are stored in ModelChain.results.dc. DC power is computed
from PVSystem.module_parameters['pdc0'] and then scaled by
PVSystem.modules_per_string and PVSystem.strings_per_inverter.

Returns
-------
self

See also
--------
pvlib.pvsystem.PVSystem.pvwatts_dc
pvlib.pvsystem.PVSystem.scale_voltage_current_power
"""
self.results.dc = self.system.pvwatts_dc(
self.results.effective_irradiance, self.results.cell_temperature)
self.results.dc = self.system.scale_voltage_current_power(
self.results.dc,
unwrap=False
)
return self

@property
Expand Down
14 changes: 7 additions & 7 deletions pvlib/pvsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -2675,20 +2675,20 @@ def pvwatts_dc(g_poa_effective, temp_cell, pdc0, gamma_pdc, temp_ref=25.):
Parameters
----------
g_poa_effective: numeric
Irradiance transmitted to the PV cells in units of W/m**2. To be
Irradiance transmitted to the PV cells. To be
fully consistent with PVWatts, the user must have already
applied angle of incidence losses, but not soiling, spectral,
etc.
etc. [W/m^2]
temp_cell: numeric
Cell temperature in degrees C.
Cell temperature [C].
pdc0: numeric
Power of the modules at 1000 W/m2 and cell reference temperature.
Power of the modules at 1000 W/m^2 and cell reference temperature. [W]
gamma_pdc: numeric
The temperature coefficient in units of 1/C. Typically -0.002 to
-0.005 per degree C.
The temperature coefficient of power. Typically -0.002 to
-0.005 per degree C. [1/C]
temp_ref: numeric, default 25.0
Cell reference temperature. PVWatts defines it to be 25 C and
is included here for flexibility.
is included here for flexibility. [C]

Returns
-------
Expand Down
17 changes: 17 additions & 0 deletions pvlib/tests/test_modelchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -1180,6 +1180,23 @@ def test_dc_model_user_func(pvwatts_dc_pvwatts_ac_system, location, weather,
assert not mc.results.ac.empty


def test_pvwatts_dc_multiple_strings(pvwatts_dc_pvwatts_ac_system, location,
weather, mocker):
system = pvwatts_dc_pvwatts_ac_system.copy()
system.modules_per_string = 2
m = mocker.spy(system, 'scale_voltage_current_power')
mc1 = ModelChain(pvwatts_dc_pvwatts_ac_system, location,
aoi_model='no_loss', spectral_model='no_loss')
mc1.run_model(weather)
mc2 = ModelChain(system, location,
aoi_model='no_loss', spectral_model='no_loss')
mc2.run_model(weather)
assert m.call_count == 1
assert isinstance(mc2.results.ac, (pd.Series, pd.DataFrame))
assert not mc2.results.ac.empty
assert np.isclose(mc2.results.dc / mc1.results.dc, 2.0)


def acdc(mc):
mc.results.ac = mc.results.dc

Expand Down
0