diff --git a/docs/sphinx/source/whatsnew/v0.11.0.rst b/docs/sphinx/source/whatsnew/v0.11.0.rst index e35cdcdc32..9a9263881f 100644 --- a/docs/sphinx/source/whatsnew/v0.11.0.rst +++ b/docs/sphinx/source/whatsnew/v0.11.0.rst @@ -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 diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 385760c967..35bf77f1d5 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -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): @@ -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. @@ -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'``. @@ -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 -------- @@ -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 @@ -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 @@ -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 diff --git a/pvlib/tests/test_pvsystem.py b/pvlib/tests/test_pvsystem.py index 256d962fb4..c98c201af4 100644 --- a/pvlib/tests/test_pvsystem.py +++ b/pvlib/tests/test_pvsystem.py @@ -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 @@ -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( @@ -1603,9 +1596,7 @@ 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])), @@ -1613,41 +1604,22 @@ def test_singlediode_series_ivcurve(cec_module_params): ('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]]), diff --git a/pvlib/tests/test_singlediode.py b/pvlib/tests/test_singlediode.py index 3cf98dd2d5..0271e53e90 100644 --- a/pvlib/tests/test_singlediode.py +++ b/pvlib/tests/test_singlediode.py @@ -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 @@ -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): """