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
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
horizon_azimuth,horizon_elevation
|
|
2
|
+
0,9.9
|
|
3
|
+
7.5,13
|
|
4
|
+
15,14.5
|
|
5
|
+
22.5,15.7
|
|
6
|
+
30,14.9
|
|
7
|
+
37.5,15.3
|
|
8
|
+
45,15.7
|
|
9
|
+
52.5,15.7
|
|
10
|
+
60,13
|
|
11
|
+
67.5,11.5
|
|
12
|
+
75,11.1
|
|
13
|
+
82.5,11.5
|
|
14
|
+
90,10.3
|
|
15
|
+
97.5,11.5
|
|
16
|
+
105,10.3
|
|
17
|
+
112.5,9.5
|
|
18
|
+
120,10.7
|
|
19
|
+
127.5,11.8
|
|
20
|
+
135,11.8
|
|
21
|
+
142.5,8.8
|
|
22
|
+
150,8.4
|
|
23
|
+
157.5,7.3
|
|
24
|
+
165,5.7
|
|
25
|
+
172.5,5.7
|
|
26
|
+
180,4.6
|
|
27
|
+
187.5,3.4
|
|
28
|
+
195,0.8
|
|
29
|
+
202.5,0
|
|
30
|
+
210,0
|
|
31
|
+
217.5,0
|
|
32
|
+
225,0
|
|
33
|
+
232.5,0
|
|
34
|
+
240,0
|
|
35
|
+
247.5,0
|
|
36
|
+
255,0
|
|
37
|
+
262.5,0
|
|
38
|
+
270,0
|
|
39
|
+
277.5,0
|
|
40
|
+
285,0
|
|
41
|
+
292.5,0
|
|
42
|
+
300,0
|
|
43
|
+
307.5,0
|
|
44
|
+
315,1.1
|
|
45
|
+
322.5,1.9
|
|
46
|
+
330,3.8
|
|
47
|
+
337.5,5
|
|
48
|
+
345,6.5
|
|
49
|
+
352.5,9.2
|
|
@@ -7,6 +7,7 @@ dni_extra;direct normal irradiance at top of atmosphere (extraterrestrial)
|
|
|
7
7
|
dhi;diffuse horizontal irradiance
|
|
8
8
|
bhi;beam/direct horizontal irradiance
|
|
9
9
|
ghi;global horizontal irradiance
|
|
10
|
+
ghi_extra;horizontal irradiance at top of atmosphere (extraterrestrial)
|
|
10
11
|
gri;ground-reflected irradiance
|
|
11
12
|
aoi;angle of incidence between :math:`90\deg` and :math:`90\deg`
|
|
12
13
|
aoi_projection;cos(aoi)
|
|
@@ -32,6 +33,8 @@ relative_humidity;relative humidity
|
|
|
32
33
|
wind_speed;wind speed
|
|
33
34
|
wind_direction;wind direction
|
|
34
35
|
pressure;atmospheric pressure
|
|
36
|
+
albedo;ratio of reflected solar irradiance to global horizontal irradiance, unitless
|
|
37
|
+
precipitable_water;total precipitable water contained in a column of unit cross section from earth to top of atmosphere
|
|
35
38
|
v_mp, i_mp, p_mp;module voltage, current, power at the maximum power point
|
|
36
39
|
v_oc;open circuit module voltage
|
|
37
40
|
i_sc;short circuit module current
|
pvlib/iam.py
CHANGED
|
@@ -11,7 +11,7 @@ irradiance to the module's surface.
|
|
|
11
11
|
import numpy as np
|
|
12
12
|
import pandas as pd
|
|
13
13
|
import functools
|
|
14
|
-
from pvlib.tools import cosd, sind
|
|
14
|
+
from pvlib.tools import cosd, sind
|
|
15
15
|
|
|
16
16
|
# a dict of required parameter names for each IAM model
|
|
17
17
|
# keys are the function names for the IAM models
|
|
@@ -91,21 +91,22 @@ def ashrae(aoi, b=0.05):
|
|
|
91
91
|
return iam
|
|
92
92
|
|
|
93
93
|
|
|
94
|
-
def physical(aoi, n=1.526, K=4
|
|
94
|
+
def physical(aoi, n=1.526, K=4.0, L=0.002, *, n_ar=None):
|
|
95
95
|
r"""
|
|
96
96
|
Determine the incidence angle modifier using refractive index ``n``,
|
|
97
|
-
extinction coefficient ``K``,
|
|
97
|
+
extinction coefficient ``K``, glazing thickness ``L`` and refractive
|
|
98
|
+
index ``n_ar`` of an optional anti-reflective coating.
|
|
98
99
|
|
|
99
100
|
``iam.physical`` calculates the incidence angle modifier as described in
|
|
100
|
-
[1]_, Section 3
|
|
101
|
+
[1]_, Section 3, with additional support of an anti-reflective coating.
|
|
102
|
+
The calculation is based on a physical model of reflections, absorption,
|
|
101
103
|
and transmission through a transparent cover.
|
|
102
104
|
|
|
103
105
|
Parameters
|
|
104
106
|
----------
|
|
105
107
|
aoi : numeric
|
|
106
108
|
The angle of incidence between the module normal vector and the
|
|
107
|
-
sun-beam vector in degrees. Angles of
|
|
108
|
-
to ensure non-nan results. Angles of nan will result in nan.
|
|
109
|
+
sun-beam vector in degrees. Angles of nan will result in nan.
|
|
109
110
|
|
|
110
111
|
n : numeric, default 1.526
|
|
111
112
|
The effective index of refraction (unitless). Reference [1]_
|
|
@@ -121,6 +122,11 @@ def physical(aoi, n=1.526, K=4., L=0.002):
|
|
|
121
122
|
indicates that 0.002 meters (2 mm) is reasonable for most
|
|
122
123
|
glass-covered PV panels.
|
|
123
124
|
|
|
125
|
+
n_ar : numeric, optional
|
|
126
|
+
The effective index of refraction of the anti-reflective (AR) coating
|
|
127
|
+
(unitless). If n_ar is None (default), no AR coating is applied.
|
|
128
|
+
A typical value for the effective index of an AR coating is 1.29.
|
|
129
|
+
|
|
124
130
|
Returns
|
|
125
131
|
-------
|
|
126
132
|
iam : numeric
|
|
@@ -149,48 +155,78 @@ def physical(aoi, n=1.526, K=4., L=0.002):
|
|
|
149
155
|
pvlib.iam.interp
|
|
150
156
|
pvlib.iam.sapm
|
|
151
157
|
"""
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
#
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
158
|
+
n1, n3 = 1, n
|
|
159
|
+
if n_ar is None or np.allclose(n_ar, n1):
|
|
160
|
+
# no AR coating
|
|
161
|
+
n2 = n
|
|
162
|
+
else:
|
|
163
|
+
n2 = n_ar
|
|
164
|
+
|
|
165
|
+
# incidence angle
|
|
166
|
+
costheta = np.maximum(0, cosd(aoi)) # always >= 0
|
|
167
|
+
sintheta = np.sqrt(1 - costheta**2) # always >= 0
|
|
168
|
+
n1costheta1 = n1 * costheta
|
|
169
|
+
n2costheta1 = n2 * costheta
|
|
170
|
+
|
|
171
|
+
# refraction angle of first interface
|
|
172
|
+
sintheta = n1 / n2 * sintheta
|
|
173
|
+
costheta = np.sqrt(1 - sintheta**2)
|
|
174
|
+
n1costheta2 = n1 * costheta
|
|
175
|
+
n2costheta2 = n2 * costheta
|
|
176
|
+
|
|
177
|
+
# reflectance of s-, p-polarized, and normal light by the first interface
|
|
178
|
+
with np.errstate(divide='ignore', invalid='ignore'):
|
|
179
|
+
rho12_s = \
|
|
180
|
+
((n1costheta1 - n2costheta2) / (n1costheta1 + n2costheta2)) ** 2
|
|
181
|
+
rho12_p = \
|
|
182
|
+
((n1costheta2 - n2costheta1) / (n1costheta2 + n2costheta1)) ** 2
|
|
183
|
+
|
|
184
|
+
rho12_0 = ((n1 - n2) / (n1 + n2)) ** 2
|
|
185
|
+
|
|
186
|
+
# transmittance through the first interface
|
|
187
|
+
tau_s = 1 - rho12_s
|
|
188
|
+
tau_p = 1 - rho12_p
|
|
189
|
+
tau_0 = 1 - rho12_0
|
|
190
|
+
|
|
191
|
+
if not np.allclose(n3, n2): # AR coated glass
|
|
192
|
+
n3costheta2 = n3 * costheta
|
|
193
|
+
# refraction angle of second interface
|
|
194
|
+
sintheta = n2 / n3 * sintheta
|
|
195
|
+
costheta = np.sqrt(1 - sintheta**2)
|
|
196
|
+
n2costheta3 = n2 * costheta
|
|
197
|
+
n3costheta3 = n3 * costheta
|
|
198
|
+
|
|
199
|
+
# reflectance by the second interface
|
|
200
|
+
rho23_s = (
|
|
201
|
+
(n2costheta2 - n3costheta3) / (n2costheta2 + n3costheta3)
|
|
202
|
+
) ** 2
|
|
203
|
+
rho23_p = (
|
|
204
|
+
(n2costheta3 - n3costheta2) / (n2costheta3 + n3costheta2)
|
|
205
|
+
) ** 2
|
|
206
|
+
rho23_0 = ((n2 - n3) / (n2 + n3)) ** 2
|
|
207
|
+
|
|
208
|
+
# transmittance through the coating, including internal reflections
|
|
209
|
+
# 1 + rho23*rho12 + (rho23*rho12)^2 + ... = 1/(1 - rho23*rho12)
|
|
210
|
+
tau_s *= (1 - rho23_s) / (1 - rho23_s * rho12_s)
|
|
211
|
+
tau_p *= (1 - rho23_p) / (1 - rho23_p * rho12_p)
|
|
212
|
+
tau_0 *= (1 - rho23_0) / (1 - rho23_0 * rho12_0)
|
|
213
|
+
|
|
214
|
+
# transmittance after absorption in the glass
|
|
215
|
+
with np.errstate(divide='ignore', invalid='ignore'):
|
|
216
|
+
tau_s *= np.exp(-K * L / costheta)
|
|
217
|
+
tau_p *= np.exp(-K * L / costheta)
|
|
218
|
+
|
|
219
|
+
tau_0 *= np.exp(-K * L)
|
|
220
|
+
|
|
221
|
+
# incidence angle modifier
|
|
222
|
+
iam = (tau_s + tau_p) / 2 / tau_0
|
|
223
|
+
|
|
224
|
+
# for light coming from behind the plane, none can enter the module
|
|
225
|
+
# when n2 > 1, this is already the case
|
|
226
|
+
if np.isclose(n2, 1).any():
|
|
227
|
+
iam = np.where(aoi >= 90, 0, iam)
|
|
228
|
+
if isinstance(aoi, pd.Series):
|
|
229
|
+
iam = pd.Series(iam, index=aoi.index)
|
|
194
230
|
|
|
195
231
|
return iam
|
|
196
232
|
|
|
@@ -227,7 +263,7 @@ def martin_ruiz(aoi, a_r=0.16):
|
|
|
227
263
|
|
|
228
264
|
.. math::
|
|
229
265
|
|
|
230
|
-
IAM = \frac{1 - \exp(-\cos(
|
|
266
|
+
IAM = \frac{1 - \exp(-\frac{\cos(aoi)}{a_r})}
|
|
231
267
|
{1 - \exp(\frac{-1}{a_r})}
|
|
232
268
|
|
|
233
269
|
which is presented as :math:`AL(\alpha) = 1 - IAM` in equation 4 of [1]_,
|
|
@@ -353,7 +389,6 @@ def martin_ruiz_diffuse(surface_tilt, a_r=0.16, c1=0.4244, c2=None):
|
|
|
353
389
|
# avoid undefined results for horizontal or upside-down surfaces
|
|
354
390
|
zeroang = 1e-06
|
|
355
391
|
|
|
356
|
-
|
|
357
392
|
surface_tilt = np.where(surface_tilt == 0, zeroang, surface_tilt)
|
|
358
393
|
surface_tilt = np.where(surface_tilt == 180, 180 - zeroang, surface_tilt)
|
|
359
394
|
|
|
@@ -541,7 +576,7 @@ def marion_diffuse(model, surface_tilt, **kwargs):
|
|
|
541
576
|
----------
|
|
542
577
|
model : str
|
|
543
578
|
The IAM function to evaluate across solid angle. Must be one of
|
|
544
|
-
`'ashrae', 'physical', 'martin_ruiz', 'sapm'`.
|
|
579
|
+
`'ashrae', 'physical', 'martin_ruiz', 'sapm', 'schlick'`.
|
|
545
580
|
|
|
546
581
|
surface_tilt : numeric
|
|
547
582
|
Surface tilt angles in decimal degrees.
|
|
@@ -592,6 +627,7 @@ def marion_diffuse(model, surface_tilt, **kwargs):
|
|
|
592
627
|
'ashrae': ashrae,
|
|
593
628
|
'sapm': sapm,
|
|
594
629
|
'martin_ruiz': martin_ruiz,
|
|
630
|
+
'schlick': schlick,
|
|
595
631
|
}
|
|
596
632
|
|
|
597
633
|
try:
|
|
@@ -748,3 +784,123 @@ def marion_integrate(function, surface_tilt, region, num=None):
|
|
|
748
784
|
Fd = pd.Series(Fd, surface_tilt.index)
|
|
749
785
|
|
|
750
786
|
return Fd
|
|
787
|
+
|
|
788
|
+
|
|
789
|
+
def schlick(aoi):
|
|
790
|
+
"""
|
|
791
|
+
Determine incidence angle modifier (IAM) for direct irradiance using the
|
|
792
|
+
Schlick approximation to the Fresnel equations.
|
|
793
|
+
|
|
794
|
+
The Schlick approximation was proposed in [1]_ as a computationally
|
|
795
|
+
efficient alternative to computing the Fresnel factor in computer
|
|
796
|
+
graphics contexts. This implementation is a normalized form of the
|
|
797
|
+
equation in [1]_ so that it can be used as a PV IAM model.
|
|
798
|
+
Unlike other IAM models, this model has no ability to describe
|
|
799
|
+
different reflection profiles.
|
|
800
|
+
|
|
801
|
+
In PV contexts, the Schlick approximation has been used as an analytically
|
|
802
|
+
integrable alternative to the Fresnel equations for estimating IAM
|
|
803
|
+
for diffuse irradiance [2]_.
|
|
804
|
+
|
|
805
|
+
Parameters
|
|
806
|
+
----------
|
|
807
|
+
aoi : numeric
|
|
808
|
+
The angle of incidence (AOI) between the module normal vector and the
|
|
809
|
+
sun-beam vector. Angles of nan will result in nan. [degrees]
|
|
810
|
+
|
|
811
|
+
Returns
|
|
812
|
+
-------
|
|
813
|
+
iam : numeric
|
|
814
|
+
The incident angle modifier.
|
|
815
|
+
|
|
816
|
+
References
|
|
817
|
+
----------
|
|
818
|
+
.. [1] Schlick, C. An inexpensive BRDF model for physically-based
|
|
819
|
+
rendering. Computer graphics forum 13 (1994).
|
|
820
|
+
|
|
821
|
+
.. [2] Xie, Y., M. Sengupta, A. Habte, A. Andreas, "The 'Fresnel Equations'
|
|
822
|
+
for Diffuse radiation on Inclined photovoltaic Surfaces (FEDIS)",
|
|
823
|
+
Renewable and Sustainable Energy Reviews, vol. 161, 112362. June 2022.
|
|
824
|
+
:doi:`10.1016/j.rser.2022.112362`
|
|
825
|
+
|
|
826
|
+
See Also
|
|
827
|
+
--------
|
|
828
|
+
pvlib.iam.schlick_diffuse
|
|
829
|
+
"""
|
|
830
|
+
iam = 1 - (1 - cosd(aoi)) ** 5
|
|
831
|
+
iam = np.where(np.abs(aoi) >= 90.0, 0.0, iam)
|
|
832
|
+
|
|
833
|
+
# preserve input type
|
|
834
|
+
if np.isscalar(aoi):
|
|
835
|
+
iam = iam.item()
|
|
836
|
+
elif isinstance(aoi, pd.Series):
|
|
837
|
+
iam = pd.Series(iam, aoi.index)
|
|
838
|
+
|
|
839
|
+
return iam
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
def schlick_diffuse(surface_tilt):
|
|
843
|
+
"""
|
|
844
|
+
Determine the incidence angle modifiers (IAM) for diffuse sky and
|
|
845
|
+
ground-reflected irradiance on a tilted surface using the Schlick
|
|
846
|
+
incident angle model.
|
|
847
|
+
|
|
848
|
+
The diffuse iam values are calculated using an analytical integration
|
|
849
|
+
of the Schlick equation [1]_ over the portion of an isotropic sky and
|
|
850
|
+
isotropic foreground that is visible from the tilted surface [2]_.
|
|
851
|
+
|
|
852
|
+
Parameters
|
|
853
|
+
----------
|
|
854
|
+
surface_tilt : numeric
|
|
855
|
+
Surface tilt angle measured from horizontal (e.g. surface facing
|
|
856
|
+
up = 0, surface facing horizon = 90). [degrees]
|
|
857
|
+
|
|
858
|
+
Returns
|
|
859
|
+
-------
|
|
860
|
+
iam_sky : numeric
|
|
861
|
+
The incident angle modifier for sky diffuse.
|
|
862
|
+
|
|
863
|
+
iam_ground : numeric
|
|
864
|
+
The incident angle modifier for ground-reflected diffuse.
|
|
865
|
+
|
|
866
|
+
References
|
|
867
|
+
----------
|
|
868
|
+
.. [1] Schlick, C. An inexpensive BRDF model for physically-based
|
|
869
|
+
rendering. Computer graphics forum 13 (1994).
|
|
870
|
+
|
|
871
|
+
.. [2] Xie, Y., M. Sengupta, A. Habte, A. Andreas, "The 'Fresnel Equations'
|
|
872
|
+
for Diffuse radiation on Inclined photovoltaic Surfaces (FEDIS)",
|
|
873
|
+
Renewable and Sustainable Energy Reviews, vol. 161, 112362. June 2022.
|
|
874
|
+
:doi:`10.1016/j.rser.2022.112362`
|
|
875
|
+
|
|
876
|
+
See Also
|
|
877
|
+
--------
|
|
878
|
+
pvlib.iam.schlick
|
|
879
|
+
"""
|
|
880
|
+
# these calculations are as in [2]_, but with the refractive index
|
|
881
|
+
# weighting coefficient w set to 1.0 (so it is omitted)
|
|
882
|
+
|
|
883
|
+
# relative transmittance of sky diffuse radiation by PV cover:
|
|
884
|
+
cosB = cosd(surface_tilt)
|
|
885
|
+
sinB = sind(surface_tilt)
|
|
886
|
+
cuk = (2 / (np.pi * (1 + cosB))) * (
|
|
887
|
+
(30/7)*np.pi - (160/21)*np.radians(surface_tilt) - (10/3)*np.pi*cosB
|
|
888
|
+
+ (160/21)*cosB*sinB - (5/3)*np.pi*cosB*sinB**2 + (20/7)*cosB*sinB**3
|
|
889
|
+
- (5/16)*np.pi*cosB*sinB**4 + (16/105)*cosB*sinB**5
|
|
890
|
+
) # Eq 4 in [2]
|
|
891
|
+
|
|
892
|
+
# relative transmittance of ground-reflected radiation by PV cover:
|
|
893
|
+
with np.errstate(divide='ignore', invalid='ignore'): # Eq 6 in [2]
|
|
894
|
+
cug = 40 / (21 * (1 - cosB)) - (1 + cosB) / (1 - cosB) * cuk
|
|
895
|
+
|
|
896
|
+
cug = np.where(surface_tilt < 1e-6, 0, cug)
|
|
897
|
+
|
|
898
|
+
# respect input types:
|
|
899
|
+
if np.isscalar(surface_tilt):
|
|
900
|
+
cuk = cuk.item()
|
|
901
|
+
cug = cug.item()
|
|
902
|
+
elif isinstance(surface_tilt, pd.Series):
|
|
903
|
+
cuk = pd.Series(cuk, surface_tilt.index)
|
|
904
|
+
cug = pd.Series(cug, surface_tilt.index)
|
|
905
|
+
|
|
906
|
+
return cuk, cug
|
pvlib/inverter.py
CHANGED
|
@@ -335,7 +335,7 @@ def pvwatts(pdc, pdc0, eta_inv_nom=0.96, eta_inv_ref=0.9637):
|
|
|
335
335
|
NREL's PVWatts inverter model.
|
|
336
336
|
|
|
337
337
|
The PVWatts inverter model [1]_ calculates inverter efficiency :math:`\eta`
|
|
338
|
-
as a function of input DC power
|
|
338
|
+
as a function of input DC power :math:`P_{dc}`
|
|
339
339
|
|
|
340
340
|
.. math::
|
|
341
341
|
|
|
@@ -369,6 +369,10 @@ def pvwatts(pdc, pdc0, eta_inv_nom=0.96, eta_inv_ref=0.9637):
|
|
|
369
369
|
|
|
370
370
|
Notes
|
|
371
371
|
-----
|
|
372
|
+
When sourcing ``pdc`` from pvlib functions
|
|
373
|
+
(e.g. :py:func:`pvlib.pvsystem.pvwatts_dc`) their DC power output is in W,
|
|
374
|
+
and ``pdc0`` should have the same unit (W).
|
|
375
|
+
|
|
372
376
|
Note that ``pdc0`` is also used as a symbol in
|
|
373
377
|
:py:func:`pvlib.pvsystem.pvwatts_dc`. ``pdc0`` in this function refers to
|
|
374
378
|
the DC power input limit of the inverter. ``pdc0`` in
|
|
@@ -393,6 +397,7 @@ def pvwatts(pdc, pdc0, eta_inv_nom=0.96, eta_inv_ref=0.9637):
|
|
|
393
397
|
pdc_neq_0 = ~np.equal(pdc, 0)
|
|
394
398
|
|
|
395
399
|
# eta < 0 if zeta < 0.006. power_ac is forced to be >= 0 below. GH 541
|
|
400
|
+
# In some published versions of [1] the parentheses are missing
|
|
396
401
|
eta = eta_inv_nom / eta_inv_ref * (
|
|
397
402
|
-0.0162 * zeta - np.divide(0.0059, zeta, out=eta, where=pdc_neq_0)
|
|
398
403
|
+ 0.9858) # noQA: W503
|
pvlib/iotools/__init__.py
CHANGED
|
@@ -2,11 +2,10 @@ from pvlib.iotools.tmy import read_tmy2, read_tmy3 # noqa: F401
|
|
|
2
2
|
from pvlib.iotools.epw import read_epw, parse_epw # noqa: F401
|
|
3
3
|
from pvlib.iotools.srml import read_srml # noqa: F401
|
|
4
4
|
from pvlib.iotools.srml import read_srml_month_from_solardat # noqa: F401
|
|
5
|
+
from pvlib.iotools.srml import get_srml # noqa: F401
|
|
5
6
|
from pvlib.iotools.surfrad import read_surfrad # noqa: F401
|
|
6
7
|
from pvlib.iotools.midc import read_midc # noqa: F401
|
|
7
8
|
from pvlib.iotools.midc import read_midc_raw_data_from_nrel # noqa: F401
|
|
8
|
-
from pvlib.iotools.ecmwf_macc import read_ecmwf_macc # noqa: F401
|
|
9
|
-
from pvlib.iotools.ecmwf_macc import get_ecmwf_macc # noqa: F401
|
|
10
9
|
from pvlib.iotools.crn import read_crn # noqa: F401
|
|
11
10
|
from pvlib.iotools.solrad import read_solrad # noqa: F401
|
|
12
11
|
from pvlib.iotools.psm3 import get_psm3 # noqa: F401
|
|
@@ -15,9 +14,15 @@ from pvlib.iotools.psm3 import parse_psm3 # noqa: F401
|
|
|
15
14
|
from pvlib.iotools.pvgis import get_pvgis_tmy, read_pvgis_tmy # noqa: F401
|
|
16
15
|
from pvlib.iotools.pvgis import read_pvgis_hourly # noqa: F401
|
|
17
16
|
from pvlib.iotools.pvgis import get_pvgis_hourly # noqa: F401
|
|
17
|
+
from pvlib.iotools.pvgis import get_pvgis_horizon # noqa: F401
|
|
18
18
|
from pvlib.iotools.bsrn import get_bsrn # noqa: F401
|
|
19
19
|
from pvlib.iotools.bsrn import read_bsrn # noqa: F401
|
|
20
20
|
from pvlib.iotools.bsrn import parse_bsrn # noqa: F401
|
|
21
21
|
from pvlib.iotools.sodapro import get_cams # noqa: F401
|
|
22
22
|
from pvlib.iotools.sodapro import read_cams # noqa: F401
|
|
23
23
|
from pvlib.iotools.sodapro import parse_cams # noqa: F401
|
|
24
|
+
from pvlib.iotools.acis import get_acis_prism # noqa: F401
|
|
25
|
+
from pvlib.iotools.acis import get_acis_nrcc # noqa: F401
|
|
26
|
+
from pvlib.iotools.acis import get_acis_mpe # noqa: F401
|
|
27
|
+
from pvlib.iotools.acis import get_acis_station_data # noqa: F401
|
|
28
|
+
from pvlib.iotools.acis import get_acis_available_stations # noqa: F401
|