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 , spectrum , temperature )
@@ -2308,7 +2308,7 @@ def singlediode(photocurrent, saturation_current, resistance_series,
2308
2308
resistance_shunt , nNsVth , ivcurve_pnts = None ,
2309
2309
method = 'lambertw' ):
2310
2310
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.
2312
2312
2313
2313
Solves the single diode equation [1]_
2314
2314
@@ -2321,11 +2321,10 @@ def singlediode(photocurrent, saturation_current, resistance_series,
2321
2321
\frac{V + I R_s}{R_{sh}}
2322
2322
2323
2323
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.
2329
2328
2330
2329
The input parameters can be calculated from meteorological data using a
2331
2330
function for a single diode model, e.g.,
@@ -2363,35 +2362,33 @@ def singlediode(photocurrent, saturation_current, resistance_series,
2363
2362
Number of points in the desired IV curve. If None or 0, no points on
2364
2363
the IV curves will be produced.
2365
2364
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
+
2366
2369
method : str, default 'lambertw'
2367
2370
Determines the method used to calculate points on the IV curve. The
2368
2371
options are ``'lambertw'``, ``'newton'``, or ``'brentq'``.
2369
2372
2370
2373
Returns
2371
2374
-------
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:
2383
2377
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)``.
2386
2385
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:
2389
2389
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.
2395
2392
2396
2393
See also
2397
2394
--------
@@ -2438,22 +2435,25 @@ def singlediode(photocurrent, saturation_current, resistance_series,
2438
2435
photovoltaic cell interconnection circuits" JW Bishop, Solar Cell (1988)
2439
2436
https://doi.org/10.1016/0379-6787(88)90059-2
2440
2437
"""
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
2441
2446
# Calculate points on the IV curve using the LambertW solution to the
2442
2447
# single diode equation
2443
2448
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 ]
2449
2451
if ivcurve_pnts :
2450
2452
ivcurve_i , ivcurve_v = out [7 :]
2451
2453
else :
2452
2454
# Calculate points on the IV curve using either 'newton' or 'brentq'
2453
2455
# methods. Voltages are determined by first solving the single diode
2454
2456
# equation for the diode voltage V_d then backing out voltage
2455
- args = (photocurrent , saturation_current , resistance_series ,
2456
- resistance_shunt , nNsVth ) # collect args
2457
2457
v_oc = _singlediode .bishop88_v_from_i (
2458
2458
0.0 , * args , method = method .lower ()
2459
2459
)
@@ -2469,6 +2469,7 @@ def singlediode(photocurrent, saturation_current, resistance_series,
2469
2469
i_xx = _singlediode .bishop88_i_from_v (
2470
2470
(v_oc + v_mp ) / 2.0 , * args , method = method .lower ()
2471
2471
)
2472
+ points = i_sc , v_oc , i_mp , v_mp , p_mp , i_x , i_xx
2472
2473
2473
2474
# calculate the IV curve if requested using bishop88
2474
2475
if ivcurve_pnts :
@@ -2477,22 +2478,23 @@ def singlediode(photocurrent, saturation_current, resistance_series,
2477
2478
)
2478
2479
ivcurve_i , ivcurve_v , _ = _singlediode .bishop88 (vd , * args )
2479
2480
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' )
2488
2482
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
2490
2493
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 )
2493
2496
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 )
2496
2498
2497
2499
return out
2498
2500
@@ -2533,7 +2535,7 @@ def max_power_point(photocurrent, saturation_current, resistance_series,
2533
2535
2534
2536
Returns
2535
2537
-------
2536
- OrderedDict or pandas.Datafrane
2538
+ OrderedDict or pandas.DataFrame
2537
2539
``(i_mp, v_mp, p_mp)``
2538
2540
2539
2541
Notes
0 commit comments