10000 Change setter for losses_model to allow it to set multiple loss funct… by ncroft-b4 · Pull Request #1084 · pvlib/pvlib-python · GitHub
[go: up one dir, main page]

Skip to content

Change setter for losses_model to allow it to set multiple loss funct… #1084

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

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/sphinx/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ Pvsyst model
temperature.pvsyst_cell
pvsystem.calcparams_pvsyst
pvsystem.singlediode
pvsystem.dc_ohms_from_percent

PVWatts model
^^^^^^^^^^^^^
Expand Down Expand Up @@ -598,6 +599,7 @@ ModelChain properties that are aliases for your specific modeling functions.
modelchain.ModelChain.aoi_model
modelchain.ModelChain.spectral_model
modelchain.ModelChain.temperature_model
modelchain.ModelChain.dc_ohmic_model
modelchain.ModelChain.losses_model
modelchain.ModelChain.effective_irradiance_model

Expand Down Expand Up @@ -628,6 +630,8 @@ ModelChain model definitions.
modelchain.ModelChain.pvsyst_temp
modelchain.ModelChain.faiman_temp
modelchain.ModelChain.fuentes_temp
modelchain.ModelChain.dc_ohmic_model
modelchain.ModelChain.no_dc_ohmic_loss
modelchain.ModelChain.pvwatts_losses
modelchain.ModelChain.no_extra_losses

Expand Down
45 changes: 45 additions & 0 deletions pvlib/modelchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,11 @@ class ModelChain:
The ModelChain instance will be passed as the first argument to a
user-defined function.

dc_ohmic_model: None, str or function, default None
Valid strings are 'dc_ohms_from_percent', 'no_loss'. The ModelChain
instance will be passed as the first argument to a user-defined
function.

losses_model: str or function, default 'no_loss'
Valid strings are 'pvwatts', 'no_loss'. The ModelChain instance
will be passed as the first argument to a user-defined function.
Expand All @@ -343,6 +348,7 @@ def __init__(self, system, location,
airmass_model='kastenyoung1989',
dc_model=None, ac_model=None, aoi_model=None,
spectral_model=None, temperature_model=None,
dc_ohmic_model=None,
losses_model='no_loss', name=None, **kwargs):

self.name = name
Expand All @@ -361,7 +367,10 @@ def __init__(self, system, location,
self.spectral_model = spectral_model
self.temperature_model = temperature_model

# losses
self.dc_ohmic_model = dc_ohmic_model
self.losses_model = losses_model

self.orientation_strategy = orientation_strategy

self.weather = None
Expand Down Expand Up @@ -924,6 +933,41 @@ def fuentes_temp(self):
self.weather['wind_speed'])
return self

@property
def dc_ohmic_model(self):
return self._dc_ohmic_model

@dc_ohmic_model.setter
def dc_ohmic_model(self, model):
if model is None:
self._dc_ohmic_model = self.no_dc_ohmic_loss
elif isinstance(model, str):
model = model.lower()
if model == 'dc_ohms_from_percent':
self._dc_ohmic_model = self.dc_ohms_from_percent
elif model == 'no_loss':
self._dc_ohmic_model = self.no_dc_ohmic_loss
else:
raise ValueError(model + ' is not a valid losses model')
else:
self._dc_ohmic_model = partial(model, self)

def dc_ohms_from_percent(self):
"""
Calculate time series of ohmic losses and apply those to the mpp power
output of the `dc_model` based on the pvsyst equivalent resistance
method. Uses a `dc_ohmic_percent` parameter in the `losses_parameters`
of the PVsystem.
"""
Rw = self.system.dc_ohms_from_percent()
ohmic_loss_fraction = Rw * self.dc['i_mp'] / self.dc['v_mp']
self.dc_ohmic_losses = ohmic_loss_fraction * self.dc['p_mp']
self.dc['p_mp'] = self.dc['p_mp'] - self.dc_ohmic_losses
return self

def no_dc_ohmic_loss(self):
return self

@property
def losses_model(self):
return self._losses_model
Expand Down Expand Up @@ -1374,6 +1418,7 @@ def _run_from_effective_irrad(self, data=None):
"""
self._prepare_temperature(data)
self.dc_model()
self.dc_ohmic_model()
self.losses_model()
self.ac_model()

Expand Down
64 changes: 64 additions & 0 deletions pvlib/pvsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,27 @@ def pvwatts_ac(self, pdc):
return inverter.pvwatts(pdc, self.inverter_parameters['pdc0'],
**kwargs)

def dc_ohms_from_percent(self):
"""
Calculates the equivalent resistance of the wires using
:py:func:`pvlib.pvsystem.dc_ohms_from_percent`,
`self.losses_parameters["dc_ohmic_percent"]`,
`self.module_parameters["V_mp_ref"]`,
`self.module_parameters["I_mp_ref"]`,
`self.modules_per_string`, and `self.strings_per_inverter`.

See :py:func:`pvlib.pvsystem.dc_ohms_from_percent` for details.
"""
kwargs = _build_kwargs(['dc_ohmic_percent'], self.losses_parameters)

kwargs.update(_build_kwargs(['V_mp_ref', 'I_mp_ref'],
self.module_parameters))

kwargs.update({'modules_per_string': self.modules_per_string,
'strings_per_inverter': self.strings_per_inverter})

return dc_ohms_from_percent(**kwargs)

@deprecated('0.8', alternative='PVSystem, Location, and ModelChain',
name='PVSystem.localize', removal='0.9')
def localize(self, location=None, latitude=None, longitude=None,
Expand Down Expand Up @@ -2334,6 +2355,49 @@ def pvwatts_losses(soiling=2, shading=3, snow=0, mismatch=2, wiring=2,
return losses


def dc_ohms_from_percent(V_mp_ref, I_mp_ref, dc_ohmic_percent,
modules_per_string=1,
strings_per_inverter=1):
"""
Calculates the equivalent resistance of the wires from a percent
ohmic loss at STC.

Equivalent resistance is calculated with the function:

.. math::

Rw = (L_{stc} / 100) * (Varray / Iarray)

:math:`L_{stc}` is the input dc loss as a percent, e.g. 1.5% loss is
input as 1.5

Parameters
----------
V_mp_ref: numeric
I_mp_ref: numeric
dc_ohmic_percent: numeric, default 0
modules_per_string: numeric, default 1
strings_per_inverter: numeric, default 1

Returns
----------
Rw: numeric
Equivalent resistance in ohms

References
----------
-- [1] PVsyst 7 Help. "Array ohmic wiring loss".
https://www.pvsyst.com/help/ohmic_loss.htm
"""
vmp = modules_per_string * V_mp_ref

imp = strings_per_inverter * I_mp_ref

Rw = (dc_ohmic_percent / 100) * (vmp / imp)

return Rw


def combine_loss_factors(index, *losses, fill_method='ffill'):
r"""
Combines Series loss fractions while setting a common index.
Expand Down
0