pvlib 0.9.4a1__py3-none-any.whl → 0.10.0__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/__init__.py +3 -2
- pvlib/atmosphere.py +23 -173
- pvlib/bifacial/infinite_sheds.py +88 -277
- pvlib/bifacial/utils.py +270 -28
- pvlib/data/adr-library-cec-inverters-2019-03-05.csv +5009 -0
- pvlib/data/precise_iv_curves1.json +10251 -0
- pvlib/data/precise_iv_curves2.json +10251 -0
- pvlib/data/precise_iv_curves_parameter_sets1.csv +33 -0
- pvlib/data/precise_iv_curves_parameter_sets2.csv +33 -0
- pvlib/data/test_psm3_2017.csv +17521 -17521
- pvlib/data/test_psm3_2019_5min.csv +288 -288
- pvlib/data/test_read_psm3.csv +17522 -17522
- pvlib/data/test_read_pvgis_horizon.csv +49 -0
- pvlib/data/variables_style_rules.csv +3 -0
- pvlib/iam.py +207 -51
- pvlib/inverter.py +6 -1
- pvlib/iotools/__init__.py +7 -2
- pvlib/iotools/acis.py +516 -0
- pvlib/iotools/midc.py +4 -4
- pvlib/iotools/psm3.py +59 -42
- pvlib/iotools/pvgis.py +84 -28
- pvlib/iotools/sodapro.py +8 -6
- pvlib/iotools/srml.py +121 -18
- pvlib/iotools/surfrad.py +2 -2
- pvlib/iotools/tmy.py +146 -102
- pvlib/irradiance.py +270 -15
- pvlib/ivtools/sde.py +14 -20
- pvlib/ivtools/sdm.py +31 -20
- pvlib/ivtools/utils.py +127 -6
- pvlib/location.py +3 -2
- pvlib/modelchain.py +67 -70
- pvlib/pvarray.py +225 -0
- pvlib/pvsystem.py +169 -539
- pvlib/shading.py +43 -2
- pvlib/singlediode.py +216 -66
- pvlib/snow.py +36 -15
- pvlib/soiling.py +3 -3
- pvlib/spa.py +327 -368
- pvlib/spectrum/__init__.py +8 -2
- pvlib/spectrum/mismatch.py +335 -0
- pvlib/temperature.py +124 -13
- pvlib/tests/bifacial/test_infinite_sheds.py +44 -106
- pvlib/tests/bifacial/test_utils.py +102 -5
- pvlib/tests/conftest.py +0 -31
- pvlib/tests/iotools/test_acis.py +213 -0
- pvlib/tests/iotools/test_midc.py +6 -6
- pvlib/tests/iotools/test_psm3.py +7 -5
- pvlib/tests/iotools/test_pvgis.py +21 -14
- pvlib/tests/iotools/test_sodapro.py +1 -1
- pvlib/tests/iotools/test_srml.py +71 -6
- pvlib/tests/iotools/test_tmy.py +43 -8
- pvlib/tests/ivtools/test_sde.py +19 -17
- pvlib/tests/ivtools/test_sdm.py +9 -4
- pvlib/tests/ivtools/test_utils.py +96 -1
- pvlib/tests/test_atmosphere.py +8 -64
- pvlib/tests/test_clearsky.py +0 -1
- pvlib/tests/test_iam.py +74 -1
- pvlib/tests/test_irradiance.py +56 -2
- pvlib/tests/test_location.py +1 -1
- pvlib/tests/test_modelchain.py +33 -76
- pvlib/tests/test_pvarray.py +46 -0
- pvlib/tests/test_pvsystem.py +366 -201
- pvlib/tests/test_shading.py +35 -0
- pvlib/tests/test_singlediode.py +306 -29
- pvlib/tests/test_snow.py +84 -1
- pvlib/tests/test_soiling.py +8 -7
- pvlib/tests/test_solarposition.py +7 -7
- pvlib/tests/test_spa.py +6 -7
- pvlib/tests/test_spectrum.py +145 -1
- pvlib/tests/test_temperature.py +29 -11
- pvlib/tests/test_tools.py +41 -0
- pvlib/tests/test_tracking.py +0 -149
- pvlib/tools.py +49 -25
- pvlib/tracking.py +1 -269
- pvlib-0.10.0.dist-info/AUTHORS.md +35 -0
- {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/LICENSE +5 -2
- {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/METADATA +3 -13
- {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/RECORD +80 -75
- {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/WHEEL +1 -1
- pvlib/data/adr-library-2013-10-01.csv +0 -1762
- pvlib/forecast.py +0 -1211
- pvlib/iotools/ecmwf_macc.py +0 -312
- pvlib/tests/iotools/test_ecmwf_macc.py +0 -162
- pvlib/tests/test_forecast.py +0 -228
- pvlib-0.9.4a1.dist-info/AUTHORS.md +0 -32
- {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/top_level.txt +0 -0
pvlib/spectrum/__init__.py
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
from pvlib.spectrum.spectrl2 import spectrl2 # noqa: F401
|
|
2
|
-
from pvlib.spectrum.mismatch import (
|
|
3
|
-
|
|
2
|
+
from pvlib.spectrum.mismatch import ( # noqa: F401
|
|
3
|
+
calc_spectral_mismatch_field,
|
|
4
|
+
get_am15g,
|
|
5
|
+
get_example_spectral_response,
|
|
6
|
+
spectral_factor_caballero,
|
|
7
|
+
spectral_factor_firstsolar,
|
|
8
|
+
spectral_factor_sapm,
|
|
9
|
+
)
|
pvlib/spectrum/mismatch.py
CHANGED
|
@@ -8,6 +8,8 @@ import pandas as pd
|
|
|
8
8
|
from scipy.interpolate import interp1d
|
|
9
9
|
import os
|
|
10
10
|
|
|
11
|
+
from warnings import warn
|
|
12
|
+
|
|
11
13
|
|
|
12
14
|
def get_example_spectral_response(wavelength=None):
|
|
13
15
|
'''
|
|
@@ -235,3 +237,336 @@ def calc_spectral_mismatch_field(sr, e_sun, e_ref=None):
|
|
|
235
237
|
smm = pd.Series(smm, index=e_sun.index)
|
|
236
238
|
|
|
237
239
|
return smm
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def spectral_factor_firstsolar(precipitable_water, airmass_absolute,
|
|
243
|
+
module_type=None, coefficients=None,
|
|
244
|
+
min_precipitable_water=0.1,
|
|
245
|
+
max_precipitable_water=8):
|
|
246
|
+
r"""
|
|
247
|
+
Spectral mismatch modifier based on precipitable water and absolute
|
|
248
|
+
(pressure-adjusted) airmass.
|
|
249
|
+
|
|
250
|
+
Estimates a spectral mismatch modifier :math:`M` representing the effect on
|
|
251
|
+
module short circuit current of variation in the spectral
|
|
252
|
+
irradiance. :math:`M` is estimated from absolute (pressure currected) air
|
|
253
|
+
mass, :math:`AM_a`, and precipitable water, :math:`Pw`, using the following
|
|
254
|
+
function:
|
|
255
|
+
|
|
256
|
+
.. math::
|
|
257
|
+
|
|
258
|
+
M = c_1 + c_2 AM_a + c_3 Pw + c_4 AM_a^{0.5}
|
|
259
|
+
+ c_5 Pw^{0.5} + c_6 \frac{AM_a} {Pw^{0.5}}
|
|
260
|
+
|
|
261
|
+
Default coefficients are determined for several cell types with
|
|
262
|
+
known quantum efficiency curves, by using the Simple Model of the
|
|
263
|
+
Atmospheric Radiative Transfer of Sunshine (SMARTS) [1]_. Using
|
|
264
|
+
SMARTS, spectrums are simulated with all combinations of AMa and
|
|
265
|
+
Pw where:
|
|
266
|
+
|
|
267
|
+
* :math:`0.5 \textrm{cm} <= Pw <= 5 \textrm{cm}`
|
|
268
|
+
* :math:`1.0 <= AM_a <= 5.0`
|
|
269
|
+
* Spectral range is limited to that of CMP11 (280 nm to 2800 nm)
|
|
270
|
+
* spectrum simulated on a plane normal to the sun
|
|
271
|
+
* All other parameters fixed at G173 standard
|
|
272
|
+
|
|
273
|
+
From these simulated spectra, M is calculated using the known
|
|
274
|
+
quantum efficiency curves. Multiple linear regression is then
|
|
275
|
+
applied to fit Eq. 1 to determine the coefficients for each module.
|
|
276
|
+
|
|
277
|
+
Based on the PVLIB Matlab function ``pvl_FSspeccorr`` by Mitchell
|
|
278
|
+
Lee and Alex Panchula of First Solar, 2016 [2]_.
|
|
279
|
+
|
|
280
|
+
Parameters
|
|
281
|
+
----------
|
|
282
|
+
precipitable_water : numeric
|
|
283
|
+
atmospheric precipitable water. [cm]
|
|
284
|
+
|
|
285
|
+
airmass_absolute : numeric
|
|
286
|
+
absolute (pressure-adjusted) airmass. [unitless]
|
|
287
|
+
|
|
288
|
+
module_type : str, optional
|
|
289
|
+
a string specifying a cell type. Values of 'cdte', 'monosi', 'xsi',
|
|
290
|
+
'multisi', and 'polysi' (can be lower or upper case). If provided,
|
|
291
|
+
module_type selects default coefficients for the following modules:
|
|
292
|
+
|
|
293
|
+
* 'cdte' - First Solar Series 4-2 CdTe module.
|
|
294
|
+
* 'monosi', 'xsi' - First Solar TetraSun module.
|
|
295
|
+
* 'multisi', 'polysi' - anonymous multi-crystalline silicon module.
|
|
296
|
+
* 'cigs' - anonymous copper indium gallium selenide module.
|
|
297
|
+
* 'asi' - anonymous amorphous silicon module.
|
|
298
|
+
|
|
299
|
+
The module used to calculate the spectral correction
|
|
300
|
+
coefficients corresponds to the Multi-crystalline silicon
|
|
301
|
+
Manufacturer 2 Model C from [3]_. The spectral response (SR) of CIGS
|
|
302
|
+
and a-Si modules used to derive coefficients can be found in [4]_
|
|
303
|
+
|
|
304
|
+
coefficients : array-like, optional
|
|
305
|
+
Allows for entry of user-defined spectral correction
|
|
306
|
+
coefficients. Coefficients must be of length 6. Derivation of
|
|
307
|
+
coefficients requires use of SMARTS and PV module quantum
|
|
308
|
+
efficiency curve. Useful for modeling PV module types which are
|
|
309
|
+
not included as defaults, or to fine tune the spectral
|
|
310
|
+
correction to a particular PV module. Note that the parameters for
|
|
311
|
+
modules with very similar quantum efficiency should be similar,
|
|
312
|
+
in most cases limiting the need for module specific coefficients.
|
|
313
|
+
|
|
314
|
+
min_precipitable_water : float, default 0.1
|
|
315
|
+
minimum atmospheric precipitable water. Any ``precipitable_water``
|
|
316
|
+
value lower than ``min_precipitable_water``
|
|
317
|
+
is set to ``min_precipitable_water`` to avoid model divergence. [cm]
|
|
318
|
+
|
|
319
|
+
max_precipitable_water : float, default 8
|
|
320
|
+
maximum atmospheric precipitable water. Any ``precipitable_water``
|
|
321
|
+
value greater than ``max_precipitable_water``
|
|
322
|
+
is set to ``np.nan`` to avoid model divergence. [cm]
|
|
323
|
+
|
|
324
|
+
Returns
|
|
325
|
+
-------
|
|
326
|
+
modifier: array-like
|
|
327
|
+
spectral mismatch factor (unitless) which can be multiplied
|
|
328
|
+
with broadband irradiance reaching a module's cells to estimate
|
|
329
|
+
effective irradiance, i.e., the irradiance that is converted to
|
|
330
|
+
electrical current.
|
|
331
|
+
|
|
332
|
+
References
|
|
333
|
+
----------
|
|
334
|
+
.. [1] Gueymard, Christian. SMARTS2: a simple model of the atmospheric
|
|
335
|
+
radiative transfer of sunshine: algorithms and performance
|
|
336
|
+
assessment. Cocoa, FL: Florida Solar Energy Center, 1995.
|
|
337
|
+
.. [2] Lee, Mitchell, and Panchula, Alex. "Spectral Correction for
|
|
338
|
+
Photovoltaic Module Performance Based on Air Mass and Precipitable
|
|
339
|
+
Water." IEEE Photovoltaic Specialists Conference, Portland, 2016
|
|
340
|
+
.. [3] Marion, William F., et al. User's Manual for Data for Validating
|
|
341
|
+
Models for PV Module Performance. National Renewable Energy
|
|
342
|
+
Laboratory, 2014. http://www.nrel.gov/docs/fy14osti/61610.pdf
|
|
343
|
+
.. [4] Schweiger, M. and Hermann, W, Influence of Spectral Effects
|
|
344
|
+
on Energy Yield of Different PV Modules: Comparison of Pwat and
|
|
345
|
+
MMF Approach, TUV Rheinland Energy GmbH report 21237296.003,
|
|
346
|
+
January 2017
|
|
347
|
+
"""
|
|
348
|
+
|
|
349
|
+
# --- Screen Input Data ---
|
|
350
|
+
|
|
351
|
+
# *** Pw ***
|
|
352
|
+
# Replace Pw Values below 0.1 cm with 0.1 cm to prevent model from
|
|
353
|
+
# diverging"
|
|
354
|
+
pw = np.atleast_1d(precipitable_water)
|
|
355
|
+
pw = pw.astype('float64')
|
|
356
|
+
if np.min(pw) < min_precipitable_water:
|
|
357
|
+
pw = np.maximum(pw, min_precipitable_water)
|
|
358
|
+
warn('Exceptionally low pw values replaced with '
|
|
359
|
+
f'{min_precipitable_water} cm to prevent model divergence')
|
|
360
|
+
|
|
361
|
+
# Warn user about Pw data that is exceptionally high
|
|
362
|
+
if np.max(pw) > max_precipitable_water:
|
|
363
|
+
pw[pw > max_precipitable_water] = np.nan
|
|
364
|
+
warn('Exceptionally high pw values replaced by np.nan: '
|
|
365
|
+
'check input data.')
|
|
366
|
+
|
|
367
|
+
# *** AMa ***
|
|
368
|
+
# Replace Extremely High AM with AM 10 to prevent model divergence
|
|
369
|
+
# AM > 10 will only occur very close to sunset
|
|
370
|
+
if np.max(airmass_absolute) > 10:
|
|
371
|
+
airmass_absolute = np.minimum(airmass_absolute, 10)
|
|
372
|
+
|
|
373
|
+
# Warn user about AMa data that is exceptionally low
|
|
374
|
+
if np.min(airmass_absolute) < 0.58:
|
|
375
|
+
warn('Exceptionally low air mass: ' +
|
|
376
|
+
'model not intended for extra-terrestrial use')
|
|
377
|
+
# pvl_absoluteairmass(1,pvl_alt2pres(4340)) = 0.58 Elevation of
|
|
378
|
+
# Mina Pirquita, Argentian = 4340 m. Highest elevation city with
|
|
379
|
+
# population over 50,000.
|
|
380
|
+
|
|
381
|
+
_coefficients = {}
|
|
382
|
+
_coefficients['cdte'] = (
|
|
383
|
+
0.86273, -0.038948, -0.012506, 0.098871, 0.084658, -0.0042948)
|
|
384
|
+
_coefficients['monosi'] = (
|
|
385
|
+
0.85914, -0.020880, -0.0058853, 0.12029, 0.026814, -0.0017810)
|
|
386
|
+
_coefficients['xsi'] = _coefficients['monosi']
|
|
387
|
+
_coefficients['polysi'] = (
|
|
388
|
+
0.84090, -0.027539, -0.0079224, 0.13570, 0.038024, -0.0021218)
|
|
389
|
+
_coefficients['multisi'] = _coefficients['polysi']
|
|
390
|
+
_coefficients['cigs'] = (
|
|
391
|
+
0.85252, -0.022314, -0.0047216, 0.13666, 0.013342, -0.0008945)
|
|
392
|
+
_coefficients['asi'] = (
|
|
393
|
+
1.12094, -0.047620, -0.0083627, -0.10443, 0.098382, -0.0033818)
|
|
394
|
+
|
|
395
|
+
if module_type is not None and coefficients is None:
|
|
396
|
+
coefficients = _coefficients[module_type.lower()]
|
|
397
|
+
elif module_type is None and coefficients is not None:
|
|
398
|
+
pass
|
|
399
|
+
elif module_type is None and coefficients is None:
|
|
400
|
+
raise TypeError('No valid input provided, both module_type and ' +
|
|
401
|
+
'coefficients are None')
|
|
402
|
+
else:
|
|
403
|
+
raise TypeError('Cannot resolve input, must supply only one of ' +
|
|
404
|
+
'module_type and coefficients')
|
|
405
|
+
|
|
406
|
+
# Evaluate Spectral Shift
|
|
407
|
+
coeff = coefficients
|
|
408
|
+
ama = airmass_absolute
|
|
409
|
+
modifier = (
|
|
410
|
+
coeff[0] + coeff[1]*ama + coeff[2]*pw + coeff[3]*np.sqrt(ama) +
|
|
411
|
+
coeff[4]*np.sqrt(pw) + coeff[5]*ama/np.sqrt(pw))
|
|
412
|
+
|
|
413
|
+
return modifier
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
def spectral_factor_sapm(airmass_absolute, module):
|
|
417
|
+
"""
|
|
418
|
+
Calculates the SAPM spectral loss coefficient, F1.
|
|
419
|
+
|
|
420
|
+
Parameters
|
|
421
|
+
----------
|
|
422
|
+
airmass_absolute : numeric
|
|
423
|
+
Absolute airmass
|
|
424
|
+
|
|
425
|
+
module : dict-like
|
|
426
|
+
A dict, Series, or DataFrame defining the SAPM performance
|
|
427
|
+
parameters. See the :py:func:`sapm` notes section for more
|
|
428
|
+
details.
|
|
429
|
+
|
|
430
|
+
Returns
|
|
431
|
+
-------
|
|
432
|
+
F1 : numeric
|
|
433
|
+
The SAPM spectral loss coefficient.
|
|
434
|
+
|
|
435
|
+
Notes
|
|
436
|
+
-----
|
|
437
|
+
nan airmass values will result in 0 output.
|
|
438
|
+
"""
|
|
439
|
+
|
|
440
|
+
am_coeff = [module['A4'], module['A3'], module['A2'], module['A1'],
|
|
441
|
+
module['A0']]
|
|
442
|
+
|
|
443
|
+
spectral_loss = np.polyval(am_coeff, airmass_absolute)
|
|
444
|
+
|
|
445
|
+
spectral_loss = np.where(np.isnan(spectral_loss), 0, spectral_loss)
|
|
446
|
+
|
|
447
|
+
spectral_loss = np.maximum(0, spectral_loss)
|
|
448
|
+
|
|
449
|
+
if isinstance(airmass_absolute, pd.Series):
|
|
450
|
+
spectral_loss = pd.Series(spectral_loss, airmass_absolute.index)
|
|
451
|
+
|
|
452
|
+
return spectral_loss
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
def spectral_factor_caballero(precipitable_water, airmass_absolute, aod500,
|
|
456
|
+
module_type=None, coefficients=None):
|
|
457
|
+
r"""
|
|
458
|
+
Estimate a technology-specific spectral mismatch modifier from
|
|
459
|
+
airmass, aerosol optical depth, and atmospheric precipitable water,
|
|
460
|
+
using the Caballero model.
|
|
461
|
+
|
|
462
|
+
The model structure was motivated by examining the effect of these three
|
|
463
|
+
atmospheric parameters on simulated irradiance spectra and spectral
|
|
464
|
+
modifiers. However, the coefficient values reported in [1]_ and
|
|
465
|
+
available here via the ``module_type`` parameter were determined
|
|
466
|
+
by fitting the model equations to spectral factors calculated from
|
|
467
|
+
global tilted spectral irradiance measurements taken in the city of
|
|
468
|
+
Jaén, Spain. See [1]_ for details.
|
|
469
|
+
|
|
470
|
+
Parameters
|
|
471
|
+
----------
|
|
472
|
+
precipitable_water : numeric
|
|
473
|
+
atmospheric precipitable water. [cm]
|
|
474
|
+
|
|
475
|
+
airmass_absolute : numeric
|
|
476
|
+
absolute (pressure-adjusted) airmass. [unitless]
|
|
477
|
+
|
|
478
|
+
aod500 : numeric
|
|
479
|
+
atmospheric aerosol optical depth at 500 nm. [unitless]
|
|
480
|
+
|
|
481
|
+
module_type : str, optional
|
|
482
|
+
One of the following PV technology strings from [1]_:
|
|
483
|
+
|
|
484
|
+
* ``'cdte'`` - anonymous CdTe module.
|
|
485
|
+
* ``'monosi'``, - anonymous sc-si module.
|
|
486
|
+
* ``'multisi'``, - anonymous mc-si- module.
|
|
487
|
+
* ``'cigs'`` - anonymous copper indium gallium selenide module.
|
|
488
|
+
* ``'asi'`` - anonymous amorphous silicon module.
|
|
489
|
+
* ``'perovskite'`` - anonymous pervoskite module.
|
|
490
|
+
|
|
491
|
+
coefficients : array-like, optional
|
|
492
|
+
user-defined coefficients, if not using one of the default coefficient
|
|
493
|
+
sets via the ``module_type`` parameter.
|
|
494
|
+
|
|
495
|
+
Returns
|
|
496
|
+
-------
|
|
497
|
+
modifier: numeric
|
|
498
|
+
spectral mismatch factor (unitless) which is multiplied
|
|
499
|
+
with broadband irradiance reaching a module's cells to estimate
|
|
500
|
+
effective irradiance, i.e., the irradiance that is converted to
|
|
501
|
+
electrical current.
|
|
502
|
+
|
|
503
|
+
References
|
|
504
|
+
----------
|
|
505
|
+
.. [1] Caballero, J.A., Fernández, E., Theristis, M.,
|
|
506
|
+
Almonacid, F., and Nofuentes, G. "Spectral Corrections Based on
|
|
507
|
+
Air Mass, Aerosol Optical Depth and Precipitable Water
|
|
508
|
+
for PV Performance Modeling."
|
|
509
|
+
IEEE Journal of Photovoltaics 2018, 8(2), 552-558.
|
|
510
|
+
:doi:`10.1109/jphotov.2017.2787019`
|
|
511
|
+
"""
|
|
512
|
+
|
|
513
|
+
if module_type is None and coefficients is None:
|
|
514
|
+
raise ValueError('Must provide either `module_type` or `coefficients`')
|
|
515
|
+
if module_type is not None and coefficients is not None:
|
|
516
|
+
raise ValueError('Only one of `module_type` and `coefficients` should '
|
|
517
|
+
'be provided')
|
|
518
|
+
|
|
519
|
+
# Experimental coefficients from [1]_.
|
|
520
|
+
# The extra 0/1 coefficients at the end are used to enable/disable
|
|
521
|
+
# terms to match the different equation forms in Table 1.
|
|
522
|
+
_coefficients = {}
|
|
523
|
+
_coefficients['cdte'] = (
|
|
524
|
+
1.0044, 0.0095, -0.0037, 0.0002, 0.0000, -0.0046,
|
|
525
|
+
-0.0182, 0, 0.0095, 0.0068, 0, 1)
|
|
526
|
+
_coefficients['monosi'] = (
|
|
527
|
+
0.9706, 0.0377, -0.0123, 0.0025, -0.0002, 0.0159,
|
|
528
|
+
-0.0165, 0, -0.0016, -0.0027, 1, 0)
|
|
529
|
+
_coefficients['multisi'] = (
|
|
530
|
+
0.9836, 0.0254, -0.0085, 0.0016, -0.0001, 0.0094,
|
|
531
|
+
-0.0132, 0, -0.0002, -0.0011, 1, 0)
|
|
532
|
+
_coefficients['cigs'] = (
|
|
533
|
+
0.9801, 0.0283, -0.0092, 0.0019, -0.0001, 0.0117,
|
|
534
|
+
-0.0126, 0, -0.0011, -0.0019, 1, 0)
|
|
535
|
+
_coefficients['asi'] = (
|
|
536
|
+
1.1060, -0.0848, 0.0302, -0.0076, 0.0006, -0.1283,
|
|
537
|
+
0.0986, -0.0254, 0.0156, 0.0146, 1, 0)
|
|
538
|
+
_coefficients['perovskite'] = (
|
|
539
|
+
1.0637, -0.0491, 0.0180, -0.0047, 0.0004, -0.0773,
|
|
540
|
+
0.0583, -0.0159, 0.01251, 0.0109, 1, 0)
|
|
541
|
+
|
|
542
|
+
if module_type is not None:
|
|
543
|
+
coeff = _coefficients[module_type]
|
|
544
|
+
else:
|
|
545
|
+
coeff = coefficients
|
|
546
|
+
|
|
547
|
+
# Evaluate spectral correction factor
|
|
548
|
+
ama = airmass_absolute
|
|
549
|
+
aod500_ref = 0.084
|
|
550
|
+
pw_ref = 1.4164
|
|
551
|
+
|
|
552
|
+
f_AM = (
|
|
553
|
+
coeff[0]
|
|
554
|
+
+ coeff[1] * ama
|
|
555
|
+
+ coeff[2] * ama**2
|
|
556
|
+
+ coeff[3] * ama**3
|
|
557
|
+
+ coeff[4] * ama**4
|
|
558
|
+
)
|
|
559
|
+
# Eq 6, with Table 1
|
|
560
|
+
f_AOD = (aod500 - aod500_ref) * (
|
|
561
|
+
coeff[5]
|
|
562
|
+
+ coeff[10] * coeff[6] * ama
|
|
563
|
+
+ coeff[11] * coeff[6] * np.log(ama)
|
|
564
|
+
+ coeff[7] * ama**2
|
|
565
|
+
)
|
|
566
|
+
# Eq 7, with Table 1
|
|
567
|
+
f_PW = (precipitable_water - pw_ref) * (
|
|
568
|
+
coeff[8]
|
|
569
|
+
+ coeff[9] * np.log(ama)
|
|
570
|
+
)
|
|
571
|
+
modifier = f_AM + f_AOD + f_PW # Eq 5
|
|
572
|
+
return modifier
|
pvlib/temperature.py
CHANGED
|
@@ -9,6 +9,7 @@ from pvlib.tools import sind
|
|
|
9
9
|
from pvlib._deprecation import warn_deprecated
|
|
10
10
|
from pvlib.tools import _get_sample_intervals
|
|
11
11
|
import scipy
|
|
12
|
+
import scipy.constants
|
|
12
13
|
import warnings
|
|
13
14
|
|
|
14
15
|
|
|
@@ -290,7 +291,7 @@ def sapm_cell_from_module(module_temperature, poa_global, deltaT,
|
|
|
290
291
|
|
|
291
292
|
|
|
292
293
|
def pvsyst_cell(poa_global, temp_air, wind_speed=1.0, u_c=29.0, u_v=0.0,
|
|
293
|
-
|
|
294
|
+
module_efficiency=0.1, alpha_absorption=0.9):
|
|
294
295
|
r"""
|
|
295
296
|
Calculate cell temperature using an empirical heat loss factor model
|
|
296
297
|
as implemented in PVsyst.
|
|
@@ -318,9 +319,7 @@ def pvsyst_cell(poa_global, temp_air, wind_speed=1.0, u_c=29.0, u_v=0.0,
|
|
|
318
319
|
u_v : float, default 0.0
|
|
319
320
|
Combined heat loss factor influenced by wind. Parameter :math:`U_{v}`
|
|
320
321
|
in :eq:`pvsyst`.
|
|
321
|
-
:math:`\left[ \frac{\text{W}/\text{m}^2}{\text{C}\ \left( \text{m/s} \right)} \right]`
|
|
322
|
-
|
|
323
|
-
eta_m : numeric, default None (deprecated, use module_efficiency instead)
|
|
322
|
+
:math:`\left[ \frac{\text{W}/\text{m}^2}{\text{C}\ \left( \text{m/s} \right)} \right]`
|
|
324
323
|
|
|
325
324
|
module_efficiency : numeric, default 0.1
|
|
326
325
|
Module external efficiency as a fraction. Parameter :math:`\eta_{m}`
|
|
@@ -375,13 +374,8 @@ def pvsyst_cell(poa_global, temp_air, wind_speed=1.0, u_c=29.0, u_v=0.0,
|
|
|
375
374
|
>>> params = TEMPERATURE_MODEL_PARAMETERS['pvsyst']['freestanding']
|
|
376
375
|
>>> pvsyst_cell(1000, 10, **params)
|
|
377
376
|
37.93103448275862
|
|
378
|
-
"""
|
|
377
|
+
""" # noQA: E501
|
|
379
378
|
|
|
380
|
-
if eta_m:
|
|
381
|
-
warn_deprecated(
|
|
382
|
-
since='v0.9', message='eta_m overwriting module_efficiency',
|
|
383
|
-
name='eta_m', alternative='module_efficiency', removal='v0.10')
|
|
384
|
-
module_efficiency = eta_m
|
|
385
379
|
total_loss_factor = u_c + u_v * wind_speed
|
|
386
380
|
heat_input = poa_global * alpha_absorption * (1 - module_efficiency)
|
|
387
381
|
temp_difference = heat_input / total_loss_factor
|
|
@@ -413,12 +407,14 @@ def faiman(poa_global, temp_air, wind_speed=1.0, u0=25.0, u1=6.84):
|
|
|
413
407
|
|
|
414
408
|
u0 : numeric, default 25.0
|
|
415
409
|
Combined heat loss factor coefficient. The default value is one
|
|
416
|
-
determined by Faiman for 7 silicon modules
|
|
410
|
+
determined by Faiman for 7 silicon modules
|
|
411
|
+
in the Negev desert on an open rack at 30.9° tilt.
|
|
417
412
|
:math:`\left[\frac{\text{W}/{\text{m}^2}}{\text{C}}\right]`
|
|
418
413
|
|
|
419
414
|
u1 : numeric, default 6.84
|
|
420
415
|
Combined heat loss factor influenced by wind. The default value is one
|
|
421
|
-
determined by Faiman for 7 silicon modules
|
|
416
|
+
determined by Faiman for 7 silicon modules
|
|
417
|
+
in the Negev desert on an open rack at 30.9° tilt.
|
|
422
418
|
:math:`\left[ \frac{\text{W}/\text{m}^2}{\text{C}\ \left( \text{m/s} \right)} \right]`
|
|
423
419
|
|
|
424
420
|
Returns
|
|
@@ -434,6 +430,7 @@ def faiman(poa_global, temp_air, wind_speed=1.0, u0=25.0, u1=6.84):
|
|
|
434
430
|
----------
|
|
435
431
|
.. [1] Faiman, D. (2008). "Assessing the outdoor operating temperature of
|
|
436
432
|
photovoltaic modules." Progress in Photovoltaics 16(4): 307-315.
|
|
433
|
+
:doi:`10.1002/pip.813`
|
|
437
434
|
|
|
438
435
|
.. [2] "IEC 61853-2 Photovoltaic (PV) module performance testing and energy
|
|
439
436
|
rating - Part 2: Spectral responsivity, incidence angle and module
|
|
@@ -442,7 +439,12 @@ def faiman(poa_global, temp_air, wind_speed=1.0, u0=25.0, u1=6.84):
|
|
|
442
439
|
.. [3] "IEC 61853-3 Photovoltaic (PV) module performance testing and energy
|
|
443
440
|
rating - Part 3: Energy rating of PV modules". IEC, Geneva, 2018.
|
|
444
441
|
|
|
445
|
-
|
|
442
|
+
See also
|
|
443
|
+
--------
|
|
444
|
+
pvlib.temperature.faiman_rad
|
|
445
|
+
|
|
446
|
+
''' # noQA: E501
|
|
447
|
+
|
|
446
448
|
# Contributed by Anton Driesse (@adriesse), PV Performance Labs. Dec., 2019
|
|
447
449
|
|
|
448
450
|
# The following lines may seem odd since u0 & u1 are probably scalar,
|
|
@@ -457,6 +459,115 @@ def faiman(poa_global, temp_air, wind_speed=1.0, u0=25.0, u1=6.84):
|
|
|
457
459
|
return temp_air + temp_difference
|
|
458
460
|
|
|
459
461
|
|
|
462
|
+
def faiman_rad(poa_global, temp_air, wind_speed=1.0, ir_down=None,
|
|
463
|
+
u0=25.0, u1=6.84, sky_view=1.0, emissivity=0.88):
|
|
464
|
+
r'''
|
|
465
|
+
Calculate cell or module temperature using the Faiman model augmented
|
|
466
|
+
with a radiative loss term.
|
|
467
|
+
|
|
468
|
+
The Faiman model uses an empirical heat loss factor model [1]_ and is
|
|
469
|
+
adopted in the IEC 61853 standards [2]_ and [3]_. The radiative loss
|
|
470
|
+
term was proposed and developed by Driesse [4]_.
|
|
471
|
+
|
|
472
|
+
The model can be used to represent cell or module temperature.
|
|
473
|
+
|
|
474
|
+
Parameters
|
|
475
|
+
----------
|
|
476
|
+
poa_global : numeric
|
|
477
|
+
Total incident irradiance [W/m^2].
|
|
478
|
+
|
|
479
|
+
temp_air : numeric
|
|
480
|
+
Ambient dry bulb temperature [C].
|
|
481
|
+
|
|
482
|
+
wind_speed : numeric, default 1.0
|
|
483
|
+
Wind speed measured at the same height for which the wind loss
|
|
484
|
+
factor was determined. The default value 1.0 m/s is the wind
|
|
485
|
+
speed at module height used to determine NOCT. [m/s]
|
|
486
|
+
|
|
487
|
+
ir_down : numeric, default 0.0
|
|
488
|
+
Downwelling infrared radiation from the sky, measured on a horizontal
|
|
489
|
+
surface. [W/m^2]
|
|
490
|
+
|
|
491
|
+
u0 : numeric, default 25.0
|
|
492
|
+
Combined heat loss factor coefficient. The default value is one
|
|
493
|
+
determined by Faiman for 7 silicon modules
|
|
494
|
+
in the Negev desert on an open rack at 30.9° tilt.
|
|
495
|
+
:math:`\left[\frac{\text{W}/{\text{m}^2}}{\text{C}}\right]`
|
|
496
|
+
|
|
497
|
+
u1 : numeric, default 6.84
|
|
498
|
+
Combined heat loss factor influenced by wind. The default value is one
|
|
499
|
+
determined by Faiman for 7 silicon modules
|
|
500
|
+
in the Negev desert on an open rack at 30.9° tilt.
|
|
501
|
+
:math:`\left[ \frac{\text{W}/\text{m}^2}{\text{C}\ \left( \text{m/s} \right)} \right]`
|
|
502
|
+
|
|
503
|
+
sky_view : numeric, default 1.0
|
|
504
|
+
Effective view factor limiting the radiative exchange between the
|
|
505
|
+
module and the sky. For a tilted array the expressions
|
|
506
|
+
(1 + 3*cos(tilt)) / 4 can be used as a first estimate for sky_view
|
|
507
|
+
as discussed in [4]_. The default value is for a horizontal module.
|
|
508
|
+
[unitless]
|
|
509
|
+
|
|
510
|
+
emissivity : numeric, default 0.88
|
|
511
|
+
Infrared emissivity of the module surface facing the sky. The default
|
|
512
|
+
value represents the middle of a range of values found in the
|
|
513
|
+
literature. [unitless]
|
|
514
|
+
|
|
515
|
+
Returns
|
|
516
|
+
-------
|
|
517
|
+
numeric, values in degrees Celsius
|
|
518
|
+
|
|
519
|
+
Notes
|
|
520
|
+
-----
|
|
521
|
+
All arguments may be scalars or vectors. If multiple arguments
|
|
522
|
+
are vectors they must be the same length.
|
|
523
|
+
|
|
524
|
+
When only irradiance, air temperature and wind speed inputs are provided
|
|
525
|
+
(`ir_down` is `None`) this function calculates the same device temperature
|
|
526
|
+
as the original faiman model. When down-welling long-wave radiation data
|
|
527
|
+
are provided as well (`ir_down` is not None) the default u0 and u1 values
|
|
528
|
+
from the original model should not be used because a portion of the
|
|
529
|
+
radiative losses would be double-counted.
|
|
530
|
+
|
|
531
|
+
References
|
|
532
|
+
----------
|
|
533
|
+
.. [1] Faiman, D. (2008). "Assessing the outdoor operating temperature of
|
|
534
|
+
photovoltaic modules." Progress in Photovoltaics 16(4): 307-315.
|
|
535
|
+
:doi:`10.1002/pip.813`
|
|
536
|
+
|
|
537
|
+
.. [2] "IEC 61853-2 Photovoltaic (PV) module performance testing and energy
|
|
538
|
+
rating - Part 2: Spectral responsivity, incidence angle and module
|
|
539
|
+
operating temperature measurements". IEC, Geneva, 2018.
|
|
540
|
+
|
|
541
|
+
.. [3] "IEC 61853-3 Photovoltaic (PV) module performance testing and energy
|
|
542
|
+
rating - Part 3: Energy rating of PV modules". IEC, Geneva, 2018.
|
|
543
|
+
|
|
544
|
+
.. [4] Driesse, A. et al (2022) "Improving Common PV Module Temperature
|
|
545
|
+
Models by Incorporating Radiative Losses to the Sky". SAND2022-11604.
|
|
546
|
+
:doi:`10.2172/1884890`
|
|
547
|
+
|
|
548
|
+
See also
|
|
549
|
+
--------
|
|
550
|
+
pvlib.temperature.faiman
|
|
551
|
+
|
|
552
|
+
''' # noQA: E501
|
|
553
|
+
|
|
554
|
+
# Contributed by Anton Driesse (@adriesse), PV Performance Labs. Nov., 2022
|
|
555
|
+
|
|
556
|
+
abs_zero = -273.15
|
|
557
|
+
sigma = scipy.constants.Stefan_Boltzmann
|
|
558
|
+
|
|
559
|
+
if ir_down is None:
|
|
560
|
+
qrad_sky = 0.0
|
|
561
|
+
else:
|
|
562
|
+
ir_up = sigma * ((temp_air - abs_zero)**4)
|
|
563
|
+
qrad_sky = emissivity * sky_view * (ir_up - ir_down)
|
|
564
|
+
|
|
565
|
+
heat_input = poa_global - qrad_sky
|
|
566
|
+
total_loss_factor = u0 + u1 * wind_speed
|
|
567
|
+
temp_difference = heat_input / total_loss_factor
|
|
568
|
+
return temp_air + temp_difference
|
|
569
|
+
|
|
570
|
+
|
|
460
571
|
def ross(poa_global, temp_air, noct):
|
|
461
572
|
r'''
|
|
462
573
|
Calculate cell temperature using the Ross model.
|