pvlib 0.10.4__py3-none-any.whl → 0.10.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pvlib/bifacial/utils.py +2 -1
- pvlib/iotools/srml.py +3 -2
- pvlib/iotools/surfrad.py +1 -1
- pvlib/location.py +3 -1
- pvlib/pvarray.py +7 -5
- pvlib/pvsystem.py +52 -43
- pvlib/scaling.py +4 -2
- pvlib/singlediode.py +37 -9
- pvlib/snow.py +3 -1
- pvlib/spectrum/mismatch.py +2 -1
- pvlib/tests/bifacial/test_utils.py +6 -5
- pvlib/tests/test_pvsystem.py +62 -89
- pvlib/tests/test_singlediode.py +68 -10
- pvlib/version.py +1 -5
- {pvlib-0.10.4.dist-info → pvlib-0.10.5.dist-info}/METADATA +3 -4
- {pvlib-0.10.4.dist-info → pvlib-0.10.5.dist-info}/RECORD +20 -20
- {pvlib-0.10.4.dist-info → pvlib-0.10.5.dist-info}/AUTHORS.md +0 -0
- {pvlib-0.10.4.dist-info → pvlib-0.10.5.dist-info}/LICENSE +0 -0
- {pvlib-0.10.4.dist-info → pvlib-0.10.5.dist-info}/WHEEL +0 -0
- {pvlib-0.10.4.dist-info → pvlib-0.10.5.dist-info}/top_level.txt +0 -0
pvlib/bifacial/utils.py
CHANGED
|
@@ -4,6 +4,7 @@ modeling.
|
|
|
4
4
|
"""
|
|
5
5
|
import numpy as np
|
|
6
6
|
from pvlib.tools import sind, cosd, tand
|
|
7
|
+
from scipy.integrate import trapezoid
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
def _solar_projection_tangent(solar_zenith, solar_azimuth, surface_azimuth):
|
|
@@ -220,7 +221,7 @@ def vf_ground_sky_2d_integ(surface_tilt, gcr, height, pitch, max_rows=10,
|
|
|
220
221
|
vf = vf_ground_sky_2d(r, gcr, z, pitch, height, max_rows)
|
|
221
222
|
fz_sky[:, k] = vf[:, 0] # remove spurious rotation dimension
|
|
222
223
|
# calculate the integrated view factor for all of the ground between rows
|
|
223
|
-
return
|
|
224
|
+
return trapezoid(fz_sky, z, axis=0)
|
|
224
225
|
|
|
225
226
|
|
|
226
227
|
def _vf_poly(surface_tilt, gcr, x, delta):
|
pvlib/iotools/srml.py
CHANGED
|
@@ -92,7 +92,7 @@ def read_srml(filename, map_variables=True):
|
|
|
92
92
|
# Mask data marked with quality flag 99 (bad or missing data)
|
|
93
93
|
for col in columns[::2]:
|
|
94
94
|
missing = data[col + '_flag'] == 99
|
|
95
|
-
data[col] = data[col].where(~(missing), np.
|
|
95
|
+
data[col] = data[col].where(~(missing), np.nan)
|
|
96
96
|
return data
|
|
97
97
|
|
|
98
98
|
|
|
@@ -175,7 +175,8 @@ def _format_index(df):
|
|
|
175
175
|
@deprecated('0.10.0', alternative='pvlib.iotools.get_srml', removal='0.11.0')
|
|
176
176
|
def read_srml_month_from_solardat(station, year, month, filetype='PO',
|
|
177
177
|
map_variables=True):
|
|
178
|
-
"""
|
|
178
|
+
"""
|
|
179
|
+
Request a month of SRML data and read it into a Dataframe.
|
|
179
180
|
|
|
180
181
|
The SRML is described in [1]_.
|
|
181
182
|
|
pvlib/iotools/surfrad.py
CHANGED
|
@@ -152,7 +152,7 @@ def read_surfrad(filename, map_variables=True):
|
|
|
152
152
|
|
|
153
153
|
data = _format_index(data)
|
|
154
154
|
missing = data == -9999.9
|
|
155
|
-
data = data.where(~missing, np.
|
|
155
|
+
data = data.where(~missing, np.nan)
|
|
156
156
|
|
|
157
157
|
if map_variables:
|
|
158
158
|
data.rename(columns=VARIABLE_MAP, inplace=True)
|
pvlib/location.py
CHANGED
|
@@ -439,8 +439,10 @@ def lookup_altitude(latitude, longitude):
|
|
|
439
439
|
# 255 is a special value that means nodata. Fallback to 0 if nodata.
|
|
440
440
|
if alt == 255:
|
|
441
441
|
return 0
|
|
442
|
+
# convert from np.uint8 to float so that the following operations succeed
|
|
443
|
+
alt = float(alt)
|
|
442
444
|
# Altitude is encoded in 28 meter steps from -450 meters to 6561 meters
|
|
443
445
|
# There are 0-254 possible altitudes, with 255 reserved for nodata.
|
|
444
446
|
alt *= 28
|
|
445
447
|
alt -= 450
|
|
446
|
-
return
|
|
448
|
+
return alt
|
pvlib/pvarray.py
CHANGED
|
@@ -311,11 +311,13 @@ def huld(effective_irradiance, temp_mod, pdc0, k=None, cell_type=None):
|
|
|
311
311
|
|
|
312
312
|
:py:func:`huld` is a component of the PV performance model implemented in
|
|
313
313
|
PVGIS. Among other components, the full PVGIS model includes:
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
314
|
+
|
|
315
|
+
- the Faiman model for module temperature
|
|
316
|
+
:py:func:`pvlib.temperature.faiman`
|
|
317
|
+
- the Martin and Ruiz model for the incidence angle modifier (IAM)
|
|
318
|
+
:py:func:`pvlib.iam.martin_ruiz`
|
|
319
|
+
- a custom model for a spectral adjustment factor
|
|
320
|
+
|
|
319
321
|
The PVGIS API (see :py:func:`pvlib.iotools.get_pvgis_hourly`) returns
|
|
320
322
|
broadband plane-of-array irradiance (``poa_global``) and DC power (``P``).
|
|
321
323
|
``poa_global`` is irradiance before applying the IAM and spectral
|
pvlib/pvsystem.py
CHANGED
|
@@ -7,7 +7,7 @@ from collections import OrderedDict
|
|
|
7
7
|
import functools
|
|
8
8
|
import io
|
|
9
9
|
import itertools
|
|
10
|
-
import
|
|
10
|
+
from pathlib import Path
|
|
11
11
|
import inspect
|
|
12
12
|
from urllib.request import urlopen
|
|
13
13
|
import numpy as np
|
|
@@ -1487,8 +1487,10 @@ def calcparams_desoto(effective_irradiance, temp_cell,
|
|
|
1487
1487
|
'''
|
|
1488
1488
|
Calculates five parameter values for the single diode equation at
|
|
1489
1489
|
effective irradiance and cell temperature using the De Soto et al.
|
|
1490
|
-
model
|
|
1491
|
-
|
|
1490
|
+
model. The five values returned by ``calcparams_desoto`` can be used by
|
|
1491
|
+
singlediode to calculate an IV curve.
|
|
1492
|
+
|
|
1493
|
+
The model is described in [1]_.
|
|
1492
1494
|
|
|
1493
1495
|
Parameters
|
|
1494
1496
|
----------
|
|
@@ -1958,9 +1960,9 @@ def calcparams_pvsyst(effective_irradiance, temp_cell,
|
|
|
1958
1960
|
|
|
1959
1961
|
|
|
1960
1962
|
def retrieve_sam(name=None, path=None):
|
|
1961
|
-
|
|
1962
|
-
Retrieve latest module and inverter info from a
|
|
1963
|
-
SAM website.
|
|
1963
|
+
"""
|
|
1964
|
+
Retrieve latest module and inverter info from a file bundled with pvlib,
|
|
1965
|
+
a path or an URL (like SAM's website).
|
|
1964
1966
|
|
|
1965
1967
|
This function will retrieve either:
|
|
1966
1968
|
|
|
@@ -1971,10 +1973,14 @@ def retrieve_sam(name=None, path=None):
|
|
|
1971
1973
|
|
|
1972
1974
|
and return it as a pandas DataFrame.
|
|
1973
1975
|
|
|
1976
|
+
.. note::
|
|
1977
|
+
Only provide one of ``name`` or ``path``.
|
|
1978
|
+
|
|
1974
1979
|
Parameters
|
|
1975
1980
|
----------
|
|
1976
1981
|
name : string, optional
|
|
1977
|
-
|
|
1982
|
+
Use one of the following strings to retrieve a database bundled with
|
|
1983
|
+
pvlib:
|
|
1978
1984
|
|
|
1979
1985
|
* 'CECMod' - returns the CEC module database
|
|
1980
1986
|
* 'CECInverter' - returns the CEC Inverter database
|
|
@@ -1985,7 +1991,7 @@ def retrieve_sam(name=None, path=None):
|
|
|
1985
1991
|
* 'ADRInverter' - returns the ADR Inverter database
|
|
1986
1992
|
|
|
1987
1993
|
path : string, optional
|
|
1988
|
-
Path to
|
|
1994
|
+
Path to a CSV file or a URL.
|
|
1989
1995
|
|
|
1990
1996
|
Returns
|
|
1991
1997
|
-------
|
|
@@ -1997,7 +2003,11 @@ def retrieve_sam(name=None, path=None):
|
|
|
1997
2003
|
Raises
|
|
1998
2004
|
------
|
|
1999
2005
|
ValueError
|
|
2000
|
-
If no name or path is provided.
|
|
2006
|
+
If no ``name`` or ``path`` is provided.
|
|
2007
|
+
ValueError
|
|
2008
|
+
If both ``name`` and ``path`` are provided.
|
|
2009
|
+
KeyError
|
|
2010
|
+
If the provided ``name`` is not a valid database name.
|
|
2001
2011
|
|
|
2002
2012
|
Notes
|
|
2003
2013
|
-----
|
|
@@ -2030,38 +2040,38 @@ def retrieve_sam(name=None, path=None):
|
|
|
2030
2040
|
CEC_Date NaN
|
|
2031
2041
|
CEC_Type Utility Interactive
|
|
2032
2042
|
Name: AE_Solar_Energy__AE6_0__277V_, dtype: object
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
if name is not None:
|
|
2036
|
-
name
|
|
2037
|
-
data_path = os.path.join(
|
|
2038
|
-
os.path.dirname(os.path.abspath(__file__)), 'data')
|
|
2039
|
-
if name == 'cecmod':
|
|
2040
|
-
csvdata = os.path.join(
|
|
2041
|
-
data_path, 'sam-library-cec-modules-2019-03-05.csv')
|
|
2042
|
-
elif name == 'sandiamod':
|
|
2043
|
-
csvdata = os.path.join(
|
|
2044
|
-
data_path, 'sam-library-sandia-modules-2015-6-30.csv')
|
|
2045
|
-
elif name == 'adrinverter':
|
|
2046
|
-
csvdata = os.path.join(
|
|
2047
|
-
data_path, 'adr-library-cec-inverters-2019-03-05.csv')
|
|
2048
|
-
elif name in ['cecinverter', 'sandiainverter']:
|
|
2049
|
-
# Allowing either, to provide for old code,
|
|
2050
|
-
# while aligning with current expectations
|
|
2051
|
-
csvdata = os.path.join(
|
|
2052
|
-
data_path, 'sam-library-cec-inverters-2019-03-05.csv')
|
|
2053
|
-
else:
|
|
2054
|
-
raise ValueError(f'invalid name {name}')
|
|
2055
|
-
elif path is not None:
|
|
2056
|
-
if path.startswith('http'):
|
|
2057
|
-
response = urlopen(path)
|
|
2058
|
-
csvdata = io.StringIO(response.read().decode(errors='ignore'))
|
|
2059
|
-
else:
|
|
2060
|
-
csvdata = path
|
|
2043
|
+
"""
|
|
2044
|
+
# error: path was previously silently ignored if name was given GH#2018
|
|
2045
|
+
if name is not None and path is not None:
|
|
2046
|
+
raise ValueError("Please provide either 'name' or 'path', not both.")
|
|
2061
2047
|
elif name is None and path is None:
|
|
2062
|
-
raise ValueError("
|
|
2063
|
-
|
|
2064
|
-
|
|
2048
|
+
raise ValueError("Please provide either 'name' or 'path'.")
|
|
2049
|
+
elif name is not None:
|
|
2050
|
+
internal_dbs = {
|
|
2051
|
+
"cecmod": "sam-library-cec-modules-2019-03-05.csv",
|
|
2052
|
+
"sandiamod": "sam-library-sandia-modules-2015-6-30.csv",
|
|
2053
|
+
"adrinverter": "adr-library-cec-inverters-2019-03-05.csv",
|
|
2054
|
+
# Both 'cecinverter' and 'sandiainverter', point to same database
|
|
2055
|
+
# to provide for old code, while aligning with current expectations
|
|
2056
|
+
"cecinverter": "sam-library-cec-inverters-2019-03-05.csv",
|
|
2057
|
+
"sandiainverter": "sam-library-cec-inverters-2019-03-05.csv",
|
|
2058
|
+
}
|
|
2059
|
+
try:
|
|
2060
|
+
csvdata_path = Path(__file__).parent.joinpath(
|
|
2061
|
+
"data", internal_dbs[name.lower()]
|
|
2062
|
+
)
|
|
2063
|
+
except KeyError:
|
|
2064
|
+
raise KeyError(
|
|
2065
|
+
f"Invalid name {name}. "
|
|
2066
|
+
+ f"Provide one of {list(internal_dbs.keys())}."
|
|
2067
|
+
) from None
|
|
2068
|
+
else: # path is not None
|
|
2069
|
+
if path.lower().startswith("http"): # URL check is not case-sensitive
|
|
2070
|
+
response = urlopen(path) # URL is case-sensitive
|
|
2071
|
+
csvdata_path = io.StringIO(response.read().decode(errors="ignore"))
|
|
2072
|
+
else:
|
|
2073
|
+
csvdata_path = path
|
|
2074
|
+
return _parse_raw_sam_df(csvdata_path)
|
|
2065
2075
|
|
|
2066
2076
|
|
|
2067
2077
|
def _normalize_sam_product_names(names):
|
|
@@ -2254,10 +2264,9 @@ def sapm(effective_irradiance, temp_cell, module):
|
|
|
2254
2264
|
module['IXO'] * (module['C4']*Ee + module['C5']*(Ee**2)) *
|
|
2255
2265
|
(1 + module['Aisc']*(temp_cell - temp_ref)))
|
|
2256
2266
|
|
|
2257
|
-
# the Ixx calculation in King 2004 has a typo (mixes up Aisc and Aimp)
|
|
2258
2267
|
out['i_xx'] = (
|
|
2259
2268
|
module['IXXO'] * (module['C6']*Ee + module['C7']*(Ee**2)) *
|
|
2260
|
-
(1 + module['
|
|
2269
|
+
(1 + module['Aimp']*(temp_cell - temp_ref)))
|
|
2261
2270
|
|
|
2262
2271
|
if isinstance(out['i_sc'], pd.Series):
|
|
2263
2272
|
out = pd.DataFrame(out)
|
|
@@ -2536,7 +2545,7 @@ def singlediode(photocurrent, saturation_current, resistance_series,
|
|
|
2536
2545
|
|
|
2537
2546
|
|
|
2538
2547
|
def max_power_point(photocurrent, saturation_current, resistance_series,
|
|
2539
|
-
resistance_shunt, nNsVth, d2mutau=0, NsVbi=np.
|
|
2548
|
+
resistance_shunt, nNsVth, d2mutau=0, NsVbi=np.inf,
|
|
2540
2549
|
method='brentq'):
|
|
2541
2550
|
"""
|
|
2542
2551
|
Given the single diode equation coefficients, calculates the maximum power
|
pvlib/scaling.py
CHANGED
|
@@ -13,8 +13,10 @@ from scipy.spatial.distance import pdist
|
|
|
13
13
|
def wvm(clearsky_index, positions, cloud_speed, dt=None):
|
|
14
14
|
"""
|
|
15
15
|
Compute spatial aggregation time series smoothing on clear sky index based
|
|
16
|
-
on the Wavelet Variability model
|
|
17
|
-
|
|
16
|
+
on the Wavelet Variability model.
|
|
17
|
+
|
|
18
|
+
This model is described in Lave et al. [1]_, [2]_.
|
|
19
|
+
Implementation is basically a port of the Matlab version of the code [3]_.
|
|
18
20
|
|
|
19
21
|
Parameters
|
|
20
22
|
----------
|
pvlib/singlediode.py
CHANGED
|
@@ -58,7 +58,7 @@ def estimate_voc(photocurrent, saturation_current, nNsVth):
|
|
|
58
58
|
|
|
59
59
|
def bishop88(diode_voltage, photocurrent, saturation_current,
|
|
60
60
|
resistance_series, resistance_shunt, nNsVth, d2mutau=0,
|
|
61
|
-
NsVbi=np.
|
|
61
|
+
NsVbi=np.inf, breakdown_factor=0., breakdown_voltage=-5.5,
|
|
62
62
|
breakdown_exp=3.28, gradients=False):
|
|
63
63
|
r"""
|
|
64
64
|
Explicit calculation of points on the IV curve described by the single
|
|
@@ -206,7 +206,7 @@ def bishop88(diode_voltage, photocurrent, saturation_current,
|
|
|
206
206
|
|
|
207
207
|
def bishop88_i_from_v(voltage, photocurrent, saturation_current,
|
|
208
208
|
resistance_series, resistance_shunt, nNsVth,
|
|
209
|
-
d2mutau=0, NsVbi=np.
|
|
209
|
+
d2mutau=0, NsVbi=np.inf, breakdown_factor=0.,
|
|
210
210
|
breakdown_voltage=-5.5, breakdown_exp=3.28,
|
|
211
211
|
method='newton', method_kwargs=None):
|
|
212
212
|
"""
|
|
@@ -285,6 +285,12 @@ def bishop88_i_from_v(voltage, photocurrent, saturation_current,
|
|
|
285
285
|
|
|
286
286
|
>>> i, method_output = bishop88_i_from_v(0.0, **args, method='newton',
|
|
287
287
|
... method_kwargs={'full_output': True})
|
|
288
|
+
|
|
289
|
+
References
|
|
290
|
+
----------
|
|
291
|
+
.. [1] "Computer simulation of the effects of electrical mismatches in
|
|
292
|
+
photovoltaic cell interconnection circuits" JW Bishop, Solar Cell (1988)
|
|
293
|
+
:doi:`10.1016/0379-6787(88)90059-2`
|
|
288
294
|
"""
|
|
289
295
|
# collect args
|
|
290
296
|
args = (photocurrent, saturation_current,
|
|
@@ -304,6 +310,9 @@ def bishop88_i_from_v(voltage, photocurrent, saturation_current,
|
|
|
304
310
|
if method == 'brentq':
|
|
305
311
|
# first bound the search using voc
|
|
306
312
|
voc_est = estimate_voc(photocurrent, saturation_current, nNsVth)
|
|
313
|
+
# start iteration slightly less than NsVbi when voc_est > NsVbi, to
|
|
314
|
+
# avoid the asymptote at NsVbi
|
|
315
|
+
xp = np.where(voc_est < NsVbi, voc_est, 0.9999*NsVbi)
|
|
307
316
|
|
|
308
317
|
# brentq only works with scalar inputs, so we need a set up function
|
|
309
318
|
# and np.vectorize to repeatedly call the optimizer with the right
|
|
@@ -317,7 +326,7 @@ def bishop88_i_from_v(voltage, photocurrent, saturation_current,
|
|
|
317
326
|
**method_kwargs)
|
|
318
327
|
|
|
319
328
|
vd_from_brent_vectorized = np.vectorize(vd_from_brent)
|
|
320
|
-
vd = vd_from_brent_vectorized(
|
|
329
|
+
vd = vd_from_brent_vectorized(xp, voltage, *args)
|
|
321
330
|
elif method == 'newton':
|
|
322
331
|
x0, (voltage, *args), method_kwargs = \
|
|
323
332
|
_prepare_newton_inputs(voltage, (voltage, *args), method_kwargs)
|
|
@@ -338,7 +347,7 @@ def bishop88_i_from_v(voltage, photocurrent, saturation_current,
|
|
|
338
347
|
|
|
339
348
|
def bishop88_v_from_i(current, photocurrent, saturation_current,
|
|
340
349
|
resistance_series, resistance_shunt, nNsVth,
|
|
341
|
-
d2mutau=0, NsVbi=np.
|
|
350
|
+
d2mutau=0, NsVbi=np.inf, breakdown_factor=0.,
|
|
342
351
|
breakdown_voltage=-5.5, breakdown_exp=3.28,
|
|
343
352
|
method='newton', method_kwargs=None):
|
|
344
353
|
"""
|
|
@@ -417,6 +426,12 @@ def bishop88_v_from_i(current, photocurrent, saturation_current,
|
|
|
417
426
|
|
|
418
427
|
>>> v, method_output = bishop88_v_from_i(0.0, **args, method='newton',
|
|
419
428
|
... method_kwargs={'full_output': True})
|
|
429
|
+
|
|
430
|
+
References
|
|
431
|
+
----------
|
|
432
|
+
.. [1] "Computer simulation of the effects of electrical mismatches in
|
|
433
|
+
photovoltaic cell interconnection circuits" JW Bishop, Solar Cell (1988)
|
|
434
|
+
:doi:`10.1016/0379-6787(88)90059-2`
|
|
420
435
|
"""
|
|
421
436
|
# collect args
|
|
422
437
|
args = (photocurrent, saturation_current,
|
|
@@ -431,6 +446,9 @@ def bishop88_v_from_i(current, photocurrent, saturation_current,
|
|
|
431
446
|
|
|
432
447
|
# first bound the search using voc
|
|
433
448
|
voc_est = estimate_voc(photocurrent, saturation_current, nNsVth)
|
|
449
|
+
# start iteration slightly less than NsVbi when voc_est > NsVbi, to avoid
|
|
450
|
+
# the asymptote at NsVbi
|
|
451
|
+
xp = np.where(voc_est < NsVbi, voc_est, 0.9999*NsVbi)
|
|
434
452
|
|
|
435
453
|
def fi(x, i, *a):
|
|
436
454
|
# calculate current residual given diode voltage "x"
|
|
@@ -449,10 +467,10 @@ def bishop88_v_from_i(current, photocurrent, saturation_current,
|
|
|
449
467
|
**method_kwargs)
|
|
450
468
|
|
|
451
469
|
vd_from_brent_vectorized = np.vectorize(vd_from_brent)
|
|
452
|
-
vd = vd_from_brent_vectorized(
|
|
470
|
+
vd = vd_from_brent_vectorized(xp, current, *args)
|
|
453
471
|
elif method == 'newton':
|
|
454
472
|
x0, (current, *args), method_kwargs = \
|
|
455
|
-
_prepare_newton_inputs(
|
|
473
|
+
_prepare_newton_inputs(xp, (current, *args), method_kwargs)
|
|
456
474
|
vd = newton(func=lambda x, *a: fi(x, current, *a), x0=x0,
|
|
457
475
|
fprime=lambda x, *a: bishop88(x, *a, gradients=True)[3],
|
|
458
476
|
args=args, **method_kwargs)
|
|
@@ -469,7 +487,7 @@ def bishop88_v_from_i(current, photocurrent, saturation_current,
|
|
|
469
487
|
|
|
470
488
|
|
|
471
489
|
def bishop88_mpp(photocurrent, saturation_current, resistance_series,
|
|
472
|
-
resistance_shunt, nNsVth, d2mutau=0, NsVbi=np.
|
|
490
|
+
resistance_shunt, nNsVth, d2mutau=0, NsVbi=np.inf,
|
|
473
491
|
breakdown_factor=0., breakdown_voltage=-5.5,
|
|
474
492
|
breakdown_exp=3.28, method='newton', method_kwargs=None):
|
|
475
493
|
"""
|
|
@@ -547,6 +565,12 @@ def bishop88_mpp(photocurrent, saturation_current, resistance_series,
|
|
|
547
565
|
|
|
548
566
|
>>> (i_mp, v_mp, p_mp), method_output = bishop88_mpp(**args,
|
|
549
567
|
... method='newton', method_kwargs={'full_output': True})
|
|
568
|
+
|
|
569
|
+
References
|
|
570
|
+
----------
|
|
571
|
+
.. [1] "Computer simulation of the effects of electrical mismatches in
|
|
572
|
+
photovoltaic cell interconnection circuits" JW Bishop, Solar Cell (1988)
|
|
573
|
+
:doi:`10.1016/0379-6787(88)90059-2`
|
|
550
574
|
"""
|
|
551
575
|
# collect args
|
|
552
576
|
args = (photocurrent, saturation_current,
|
|
@@ -561,6 +585,9 @@ def bishop88_mpp(photocurrent, saturation_current, resistance_series,
|
|
|
561
585
|
|
|
562
586
|
# first bound the search using voc
|
|
563
587
|
voc_est = estimate_voc(photocurrent, saturation_current, nNsVth)
|
|
588
|
+
# start iteration slightly less than NsVbi when voc_est > NsVbi, to avoid
|
|
589
|
+
# the asymptote at NsVbi
|
|
590
|
+
xp = np.where(voc_est < NsVbi, voc_est, 0.9999*NsVbi)
|
|
564
591
|
|
|
565
592
|
def fmpp(x, *a):
|
|
566
593
|
return bishop88(x, *a, gradients=True)[6]
|
|
@@ -574,12 +601,13 @@ def bishop88_mpp(photocurrent, saturation_current, resistance_series,
|
|
|
574
601
|
vbr_a, vbr, vbr_exp),
|
|
575
602
|
**method_kwargs)
|
|
576
603
|
)
|
|
577
|
-
vd = vec_fun(
|
|
604
|
+
vd = vec_fun(xp, *args)
|
|
578
605
|
elif method == 'newton':
|
|
579
606
|
# make sure all args are numpy arrays if max size > 1
|
|
580
607
|
# if voc_est is an array, then make a copy to use for initial guess, v0
|
|
608
|
+
|
|
581
609
|
x0, args, method_kwargs = \
|
|
582
|
-
_prepare_newton_inputs(
|
|
610
|
+
_prepare_newton_inputs(xp, args, method_kwargs)
|
|
583
611
|
vd = newton(func=fmpp, x0=x0,
|
|
584
612
|
fprime=lambda x, *a: bishop88(x, *a, gradients=True)[7],
|
|
585
613
|
args=args, **method_kwargs)
|
pvlib/snow.py
CHANGED
|
@@ -222,7 +222,9 @@ def loss_townsend(snow_total, snow_events, surface_tilt, relative_humidity,
|
|
|
222
222
|
string_factor=1.0, angle_of_repose=40):
|
|
223
223
|
'''
|
|
224
224
|
Calculates monthly snow loss based on the Townsend monthly snow loss
|
|
225
|
-
model
|
|
225
|
+
model.
|
|
226
|
+
|
|
227
|
+
This model is described in [1]_.
|
|
226
228
|
|
|
227
229
|
Parameters
|
|
228
230
|
----------
|
pvlib/spectrum/mismatch.py
CHANGED
|
@@ -6,6 +6,7 @@ import pvlib
|
|
|
6
6
|
import numpy as np
|
|
7
7
|
import pandas as pd
|
|
8
8
|
from scipy.interpolate import interp1d
|
|
9
|
+
from scipy.integrate import trapezoid
|
|
9
10
|
import os
|
|
10
11
|
|
|
11
12
|
from warnings import warn
|
|
@@ -224,7 +225,7 @@ def calc_spectral_mismatch_field(sr, e_sun, e_ref=None):
|
|
|
224
225
|
|
|
225
226
|
# a helper function to make usable fraction calculations more readable
|
|
226
227
|
def integrate(e):
|
|
227
|
-
return
|
|
228
|
+
return trapezoid(e, x=e.T.index, axis=-1)
|
|
228
229
|
|
|
229
230
|
# calculate usable fractions
|
|
230
231
|
uf_sun = integrate(e_sun * sr_sun) / integrate(e_sun)
|
|
@@ -6,6 +6,7 @@ import pytest
|
|
|
6
6
|
from pvlib.bifacial import utils
|
|
7
7
|
from pvlib.shading import masking_angle, ground_angle
|
|
8
8
|
from pvlib.tools import cosd
|
|
9
|
+
from scipy.integrate import trapezoid
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
@pytest.fixture
|
|
@@ -99,7 +100,7 @@ def test_vf_ground_sky_2d_integ(test_system_fixed_tilt, vectorize):
|
|
|
99
100
|
vf_integ = utils.vf_ground_sky_2d_integ(
|
|
100
101
|
ts['rotation'], ts['gcr'], ts['height'], ts['pitch'],
|
|
101
102
|
max_rows=1, npoints=3, vectorize=vectorize)
|
|
102
|
-
expected_vf_integ =
|
|
103
|
+
expected_vf_integ = trapezoid(vfs_gnd_sky, pts, axis=0)
|
|
103
104
|
assert np.isclose(vf_integ, expected_vf_integ, rtol=0.1)
|
|
104
105
|
|
|
105
106
|
|
|
@@ -134,7 +135,7 @@ def test_vf_row_sky_2d_integ(test_system_fixed_tilt):
|
|
|
134
135
|
x = np.arange(fx0[1], fx1[1], 1e-4)
|
|
135
136
|
phi_y = masking_angle(ts['surface_tilt'], ts['gcr'], x)
|
|
136
137
|
y = 0.5 * (1 + cosd(ts['surface_tilt'] + phi_y))
|
|
137
|
-
y1 =
|
|
138
|
+
y1 = trapezoid(y, x) / (fx1[1] - fx0[1])
|
|
138
139
|
expected = np.array([y0, y1])
|
|
139
140
|
assert np.allclose(vf, expected, rtol=1e-3)
|
|
140
141
|
# with defaults (0, 1)
|
|
@@ -142,7 +143,7 @@ def test_vf_row_sky_2d_integ(test_system_fixed_tilt):
|
|
|
142
143
|
x = np.arange(0, 1, 1e-4)
|
|
143
144
|
phi_y = masking_angle(ts['surface_tilt'], ts['gcr'], x)
|
|
144
145
|
y = 0.5 * (1 + cosd(ts['surface_tilt'] + phi_y))
|
|
145
|
-
y1 =
|
|
146
|
+
y1 = trapezoid(y, x) / (1 - 0)
|
|
146
147
|
assert np.allclose(vf, y1, rtol=1e-3)
|
|
147
148
|
|
|
148
149
|
|
|
@@ -179,7 +180,7 @@ def test_vf_ground_2d_integ(test_system_fixed_tilt):
|
|
|
179
180
|
x = np.arange(fx0[1], fx1[1], 1e-4)
|
|
180
181
|
phi_y = ground_angle(ts['surface_tilt'], ts['gcr'], x)
|
|
181
182
|
y = 0.5 * (1 - cosd(phi_y - ts['surface_tilt']))
|
|
182
|
-
y1 =
|
|
183
|
+
y1 = trapezoid(y, x) / (fx1[1] - fx0[1])
|
|
183
184
|
expected = np.array([y0, y1])
|
|
184
185
|
assert np.allclose(vf, expected, rtol=1e-2)
|
|
185
186
|
# with defaults (0, 1)
|
|
@@ -187,5 +188,5 @@ def test_vf_ground_2d_integ(test_system_fixed_tilt):
|
|
|
187
188
|
x = np.arange(0, 1, 1e-4)
|
|
188
189
|
phi_y = ground_angle(ts['surface_tilt'], ts['gcr'], x)
|
|
189
190
|
y = 0.5 * (1 - cosd(phi_y - ts['surface_tilt']))
|
|
190
|
-
y1 =
|
|
191
|
+
y1 = trapezoid(y, x) / (1 - 0)
|
|
191
192
|
assert np.allclose(vf, y1, rtol=1e-2)
|
pvlib/tests/test_pvsystem.py
CHANGED
|
@@ -103,82 +103,57 @@ def test_PVSystem_get_iam_invalid(sapm_module_params, mocker):
|
|
|
103
103
|
system.get_iam(45, iam_model='not_a_model')
|
|
104
104
|
|
|
105
105
|
|
|
106
|
-
def
|
|
106
|
+
def test_retrieve_sam_raises_exceptions():
|
|
107
107
|
"""
|
|
108
|
-
Raise an exception if
|
|
108
|
+
Raise an exception if an invalid parameter is provided to `retrieve_sam()`.
|
|
109
109
|
"""
|
|
110
|
-
with pytest.raises(ValueError
|
|
110
|
+
with pytest.raises(ValueError, match="Please provide either"):
|
|
111
111
|
pvsystem.retrieve_sam()
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
'
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
'
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
'
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
'
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
112
|
+
with pytest.raises(ValueError, match="Please provide either.*, not both."):
|
|
113
|
+
pvsystem.retrieve_sam(name="this_surely_wont_work", path="wont_work")
|
|
114
|
+
with pytest.raises(KeyError, match="Invalid name"):
|
|
115
|
+
pvsystem.retrieve_sam(name="this_surely_wont_work")
|
|
116
|
+
with pytest.raises(FileNotFoundError):
|
|
117
|
+
pvsystem.retrieve_sam(path="this_surely_wont_work.csv")
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def test_retrieve_sam_databases():
|
|
121
|
+
"""Test the expected keys are retrieved from each database."""
|
|
122
|
+
keys_per_database = {
|
|
123
|
+
"cecmod": {'Technology', 'Bifacial', 'STC', 'PTC', 'A_c', 'Length',
|
|
124
|
+
'Width', 'N_s', 'I_sc_ref', 'V_oc_ref', 'I_mp_ref',
|
|
125
|
+
'V_mp_ref', 'alpha_sc', 'beta_oc', 'T_NOCT', 'a_ref',
|
|
126
|
+
'I_L_ref', 'I_o_ref', 'R_s', 'R_sh_ref', 'Adjust',
|
|
127
|
+
'gamma_r', 'BIPV', 'Version', 'Date'},
|
|
128
|
+
"sandiamod": {'Vintage', 'Area', 'Material', 'Cells_in_Series',
|
|
129
|
+
'Parallel_Strings', 'Isco', 'Voco', 'Impo', 'Vmpo',
|
|
130
|
+
'Aisc', 'Aimp', 'C0', 'C1', 'Bvoco', 'Mbvoc', 'Bvmpo',
|
|
131
|
+
'Mbvmp', 'N', 'C2', 'C3', 'A0', 'A1', 'A2', 'A3', 'A4',
|
|
132
|
+
'B0', 'B1', 'B2', 'B3', 'B4', 'B5', 'DTC', 'FD', 'A',
|
|
133
|
+
'B', 'C4', 'C5', 'IXO', 'IXXO', 'C6', 'C7', 'Notes'},
|
|
134
|
+
"adrinverter": {'Manufacturer', 'Model', 'Source', 'Vac', 'Vintage',
|
|
135
|
+
'Pacmax', 'Pnom', 'Vnom', 'Vmin', 'Vmax',
|
|
136
|
+
'ADRCoefficients', 'Pnt', 'Vdcmax', 'Idcmax',
|
|
137
|
+
'MPPTLow', 'MPPTHi', 'TambLow', 'TambHi', 'Weight',
|
|
138
|
+
'PacFitErrMax', 'YearOfData'},
|
|
139
|
+
"cecinverter": {'Vac', 'Paco', 'Pdco', 'Vdco', 'Pso', 'C0', 'C1', 'C2',
|
|
140
|
+
'C3', 'Pnt', 'Vdcmax', 'Idcmax', 'Mppt_low',
|
|
141
|
+
'Mppt_high', 'CEC_Date', 'CEC_Type'}
|
|
142
|
+
} # fmt: skip
|
|
143
|
+
item_per_database = {
|
|
144
|
+
"cecmod": "Itek_Energy_LLC_iT_300_HE",
|
|
145
|
+
"sandiamod": "Canadian_Solar_CS6X_300M__2013_",
|
|
146
|
+
"adrinverter": "Sainty_Solar__SSI_4K4U_240V__CEC_2011_",
|
|
147
|
+
"cecinverter": "ABB__PVI_3_0_OUTD_S_US__208V_",
|
|
148
|
+
}
|
|
149
|
+
# duplicate the cecinverter items for sandiainverter, for backwards compat
|
|
150
|
+
keys_per_database["sandiainverter"] = keys_per_database["cecinverter"]
|
|
151
|
+
item_per_database["sandiainverter"] = item_per_database["cecinverter"]
|
|
153
152
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
expected keys for that inverter.
|
|
159
|
-
"""
|
|
160
|
-
data = pvsystem.retrieve_sam('cecinverter')
|
|
161
|
-
keys = [
|
|
162
|
-
'Vac',
|
|
163
|
-
'Paco',
|
|
164
|
-
'Pdco',
|
|
165
|
-
'Vdco',
|
|
166
|
-
'Pso',
|
|
167
|
-
'C0',
|
|
168
|
-
'C1',
|
|
169
|
-
'C2',
|
|
170
|
-
'C3',
|
|
171
|
-
'Pnt',
|
|
172
|
-
'Vdcmax',
|
|
173
|
-
'Idcmax',
|
|
174
|
-
'Mppt_low',
|
|
175
|
-
'Mppt_high',
|
|
176
|
-
'CEC_Date',
|
|
177
|
-
'CEC_Type',
|
|
178
|
-
]
|
|
179
|
-
inverter = 'Yaskawa_Solectria_Solar__PVI_5300_208__208V_'
|
|
180
|
-
assert inverter in data
|
|
181
|
-
assert set(data[inverter].keys()) == set(keys)
|
|
153
|
+
for database in keys_per_database.keys():
|
|
154
|
+
data = pvsystem.retrieve_sam(database)
|
|
155
|
+
assert set(data.index) == keys_per_database[database]
|
|
156
|
+
assert item_per_database[database] in data.columns
|
|
182
157
|
|
|
183
158
|
|
|
184
159
|
def test_sapm(sapm_module_params):
|
|
@@ -191,16 +166,14 @@ def test_sapm(sapm_module_params):
|
|
|
191
166
|
out = pvsystem.sapm(effective_irradiance, temp_cell, sapm_module_params)
|
|
192
167
|
|
|
193
168
|
expected = pd.DataFrame(np.array(
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
[ nan, nan, nan, nan,
|
|
203
|
-
nan, nan, nan]]),
|
|
169
|
+
[[-5.0608322, -4.65037767, np.nan, np.nan, np.nan,
|
|
170
|
+
-4.91119927, -4.16721569],
|
|
171
|
+
[2.545575, 2.28773882, 56.86182059, 47.21121608, 108.00693168,
|
|
172
|
+
2.48357383, 1.71782772],
|
|
173
|
+
[5.65584763, 5.01709903, 54.1943277, 42.51861718, 213.32011294,
|
|
174
|
+
5.52987899, 3.46796463],
|
|
175
|
+
[np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
|
|
176
|
+
[np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan]]),
|
|
204
177
|
columns=['i_sc', 'i_mp', 'v_oc', 'v_mp', 'p_mp', 'i_x', 'i_xx'],
|
|
205
178
|
index=times)
|
|
206
179
|
|
|
@@ -209,13 +182,13 @@ def test_sapm(sapm_module_params):
|
|
|
209
182
|
out = pvsystem.sapm(1000, 25, sapm_module_params)
|
|
210
183
|
|
|
211
184
|
expected = OrderedDict()
|
|
212
|
-
expected['i_sc'] =
|
|
213
|
-
expected['i_mp'] =
|
|
214
|
-
expected['v_oc'] =
|
|
215
|
-
expected['v_mp'] =
|
|
216
|
-
expected['p_mp'] =
|
|
217
|
-
expected['i_x'] =
|
|
218
|
-
expected['i_xx'] =
|
|
185
|
+
expected['i_sc'] = sapm_module_params['Isco']
|
|
186
|
+
expected['i_mp'] = sapm_module_params['Impo']
|
|
187
|
+
expected['v_oc'] = sapm_module_params['Voco']
|
|
188
|
+
expected['v_mp'] = sapm_module_params['Vmpo']
|
|
189
|
+
expected['p_mp'] = sapm_module_params['Impo'] * sapm_module_params['Vmpo']
|
|
190
|
+
expected['i_x'] = sapm_module_params['IXO']
|
|
191
|
+
expected['i_xx'] = sapm_module_params['IXXO']
|
|
219
192
|
|
|
220
193
|
for k, v in expected.items():
|
|
221
194
|
assert_allclose(out[k], v, atol=1e-4)
|
pvlib/tests/test_singlediode.py
CHANGED
|
@@ -10,6 +10,7 @@ from pvlib.singlediode import (bishop88_mpp, estimate_voc, VOLTAGE_BUILTIN,
|
|
|
10
10
|
bishop88, bishop88_i_from_v, bishop88_v_from_i)
|
|
11
11
|
from pvlib._deprecation import pvlibDeprecationWarning
|
|
12
12
|
import pytest
|
|
13
|
+
from numpy.testing import assert_array_equal
|
|
13
14
|
from .conftest import DATA_DIR
|
|
14
15
|
|
|
15
16
|
POA = 888
|
|
@@ -167,17 +168,24 @@ def test_singlediode_precision(method, precise_iv_curves):
|
|
|
167
168
|
assert np.allclose(pc['i_xx'], outs['i_xx'], atol=1e-6, rtol=0)
|
|
168
169
|
|
|
169
170
|
|
|
170
|
-
def test_singlediode_lambert_negative_voc():
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
171
|
+
def test_singlediode_lambert_negative_voc(mocker):
|
|
172
|
+
"""Tests approximation to zero of v_oc when it is negative and small.
|
|
173
|
+
See singlediode.py:_lambertw > comment 'Set small elements <0 in v_oc to 0'
|
|
174
|
+
"""
|
|
175
|
+
# Next values should result in a negative v_oc out of `_lambertw_v_from_i`
|
|
176
|
+
# however, we can't ensure that the output belongs to (-1e-12, 0), so we
|
|
177
|
+
# mock it. It depends on the platform and Python distro. See issue #2000.
|
|
178
|
+
patcher = mocker.patch("pvlib.singlediode._lambertw_v_from_i")
|
|
179
|
+
x = np.array([0.0, 1.480501e-11, 0.178, 8000.0, 1.797559])
|
|
180
|
+
patcher.return_value = -9.999e-13
|
|
181
|
+
outs = pvsystem.singlediode(*x, method="lambertw")
|
|
182
|
+
assert outs["v_oc"] == 0
|
|
176
183
|
|
|
177
184
|
# Testing for an array
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
185
|
+
patcher.return_value = np.array([-9.999e-13, -1.001e-13])
|
|
186
|
+
x = np.array([x, x]).T
|
|
187
|
+
outs = pvsystem.singlediode(*x, method="lambertw")
|
|
188
|
+
assert_array_equal(outs["v_oc"], [0, 0])
|
|
181
189
|
|
|
182
190
|
|
|
183
191
|
@pytest.mark.parametrize('method', ['lambertw'])
|
|
@@ -347,7 +355,7 @@ def test_pvsyst_recombination_loss(method, poa, temp_cell, expected, tol):
|
|
|
347
355
|
# other conditions with breakdown model on and recombination model off
|
|
348
356
|
(
|
|
349
357
|
(1.e-4, -5.5, 3.28),
|
|
350
|
-
(0., np.
|
|
358
|
+
(0., np.inf),
|
|
351
359
|
POA,
|
|
352
360
|
TCELL,
|
|
353
361
|
{
|
|
@@ -567,3 +575,53 @@ def test_bishop88_pdSeries_len_one(method, bishop88_arguments):
|
|
|
567
575
|
bishop88_i_from_v(pd.Series([0]), **bishop88_arguments, method=method)
|
|
568
576
|
bishop88_v_from_i(pd.Series([0]), **bishop88_arguments, method=method)
|
|
569
577
|
bishop88_mpp(**bishop88_arguments, method=method)
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
def _sde_check_solution(i, v, il, io, rs, rsh, a, d2mutau=0., NsVbi=np.inf):
|
|
581
|
+
vd = v + rs * i
|
|
582
|
+
return il - io*np.expm1(vd/a) - vd/rsh - il*d2mutau/(NsVbi - vd) - i
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
@pytest.mark.parametrize('method', ['newton', 'brentq'])
|
|
586
|
+
def test_bishop88_init_cond(method):
|
|
587
|
+
# GH 2013
|
|
588
|
+
p = {'alpha_sc': 0.0012256,
|
|
589
|
+
'gamma_ref': 1.2916241612804187,
|
|
590
|
+
'mu_gamma': 0.00047308959960937403,
|
|
591
|
+
'I_L_ref': 3.068717040806731,
|
|
592
|
+
'I_o_ref': 2.2691248021217617e-11,
|
|
593
|
+
'R_sh_ref': 7000,
|
|
594
|
+
'R_sh_0': 7000,
|
|
595
|
+
'R_s': 4.602,
|
|
596
|
+
'cells_in_series': 268,
|
|
597
|
+
'R_sh_exp': 5.5,
|
|
598
|
+
'EgRef': 1.5}
|
|
599
|
+
NsVbi = 268 * 0.9
|
|
600
|
+
d2mutau = 1.4
|
|
601
|
+
irrad = np.arange(20, 1100, 20)
|
|
602
|
+
tc = np.arange(-25, 74, 1)
|
|
603
|
+
weather = np.array(np.meshgrid(irrad, tc)).T.reshape(-1, 2)
|
|
604
|
+
# with the above parameters and weather conditions, a few combinations
|
|
605
|
+
# result in voc_est > NsVbi, which causes failure of brentq and newton
|
|
606
|
+
# when the recombination parameters NsVbi and d2mutau are used.
|
|
607
|
+
sde_params = pvsystem.calcparams_pvsyst(weather[:, 0], weather[:, 1], **p)
|
|
608
|
+
# test _mpp
|
|
609
|
+
result = bishop88_mpp(*sde_params, d2mutau=d2mutau, NsVbi=NsVbi)
|
|
610
|
+
imp, vmp, pmp = result
|
|
611
|
+
err = np.abs(_sde_check_solution(
|
|
612
|
+
imp, vmp, sde_params[0], sde_params[1], sde_params[2], sde_params[3],
|
|
613
|
+
sde_params[4], d2mutau=d2mutau, NsVbi=NsVbi))
|
|
614
|
+
bad_results = np.isnan(pmp) | (pmp < 0) | (err > 0.00001) # 0.01mA error
|
|
615
|
+
assert not bad_results.any()
|
|
616
|
+
# test v_from_i
|
|
617
|
+
vmp2 = bishop88_v_from_i(imp, *sde_params, d2mutau=d2mutau, NsVbi=NsVbi)
|
|
618
|
+
err = np.abs(_sde_check_solution(imp, vmp2, *sde_params, d2mutau=d2mutau,
|
|
619
|
+
NsVbi=NsVbi))
|
|
620
|
+
bad_results = np.isnan(vmp2) | (vmp2 < 0) | (err > 0.00001)
|
|
621
|
+
assert not bad_results.any()
|
|
622
|
+
# test v_from_i
|
|
623
|
+
imp2 = bishop88_i_from_v(vmp, *sde_params, d2mutau=d2mutau, NsVbi=NsVbi)
|
|
624
|
+
err = np.abs(_sde_check_solution(imp2, vmp, *sde_params, d2mutau=d2mutau,
|
|
625
|
+
NsVbi=NsVbi))
|
|
626
|
+
bad_results = np.isnan(imp2) | (imp2 < 0) | (err > 0.00001)
|
|
627
|
+
assert not bad_results.any()
|
pvlib/version.py
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
from importlib.metadata import PackageNotFoundError, version
|
|
3
|
-
except ImportError:
|
|
4
|
-
# for python < 3.8
|
|
5
|
-
from importlib_metadata import PackageNotFoundError, version
|
|
1
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
6
2
|
|
|
7
3
|
try:
|
|
8
4
|
__version__ = version(__package__)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pvlib
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.5
|
|
4
4
|
Summary: A set of functions and classes for simulating the performance of photovoltaic energy systems.
|
|
5
5
|
Home-page: https://github.com/pvlib/pvlib-python
|
|
6
6
|
Author-email: pvlib python Developers <pvlib-admin@googlegroups.com>
|
|
@@ -15,7 +15,7 @@ Classifier: Intended Audience :: Science/Research
|
|
|
15
15
|
Classifier: Programming Language :: Python
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
17
|
Classifier: Topic :: Scientific/Engineering
|
|
18
|
-
Requires-Python: >=3.
|
|
18
|
+
Requires-Python: >=3.8
|
|
19
19
|
Description-Content-Type: text/x-rst
|
|
20
20
|
License-File: LICENSE
|
|
21
21
|
License-File: AUTHORS.md
|
|
@@ -23,9 +23,8 @@ Requires-Dist: numpy >=1.17.3
|
|
|
23
23
|
Requires-Dist: pandas >=1.3.0
|
|
24
24
|
Requires-Dist: pytz
|
|
25
25
|
Requires-Dist: requests
|
|
26
|
-
Requires-Dist: scipy >=1.
|
|
26
|
+
Requires-Dist: scipy >=1.6.0
|
|
27
27
|
Requires-Dist: h5py
|
|
28
|
-
Requires-Dist: importlib-metadata ; python_version < "3.8"
|
|
29
28
|
Provides-Extra: all
|
|
30
29
|
Requires-Dist: pvlib[doc,optional,test] ; extra == 'all'
|
|
31
30
|
Provides-Extra: doc
|
|
@@ -5,25 +5,25 @@ pvlib/clearsky.py,sha256=uB26zFv914f2BAWvo33sUESbNaWydaU28CfvyCyd0FY,38289
|
|
|
5
5
|
pvlib/iam.py,sha256=uYwdOaw5Brkl0d1WmueQG9XqL2eMJP_TZ2x7dQ5UxZo,44330
|
|
6
6
|
pvlib/inverter.py,sha256=ZpSv3cjt-Qm_JundL_jkvhCUd3iGjmlKcnNJeJqA2Qw,19127
|
|
7
7
|
pvlib/irradiance.py,sha256=HNZ5N71FGcz7-Y4bqZDt8SB-CGKy5E7uVs6vOlPMyew,141985
|
|
8
|
-
pvlib/location.py,sha256=
|
|
8
|
+
pvlib/location.py,sha256=cHdX6m3aAZAY96DXCC7W-W6ExisB2sidY4tEqBMELJk,15455
|
|
9
9
|
pvlib/modelchain.py,sha256=f-6mSWVqyjLNX6SW0fMx4zWwI4BMSwKXmxs1MAX0e04,79453
|
|
10
|
-
pvlib/pvarray.py,sha256=
|
|
11
|
-
pvlib/pvsystem.py,sha256=
|
|
12
|
-
pvlib/scaling.py,sha256=
|
|
10
|
+
pvlib/pvarray.py,sha256=r60sGTxFNlPiFQndusCJmlEIPX0dv9_7ozKw8zxh7IM,12677
|
|
11
|
+
pvlib/pvsystem.py,sha256=6jF0iXatWhVU_vVgcWhIFgKwqJ7sksCCx42spG2yXv8,109775
|
|
12
|
+
pvlib/scaling.py,sha256=SsQEmM4f4O1wC7e0amEV4SgaRTBX8nG5IiSV9Xs0i5o,10983
|
|
13
13
|
pvlib/shading.py,sha256=P6GmKxHXQGF0oCqDNN-2NjsvYHqpGG5GzRpepOAXhTk,12495
|
|
14
|
-
pvlib/singlediode.py,sha256=
|
|
15
|
-
pvlib/snow.py,sha256=
|
|
14
|
+
pvlib/singlediode.py,sha256=Bsr4YlTFBcR1kIIgMbL-QelO5YF-20c2kJjSyql2FYs,35399
|
|
15
|
+
pvlib/snow.py,sha256=LYFEpU5AnP82o6q5v6kQfgopkYtHO-aEyYFV9knpNvM,12764
|
|
16
16
|
pvlib/soiling.py,sha256=zDJ3N0uyeS1CoO0mxSdG16q2FCBLZSHbujJHgish54U,8799
|
|
17
17
|
pvlib/solarposition.py,sha256=FFafBzWYdLgNOsJiQY4l1LuqTn1-TYMvgoaLW2bQstI,50502
|
|
18
18
|
pvlib/spa.py,sha256=fTHdkU44M2d8hG9_i2MuBdDsqlgERBwVnsEMMPYLCuo,44802
|
|
19
19
|
pvlib/temperature.py,sha256=cNdbMx_x38XK5YwyxdWVBlnKkfXDBSjb9X_KTHY2hV8,55424
|
|
20
20
|
pvlib/tools.py,sha256=S3TswC_biexLSL8BlNdcLlWNVYSs7nG3EJhUEbHh59E,12650
|
|
21
21
|
pvlib/tracking.py,sha256=fwssoO_9vi5_aLBl59G0KE_EmsB3Jt0yIJlllFcpb5s,15802
|
|
22
|
-
pvlib/version.py,sha256=
|
|
22
|
+
pvlib/version.py,sha256=0CONzyOSN34Jgbaj9JzemFuaEnbRON_yxp-ah6_KxxQ,165
|
|
23
23
|
pvlib/bifacial/__init__.py,sha256=8uOiQ8cR0Wp62F-dLW25b1_xI3AxhwWlNagXqMyZUqA,412
|
|
24
24
|
pvlib/bifacial/infinite_sheds.py,sha256=rbiluCon6Tqpa_FizUfk5zBc6tH3ubk7xRqRAXp2Xq0,23051
|
|
25
25
|
pvlib/bifacial/pvfactors.py,sha256=QJXqjok4UcaUToNs6eR5ZDMsVf3HHT2AqW2u36hOOSI,5437
|
|
26
|
-
pvlib/bifacial/utils.py,sha256=
|
|
26
|
+
pvlib/bifacial/utils.py,sha256=Q2KSzn-vltO13QHYEfLVEWkTqed8Q8f_Eu4tlyrK2Ts,14542
|
|
27
27
|
pvlib/data/12839.tm2,sha256=6v86FhwMJeUJIEx8Mj9Rqp_OqmeaQ3rpObunQVaM6ss,1261501
|
|
28
28
|
pvlib/data/703165TY.csv,sha256=8DM6aKEW9a6S8ShaKrh4TY4A5So2dEVlisiNctk9jKQ,1760582
|
|
29
29
|
pvlib/data/723170TYA.CSV,sha256=Hpb4RjjOmOaykAK8RaJ6ppuymw7QNo07Urex-BYQxsk,1716576
|
|
@@ -106,8 +106,8 @@ pvlib/iotools/solaranywhere.py,sha256=_kDetQ0R8rQgcfTZjeQArq9nmCtVa4upF_KGrcipov
|
|
|
106
106
|
pvlib/iotools/solargis.py,sha256=6FeIsqs_bs2oNrUGvkv7Dc4AlIsDiwpCs5oFVcBheO8,8274
|
|
107
107
|
pvlib/iotools/solcast.py,sha256=d-2LAC-Tlazmih_QZKYbOKCyZaP7U08pIwoKTfciTCk,15332
|
|
108
108
|
pvlib/iotools/solrad.py,sha256=M8Xwasro6_hFiZP7hcsYSeEze3q5kNmnV0kAdNHqgBI,7177
|
|
109
|
-
pvlib/iotools/srml.py,sha256=
|
|
110
|
-
pvlib/iotools/surfrad.py,sha256=
|
|
109
|
+
pvlib/iotools/srml.py,sha256=XRbq1vf1D3XCl2vMC9YHeuYdoFsjYqcu-r4voIvsMiA,10838
|
|
110
|
+
pvlib/iotools/surfrad.py,sha256=WFh2__FGlOwHg6RTxIkcMmdMucX0vbQfHEz9q_HLGjY,7349
|
|
111
111
|
pvlib/iotools/tmy.py,sha256=-lxHnehZ2FnblM_28KYPG4FWd_rnDXIHv_dHJz092K0,30719
|
|
112
112
|
pvlib/ivtools/__init__.py,sha256=bnUDPqkzCP96CaFFK3Gw4HNczJoHtO-cI9GBGAtZVGI,159
|
|
113
113
|
pvlib/ivtools/sde.py,sha256=HL2oE70Ls7xccikyaUSi6SQKx3cWES5XoaMAGuMjPIw,17008
|
|
@@ -120,7 +120,7 @@ pvlib/spa_c_files/setup.py,sha256=RcMEf0R2wKHJjvpUH5y6h22m86y6UrdXwkPkHKNme48,11
|
|
|
120
120
|
pvlib/spa_c_files/spa_py.pyx,sha256=XMjlxfcSPM2nXTWVbyGme0HFBvPhOxRFuQEnbhQfT3Q,809
|
|
121
121
|
pvlib/spa_c_files/spa_py_example.py,sha256=p3ms0mhLycAuZJyaE3Wageqnd_56zh2EKxXK-jlTJfg,1179
|
|
122
122
|
pvlib/spectrum/__init__.py,sha256=Xtu6PejkWxUuJSkmXjdsAQJn1GUj4HmRGlOmGZbqUL8,286
|
|
123
|
-
pvlib/spectrum/mismatch.py,sha256=
|
|
123
|
+
pvlib/spectrum/mismatch.py,sha256=VvTv6iklE8eKTaZ3SMrrh8_JE7s8eBjFhPNy-uC40sM,22647
|
|
124
124
|
pvlib/spectrum/spectrl2.py,sha256=gJiHlJrmxHQkqWDVY2htU3hihFvt9JDvY3QZeL0FkyQ,18964
|
|
125
125
|
pvlib/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
126
126
|
pvlib/tests/conftest.py,sha256=gqTLfGacGrfSYhhRCRkfjXQgdr50KfuwliZWQvPQfNc,13217
|
|
@@ -134,10 +134,10 @@ pvlib/tests/test_location.py,sha256=UhGawiOEdXIcym_kVC8wbxZULuqU3MzZ3k_3Zgzkl9Y,
|
|
|
134
134
|
pvlib/tests/test_modelchain.py,sha256=vaCCtALPaB1FWtC9Iw3ty3vctqyAVvdxSkvIt6OFsH8,89421
|
|
135
135
|
pvlib/tests/test_numerical_precision.py,sha256=hu9ebaykI3WxZhE1SOzbw0zjjcYjg79-T5oGQlBNzXo,4331
|
|
136
136
|
pvlib/tests/test_pvarray.py,sha256=zAxaK-2jUPLRwgOlnPdpvgLeSHL7op_63XxSDzKup8s,2694
|
|
137
|
-
pvlib/tests/test_pvsystem.py,sha256=
|
|
137
|
+
pvlib/tests/test_pvsystem.py,sha256=eFlc0UeqwFu-Etf81kiohAUW5ZohKgyvgfenqCMb45o,99567
|
|
138
138
|
pvlib/tests/test_scaling.py,sha256=KlzMAiZcpWHLega4JJIBUy5PbzworWm9tqjLFaqoFcg,6832
|
|
139
139
|
pvlib/tests/test_shading.py,sha256=QH6wb0wAE3DGhaNUnhQLlknEmz_EL_tRTUe25yyPZ1Y,7846
|
|
140
|
-
pvlib/tests/test_singlediode.py,sha256=
|
|
140
|
+
pvlib/tests/test_singlediode.py,sha256=qnSRMO_iD6qz2mKQxX0hkqOKQSGrNo0hWdlWj9M58zo,25191
|
|
141
141
|
pvlib/tests/test_snow.py,sha256=YyPpF-_VwNadrsuUzv32UgRlzZHEDxSYpciLNga16P0,8590
|
|
142
142
|
pvlib/tests/test_soiling.py,sha256=QepAr_jVS24l07EUx8rrTjG67t7_vltJ1si_MlOXAGE,8183
|
|
143
143
|
pvlib/tests/test_solarposition.py,sha256=K4_EOZ4arSHRxbdiytjalANLQadASE4zFSpmTAr4QOg,41652
|
|
@@ -149,7 +149,7 @@ pvlib/tests/test_tracking.py,sha256=tqnVv3wGagJetly9qwJFstuMHAiakweTi31sR0VZbSU,
|
|
|
149
149
|
pvlib/tests/bifacial/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
150
150
|
pvlib/tests/bifacial/test_infinite_sheds.py,sha256=wYuJ8U7gEiG-lg0L3j2NaGOG6NhQWB2ZAUnrffH-n0Y,13549
|
|
151
151
|
pvlib/tests/bifacial/test_pvfactors.py,sha256=vocfxIsBAZwaEeRDfRAZmvemuYIRXI0UVbuKqUXRU6g,3144
|
|
152
|
-
pvlib/tests/bifacial/test_utils.py,sha256=
|
|
152
|
+
pvlib/tests/bifacial/test_utils.py,sha256=c6Q9H_3pocHDNokxq26HCPiyoNvZGS1h9FmSLrWPPh4,8346
|
|
153
153
|
pvlib/tests/iotools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
154
154
|
pvlib/tests/iotools/test_acis.py,sha256=Ya1CzAcQDzUWFaVZduiE_rGfx7RBbQtxajW4ekfWIWE,8440
|
|
155
155
|
pvlib/tests/iotools/test_bsrn.py,sha256=7DHT6CcEGWZ_qNsLXDSSF_Rk6hpa1zqgNnvpnK_T8_k,4781
|
|
@@ -171,9 +171,9 @@ pvlib/tests/ivtools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
|
|
|
171
171
|
pvlib/tests/ivtools/test_sde.py,sha256=dBJkk9tWskwc6Iyoziar9MoZESrOSkepOk51g5QOy1I,13844
|
|
172
172
|
pvlib/tests/ivtools/test_sdm.py,sha256=5ioqsEJJE-JCSCGRLXj1zCuJzGIPNY622GyflJMU_MM,16406
|
|
173
173
|
pvlib/tests/ivtools/test_utils.py,sha256=-BPEUgB5aCkJOv-apRkjeg0IraZ1Ebf5SmObk4Zusz4,6905
|
|
174
|
-
pvlib-0.10.
|
|
175
|
-
pvlib-0.10.
|
|
176
|
-
pvlib-0.10.
|
|
177
|
-
pvlib-0.10.
|
|
178
|
-
pvlib-0.10.
|
|
179
|
-
pvlib-0.10.
|
|
174
|
+
pvlib-0.10.5.dist-info/AUTHORS.md,sha256=Fxk4p_lXlMeQ6g2A1-7oPrgpULDxuJuC9Ebc-3yyj_o,1474
|
|
175
|
+
pvlib-0.10.5.dist-info/LICENSE,sha256=oC4S3araPPDV292K_91XfC7sZAdYqVhCowT3UTuMC-Q,1622
|
|
176
|
+
pvlib-0.10.5.dist-info/METADATA,sha256=cimQNDgoZe_S2_jiDXi0v2UfEVboTEyLIFY-EVqzaQU,2785
|
|
177
|
+
pvlib-0.10.5.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
178
|
+
pvlib-0.10.5.dist-info/top_level.txt,sha256=eq9CH6YXUc3Fh3dyQ5hQXoGYfSm1SYEAlMygyR22MgE,6
|
|
179
|
+
pvlib-0.10.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|