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 , temperature )
@@ -2711,7 +2711,7 @@ def singlediode(photocurrent, saturation_current, resistance_series,
27112711 resistance_shunt , nNsVth , ivcurve_pnts = None ,
27122712 method = 'lambertw' ):
27132713 r"""
2714- Solve the single- diode equation to obtain a photovoltaic IV curve.
2714+ Solve the single diode equation to obtain a photovoltaic IV curve.
27152715
27162716 Solves the single diode equation [1]_
27172717
@@ -2724,11 +2724,10 @@ def singlediode(photocurrent, saturation_current, resistance_series,
27242724 \frac{V + I R_s}{R_{sh}}
27252725
27262726 for :math:`I` and :math:`V` when given :math:`I_L, I_0, R_s, R_{sh},` and
2727- :math:`n N_s V_{th}` which are described later. Returns a DataFrame
2728- which contains the 5 points on the I-V curve specified in
2729- [3]_. If all :math:`I_L, I_0, R_s, R_{sh},` and
2730- :math:`n N_s V_{th}` are scalar, a single curve is returned, if any
2731- are Series (of the same length), multiple IV curves are calculated.
2727+ :math:`n N_s V_{th}` which are described later. The five points on the I-V
2728+ curve specified in [3]_ are returned. If :math:`I_L, I_0, R_s, R_{sh},` and
2729+ :math:`n N_s V_{th}` are all scalars, a single curve is returned. If any
2730+ are array-like (of the same length), multiple IV curves are calculated.
27322731
27332732 The input parameters can be calculated from meteorological data using a
27342733 function for a single diode model, e.g.,
@@ -2766,35 +2765,33 @@ def singlediode(photocurrent, saturation_current, resistance_series,
27662765 Number of points in the desired IV curve. If None or 0, no points on
27672766 the IV curves will be produced.
27682767
2768+ .. deprecated:: 0.10.0
2769+ Use :py:func:`pvlib.pvsystem.v_from_i` and
2770+ :py:func:`pvlib.pvsystem.i_from_v` instead.
2771+
27692772 method : str, default 'lambertw'
27702773 Determines the method used to calculate points on the IV curve. The
27712774 options are ``'lambertw'``, ``'newton'``, or ``'brentq'``.
27722775
27732776 Returns
27742777 -------
2775- OrderedDict or DataFrame
2776-
2777- The returned dict-like object always contains the keys/columns:
2778-
2779- * i_sc - short circuit current in amperes.
2780- * v_oc - open circuit voltage in volts.
2781- * i_mp - current at maximum power point in amperes.
2782- * v_mp - voltage at maximum power point in volts.
2783- * p_mp - power at maximum power point in watts.
2784- * i_x - current, in amperes, at ``v = 0.5*v_oc``.
2785- * i_xx - current, in amperes, at ``V = 0.5*(v_oc+v_mp)``.
2778+ dict or pandas.DataFrame
2779+ The returned dict-like object always contains the keys/columns:
27862780
2787- If ivcurve_pnts is greater than 0, the output dictionary will also
2788- include the keys:
2781+ * i_sc - short circuit current in amperes.
2782+ * v_oc - open circuit voltage in volts.
2783+ * i_mp - current at maximum power point in amperes.
2784+ * v_mp - voltage at maximum power point in volts.
2785+ * p_mp - power at maximum power point in watts.
2786+ * i_x - current, in amperes, at ``v = 0.5*v_oc``.
2787+ * i_xx - current, in amperes, at ``V = 0.5*(v_oc+v_mp)``.
27892788
2790- * i - IV curve current in amperes.
2791- * v - IV curve voltage in volts.
2789+ A dict is returned when the input parameters are scalars or
2790+ ``ivcurve_pnts > 0``. If ``ivcurve_pnts > 0``, the output dictionary
2791+ will also include the keys:
27922792
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.
2793+ * i - IV curve current in amperes.
2794+ * v - IV curve voltage in volts.
27982795
27992796 See also
28002797 --------
@@ -2841,22 +2838,25 @@ def singlediode(photocurrent, saturation_current, resistance_series,
28412838 photovoltaic cell interconnection circuits" JW Bishop, Solar Cell (1988)
28422839 https://doi.org/10.1016/0379-6787(88)90059-2
28432840 """
2841+ if ivcurve_pnts :
2842+ warn_deprecated ('0.10.0' , name = 'pvlib.pvsystem.singlediode' ,
2843+ alternative = ('pvlib.pvsystem.v_from_i and '
2844+ 'pvlib.pvsystem.i_from_v' ),
2845+ obj_type = 'parameter ivcurve_pnts' ,
2846+ removal = '0.11.0' )
2847+ args = (photocurrent , saturation_current , resistance_series ,
2848+ resistance_shunt , nNsVth ) # collect args
28442849 # Calculate points on the IV curve using the LambertW solution to the
28452850 # single diode equation
28462851 if method .lower () == 'lambertw' :
2847- out = _singlediode ._lambertw (
2848- photocurrent , saturation_current , resistance_series ,
2849- resistance_shunt , nNsVth , ivcurve_pnts
2850- )
2851- i_sc , v_oc , i_mp , v_mp , p_mp , i_x , i_xx = out [:7 ]
2852+ out = _singlediode ._lambertw (* args , ivcurve_pnts )
2853+ points = out [:7 ]
28522854 if ivcurve_pnts :
28532855 ivcurve_i , ivcurve_v = out [7 :]
28542856 else :
28552857 # Calculate points on the IV curve using either 'newton' or 'brentq'
28562858 # methods. Voltages are determined by first solving the single diode
28572859 # equation for the diode voltage V_d then backing out voltage
2858- args = (photocurrent , saturation_current , resistance_series ,
2859- resistance_shunt , nNsVth ) # collect args
28602860 v_oc = _singlediode .bishop88_v_from_i (
28612861 0.0 , * args , method = method .lower ()
28622862 )
@@ -2872,6 +2872,7 @@ def singlediode(photocurrent, saturation_current, resistance_series,
28722872 i_xx = _singlediode .bishop88_i_from_v (
28732873 (v_oc + v_mp ) / 2.0 , * args , method = method .lower ()
28742874 )
2875+ points = i_sc , v_oc , i_mp , v_mp , p_mp , i_x , i_xx
28752876
28762877 # calculate the IV curve if requested using bishop88
28772878 if ivcurve_pnts :
@@ -2880,22 +2881,23 @@ def singlediode(photocurrent, saturation_current, resistance_series,
28802881 )
28812882 ivcurve_i , ivcurve_v , _ = _singlediode .bishop88 (vd , * args )
28822883
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
2884+ columns = ('i_sc' , 'v_oc' , 'i_mp' , 'v_mp' , 'p_mp' , 'i_x' , 'i_xx' )
28912885
2892- if ivcurve_pnts :
2886+ if all (map (np .isscalar , args )) or ivcurve_pnts :
2887+ out = {c : p for c , p in zip (columns , points )}
2888+
2889+ if ivcurve_pnts :
2890+ out .update (i = ivcurve_i , v = ivcurve_v )
2891+
2892+ return out
2893+
2894+ points = np .atleast_1d (* points ) # convert scalars to 1d-arrays
2895+ points = np .vstack (points ).T # collect rows into DataFrame columns
28932896
2894- out [ 'v' ] = ivcurve_v
2895- out [ 'i' ] = ivcurve_i
2897+ # save the first available pd.Series index, otherwise set to None
2898+ index = next (( a . index for a in args if isinstance ( a , pd . Series )), None )
28962899
2897- if isinstance (photocurrent , pd .Series ) and not ivcurve_pnts :
2898- out = pd .DataFrame (out , index = photocurrent .index )
2900+ out = pd .DataFrame (points , columns = columns , index = index )
28992901
29002902 return out
29012903
@@ -2936,7 +2938,7 @@ def max_power_point(photocurrent, saturation_current, resistance_series,
29362938
29372939 Returns
29382940 -------
2939- OrderedDict or pandas.Datafrane
2941+ OrderedDict or pandas.DataFrame
29402942 ``(i_mp, v_mp, p_mp)``
29412943
29422944 Notes
0 commit comments