Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/sphinx/source/whatsnew/v0.13.2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ Enhancements
:py:func:`~pvlib.singlediode.bishop88_mpp`,
:py:func:`~pvlib.singlediode.bishop88_v_from_i`, and
:py:func:`~pvlib.singlediode.bishop88_i_from_v`. (:issue:`2497`, :pull:`2498`)

* Accelerate :py:func:`~pvlib.pvsystem.singlediode` when scipy>=1.15 is
installed. (:issue:`2497`, :pull:`XXXX`)


Documentation
Expand All @@ -53,4 +54,4 @@ Maintenance

Contributors
~~~~~~~~~~~~

* Cliff Hansen (:ghuser:`cwhanse`)
34 changes: 21 additions & 13 deletions pvlib/pvsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -2534,28 +2534,35 @@ def singlediode(photocurrent, saturation_current, resistance_series,
explicit function of :math:`V=f(I)` and :math:`I=f(V)` as shown in [2]_.

If the method is ``'newton'`` then the root-finding Newton-Raphson method
is used. It should be safe for well behaved IV-curves, but the ``'brentq'``
method is recommended for reliability.
is used. It should be safe for well-behaved IV curves, otherwise the
``'chandrupatla``` or ``'brentq'`` methods are recommended for reliability.

If the method is ``'brentq'`` then Brent's bisection search method is used
that guarantees convergence by bounding the voltage between zero and
open-circuit.
open-circuit. ``'brentq'`` is generally slower than the other options.

If the method is ``'chandrupatla'`` then Chandrupatla's method is used
that guarantees convergence.

References
----------
.. [1] S.R. Wenham, M.A. Green, M.E. Watt, "Applied Photovoltaics" ISBN
0 86758 909 4
.. [1] S. R. Wenham, M. A. Green, M. E. Watt, "Applied Photovoltaics",
Centre for Photovoltaic Devices and Systems, 1995. ISBN
0867589094

.. [2] A. Jain, A. Kapoor, "Exact analytical solutions of the
parameters of real solar cells using Lambert W-function", Solar
Energy Materials and Solar Cells, 81 (2004) 269-277.
Energy Materials and Solar Cells, vol. 81 no. 2, pp. 269-277, Feb. 2004.
:doi:`10.1016/j.solmat.2003.11.018`.

.. [3] D. King et al, "Sandia Photovoltaic Array Performance Model",
SAND2004-3535, Sandia National Laboratories, Albuquerque, NM
.. [3] D. L. King, E. E. Boyson and J. A. Kratochvil "Photovoltaic Array
Performance Model", Sandia National Laboratories, Albuquerque, NM, USA.
Report SAND2004-3535, 2004.

.. [4] "Computer simulation of the effects of electrical mismatches in
photovoltaic cell interconnection circuits" JW Bishop, Solar Cell (1988)
https://doi.org/10.1016/0379-6787(88)90059-2
.. [4] J.W. Bishop, "Computer simulation of the effects of electrical
mismatches in photovoltaic cell interconnection circuits" Solar Cells,
vol. 25 no. 1, pp. 73-89, Oct. 1988.
:doi:`doi.org/10.1016/0379-6787(88)90059-2`
"""
args = (photocurrent, saturation_current, resistance_series,
resistance_shunt, nNsVth) # collect args
Expand All @@ -2565,8 +2572,9 @@ def singlediode(photocurrent, saturation_current, resistance_series,
out = _singlediode._lambertw(*args)
points = out[:7]
else:
# Calculate points on the IV curve using either 'newton' or 'brentq'
# methods. Voltages are determined by first solving the single diode
# Calculate points on the IV curve using Bishop's algorithm and solving
# with 'newton', 'brentq' or 'chandrupatla' method.
# Voltages are determined by first solving the single diode
# equation for the diode voltage V_d then backing out voltage
v_oc = _singlediode.bishop88_v_from_i(
0.0, *args, method=method.lower()
Expand Down
52 changes: 39 additions & 13 deletions pvlib/singlediode.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,18 +141,20 @@ def bishop88(diode_voltage, photocurrent, saturation_current,

References
----------
.. [1] "Computer simulation of the effects of electrical mismatches in
photovoltaic cell interconnection circuits" JW Bishop, Solar Cell (1988)
:doi:`10.1016/0379-6787(88)90059-2`

.. [2] "Improved equivalent circuit and Analytical Model for Amorphous
Silicon Solar Cells and Modules." J. Mertens, et al., IEEE Transactions
on Electron Devices, Vol 45, No 2, Feb 1998.
.. [1] J.W. Bishop, "Computer simulation of the effects of electrical
mismatches in photovoltaic cell interconnection circuits" Solar Cells,
vol. 25 no. 1, pp. 73-89, Oct. 1988.
:doi:`doi.org/10.1016/0379-6787(88)90059-2`

.. [2] J. Merten, J. M. Asensi, C. Voz, A. V. Shah, R. Platz and J. Andreu,
"Improved equivalent circuit and Analytical Model for Amorphous
Silicon Solar Cells and Modules." , IEEE Transactions
on Electron Devices, vol. 45, no. 2, pp. 423-429, Feb 1998.
:doi:`10.1109/16.658676`

.. [3] "Performance assessment of a simulation model for PV modules of any
available technology", André Mermoud and Thibault Lejeune, 25th EUPVSEC,
2010
.. [3] A. Mermoud and T. Lejeune, "Performance assessment of a simulation
model for PV modules of any available technology", In Proc. of the 25th
European PVSEC, Valencia, ES, 2010.
:doi:`10.4229/25thEUPVSEC2010-4BV.1.114`
"""
# calculate recombination loss current where d2mutau > 0
Expand Down Expand Up @@ -913,10 +915,25 @@ def _lambertw(photocurrent, saturation_current, resistance_series,
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)
# use scipy.elementwise if available
# remove try/except when scipy>=1.15, and golden mean is retired
try:
from scipy.optimize.elementwise import find_minimum
# left negative to insure strict inequality
init = (-1., 0.8*v_oc, v_oc)
res = find_minimum(_vmp_opt, init,
args=(params['photocurrent'],
params['saturation_current'],
params['resistance_series'],
params['resistance_shunt'],
params['nNsVth'],))
v_mp = res.x
p_mp = -1.*res.f_x
except ModuleNotFoundError:
# switch to old golden section method
p_mp, v_mp = _golden_sect_DataFrame(params, 0., v_oc * 1.14,
_pwr_optfcn)

# Find Imp using Lambert W
i_mp = _lambertw_i_from_v(v_mp, **params)

# Find Ix and Ixx using Lambert W
Expand All @@ -938,6 +955,15 @@ def _lambertw(photocurrent, saturation_current, resistance_series,
return out


def _vmp_opt(v, iph, io, rs, rsh, nNsVth):
'''
Function to find negative of power from ``i_from_v``.
'''
current = _lambertw_i_from_v(v, iph, io, rs, rsh, nNsVth)

return -v * current


def _pwr_optfcn(df, loc):
'''
Function to find power from ``i_from_v``.
Expand Down
2 changes: 1 addition & 1 deletion tests/test_singlediode.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ def test_singlediode_precision(method, precise_iv_curves):

assert np.allclose(pc['i_sc'], outs['i_sc'], atol=1e-10, rtol=0)
assert np.allclose(pc['v_oc'], outs['v_oc'], atol=1e-10, rtol=0)
assert np.allclose(pc['i_mp'], outs['i_mp'], atol=7e-8, rtol=0)
assert np.allclose(pc['i_mp'], outs['i_mp'], atol=1e-7, rtol=0)
assert np.allclose(pc['v_mp'], outs['v_mp'], atol=1e-6, rtol=0)
assert np.allclose(pc['p_mp'], outs['p_mp'], atol=1e-10, rtol=0)
assert np.allclose(pc['i_x'], outs['i_x'], atol=1e-10, rtol=0)
Expand Down
Loading