8000 start to removing ivcurve_pnts from pvsystem.singlediode · reepoi/pvlib-python@5f28153 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5f28153

Browse files
committed
start to removing ivcurve_pnts from pvsystem.singlediode
1 parent 7a2ec9b commit 5f28153

File tree

3 files changed

+26
-119
lines changed

3 files changed

+26
-119
lines changed

pvlib/pvsystem.py

Lines changed: 18 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from dataclasses import dataclass
1616
from abc import ABC, abstractmethod
1717
from typing import Optional
18+
import pvlib.tools as tools
1819

1920
from pvlib._deprecation import deprecated
2021

@@ -934,15 +935,13 @@ def _spectral_correction(array, pw):
934935
)
935936

936937
def singlediode(self, photocurrent, saturation_current,
937-
resistance_series, resistance_shunt, nNsVth,
938-
ivcurve_pnts=None):
938+
resistance_series, resistance_shunt, nNsVth):
939939
"""Wrapper around the :py:func:`pvlib.pvsystem.singlediode` function.
940940
941941
See :py:func:`pvsystem.singlediode` for details
942942
"""
943943
return singlediode(photocurrent, saturation_current,
944-
resistance_series, resistance_shunt, nNsVth,
945-
ivcurve_pnts=ivcurve_pnts)
944+
resistance_series, resistance_shunt, nNsVth)
946945

947946
def i_from_v(self, resistance_shunt, resistance_series, nNsVth, voltage,
948947
saturation_current, photocurrent):
@@ -2708,8 +2707,7 @@ def sapm_effective_irradiance(poa_direct, poa_diffuse, airmass_absolute, aoi,
27082707

27092708

27102709
def singlediode(photocurrent, saturation_current, resistance_series,
2711-
resistance_shunt, nNsVth, ivcurve_pnts=None,
2712-
method='lambertw'):
2710+
resistance_shunt, nNsVth, method='lambertw'):
27132711
r"""
27142712
Solve the single-diode equation to obtain a photovoltaic IV curve.
27152713
@@ -2762,19 +2760,13 @@ def singlediode(photocurrent, saturation_current, resistance_series,
27622760
junction in Kelvin, and :math:`q` is the charge of an electron
27632761
(coulombs). ``0 < nNsVth``. [V]
27642762
2765-
ivcurve_pnts : None or int, default None
2766-
Number of points in the desired IV curve. If None or 0, no points on
2767-
the IV curves will be produced.
2768-
27692763
method : str, default 'lambertw'
27702764
Determines the method used to calculate points on the IV curve. The
27712765
options are ``'lambertw'``, ``'newton'``, or ``'brentq'``.
27722766
27732767
Returns
27742768
-------
2775-
OrderedDict or DataFrame
2776-
2777-
The returned dict-like object always contains the keys/columns:
2769+
DataFrame with the columns:
27782770
27792771
* i_sc - short circuit current in amperes.
27802772
* v_oc - open circuit voltage in volts.
@@ -2784,18 +2776,6 @@ def singlediode(photocurrent, saturation_current, resistance_series,
27842776
* i_x - current, in amperes, at ``v = 0.5*v_oc``.
27852777
* i_xx - current, in amperes, at ``V = 0.5*(v_oc+v_mp)``.
27862778
2787-
If ivcurve_pnts is greater than 0, the output dictionary will also
2788-
include the keys:
2789-
2790-
* i - IV curve current in amperes.
2791-
* v - IV curve voltage in volts.
2792-
2793-
The output will be an OrderedDict if photocurrent is a scalar,
2794-
array, or ivcurve_pnts is not None.
2795-
2796-
The output will be a DataFrame if photocurrent is a Series and
2797-
ivcurve_pnts is None.
2798-
27992779
See also
28002780
--------
28012781
calcparams_desoto
@@ -2818,13 +2798,6 @@ def singlediode(photocurrent, saturation_current, resistance_series,
28182798
that guarantees convergence by bounding the voltage between zero and
28192799
open-circuit.
28202800
2821-
If the method is either ``'newton'`` or ``'brentq'`` and ``ivcurve_pnts``
2822-
are indicated, then :func:`pvlib.singlediode.bishop88` [4]_ is used to
2823-
calculate the points on the IV curve points at diode voltages from zero to
2824-
open-circuit voltage with a log spacing that gets closer as voltage
2825-
increases. If the method is ``'lambertw'`` then the calculated points on
2826-
the IV curve are linearly spaced.
2827-
28282801
References
28292802
----------
28302803
.. [1] S.R. Wenham, M.A. Green, M.E. Watt, "Applied Photovoltaics" ISBN
@@ -2846,11 +2819,9 @@ def singlediode(photocurrent, saturation_current, resistance_series,
28462819
if method.lower() == 'lambertw':
28472820
out = _singlediode._lambertw(
28482821
photocurrent, saturation_current, resistance_series,
2849-
resistance_shunt, nNsVth, ivcurve_pnts
2822+
resistance_shunt, nNsVth
28502823
)
2851-
i_sc, v_oc, i_mp, v_mp, p_mp, i_x, i_xx = out[:7]
2852-
if ivcurve_pnts:
2853-
ivcurve_i, ivcurve_v = out[7:]
2824+
points = out[:7]
28542825
else:
28552826
# Calculate points on the IV curve using either 'newton' or 'brentq'
28562827
# methods. Voltages are determined by first solving the single diode
@@ -2872,32 +2843,20 @@ def singlediode(photocurrent, saturation_current, resistance_series,
28722843
i_xx = _singlediode.bishop88_i_from_v(
28732844
(v_oc + v_mp) / 2.0, *args, method=method.lower()
28742845
)
2846+
points = i_sc, v_oc, i_mp, v_mp, p_mp, i_x, i_xx
28752847

2876-
# calculate the IV curve if requested using bishop88
2877-
if ivcurve_pnts:
2878-
vd = v_oc * (
2879-
(11.0 - np.logspace(np.log10(11.0), 0.0, ivcurve_pnts)) / 10.0
2880-
)
2881-
ivcurve_i, ivcurve_v, _ = _singlediode.bishop88(vd, *args)
2848+
points = np.atleast_1d(*points) # covert scalars to 1d arrays
2849+
points = np.vstack(points).T # create DataFrame rows
28822850

2883-
out = OrderedDict()
2884-
out['i_sc'] = i_sc
2885-
out['v_oc'] = v_oc
2886-
out['i_mp'] = i_mp
2887-
out['v_mp'] = v_mp
2888-
out['p_mp'] = p_mp
2889-
out['i_x'] = i_x
2890-
out['i_xx'] = i_xx
2891-
2892-
if ivcurve_pnts:
2893-
2894-
out['v'] = ivcurve_v
2895-
out['i'] = ivcurve_i
2896-
2897-
if isinstance(photocurrent, pd.Series) and not ivcurve_pnts:
2898-
out = pd.DataFrame(out, index=photocurrent.index)
2851+
index = None # keep pd.Series index, if available
2852+
if isinstance(photocurrent, pd.Series):
2853+
index = photocurrent.index
28992854

2900-
return out
2855+
return pd.DataFrame(
2856+
points,
2857+
columns=['i_sc', 'v_oc', 'i_mp', 'v_mp', 'p_mp', 'i_x', 'i_xx'],
2858+
index=index
2859+
)
29012860

29022861

29032862
def max_power_point(photocurrent, saturation_current, resistance_series,

pvlib/tests/test_pvsystem.py

Lines changed: 5 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,32 +1342,8 @@ def test_singlediode_floats():
13421342
'p_mp': 38.19421055,
13431343
'i_x': 6.7558815684,
13441344
'i_sc': 6.965172322,
1345-
'v_mp': 6.224339375,
1346-
'i': None,
1347-
'v': None}
1348-
assert isinstance(out, dict)
1349-
for k, v in out.items():
1350-
if k in ['i', 'v']:
1351-
assert v is None
1352-
else:
1353-
assert_allclose(v, expected[k], atol=1e-6)
1354-
1355-
1356-
def test_singlediode_floats_ivcurve():
1357-
out = pvsystem.singlediode(7., 6e-7, .1, 20., .5, ivcurve_pnts=3,
1358-
method='lambertw')
1359-
expected = {'i_xx': 4.264060478,
1360-
'i_mp': 6.136267360,
1361-
'v_oc': 8.106300147,
1362-
'p_mp': 38.19421055,
1363-
'i_x': 6.7558815684,
1364-
'i_sc': 6.965172322,
1365-
'v_mp': 6.224339375,
1366-
'i': np.array([
1367-
6.965172322, 6.755881568, 2.664535259e-14]),
1368-
'v': np.array([
1369-
0., 4.053150073, 8.106300147])}
1370-
assert isinstance(out, dict)
1345+
'v_mp': 6.224339375}
1346+
assert isinstance(out, pd.DataFrame)
13711347
for k, v in out.items():
13721348
assert_allclose(v, expected[k], atol=1e-6)
13731349

@@ -1387,37 +1363,25 @@ def test_singlediode_series_ivcurve(cec_module_params):
13871363
EgRef=1.121,
13881364
dEgdT=-0.0002677)
13891365

1390-
out = pvsystem.singlediode(IL, I0, Rs, Rsh, nNsVth, ivcurve_pnts=3,
1391-
method='lambertw')
1366+
out = pvsystem.singlediode(IL, I0, Rs, Rsh, nNsVth, method='lambertw')
13921367

13931368
expected = OrderedDict([('i_sc', array([0., 3.01079860, 6.00726296])),
13941369
('v_oc', array([0., 9.96959733, 10.29603253])),
13951370
('i_mp', array([0., 2.656285960, 5.290525645])),
13961371
('v_mp', array([0., 8.321092255, 8.409413795])),
13971372
('p_mp', array([0., 22.10320053, 44.49021934])),
13981373
('i_x', array([0., 2.884132006, 5.746202281])),
1399-
('i_xx', array([0., 2.052691562, 3.909673879])),
1400-
('v', array([[0., 0., 0.],
1401-
[0., 4.984798663, 9.969597327],
1402-
[0., 5.148016266, 10.29603253]])),
1403-
('i', array([[0., 0., 0.],
1404-
[3.0107985972, 2.8841320056, 0.],
1405-
[6.0072629615, 5.7462022810, 0.]]))])
1406-
1374+
('i_xx', array([0., 2.052691562, 3.909673879]))])
14071375

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

1411-
out = pvsystem.singlediode(IL, I0, Rs, Rsh, nNsVth, ivcurve_pnts=3)
1379+
out = pvsystem.singlediode(IL, I0, Rs, Rsh, nNsVth)
14121380

14131381
expected['i_mp'] = pvsystem.i_from_v(Rsh, Rs, nNsVth, out['v_mp'], I0, IL,
14141382
method='lambertw')
14151383
expected['v_mp'] = pvsystem.v_from_i(Rsh, Rs, nNsVth, out['i_mp'], I0, IL,
14161384
method='lambertw')
1417-
expected['i'] = pvsystem.i_from_v(Rsh, Rs, nNsVth, out['v'].T, I0, IL,
1418-
method='lambertw').T
1419-
expected['v'] = pvsystem.v_from_i(Rsh, Rs, nNsVth, out['i'].T, I0, IL,
1420-
method='lambertw').T
14211385

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

pvlib/tests/test_singlediode.py

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def test_method_spr_e20_327(method, cec_module_spr_e20_327):
2828
il, io, rs, rsh, nnsvt = x
2929
pvs = pvsystem.singlediode(*x, method='lambertw')
3030
out = pvsystem.singlediode(*x, method=method)
31-
isc, voc, imp, vmp, pmp, ix, ixx = out.values()
31+
isc, voc, imp, vmp, pmp, ix, ixx = out.to_numpy().T # unpack columns
3232
assert np.isclose(pvs['i_sc'], isc)
3333
assert np.isclose(pvs['v_oc'], voc)
3434
# the singlediode method doesn't actually get the MPP correct
@@ -54,10 +54,9 @@ def test_newton_fs_495(method, cec_module_fs_495):
5454
R_sh_ref=fs_495['R_sh_ref'], R_s=fs_495['R_s'],
5555
EgRef=1.475, dEgdT=-0.0003)
5656
il, io, rs, rsh, nnsvt = x
57-
x += (101, )
5857
pvs = pvsystem.singlediode(*x, method='lambertw')
5958
out = pvsystem.singlediode(*x, method=method)
60-
isc, voc, imp, vmp, pmp, ix, ixx, i, v = out.values()
59+
isc, voc, imp, vmp, pmp, ix, ixx = out.to_numpy().T # unpack columns
6160
assert np.isclose(pvs['i_sc'], isc)
6261
assert np.isclose(pvs['v_oc'], voc)
6362
# the singlediode method doesn't actually get the MPP correct
@@ -162,7 +161,7 @@ def precise_iv_curves(request):
162161
@pytest.mark.parametrize('method', ['lambertw', 'brentq', 'newton'])
163162
def test_singlediode_precision(method, precise_iv_curves):
164163
"""
165-
Tests the accuracy of singlediode. ivcurve_pnts is not tested.
164+
Tests the accuracy of singlediode.
166165
"""
167166
x, pc = precise_iv_curves
168167
outs = pvsystem.singlediode(method=method, **x)
@@ -180,21 +179,6 @@ def test_singlediode_precision(method, precise_iv_curves):
180179
assert np.allclose(pc['i_xx'], outs['i_xx'], atol=1e-6, rtol=0)
181180

182181

183-
@pytest.mark.parametrize('method', ['lambertw'])
184-
def test_ivcurve_pnts_precision(method, precise_iv_curves):
185-
"""
186-
Tests the accuracy of the IV curve points calcuated by singlediode. Only
187-
methods of singlediode that linearly spaced points are tested.
188-
"""
189-
x, pc = precise_iv_curves
190-
pc_i, pc_v = np.stack(pc['Currents']), np.stack(pc['Voltages'])
191-
ivcurve_pnts = len(pc['Currents'][0])
192-
outs = pvsystem.singlediode(method=method, ivcurve_pnts=ivcurve_pnts, **x)
193-
194-
assert np.allclose(pc_i, outs['i'], atol=1e-10, rtol=0)
195-
assert np.allclose(pc_v, outs['v'], atol=1e-10, rtol=0)
196-
197-
198182
@pytest.mark.parametrize('method', ['lambertw', 'brentq', 'newton'])
199183
def test_v_from_i_i_from_v_precision(method, precise_iv_curves):
200184
"""

0 commit comments

Comments
 (0)
0