1616from abc import ABC , abstractmethod
1717from typing import Optional
1818
19- from pvlib ._deprecation import deprecated
19+ from pvlib ._deprecation import deprecated , warn_deprecated
2020
2121from pvlib import (atmosphere , iam , inverter , irradiance ,
2222 singlediode as _singlediode , spectrum , temperature )
@@ -2308,7 +2308,7 @@ def singlediode(photocurrent, saturation_current, resistance_series,
23082308 resistance_shunt , nNsVth , ivcurve_pnts = None ,
23092309 method = 'lambertw' ):
23102310 r"""
2311- Solve the single- diode equation to obtain a photovoltaic IV curve.
2311+ Solve the single diode equation to obtain a photovoltaic IV curve.
23122312
23132313 Solves the single diode equation [1]_
23142314
@@ -2321,11 +2321,10 @@ def singlediode(photocurrent, saturation_current, resistance_series,
23212321 \frac{V + I R_s}{R_{sh}}
23222322
23232323 for :math:`I` and :math:`V` when given :math:`I_L, I_0, R_s, R_{sh},` and
2324- :math:`n N_s V_{th}` which are described later. Returns a DataFrame
2325- which contains the 5 points on the I-V curve specified in
2326- [3]_. If all :math:`I_L, I_0, R_s, R_{sh},` and
2327- :math:`n N_s V_{th}` are scalar, a single curve is returned, if any
2328- are Series (of the same length), multiple IV curves are calculated.
2324+ :math:`n N_s V_{th}` which are described later. The five points on the I-V
2325+ curve specified in [3]_ are returned. If :math:`I_L, I_0, R_s, R_{sh},` and
2326+ :math:`n N_s V_{th}` are all scalars, a single curve is returned. If any
2327+ are array-like (of the same length), multiple IV curves are calculated.
23292328
23302329 The input parameters can be calculated from meteorological data using a
23312330 function for a single diode model, e.g.,
@@ -2363,35 +2362,33 @@ def singlediode(photocurrent, saturation_current, resistance_series,
23632362 Number of points in the desired IV curve. If None or 0, no points on
23642363 the IV curves will be produced.
23652364
2365+ .. deprecated:: 0.10.0
2366+ Use :py:func:`pvlib.pvsystem.v_from_i` and
2367+ :py:func:`pvlib.pvsystem.i_from_v` instead.
2368+
23662369 method : str, default 'lambertw'
23672370 Determines the method used to calculate points on the IV curve. The
23682371 options are ``'lambertw'``, ``'newton'``, or ``'brentq'``.
23692372
23702373 Returns
23712374 -------
2372- OrderedDict or DataFrame
2373-
2374- The returned dict-like object always contains the keys/columns:
2375-
2376- * i_sc - short circuit current in amperes.
2377- * v_oc - open circuit voltage in volts.
2378- * i_mp - current at maximum power point in amperes.
2379- * v_mp - voltage at maximum power point in volts.
2380- * p_mp - power at maximum power point in watts.
2381- * i_x - current, in amperes, at ``v = 0.5*v_oc``.
2382- * i_xx - current, in amperes, at ``V = 0.5*(v_oc+v_mp)``.
2375+ dict or pandas.DataFrame
2376+ The returned dict-like object always contains the keys/columns:
23832377
2384- If ivcurve_pnts is greater than 0, the output dictionary will also
2385- include the keys:
2378+ * i_sc - short circuit current in amperes.
2379+ * v_oc - open circuit voltage in volts.
2380+ * i_mp - current at maximum power point in amperes.
2381+ * v_mp - voltage at maximum power point in volts.
2382+ * p_mp - power at maximum power point in watts.
2383+ * i_x - current, in amperes, at ``v = 0.5*v_oc``.
2384+ * i_xx - current, in amperes, at ``v = 0.5*(v_oc+v_mp)``.
23862385
2387- * i - IV curve current in amperes.
2388- * v - IV curve voltage in volts.
2386+ A dict is returned when the input parameters are scalars or
2387+ ``ivcurve_pnts > 0``. If ``ivcurve_pnts > 0``, the output dictionary
2388+ will also include the keys:
23892389
2390- The output will be an OrderedDict if photocurrent is a scalar,
2391- array, or ivcurve_pnts is not None.
2392-
2393- The output will be a DataFrame if photocurrent is a Series and
2394- ivcurve_pnts is None.
2390+ * i - IV curve current in amperes.
2391+ * v - IV curve voltage in volts.
23952392
23962393 See also
23972394 --------
@@ -2438,22 +2435,25 @@ def singlediode(photocurrent, saturation_current, resistance_series,
24382435 photovoltaic cell interconnection circuits" JW Bishop, Solar Cell (1988)
24392436 https://doi.org/10.1016/0379-6787(88)90059-2
24402437 """
2438+ if ivcurve_pnts :
2439+ warn_deprecated ('0.10.0' , name = 'pvlib.pvsystem.singlediode' ,
2440+ alternative = ('pvlib.pvsystem.v_from_i and '
2441+ 'pvlib.pvsystem.i_from_v' ),
2442+ obj_type = 'parameter ivcurve_pnts' ,
2443+ removal = '0.11.0' )
2444+ args = (photocurrent , saturation_current , resistance_series ,
2445+ resistance_shunt , nNsVth ) # collect args
24412446 # Calculate points on the IV curve using the LambertW solution to the
24422447 # single diode equation
24432448 if method .lower () == 'lambertw' :
2444- out = _singlediode ._lambertw (
2445- photocurrent , saturation_current , resistance_series ,
2446- resistance_shunt , nNsVth , ivcurve_pnts
2447- )
2448- i_sc , v_oc , i_mp , v_mp , p_mp , i_x , i_xx = out [:7 ]
2449+ out = _singlediode ._lambertw (* args , ivcurve_pnts )
2450+ points = out [:7 ]
24492451 if ivcurve_pnts :
24502452 ivcurve_i , ivcurve_v = out [7 :]
24512453 else :
24522454 # Calculate points on the IV curve using either 'newton' or 'brentq'
24532455 # methods. Voltages are determined by first solving the single diode
24542456 # equation for the diode voltage V_d then backing out voltage
2455- args = (photocurrent , saturation_current , resistance_series ,
2456- resistance_shunt , nNsVth ) # collect args
24572457 v_oc = _singlediode .bishop88_v_from_i (
24582458 0.0 , * args , method = method .lower ()
24592459 )
@@ -2469,6 +2469,7 @@ def singlediode(photocurrent, saturation_current, resistance_series,
24692469 i_xx = _singlediode .bishop88_i_from_v (
24702470 (v_oc + v_mp ) / 2.0 , * args , method = method .lower ()
24712471 )
2472+ points = i_sc , v_oc , i_mp , v_mp , p_mp , i_x , i_xx
24722473
24732474 # calculate the IV curve if requested using bishop88
24742475 if ivcurve_pnts :
@@ -2477,22 +2478,23 @@ def singlediode(photocurrent, saturation_current, resistance_series,
24772478 )
24782479 ivcurve_i , ivcurve_v , _ = _singlediode .bishop88 (vd , * args )
24792480
2480- out = OrderedDict ()
2481- out ['i_sc' ] = i_sc
2482- out ['v_oc' ] = v_oc
2483- out ['i_mp' ] = i_mp
2484- out ['v_mp' ] = v_mp
2485- out ['p_mp' ] = p_mp
2486- out ['i_x' ] = i_x
2487- out ['i_xx' ] = i_xx
2481+ columns = ('i_sc' , 'v_oc' , 'i_mp' , 'v_mp' , 'p_mp' , 'i_x' , 'i_xx' )
24882482
2489- if ivcurve_pnts :
2483+ if all (map (np .isscalar , args )) or ivcurve_pnts :
2484+ out = {c : p for c , p in zip (columns , points )}
2485+
2486+ if ivcurve_pnts :
2487+ out .update (i = ivcurve_i , v = ivcurve_v )
2488+
2489+ return out
2490+
2491+ points = np .atleast_1d (* points ) # convert scalars to 1d-arrays
2492+ points = np .vstack (points ).T # collect rows into DataFrame columns
24902493
2491- out [ 'v' ] = ivcurve_v
2492- out [ 'i' ] = ivcurve_i
2494+ # save the first available pd.Series index, otherwise set to None
2495+ index = next (( a . index for a in args if isinstance ( a , pd . Series )), None )
24932496
2494- if isinstance (photocurrent , pd .Series ) and not ivcurve_pnts :
2495- out = pd .DataFrame (out , index = photocurrent .index )
2497+ out = pd .DataFrame (points , columns = columns , index = index )
24962498
24972499 return out
24982500
@@ -2533,7 +2535,7 @@ def max_power_point(photocurrent, saturation_current, resistance_series,
25332535
25342536 Returns
25352537 -------
2536- OrderedDict or pandas.Datafrane
2538+ OrderedDict or pandas.DataFrame
25372539 ``(i_mp, v_mp, p_mp)``
25382540
25392541 Notes
0 commit comments