pvlib 0.10.4__py3-none-any.whl → 0.11.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 +1 -0
- pvlib/albedo.py +168 -0
- pvlib/bifacial/utils.py +2 -1
- pvlib/data/ASTMG173.csv +2004 -0
- pvlib/iam.py +28 -28
- pvlib/iotools/__init__.py +0 -1
- pvlib/iotools/midc.py +15 -10
- pvlib/iotools/psm3.py +10 -25
- pvlib/iotools/srml.py +1 -61
- pvlib/iotools/surfrad.py +1 -1
- pvlib/irradiance.py +133 -95
- pvlib/location.py +16 -6
- pvlib/modelchain.py +2 -165
- pvlib/pvarray.py +7 -5
- pvlib/pvsystem.py +75 -106
- pvlib/scaling.py +4 -2
- pvlib/shading.py +350 -0
- pvlib/singlediode.py +37 -9
- pvlib/snow.py +3 -1
- pvlib/spectrum/__init__.py +5 -0
- pvlib/spectrum/mismatch.py +573 -43
- pvlib/spectrum/spectrl2.py +8 -8
- pvlib/tests/bifacial/test_utils.py +6 -5
- pvlib/tests/iotools/test_psm3.py +0 -18
- pvlib/tests/iotools/test_srml.py +1 -43
- pvlib/tests/test_albedo.py +84 -0
- pvlib/tests/test_inverter.py +2 -2
- pvlib/tests/test_irradiance.py +35 -2
- pvlib/tests/test_location.py +26 -18
- pvlib/tests/test_modelchain.py +0 -57
- pvlib/tests/test_pvsystem.py +73 -128
- pvlib/tests/test_shading.py +167 -1
- pvlib/tests/test_singlediode.py +68 -29
- pvlib/tests/test_spectrum.py +283 -22
- pvlib/tests/test_temperature.py +7 -7
- pvlib/tests/test_tools.py +24 -0
- pvlib/tests/test_transformer.py +60 -0
- pvlib/tools.py +27 -0
- pvlib/transformer.py +117 -0
- pvlib/version.py +1 -5
- {pvlib-0.10.4.dist-info → pvlib-0.11.0.dist-info}/METADATA +3 -4
- {pvlib-0.10.4.dist-info → pvlib-0.11.0.dist-info}/RECORD +46 -42
- {pvlib-0.10.4.dist-info → pvlib-0.11.0.dist-info}/WHEEL +1 -1
- pvlib/data/astm_g173_am15g.csv +0 -2003
- {pvlib-0.10.4.dist-info → pvlib-0.11.0.dist-info}/AUTHORS.md +0 -0
- {pvlib-0.10.4.dist-info → pvlib-0.11.0.dist-info}/LICENSE +0 -0
- {pvlib-0.10.4.dist-info → pvlib-0.11.0.dist-info}/top_level.txt +0 -0
pvlib/irradiance.py
CHANGED
|
@@ -16,22 +16,18 @@ from scipy.optimize import bisect
|
|
|
16
16
|
from pvlib import atmosphere, solarposition, tools
|
|
17
17
|
import pvlib # used to avoid dni name collision in complete_irradiance
|
|
18
18
|
|
|
19
|
+
from pvlib._deprecation import pvlibDeprecationWarning
|
|
20
|
+
import warnings
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
'concrete': 0.30,
|
|
30
|
-
'aluminum': 0.85,
|
|
31
|
-
'copper': 0.74,
|
|
32
|
-
'fresh steel': 0.35,
|
|
33
|
-
'dirty steel': 0.08,
|
|
34
|
-
'sea': 0.06}
|
|
22
|
+
|
|
23
|
+
# Deprecation warning based on https://peps.python.org/pep-0562/
|
|
24
|
+
def __getattr__(attr):
|
|
25
|
+
if attr == 'SURFACE_ALBEDOS':
|
|
26
|
+
warnings.warn(f"{attr} has been moved to the albedo module as of "
|
|
27
|
+
"v0.11.0. Please use pvlib.albedo.SURFACE_ALBEDOS.",
|
|
28
|
+
pvlibDeprecationWarning)
|
|
29
|
+
return pvlib.albedo.SURFACE_ALBEDOS
|
|
30
|
+
raise AttributeError(f"module {__name__!r} has no attribute {attr!r}")
|
|
35
31
|
|
|
36
32
|
|
|
37
33
|
def get_extra_radiation(datetime_or_doy, solar_constant=1366.1,
|
|
@@ -232,48 +228,6 @@ def aoi(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth):
|
|
|
232
228
|
return aoi_value
|
|
233
229
|
|
|
234
230
|
|
|
235
|
-
def poa_horizontal_ratio(surface_tilt, surface_azimuth,
|
|
236
|
-
solar_zenith, solar_azimuth):
|
|
237
|
-
"""
|
|
238
|
-
Calculates the ratio of the beam components of the plane of array
|
|
239
|
-
irradiance and the horizontal irradiance.
|
|
240
|
-
|
|
241
|
-
Input all angles in degrees.
|
|
242
|
-
|
|
243
|
-
Parameters
|
|
244
|
-
----------
|
|
245
|
-
surface_tilt : numeric
|
|
246
|
-
Panel tilt from horizontal.
|
|
247
|
-
surface_azimuth : numeric
|
|
248
|
-
Panel azimuth from north.
|
|
249
|
-
solar_zenith : numeric
|
|
250
|
-
Solar zenith angle.
|
|
251
|
-
solar_azimuth : numeric
|
|
252
|
-
Solar azimuth angle.
|
|
253
|
-
|
|
254
|
-
Returns
|
|
255
|
-
-------
|
|
256
|
-
ratio : numeric
|
|
257
|
-
Ratio of the plane of array irradiance to the horizontal plane
|
|
258
|
-
irradiance
|
|
259
|
-
"""
|
|
260
|
-
|
|
261
|
-
cos_poa_zen = aoi_projection(surface_tilt, surface_azimuth,
|
|
262
|
-
solar_zenith, solar_azimuth)
|
|
263
|
-
|
|
264
|
-
cos_solar_zenith = tools.cosd(solar_zenith)
|
|
265
|
-
|
|
266
|
-
# ratio of tilted and horizontal beam irradiance
|
|
267
|
-
ratio = cos_poa_zen / cos_solar_zenith
|
|
268
|
-
|
|
269
|
-
try:
|
|
270
|
-
ratio.name = 'poa_ratio'
|
|
271
|
-
except AttributeError:
|
|
272
|
-
pass
|
|
273
|
-
|
|
274
|
-
return ratio
|
|
275
|
-
|
|
276
|
-
|
|
277
231
|
def beam_component(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
|
|
278
232
|
dni):
|
|
279
233
|
"""
|
|
@@ -450,6 +404,11 @@ def get_sky_diffuse(surface_tilt, surface_azimuth,
|
|
|
450
404
|
require ``'dni_extra'``. Values can be calculated using
|
|
451
405
|
:py:func:`~pvlib.irradiance.get_extra_radiation`.
|
|
452
406
|
|
|
407
|
+
The ``'Perez'`` transposition model features discontinuities in the
|
|
408
|
+
predicted tilted diffuse irradiance due to relying on discrete input
|
|
409
|
+
values. For applications that benefit from continuous output, consider
|
|
410
|
+
using :py:func:`~pvlib.irradiance.perez_driesse`.
|
|
411
|
+
|
|
453
412
|
The ``'perez'`` and ``'perez-driesse'`` models require relative airmass
|
|
454
413
|
(``airmass``) as input. If ``airmass`` is not provided, it is calculated
|
|
455
414
|
using the defaults in :py:func:`~pvlib.atmosphere.get_relative_airmass`.
|
|
@@ -592,7 +551,7 @@ def get_ground_diffuse(surface_tilt, ghi, albedo=.25, surface_type=None):
|
|
|
592
551
|
Notes
|
|
593
552
|
-----
|
|
594
553
|
Table of albedo values by ``surface_type`` are from [2]_, [3]_, [4]_;
|
|
595
|
-
see :py:
|
|
554
|
+
see :py:const:`~pvlib.albedo.SURFACE_ALBEDOS`.
|
|
596
555
|
|
|
597
556
|
References
|
|
598
557
|
----------
|
|
@@ -607,7 +566,7 @@ def get_ground_diffuse(surface_tilt, ghi, albedo=.25, surface_type=None):
|
|
|
607
566
|
'''
|
|
608
567
|
|
|
609
568
|
if surface_type is not None:
|
|
610
|
-
albedo = SURFACE_ALBEDOS[surface_type]
|
|
569
|
+
albedo = pvlib.albedo.SURFACE_ALBEDOS[surface_type]
|
|
611
570
|
|
|
612
571
|
diffuse_irrad = ghi * albedo * (1 - np.cos(np.radians(surface_tilt))) * 0.5
|
|
613
572
|
|
|
@@ -896,8 +855,8 @@ def reindl(surface_tilt, surface_azimuth, dhi, dni, ghi, dni_extra,
|
|
|
896
855
|
|
|
897
856
|
.. math::
|
|
898
857
|
|
|
899
|
-
I_{d} = DHI (A R_b + (1 - A) (\frac{1 + \cos\beta}{2})
|
|
900
|
-
(1 + \sqrt{\frac{I_{hb}}{I_h}} \sin^3(\beta/2)) )
|
|
858
|
+
I_{d} = DHI \left(A R_b + (1 - A) \left(\frac{1 + \cos\beta}{2}\right)
|
|
859
|
+
\left(1 + \sqrt{\frac{I_{hb}}{I_h}} \sin^3(\beta/2)\right) \right)
|
|
901
860
|
|
|
902
861
|
Reindl's 1990 model determines the diffuse irradiance from the sky
|
|
903
862
|
(ground reflected irradiance is not included in this algorithm) on a
|
|
@@ -1050,6 +1009,13 @@ def perez(surface_tilt, surface_azimuth, dhi, dni, dni_extra,
|
|
|
1050
1009
|
pressure-corrected) airmass. Optionally a selector may be used to
|
|
1051
1010
|
use any of Perez's model coefficient sets.
|
|
1052
1011
|
|
|
1012
|
+
Warning
|
|
1013
|
+
-------
|
|
1014
|
+
The Perez transposition model features discontinuities in the
|
|
1015
|
+
predicted tilted diffuse irradiance due to relying on discrete input
|
|
1016
|
+
values. For applications that benefit from continuous output, consider
|
|
1017
|
+
using :py:func:`~pvlib.irradiance.perez_driesse`.
|
|
1018
|
+
|
|
1053
1019
|
Parameters
|
|
1054
1020
|
----------
|
|
1055
1021
|
surface_tilt : numeric
|
|
@@ -1551,9 +1517,9 @@ def ghi_from_poa_driesse_2023(surface_tilt, surface_azimuth,
|
|
|
1551
1517
|
Solar azimuth angle. [degree]
|
|
1552
1518
|
poa_global : numeric
|
|
1553
1519
|
Plane-of-array global irradiance, aka global tilted irradiance. [W/m^2]
|
|
1554
|
-
dni_extra :
|
|
1520
|
+
dni_extra : numeric, optional
|
|
1555
1521
|
Extraterrestrial direct normal irradiance. [W/m^2]
|
|
1556
|
-
airmass :
|
|
1522
|
+
airmass : numeric, optional
|
|
1557
1523
|
Relative airmass (not adjusted for pressure). [unitless]
|
|
1558
1524
|
albedo : numeric, default 0.25
|
|
1559
1525
|
Ground surface albedo. [unitless]
|
|
@@ -2334,10 +2300,10 @@ def gti_dirint(poa_global, aoi, solar_zenith, solar_azimuth, times,
|
|
|
2334
2300
|
data : DataFrame
|
|
2335
2301
|
Contains the following keys/columns:
|
|
2336
2302
|
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2303
|
+
* ``ghi``: the modeled global horizontal irradiance in W/m^2.
|
|
2304
|
+
* ``dni``: the modeled direct normal irradiance in W/m^2.
|
|
2305
|
+
* ``dhi``: the modeled diffuse horizontal irradiance in
|
|
2306
|
+
W/m^2.
|
|
2341
2307
|
|
|
2342
2308
|
References
|
|
2343
2309
|
----------
|
|
@@ -2484,7 +2450,6 @@ def _gti_dirint_lt_90(poa_global, aoi, aoi_lt_90, solar_zenith, solar_azimuth,
|
|
|
2484
2450
|
else:
|
|
2485
2451
|
# we are here because we ran out of coeffs to loop over and
|
|
2486
2452
|
# therefore we have exceeded max_iterations
|
|
2487
|
-
import warnings
|
|
2488
2453
|
failed_points = best_diff[aoi_lt_90][~best_diff_lte_1_lt_90]
|
|
2489
2454
|
warnings.warn(
|
|
2490
2455
|
('%s points failed to converge after %s iterations. best_diff:\n%s'
|
|
@@ -2618,11 +2583,11 @@ def erbs(ghi, zenith, datetime_or_doy, min_cos_zenith=0.065, max_zenith=87):
|
|
|
2618
2583
|
data : OrderedDict or DataFrame
|
|
2619
2584
|
Contains the following keys/columns:
|
|
2620
2585
|
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2586
|
+
* ``dni``: the modeled direct normal irradiance in W/m^2.
|
|
2587
|
+
* ``dhi``: the modeled diffuse horizontal irradiance in
|
|
2588
|
+
W/m^2.
|
|
2589
|
+
* ``kt``: Ratio of global to extraterrestrial irradiance
|
|
2590
|
+
on a horizontal plane.
|
|
2626
2591
|
|
|
2627
2592
|
References
|
|
2628
2593
|
----------
|
|
@@ -2721,11 +2686,11 @@ def erbs_driesse(ghi, zenith, datetime_or_doy=None, dni_extra=None,
|
|
|
2721
2686
|
data : OrderedDict or DataFrame
|
|
2722
2687
|
Contains the following keys/columns:
|
|
2723
2688
|
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2689
|
+
* ``dni``: the modeled direct normal irradiance in W/m^2.
|
|
2690
|
+
* ``dhi``: the modeled diffuse horizontal irradiance in
|
|
2691
|
+
W/m^2.
|
|
2692
|
+
* ``kt``: Ratio of global to extraterrestrial irradiance
|
|
2693
|
+
on a horizontal plane.
|
|
2729
2694
|
|
|
2730
2695
|
Raises
|
|
2731
2696
|
------
|
|
@@ -2839,17 +2804,17 @@ def orgill_hollands(ghi, zenith, datetime_or_doy, dni_extra=None,
|
|
|
2839
2804
|
data : OrderedDict or DataFrame
|
|
2840
2805
|
Contains the following keys/columns:
|
|
2841
2806
|
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2807
|
+
* ``dni``: the modeled direct normal irradiance in W/m^2.
|
|
2808
|
+
* ``dhi``: the modeled diffuse horizontal irradiance in
|
|
2809
|
+
W/m^2.
|
|
2810
|
+
* ``kt``: Ratio of global to extraterrestrial irradiance
|
|
2811
|
+
on a horizontal plane.
|
|
2847
2812
|
|
|
2848
2813
|
References
|
|
2849
2814
|
----------
|
|
2850
2815
|
.. [1] Orgill, J.F., Hollands, K.G.T., Correlation equation for hourly
|
|
2851
|
-
diffuse radiation on a horizontal surface, Solar Energy 19(4),
|
|
2852
|
-
1977. Eqs. 3(a), 3(b) and 3(c)
|
|
2816
|
+
diffuse radiation on a horizontal surface, Solar Energy 19(4),
|
|
2817
|
+
pp 357–359, 1977. Eqs. 3(a), 3(b) and 3(c)
|
|
2853
2818
|
:doi:`10.1016/0038-092X(77)90006-8`
|
|
2854
2819
|
|
|
2855
2820
|
See Also
|
|
@@ -2934,11 +2899,11 @@ def boland(ghi, solar_zenith, datetime_or_doy, a_coeff=8.645, b_coeff=0.613,
|
|
|
2934
2899
|
data : OrderedDict or DataFrame
|
|
2935
2900
|
Contains the following keys/columns:
|
|
2936
2901
|
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2902
|
+
* ``dni``: the modeled direct normal irradiance in W/m^2.
|
|
2903
|
+
* ``dhi``: the modeled diffuse horizontal irradiance in
|
|
2904
|
+
W/m^2.
|
|
2905
|
+
* ``kt``: Ratio of global to extraterrestrial irradiance
|
|
2906
|
+
on a horizontal plane.
|
|
2942
2907
|
|
|
2943
2908
|
References
|
|
2944
2909
|
----------
|
|
@@ -3771,11 +3736,11 @@ def louche(ghi, solar_zenith, datetime_or_doy, max_zenith=90):
|
|
|
3771
3736
|
data: OrderedDict or DataFrame
|
|
3772
3737
|
Contains the following keys/columns:
|
|
3773
3738
|
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3739
|
+
* ``dni``: the modeled direct normal irradiance in W/m^2.
|
|
3740
|
+
* ``dhi``: the modeled diffuse horizontal irradiance in
|
|
3741
|
+
W/m^2.
|
|
3742
|
+
* ``kt``: Ratio of global to extraterrestrial irradiance
|
|
3743
|
+
on a horizontal plane.
|
|
3779
3744
|
|
|
3780
3745
|
References
|
|
3781
3746
|
-------
|
|
@@ -3808,3 +3773,76 @@ def louche(ghi, solar_zenith, datetime_or_doy, max_zenith=90):
|
|
|
3808
3773
|
data = pd.DataFrame(data, index=datetime_or_doy)
|
|
3809
3774
|
|
|
3810
3775
|
return data
|
|
3776
|
+
|
|
3777
|
+
|
|
3778
|
+
def diffuse_par_spitters(daily_solar_zenith, global_diffuse_fraction):
|
|
3779
|
+
r"""
|
|
3780
|
+
Derive daily diffuse fraction of Photosynthetically Active Radiation (PAR)
|
|
3781
|
+
from daily average solar zenith and diffuse fraction of daily insolation.
|
|
3782
|
+
|
|
3783
|
+
The relationship is based on the work of Spitters et al. (1986) [1]_. The
|
|
3784
|
+
resulting value is the fraction of daily PAR that is diffuse.
|
|
3785
|
+
|
|
3786
|
+
.. note::
|
|
3787
|
+
The diffuse fraction is defined as the ratio of
|
|
3788
|
+
diffuse to global daily insolation, in J m⁻² day⁻¹ or equivalent.
|
|
3789
|
+
|
|
3790
|
+
Parameters
|
|
3791
|
+
----------
|
|
3792
|
+
daily_solar_zenith : numeric
|
|
3793
|
+
Average daily solar zenith angle. In degrees [°].
|
|
3794
|
+
|
|
3795
|
+
global_diffuse_fraction : numeric
|
|
3796
|
+
Fraction of daily global broadband insolation that is diffuse.
|
|
3797
|
+
Unitless [0, 1].
|
|
3798
|
+
|
|
3799
|
+
Returns
|
|
3800
|
+
-------
|
|
3801
|
+
par_diffuse_fraction : numeric
|
|
3802
|
+
Fraction of daily photosynthetically active radiation (PAR) that is
|
|
3803
|
+
diffuse. Unitless [0, 1].
|
|
3804
|
+
|
|
3805
|
+
Notes
|
|
3806
|
+
-----
|
|
3807
|
+
The relationship is given by equations (9) & (10) in [1]_ and (1) in [2]_:
|
|
3808
|
+
|
|
3809
|
+
.. math::
|
|
3810
|
+
|
|
3811
|
+
k_{diffuse\_PAR}^{model} = \frac{PAR_{diffuse}}{PAR_{total}} =
|
|
3812
|
+
\frac{\left[1 + 0.3 \left(1 - \left(k_d\right) ^2\right)\right]
|
|
3813
|
+
k_d}
|
|
3814
|
+
{1 + \left(1 - \left(k_d\right)^2\right) \cos ^2 (90 - \beta)
|
|
3815
|
+
\cos ^3 \beta}
|
|
3816
|
+
|
|
3817
|
+
where :math:`k_d` is the diffuse fraction of the global insolation, and
|
|
3818
|
+
:math:`\beta` is the daily average of the solar elevation angle in degrees.
|
|
3819
|
+
|
|
3820
|
+
A comparison using different models for the diffuse fraction of
|
|
3821
|
+
the global insolation can be found in [2]_ in the context of Sweden.
|
|
3822
|
+
|
|
3823
|
+
References
|
|
3824
|
+
----------
|
|
3825
|
+
.. [1] C. J. T. Spitters, H. A. J. M. Toussaint, and J. Goudriaan,
|
|
3826
|
+
'Separating the diffuse and direct component of global radiation and its
|
|
3827
|
+
implications for modeling canopy photosynthesis Part I. Components of
|
|
3828
|
+
incoming radiation', Agricultural and Forest Meteorology, vol. 38,
|
|
3829
|
+
no. 1, pp. 217-229, Oct. 1986, :doi:`10.1016/0168-1923(86)90060-2`.
|
|
3830
|
+
.. [2] S. Ma Lu et al., 'Photosynthetically active radiation decomposition
|
|
3831
|
+
models for agrivoltaic systems applications', Solar Energy, vol. 244,
|
|
3832
|
+
pp. 536-549, Sep. 2022, :doi:`10.1016/j.solener.2022.05.046`.
|
|
3833
|
+
"""
|
|
3834
|
+
# notation change:
|
|
3835
|
+
# cosd(90-x) = sind(x) and 90-solar_elevation = solar_zenith
|
|
3836
|
+
cosd_solar_zenith = tools.cosd(daily_solar_zenith)
|
|
3837
|
+
cosd_solar_elevation = tools.sind(daily_solar_zenith)
|
|
3838
|
+
par_diffuse_fraction = (
|
|
3839
|
+
(1 + 0.3 * (1 - global_diffuse_fraction**2))
|
|
3840
|
+
* global_diffuse_fraction
|
|
3841
|
+
/ (
|
|
3842
|
+
1
|
|
3843
|
+
+ (1 - global_diffuse_fraction**2)
|
|
3844
|
+
* cosd_solar_zenith**2
|
|
3845
|
+
* cosd_solar_elevation**3
|
|
3846
|
+
)
|
|
3847
|
+
)
|
|
3848
|
+
return par_diffuse_fraction
|
pvlib/location.py
CHANGED
|
@@ -4,7 +4,7 @@ This module contains the Location class.
|
|
|
4
4
|
|
|
5
5
|
# Will Holmgren, University of Arizona, 2014-2016.
|
|
6
6
|
|
|
7
|
-
import
|
|
7
|
+
import pathlib
|
|
8
8
|
import datetime
|
|
9
9
|
|
|
10
10
|
import pandas as pd
|
|
@@ -14,6 +14,7 @@ import h5py
|
|
|
14
14
|
from pvlib import solarposition, clearsky, atmosphere, irradiance
|
|
15
15
|
from pvlib.tools import _degrees_to_index
|
|
16
16
|
|
|
17
|
+
|
|
17
18
|
class Location:
|
|
18
19
|
"""
|
|
19
20
|
Location objects are convenient containers for latitude, longitude,
|
|
@@ -44,8 +45,11 @@ class Location:
|
|
|
44
45
|
pytz.timezone objects will be converted to strings.
|
|
45
46
|
ints and floats must be in hours from UTC.
|
|
46
47
|
|
|
47
|
-
altitude : float,
|
|
48
|
+
altitude : float, optional
|
|
48
49
|
Altitude from sea level in meters.
|
|
50
|
+
If not specified, the altitude will be fetched from
|
|
51
|
+
:py:func:`pvlib.location.lookup_altitude`.
|
|
52
|
+
If no data is available for the location, the altitude is set to 0.
|
|
49
53
|
|
|
50
54
|
name : string, optional
|
|
51
55
|
Sets the name attribute of the Location object.
|
|
@@ -55,7 +59,8 @@ class Location:
|
|
|
55
59
|
pvlib.pvsystem.PVSystem
|
|
56
60
|
"""
|
|
57
61
|
|
|
58
|
-
def __init__(self, latitude, longitude, tz='UTC', altitude=
|
|
62
|
+
def __init__(self, latitude, longitude, tz='UTC', altitude=None,
|
|
63
|
+
name=None):
|
|
59
64
|
|
|
60
65
|
self.latitude = latitude
|
|
61
66
|
self.longitude = longitude
|
|
@@ -75,6 +80,9 @@ class Location:
|
|
|
75
80
|
else:
|
|
76
81
|
raise TypeError('Invalid tz specification')
|
|
77
82
|
|
|
83
|
+
if altitude is None:
|
|
84
|
+
altitude = lookup_altitude(latitude, longitude)
|
|
85
|
+
|
|
78
86
|
self.altitude = altitude
|
|
79
87
|
|
|
80
88
|
self.name = name
|
|
@@ -427,8 +435,8 @@ def lookup_altitude(latitude, longitude):
|
|
|
427
435
|
|
|
428
436
|
"""
|
|
429
437
|
|
|
430
|
-
pvlib_path =
|
|
431
|
-
filepath =
|
|
438
|
+
pvlib_path = pathlib.Path(__file__).parent
|
|
439
|
+
filepath = pvlib_path / 'data' / 'Altitude.h5'
|
|
432
440
|
|
|
433
441
|
latitude_index = _degrees_to_index(latitude, coordinate='latitude')
|
|
434
442
|
longitude_index = _degrees_to_index(longitude, coordinate='longitude')
|
|
@@ -439,8 +447,10 @@ def lookup_altitude(latitude, longitude):
|
|
|
439
447
|
# 255 is a special value that means nodata. Fallback to 0 if nodata.
|
|
440
448
|
if alt == 255:
|
|
441
449
|
return 0
|
|
450
|
+
# convert from np.uint8 to float so that the following operations succeed
|
|
451
|
+
alt = float(alt)
|
|
442
452
|
# Altitude is encoded in 28 meter steps from -450 meters to 6561 meters
|
|
443
453
|
# There are 0-254 possible altitudes, with 255 reserved for nodata.
|
|
444
454
|
alt *= 28
|
|
445
455
|
alt -= 450
|
|
446
|
-
return
|
|
456
|
+
return alt
|
pvlib/modelchain.py
CHANGED
|
@@ -13,14 +13,11 @@ import pandas as pd
|
|
|
13
13
|
from dataclasses import dataclass, field
|
|
14
14
|
from typing import Union, Tuple, Optional, TypeVar
|
|
15
15
|
|
|
16
|
-
from pvlib import
|
|
17
|
-
temperature, iam)
|
|
16
|
+
from pvlib import pvsystem, iam
|
|
18
17
|
import pvlib.irradiance # avoid name conflict with full import
|
|
19
18
|
from pvlib.pvsystem import _DC_MODEL_PARAMS
|
|
20
19
|
from pvlib.tools import _build_kwargs
|
|
21
20
|
|
|
22
|
-
from pvlib._deprecation import deprecated
|
|
23
|
-
|
|
24
21
|
# keys that are used to detect input data and assign data to appropriate
|
|
25
22
|
# ModelChain attribute
|
|
26
23
|
# for ModelChain.weather
|
|
@@ -41,7 +38,7 @@ DATA_KEYS = WEATHER_KEYS + POA_KEYS + TEMPERATURE_KEYS
|
|
|
41
38
|
|
|
42
39
|
# these dictionaries contain the default configuration for following
|
|
43
40
|
# established modeling sequences. They can be used in combination with
|
|
44
|
-
#
|
|
41
|
+
# ModelChain, particularly they are used by the methods
|
|
45
42
|
# ModelChain.with_pvwatts, ModelChain.with_sapm, etc.
|
|
46
43
|
|
|
47
44
|
# pvwatts documentation states that it uses the following reference for
|
|
@@ -62,165 +59,6 @@ SAPM_CONFIG = dict(
|
|
|
62
59
|
)
|
|
63
60
|
|
|
64
61
|
|
|
65
|
-
@deprecated(
|
|
66
|
-
since='0.9.1',
|
|
67
|
-
name='pvlib.modelchain.basic_chain',
|
|
68
|
-
alternative=('pvlib.modelchain.ModelChain.with_pvwatts'
|
|
69
|
-
' or pvlib.modelchain.ModelChain.with_sapm'),
|
|
70
|
-
addendum='Note that the with_xyz methods take different model parameters.'
|
|
71
|
-
)
|
|
72
|
-
def basic_chain(times, latitude, longitude,
|
|
73
|
-
surface_tilt, surface_azimuth,
|
|
74
|
-
module_parameters, temperature_model_parameters,
|
|
75
|
-
inverter_parameters,
|
|
76
|
-
irradiance=None, weather=None,
|
|
77
|
-
transposition_model='haydavies',
|
|
78
|
-
solar_position_method='nrel_numpy',
|
|
79
|
-
airmass_model='kastenyoung1989',
|
|
80
|
-
altitude=None, pressure=None,
|
|
81
|
-
**kwargs):
|
|
82
|
-
"""
|
|
83
|
-
An experimental function that computes all of the modeling steps
|
|
84
|
-
necessary for calculating power or energy for a PV system at a given
|
|
85
|
-
location.
|
|
86
|
-
|
|
87
|
-
Parameters
|
|
88
|
-
----------
|
|
89
|
-
times : DatetimeIndex
|
|
90
|
-
Times at which to evaluate the model.
|
|
91
|
-
|
|
92
|
-
latitude : float.
|
|
93
|
-
Positive is north of the equator.
|
|
94
|
-
Use decimal degrees notation.
|
|
95
|
-
|
|
96
|
-
longitude : float.
|
|
97
|
-
Positive is east of the prime meridian.
|
|
98
|
-
Use decimal degrees notation.
|
|
99
|
-
|
|
100
|
-
surface_tilt : numeric
|
|
101
|
-
Surface tilt angles in decimal degrees.
|
|
102
|
-
The tilt angle is defined as degrees from horizontal
|
|
103
|
-
(e.g. surface facing up = 0, surface facing horizon = 90)
|
|
104
|
-
|
|
105
|
-
surface_azimuth : numeric
|
|
106
|
-
Surface azimuth angles in decimal degrees.
|
|
107
|
-
The azimuth convention is defined
|
|
108
|
-
as degrees east of north
|
|
109
|
-
(North=0, South=180, East=90, West=270).
|
|
110
|
-
|
|
111
|
-
module_parameters : dict or Series
|
|
112
|
-
Module parameters as defined by the SAPM. See pvsystem.sapm for
|
|
113
|
-
details.
|
|
114
|
-
|
|
115
|
-
temperature_model_parameters : dict or Series
|
|
116
|
-
Temperature model parameters as defined by the SAPM.
|
|
117
|
-
See temperature.sapm_cell for details.
|
|
118
|
-
|
|
119
|
-
inverter_parameters : dict or Series
|
|
120
|
-
Inverter parameters as defined by the CEC. See
|
|
121
|
-
:py:func:`inverter.sandia` for details.
|
|
122
|
-
|
|
123
|
-
irradiance : DataFrame, optional
|
|
124
|
-
If not specified, calculates clear sky data.
|
|
125
|
-
Columns must be 'dni', 'ghi', 'dhi'.
|
|
126
|
-
|
|
127
|
-
weather : DataFrame, optional
|
|
128
|
-
If not specified, assumes air temperature is 20 C and
|
|
129
|
-
wind speed is 0 m/s.
|
|
130
|
-
Columns must be 'wind_speed', 'temp_air'.
|
|
131
|
-
|
|
132
|
-
transposition_model : str, default 'haydavies'
|
|
133
|
-
Passed to system.get_irradiance.
|
|
134
|
-
|
|
135
|
-
solar_position_method : str, default 'nrel_numpy'
|
|
136
|
-
Passed to solarposition.get_solarposition.
|
|
137
|
-
|
|
138
|
-
airmass_model : str, default 'kastenyoung1989'
|
|
139
|
-
Passed to atmosphere.relativeairmass.
|
|
140
|
-
|
|
141
|
-
altitude : float, optional
|
|
142
|
-
If not specified, computed from ``pressure``. Assumed to be 0 m
|
|
143
|
-
if ``pressure`` is also unspecified.
|
|
144
|
-
|
|
145
|
-
pressure : float, optional
|
|
146
|
-
If not specified, computed from ``altitude``. Assumed to be 101325 Pa
|
|
147
|
-
if ``altitude`` is also unspecified.
|
|
148
|
-
|
|
149
|
-
**kwargs
|
|
150
|
-
Arbitrary keyword arguments.
|
|
151
|
-
See code for details.
|
|
152
|
-
|
|
153
|
-
Returns
|
|
154
|
-
-------
|
|
155
|
-
output : (dc, ac)
|
|
156
|
-
Tuple of DC power (with SAPM parameters) (DataFrame) and AC
|
|
157
|
-
power (Series).
|
|
158
|
-
"""
|
|
159
|
-
|
|
160
|
-
if altitude is None and pressure is None:
|
|
161
|
-
altitude = 0.
|
|
162
|
-
pressure = 101325.
|
|
163
|
-
elif altitude is None:
|
|
164
|
-
altitude = atmosphere.pres2alt(pressure)
|
|
165
|
-
elif pressure is None:
|
|
166
|
-
pressure = atmosphere.alt2pres(altitude)
|
|
167
|
-
|
|
168
|
-
solar_position = solarposition.get_solarposition(
|
|
169
|
-
times, latitude, longitude, altitude=altitude, pressure=pressure,
|
|
170
|
-
method=solar_position_method, **kwargs)
|
|
171
|
-
|
|
172
|
-
# possible error with using apparent zenith with some models
|
|
173
|
-
airmass = atmosphere.get_relative_airmass(
|
|
174
|
-
solar_position['apparent_zenith'], model=airmass_model)
|
|
175
|
-
airmass = atmosphere.get_absolute_airmass(airmass, pressure)
|
|
176
|
-
dni_extra = pvlib.irradiance.get_extra_radiation(solar_position.index)
|
|
177
|
-
|
|
178
|
-
aoi = pvlib.irradiance.aoi(surface_tilt, surface_azimuth,
|
|
179
|
-
solar_position['apparent_zenith'],
|
|
180
|
-
solar_position['azimuth'])
|
|
181
|
-
|
|
182
|
-
if irradiance is None:
|
|
183
|
-
linke_turbidity = clearsky.lookup_linke_turbidity(
|
|
184
|
-
solar_position.index, latitude, longitude)
|
|
185
|
-
irradiance = clearsky.ineichen(
|
|
186
|
-
solar_position['apparent_zenith'],
|
|
187
|
-
airmass,
|
|
188
|
-
linke_turbidity,
|
|
189
|
-
altitude=altitude,
|
|
190
|
-
dni_extra=dni_extra
|
|
191
|
-
)
|
|
192
|
-
|
|
193
|
-
total_irrad = pvlib.irradiance.get_total_irradiance(
|
|
194
|
-
surface_tilt,
|
|
195
|
-
surface_azimuth,
|
|
196
|
-
solar_position['apparent_zenith'],
|
|
197
|
-
solar_position['azimuth'],
|
|
198
|
-
irradiance['dni'],
|
|
199
|
-
irradiance['ghi'],
|
|
200
|
-
irradiance['dhi'],
|
|
201
|
-
model=transposition_model,
|
|
202
|
-
dni_extra=dni_extra)
|
|
203
|
-
|
|
204
|
-
if weather is None:
|
|
205
|
-
weather = {'wind_speed': 0, 'temp_air': 20}
|
|
206
|
-
|
|
207
|
-
cell_temperature = temperature.sapm_cell(
|
|
208
|
-
total_irrad['poa_global'], weather['temp_air'], weather['wind_speed'],
|
|
209
|
-
temperature_model_parameters['a'], temperature_model_parameters['b'],
|
|
210
|
-
temperature_model_parameters['deltaT'])
|
|
211
|
-
|
|
212
|
-
effective_irradiance = pvsystem.sapm_effective_irradiance(
|
|
213
|
-
total_irrad['poa_direct'], total_irrad['poa_diffuse'], airmass, aoi,
|
|
214
|
-
module_parameters)
|
|
215
|
-
|
|
216
|
-
dc = pvsystem.sapm(effective_irradiance, cell_temperature,
|
|
217
|
-
module_parameters)
|
|
218
|
-
|
|
219
|
-
ac = inverter.sandia(dc['v_mp'], dc['p_mp'], inverter_parameters)
|
|
220
|
-
|
|
221
|
-
return dc, ac
|
|
222
|
-
|
|
223
|
-
|
|
224
62
|
def get_orientation(strategy, **kwargs):
|
|
225
63
|
"""
|
|
226
64
|
Determine a PV system's surface tilt and surface azimuth
|
|
@@ -238,7 +76,6 @@ def get_orientation(strategy, **kwargs):
|
|
|
238
76
|
-------
|
|
239
77
|
surface_tilt, surface_azimuth
|
|
240
78
|
"""
|
|
241
|
-
|
|
242
79
|
if strategy == 'south_at_latitude_tilt':
|
|
243
80
|
surface_azimuth = 180
|
|
244
81
|
surface_tilt = kwargs['latitude']
|
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
|