Skip to content

Commit

Permalink
Merge branch 'main' into refactor-docstring-params
Browse files Browse the repository at this point in the history
  • Loading branch information
echedey-ls authored Jun 28, 2023
2 parents 6500add + cfd6e78 commit cdd022c
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 5 deletions.
5 changes: 5 additions & 0 deletions docs/sphinx/source/whatsnew/v0.10.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ Enhancements
Bug fixes
~~~~~~~~~

* Prevent small negative values of `v_oc` in :py:func:`pvlib.singlediode._lambertw`
which result from accumulated roundoff error. (:issue:`1780`, :issue:`1673`, :pull:`1782`)


Testing
~~~~~~~
Expand All @@ -71,3 +74,5 @@ Contributors
* Adam R. Jensen (:ghuser:`AdamRJensen`)
* Echedey Luis (:ghuser:`echedey-ls`)
* Cliff Hansen (:ghuser:`cwhanse`)
* Cédric Leroy (:ghuser:`cedricleroy`)
* Jean-Baptiste Pasquier (:ghuser:`pasquierjb`)
7 changes: 6 additions & 1 deletion pvlib/inverter.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ def pvwatts(pdc, pdc0, eta_inv_nom=0.96, eta_inv_ref=0.9637):
NREL's PVWatts inverter model.
The PVWatts inverter model [1]_ calculates inverter efficiency :math:`\eta`
as a function of input DC power
as a function of input DC power :math:`P_{dc}`
.. math::
Expand Down Expand Up @@ -369,6 +369,10 @@ def pvwatts(pdc, pdc0, eta_inv_nom=0.96, eta_inv_ref=0.9637):
Notes
-----
When sourcing ``pdc`` from pvlib functions
(e.g. :py:func:`pvlib.pvsystem.pvwatts_dc`) their DC power output is in W,
and ``pdc0`` should have the same unit (W).
Note that ``pdc0`` is also used as a symbol in
:py:func:`pvlib.pvsystem.pvwatts_dc`. ``pdc0`` in this function refers to
the DC power input limit of the inverter. ``pdc0`` in
Expand All @@ -393,6 +397,7 @@ def pvwatts(pdc, pdc0, eta_inv_nom=0.96, eta_inv_ref=0.9637):
pdc_neq_0 = ~np.equal(pdc, 0)

# eta < 0 if zeta < 0.006. power_ac is forced to be >= 0 below. GH 541
# In some published versions of [1] the parentheses are missing
eta = eta_inv_nom / eta_inv_ref * (
-0.0162 * zeta - np.divide(0.0059, zeta, out=eta, where=pdc_neq_0)
+ 0.9858) # noQA: W503
Expand Down
8 changes: 4 additions & 4 deletions pvlib/pvsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -2809,9 +2809,9 @@ def pvwatts_dc(g_poa_effective, temp_cell, pdc0, gamma_pdc, temp_ref=25.):
P_{dc} = \frac{G_{poa eff}}{1000} P_{dc0} ( 1 + \gamma_{pdc} (T_{cell} - T_{ref}))
Note that the pdc0 is also used as a symbol in
:py:func:`pvlib.inverter.pvwatts`. pdc0 in this function refers to the DC
power of the modules at reference conditions. pdc0 in
Note that ``pdc0`` is also used as a symbol in
:py:func:`pvlib.inverter.pvwatts`. ``pdc0`` in this function refers to the DC
power of the modules at reference conditions. ``pdc0`` in
:py:func:`pvlib.inverter.pvwatts` refers to the DC power input limit of
the inverter.
Expand All @@ -2836,7 +2836,7 @@ def pvwatts_dc(g_poa_effective, temp_cell, pdc0, gamma_pdc, temp_ref=25.):
Returns
-------
pdc : numeric
DC power.
DC power. [W]
References
----------
Expand Down
7 changes: 7 additions & 0 deletions pvlib/singlediode.py
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,13 @@ def _lambertw(photocurrent, saturation_current, resistance_series,
# Compute open circuit voltage
v_oc = _lambertw_v_from_i(0., **params)

# Set small elements <0 in v_oc to 0
if isinstance(v_oc, np.ndarray):
v_oc[(v_oc < 0) & (v_oc > -1e-12)] = 0.
elif isinstance(v_oc, (float, int)):
if v_oc < 0 and v_oc > -1e-12:
v_oc = 0.

# Find the voltage, v_mp, where the power is maximized.
# Start the golden section search at v_oc * 1.14
p_mp, v_mp = _golden_sect_DataFrame(params, 0., v_oc * 1.14, _pwr_optfcn)
Expand Down
13 changes: 13 additions & 0 deletions pvlib/tests/test_singlediode.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,19 @@ def test_singlediode_precision(method, precise_iv_curves):
assert np.allclose(pc['i_xx'], outs['i_xx'], atol=1e-6, rtol=0)


def test_singlediode_lambert_negative_voc():

# Those values result in a negative v_oc out of `_lambertw_v_from_i`
x = np.array([0., 1.480501e-11, 0.178, 8000., 1.797559])
outs = pvsystem.singlediode(*x, method='lambertw')
assert outs['v_oc'] == 0

# Testing for an array
x = np.array([x, x]).T
outs = pvsystem.singlediode(*x, method='lambertw')
assert np.array_equal(outs['v_oc'], [0, 0])


@pytest.mark.parametrize('method', ['lambertw'])
def test_ivcurve_pnts_precision(method, precise_iv_curves):
"""
Expand Down

0 comments on commit cdd022c

Please sign in to comment.