Skip to content

Commit cfd9fcc

Browse files
cedricleroycwhansekandersolar
authored
Prevent v_oc to be negative in _lambertw (#1782)
* Prevent `v_oc` to be negative in `_lambertw` * Update docs/sphinx/source/whatsnew/v0.10.0.rst Co-authored-by: Cliff Hansen <cwhanse@sandia.gov> * Target small negative elements only * Update docs/sphinx/source/whatsnew/v0.10.0.rst --------- Co-authored-by: Cliff Hansen <cwhanse@sandia.gov> Co-authored-by: Kevin Anderson <kevin.anderso@gmail.com>
1 parent 0bc5a53 commit cfd9fcc

File tree

3 files changed

+25
-0
lines changed

3 files changed

+25
-0
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ Enhancements
4949
Bug fixes
5050
~~~~~~~~~
5151

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

5356
Testing
5457
~~~~~~~
@@ -71,3 +74,5 @@ Contributors
7174
* Adam R. Jensen (:ghuser:`AdamRJensen`)
7275
* Echedey Luis (:ghuser:`echedey-ls`)
7376
* Cliff Hansen (:ghuser:`cwhanse`)
77+
* Cédric Leroy (:ghuser:`cedricleroy`)
78+
* Jean-Baptiste Pasquier (:ghuser:`pasquierjb`)

pvlib/singlediode.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,13 @@ def _lambertw(photocurrent, saturation_current, resistance_series,
794794
# Compute open circuit voltage
795795
v_oc = _lambertw_v_from_i(0., **params)
796796

797+
# Set small elements <0 in v_oc to 0
798+
if isinstance(v_oc, np.ndarray):
799+
v_oc[(v_oc < 0) & (v_oc > -1e-12)] = 0.
800+
elif isinstance(v_oc, (float, int)):
801+
if v_oc < 0 and v_oc > -1e-12:
802+
v_oc = 0.
803+
797804
# Find the voltage, v_mp, where the power is maximized.
798805
# Start the golden section search at v_oc * 1.14
799806
p_mp, v_mp = _golden_sect_DataFrame(params, 0., v_oc * 1.14, _pwr_optfcn)

pvlib/tests/test_singlediode.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,19 @@ def test_singlediode_precision(method, precise_iv_curves):
168168
assert np.allclose(pc['i_xx'], outs['i_xx'], atol=1e-6, rtol=0)
169169

170170

171+
def test_singlediode_lambert_negative_voc():
172+
173+
# Those values result in a negative v_oc out of `_lambertw_v_from_i`
174+
x = np.array([0., 1.480501e-11, 0.178, 8000., 1.797559])
175+
outs = pvsystem.singlediode(*x, method='lambertw')
176+
assert outs['v_oc'] == 0
177+
178+
# Testing for an array
179+
x = np.array([x, x]).T
180+
outs = pvsystem.singlediode(*x, method='lambertw')
181+
assert np.array_equal(outs['v_oc'], [0, 0])
182+
183+
171184
@pytest.mark.parametrize('method', ['lambertw'])
172185
def test_ivcurve_pnts_precision(method, precise_iv_curves):
173186
"""

0 commit comments

Comments
 (0)