16
16
from abc import ABC , abstractmethod
17
17
from typing import Optional
18
18
19
- from pvlib ._deprecation import deprecated
19
+ from pvlib ._deprecation import deprecated , warn_deprecated
20
20
21
21
from pvlib import (atmosphere , iam , inverter , irradiance ,
22
22
singlediode as _singlediode , temperature )
@@ -2711,7 +2711,7 @@ def singlediode(photocurrent, saturation_current, resistance_series,
2711
2711
resistance_shunt , nNsVth , ivcurve_pnts = None ,
2712
2712
method = 'lambertw' ):
2713
2713
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.
2715
2715
2716
2716
Solves the single diode equation [1]_
2717
2717
@@ -2724,11 +2724,10 @@ def singlediode(photocurrent, saturation_current, resistance_series,
2724
2724
\frac{V + I R_s}{R_{sh}}
2725
2725
2726
2726
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.
2732
2731
2733
2732
The input parameters can be calculated from meteorological data using a
2734
2733
function for a single diode model, e.g.,
@@ -2766,35 +2765,33 @@ def singlediode(photocurrent, saturation_current, resistance_series,
2766
2765
Number of points in the desired IV curve. If None or 0, no points on
2767
2766
the IV curves will be produced.
2768
2767
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
+
2769
2772
method : str, default 'lambertw'
2770
2773
Determines the method used to calculate points on the IV curve. The
2771
2774
options are ``'lambertw'``, ``'newton'``, or ``'brentq'``.
2772
2775
2773
2776
Returns
2774
2777
-------
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:
2786
2780
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)``.
2789
2788
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:
2792
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.
2793
+ * i - IV curve current in amperes.
2794
+ * v - IV curve voltage in volts.
2798
2795
2799
2796
See also
2800
2797
--------
@@ -2841,22 +2838,25 @@ def singlediode(photocurrent, saturation_current, resistance_series,
2841
2838
photovoltaic cell interconnection circuits" JW Bishop, Solar Cell (1988)
2842
2839
https://doi.org/10.1016/0379-6787(88)90059-2
2843
2840
"""
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
2844
2849
# Calculate points on the IV curve using the LambertW solution to the
2845
2850
# single diode equation
2846
2851
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 ]
2852
2854
if ivcurve_pnts :
2853
2855
ivcurve_i , ivcurve_v = out [7 :]
2854
2856
else :
2855
2857
# Calculate points on the IV curve using either 'newton' or 'brentq'
2856
2858
# methods. Voltages are determined by first solving the single diode
2857
2859
# equation for the diode voltage V_d then backing out voltage
2858
- args = (photocurrent , saturation_current , resistance_series ,
2859
- resistance_shunt , nNsVth ) # collect args
2860
2860
v_oc = _singlediode .bishop88_v_from_i (
2861
2861
0.0 , * args , method = method .lower ()
2862
2862
)
@@ -2872,6 +2872,7 @@ def singlediode(photocurrent, saturation_current, resistance_series,
2872
2872
i_xx = _singlediode .bishop88_i_from_v (
2873
2873
(v_oc + v_mp ) / 2.0 , * args , method = method .lower ()
2874
2874
)
2875
+ points = i_sc , v_oc , i_mp , v_mp , p_mp , i_x , i_xx
2875
2876
2876
2877
# calculate the IV curve if requested using bishop88
2877
2878
if ivcurve_pnts :
@@ -2880,22 +2881,23 @@ def singlediode(photocurrent, saturation_current, resistance_series,
2880
2881
)
2881
2882
ivcurve_i , ivcurve_v , _ = _singlediode .bishop88 (vd , * args )
2882
2883
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' )
2891
2885
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
2893
2896
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 )
2896
2899
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 )
2899
2901
2900
2902
return out
2901
2903
@@ -2936,7 +2938,7 @@ def max_power_point(photocurrent, saturation_current, resistance_series,
2936
2938
2937
2939
Returns
2938
2940
-------
2939
- OrderedDict or pandas.Datafrane
2941
+ OrderedDict or pandas.DataFrame
2940
2942
``(i_mp, v_mp, p_mp)``
2941
2943
2942
2944
Notes
0 commit comments