Skip to content

Commit

Permalink
pvlib.pvsystem.singlediode: remove deprecated ivcurve_pnts parame…
Browse files Browse the repository at this point in the history
…ter (#2101)

* remove deprecated singlediode ivcurve_pnts parameter

* whatsnew
  • Loading branch information
kandersolar committed Jun 21, 2024
1 parent c6547b5 commit 4b1ba1d
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 103 deletions.
3 changes: 3 additions & 0 deletions docs/sphinx/source/whatsnew/v0.11.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ Breaking changes
* :py:func:`~pvlib.iotools.get_psm3`, :py:func:`~pvlib.iotools.read_psm3`, and
:py:func:`~pvlib.iotools.parse_psm3` all now have ``map_variables=True`` by
default. (:issue:`1425`, :pull:`2094`)
* The deprecated ``ivcurve_pnts`` parameter of :py:func:`pvlib.pvsystem.singlediode`
is removed. Use :py:func:`pvlib.pvsystem.v_from_i` and
:py:func:`pvlib.pvsystem.i_from_v` instead. (:pull:`2101`)


Deprecations
Expand Down
54 changes: 6 additions & 48 deletions pvlib/pvsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -722,15 +722,13 @@ def _spectral_correction(array, pw):
)

def singlediode(self, photocurrent, saturation_current,
resistance_series, resistance_shunt, nNsVth,
ivcurve_pnts=None):
resistance_series, resistance_shunt, nNsVth):
"""Wrapper around the :py:func:`pvlib.pvsystem.singlediode` function.
See :py:func:`pvsystem.singlediode` for details
"""
return singlediode(photocurrent, saturation_current,
resistance_series, resistance_shunt, nNsVth,
ivcurve_pnts=ivcurve_pnts)
resistance_series, resistance_shunt, nNsVth)

def i_from_v(self, voltage, photocurrent, saturation_current,
resistance_series, resistance_shunt, nNsVth):
Expand Down Expand Up @@ -2352,8 +2350,7 @@ def sapm_effective_irradiance(poa_direct, poa_diffuse, airmass_absolute, aoi,


def singlediode(photocurrent, saturation_current, resistance_series,
resistance_shunt, nNsVth, ivcurve_pnts=None,
method='lambertw'):
resistance_shunt, nNsVth, method='lambertw'):
r"""
Solve the single diode equation to obtain a photovoltaic IV curve.
Expand Down Expand Up @@ -2405,14 +2402,6 @@ def singlediode(photocurrent, saturation_current, resistance_series,
junction in Kelvin, and :math:`q` is the charge of an electron
(coulombs). ``0 < nNsVth``. [V]
ivcurve_pnts : int, optional
Number of points in the desired IV curve. If not specified or 0, no
points on the IV curves will be produced.
.. deprecated:: 0.10.0
Use :py:func:`pvlib.pvsystem.v_from_i` and
:py:func:`pvlib.pvsystem.i_from_v` instead.
method : str, default 'lambertw'
Determines the method used to calculate points on the IV curve. The
options are ``'lambertw'``, ``'newton'``, or ``'brentq'``.
Expand All @@ -2430,12 +2419,7 @@ def singlediode(photocurrent, saturation_current, resistance_series,
* i_x - current, in amperes, at ``v = 0.5*v_oc``.
* i_xx - current, in amperes, at ``v = 0.5*(v_oc+v_mp)``.
A dict is returned when the input parameters are scalars or
``ivcurve_pnts > 0``. If ``ivcurve_pnts > 0``, the output dictionary
will also include the keys:
* i - IV curve current in amperes.
* v - IV curve voltage in volts.
A dict is returned when the input parameters are scalars.
See also
--------
Expand All @@ -2459,13 +2443,6 @@ def singlediode(photocurrent, saturation_current, resistance_series,
that guarantees convergence by bounding the voltage between zero and
open-circuit.
If the method is either ``'newton'`` or ``'brentq'`` and ``ivcurve_pnts``
are indicated, then :func:`pvlib.singlediode.bishop88` [4]_ is used to
calculate the points on the IV curve points at diode voltages from zero to
open-circuit voltage with a log spacing that gets closer as voltage
increases. If the method is ``'lambertw'`` then the calculated points on
the IV curve are linearly spaced.
References
----------
.. [1] S.R. Wenham, M.A. Green, M.E. Watt, "Applied Photovoltaics" ISBN
Expand All @@ -2482,21 +2459,13 @@ def singlediode(photocurrent, saturation_current, resistance_series,
photovoltaic cell interconnection circuits" JW Bishop, Solar Cell (1988)
https://doi.org/10.1016/0379-6787(88)90059-2
"""
if ivcurve_pnts:
warn_deprecated('0.10.0', name='pvlib.pvsystem.singlediode',
alternative=('pvlib.pvsystem.v_from_i and '
'pvlib.pvsystem.i_from_v'),
obj_type='parameter ivcurve_pnts',
removal='0.11.0')
args = (photocurrent, saturation_current, resistance_series,
resistance_shunt, nNsVth) # collect args
# Calculate points on the IV curve using the LambertW solution to the
# single diode equation
if method.lower() == 'lambertw':
out = _singlediode._lambertw(*args, ivcurve_pnts)
out = _singlediode._lambertw(*args)
points = out[:7]
if ivcurve_pnts:
ivcurve_i, ivcurve_v = out[7:]
else:
# Calculate points on the IV curve using either 'newton' or 'brentq'
# methods. Voltages are determined by first solving the single diode
Expand All @@ -2518,21 +2487,10 @@ def singlediode(photocurrent, saturation_current, resistance_series,
)
points = i_sc, v_oc, i_mp, v_mp, p_mp, i_x, i_xx

# calculate the IV curve if requested using bishop88
if ivcurve_pnts:
vd = v_oc * (
(11.0 - np.logspace(np.log10(11.0), 0.0, ivcurve_pnts)) / 10.0
)
ivcurve_i, ivcurve_v, _ = _singlediode.bishop88(vd, *args)

columns = ('i_sc', 'v_oc', 'i_mp', 'v_mp', 'p_mp', 'i_x', 'i_xx')

if all(map(np.isscalar, args)) or ivcurve_pnts:
if all(map(np.isscalar, args)):
out = {c: p for c, p in zip(columns, points)}

if ivcurve_pnts:
out.update(i=ivcurve_i, v=ivcurve_v)

return out

points = np.atleast_1d(*points) # convert scalars to 1d-arrays
Expand Down
44 changes: 8 additions & 36 deletions pvlib/tests/test_pvsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
import pandas as pd

import pytest
from .conftest import (
assert_series_equal, assert_frame_equal, fail_on_pvlib_version)
from .conftest import assert_series_equal, assert_frame_equal
from numpy.testing import assert_allclose
import unittest.mock as mock

Expand Down Expand Up @@ -1568,27 +1567,21 @@ def test_singlediode_floats():
assert_allclose(v, expected[k], atol=1e-6)


def test_singlediode_floats_ivcurve():
with pytest.warns(pvlibDeprecationWarning, match='ivcurve_pnts'):
out = pvsystem.singlediode(7., 6e-7, .1, 20., .5, ivcurve_pnts=3,
method='lambertw')
def test_singlediode_floats_expected():
out = pvsystem.singlediode(7., 6e-7, .1, 20., .5, method='lambertw')
expected = {'i_xx': 4.264060478,
'i_mp': 6.136267360,
'v_oc': 8.106300147,
'p_mp': 38.19421055,
'i_x': 6.7558815684,
'i_sc': 6.965172322,
'v_mp': 6.224339375,
'i': np.array([
6.965172322, 6.755881568, 2.664535259e-14]),
'v': np.array([
0., 4.053150073, 8.106300147])}
'v_mp': 6.224339375}
assert isinstance(out, dict)
for k, v in out.items():
assert_allclose(v, expected[k], atol=1e-6)


def test_singlediode_series_ivcurve(cec_module_params):
def test_singlediode_series_expected(cec_module_params):
times = pd.date_range(start='2015-06-01', periods=3, freq='6h')
effective_irradiance = pd.Series([0.0, 400.0, 800.0], index=times)
IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto(
Expand All @@ -1603,51 +1596,30 @@ def test_singlediode_series_ivcurve(cec_module_params):
EgRef=1.121,
dEgdT=-0.0002677)

with pytest.warns(pvlibDeprecationWarning, match='ivcurve_pnts'):
out = pvsystem.singlediode(IL, I0, Rs, Rsh, nNsVth, ivcurve_pnts=3,
method='lambertw')
out = pvsystem.singlediode(IL, I0, Rs, Rsh, nNsVth, method='lambertw')

expected = OrderedDict([('i_sc', array([0., 3.01079860, 6.00726296])),
('v_oc', array([0., 9.96959733, 10.29603253])),
('i_mp', array([0., 2.656285960, 5.290525645])),
('v_mp', array([0., 8.321092255, 8.409413795])),
('p_mp', array([0., 22.10320053, 44.49021934])),
('i_x', array([0., 2.884132006, 5.746202281])),
('i_xx', array([0., 2.052691562, 3.909673879])),
('v', array([[0., 0., 0.],
[0., 4.984798663, 9.969597327],
[0., 5.148016266, 10.29603253]])),
('i', array([[0., 0., 0.],
[3.0107985972, 2.8841320056, 0.],
[6.0072629615, 5.7462022810, 0.]]))])
('i_xx', array([0., 2.052691562, 3.909673879]))])

for k, v in out.items():
assert_allclose(v, expected[k], atol=1e-2)

with pytest.warns(pvlibDeprecationWarning, match='ivcurve_pnts'):
out = pvsystem.singlediode(IL, I0, Rs, Rsh, nNsVth, ivcurve_pnts=3)
out = pvsystem.singlediode(IL, I0, Rs, Rsh, nNsVth)

expected['i_mp'] = pvsystem.i_from_v(out['v_mp'], IL, I0, Rs, Rsh, nNsVth,
method='lambertw')
expected['v_mp'] = pvsystem.v_from_i(out['i_mp'], IL, I0, Rs, Rsh, nNsVth,
method='lambertw')
expected['i'] = pvsystem.i_from_v(out['v'].T, IL, I0, Rs, Rsh, nNsVth,
method='lambertw').T
expected['v'] = pvsystem.v_from_i(out['i'].T, IL, I0, Rs, Rsh, nNsVth,
method='lambertw').T

for k, v in out.items():
assert_allclose(v, expected[k], atol=1e-6)


@fail_on_pvlib_version('0.11')
@pytest.mark.parametrize('method', ['lambertw', 'brentq', 'newton'])
def test_singlediode_ivcurvepnts_deprecation_warning(method):
with pytest.warns(pvlibDeprecationWarning, match='ivcurve_pnts'):
pvsystem.singlediode(7., 6e-7, .1, 20., .5, ivcurve_pnts=3,
method=method)


def test_scale_voltage_current_power():
data = pd.DataFrame(
np.array([[2, 1.5, 10, 8, 12, 0.5, 1.5]]),
Expand Down
19 changes: 0 additions & 19 deletions pvlib/tests/test_singlediode.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from pvlib import pvsystem
from pvlib.singlediode import (bishop88_mpp, estimate_voc, VOLTAGE_BUILTIN,
bishop88, bishop88_i_from_v, bishop88_v_from_i)
from pvlib._deprecation import pvlibDeprecationWarning
import pytest
from numpy.testing import assert_array_equal
from .conftest import DATA_DIR
Expand Down Expand Up @@ -188,24 +187,6 @@ def test_singlediode_lambert_negative_voc(mocker):
assert_array_equal(outs["v_oc"], [0, 0])


@pytest.mark.parametrize('method', ['lambertw'])
def test_ivcurve_pnts_precision(method, precise_iv_curves):
"""
Tests the accuracy of the IV curve points calcuated by singlediode. Only
methods of singlediode that linearly spaced points are tested.
"""
x, pc = precise_iv_curves
pc_i, pc_v = np.stack(pc['Currents']), np.stack(pc['Voltages'])
ivcurve_pnts = len(pc['Currents'][0])

with pytest.warns(pvlibDeprecationWarning, match='ivcurve_pnts'):
outs = pvsystem.singlediode(method=method, ivcurve_pnts=ivcurve_pnts,
**x)

assert np.allclose(pc_i, outs['i'], atol=1e-10, rtol=0)
assert np.allclose(pc_v, outs['v'], atol=1e-10, rtol=0)


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

0 comments on commit 4b1ba1d

Please sign in to comment.