pvlib 0.10.5__py3-none-any.whl → 0.11.0a1__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/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 +0 -61
- pvlib/irradiance.py +133 -95
- pvlib/location.py +13 -5
- pvlib/modelchain.py +2 -165
- pvlib/pvsystem.py +23 -63
- pvlib/shading.py +350 -0
- pvlib/spectrum/__init__.py +5 -0
- pvlib/spectrum/mismatch.py +572 -43
- pvlib/spectrum/spectrl2.py +8 -8
- 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 +11 -39
- pvlib/tests/test_shading.py +167 -1
- pvlib/tests/test_singlediode.py +0 -19
- 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-0.10.5.dist-info → pvlib-0.11.0a1.dist-info}/METADATA +1 -1
- {pvlib-0.10.5.dist-info → pvlib-0.11.0a1.dist-info}/RECORD +38 -34
- {pvlib-0.10.5.dist-info → pvlib-0.11.0a1.dist-info}/WHEEL +1 -1
- pvlib/data/astm_g173_am15g.csv +0 -2003
- {pvlib-0.10.5.dist-info → pvlib-0.11.0a1.dist-info}/AUTHORS.md +0 -0
- {pvlib-0.10.5.dist-info → pvlib-0.11.0a1.dist-info}/LICENSE +0 -0
- {pvlib-0.10.5.dist-info → pvlib-0.11.0a1.dist-info}/top_level.txt +0 -0
pvlib/iam.py
CHANGED
|
@@ -592,10 +592,10 @@ def marion_diffuse(model, surface_tilt, **kwargs):
|
|
|
592
592
|
iam : dict
|
|
593
593
|
IAM values for each type of diffuse irradiance:
|
|
594
594
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
595
|
+
* 'sky': radiation from the sky dome (zenith <= 90)
|
|
596
|
+
* 'horizon': radiation from the region of the sky near the horizon
|
|
597
|
+
(89.5 <= zenith <= 90)
|
|
598
|
+
* 'ground': radiation reflected from the ground (zenith >= 90)
|
|
599
599
|
|
|
600
600
|
See [1]_ for a detailed description of each class.
|
|
601
601
|
|
|
@@ -667,10 +667,10 @@ def marion_integrate(function, surface_tilt, region, num=None):
|
|
|
667
667
|
region : {'sky', 'horizon', 'ground'}
|
|
668
668
|
The region to integrate over. Must be one of:
|
|
669
669
|
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
670
|
+
* 'sky': radiation from the sky dome (zenith <= 90)
|
|
671
|
+
* 'horizon': radiation from the region of the sky near the horizon
|
|
672
|
+
(89.5 <= zenith <= 90)
|
|
673
|
+
* 'ground': radiation reflected from the ground (zenith >= 90)
|
|
674
674
|
|
|
675
675
|
See [1]_ for a detailed description of each class.
|
|
676
676
|
|
|
@@ -678,8 +678,8 @@ def marion_integrate(function, surface_tilt, region, num=None):
|
|
|
678
678
|
The number of increments in the zenith integration.
|
|
679
679
|
If not specified, N will follow the values used in [1]_:
|
|
680
680
|
|
|
681
|
-
|
|
682
|
-
|
|
681
|
+
* 'sky' or 'ground': num = 180
|
|
682
|
+
* 'horizon': num = 1800
|
|
683
683
|
|
|
684
684
|
Returns
|
|
685
685
|
-------
|
|
@@ -1107,14 +1107,14 @@ def convert(source_name, source_params, target_name, weight=_sin_weight,
|
|
|
1107
1107
|
source_params : dict
|
|
1108
1108
|
A dictionary of parameters for the source model.
|
|
1109
1109
|
|
|
1110
|
-
|
|
1111
|
-
|
|
1110
|
+
If source model is ``'ashrae'``, the dictionary must contain
|
|
1111
|
+
the key ``'b'``.
|
|
1112
1112
|
|
|
1113
|
-
|
|
1114
|
-
|
|
1113
|
+
If source model is ``'martin_ruiz'``, the dictionary must
|
|
1114
|
+
contain the key ``'a_r'``.
|
|
1115
1115
|
|
|
1116
|
-
|
|
1117
|
-
|
|
1116
|
+
If source model is ``'physical'``, the dictionary must
|
|
1117
|
+
contain the keys ``'n'``, ``'K'``, and ``'L'``.
|
|
1118
1118
|
|
|
1119
1119
|
target_name : str
|
|
1120
1120
|
Name of the target model. Must be ``'ashrae'``, ``'martin_ruiz'``, or
|
|
@@ -1146,14 +1146,14 @@ def convert(source_name, source_params, target_name, weight=_sin_weight,
|
|
|
1146
1146
|
dict
|
|
1147
1147
|
Parameters for the target model.
|
|
1148
1148
|
|
|
1149
|
-
|
|
1150
|
-
|
|
1149
|
+
If target model is ``'ashrae'``, the dictionary will contain
|
|
1150
|
+
the key ``'b'``.
|
|
1151
1151
|
|
|
1152
|
-
|
|
1153
|
-
|
|
1152
|
+
If target model is ``'martin_ruiz'``, the dictionary will
|
|
1153
|
+
contain the key ``'a_r'``.
|
|
1154
1154
|
|
|
1155
|
-
|
|
1156
|
-
|
|
1155
|
+
If target model is ``'physical'``, the dictionary will
|
|
1156
|
+
contain the keys ``'n'``, ``'K'``, and ``'L'``.
|
|
1157
1157
|
|
|
1158
1158
|
Note
|
|
1159
1159
|
----
|
|
@@ -1243,14 +1243,14 @@ def fit(measured_aoi, measured_iam, model_name, weight=_sin_weight, xtol=None):
|
|
|
1243
1243
|
dict
|
|
1244
1244
|
Parameters for target model.
|
|
1245
1245
|
|
|
1246
|
-
|
|
1247
|
-
|
|
1246
|
+
If target model is ``'ashrae'``, the dictionary will contain
|
|
1247
|
+
the key ``'b'``.
|
|
1248
1248
|
|
|
1249
|
-
|
|
1250
|
-
|
|
1249
|
+
If target model is ``'martin_ruiz'``, the dictionary will
|
|
1250
|
+
contain the key ``'a_r'``.
|
|
1251
1251
|
|
|
1252
|
-
|
|
1253
|
-
|
|
1252
|
+
If target model is ``'physical'``, the dictionary will
|
|
1253
|
+
contain the keys ``'n'``, ``'K'``, and ``'L'``.
|
|
1254
1254
|
|
|
1255
1255
|
References
|
|
1256
1256
|
----------
|
pvlib/iotools/__init__.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
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
|
-
from pvlib.iotools.srml import read_srml_month_from_solardat # noqa: F401
|
|
5
4
|
from pvlib.iotools.srml import get_srml # noqa: F401
|
|
6
5
|
from pvlib.iotools.surfrad import read_surfrad # noqa: F401
|
|
7
6
|
from pvlib.iotools.midc import read_midc # noqa: F401
|
pvlib/iotools/midc.py
CHANGED
|
@@ -20,15 +20,21 @@ import pandas as pd
|
|
|
20
20
|
MIDC_VARIABLE_MAP = {
|
|
21
21
|
'BMS': {
|
|
22
22
|
'Global CMP22 (vent/cor) [W/m^2]': 'ghi',
|
|
23
|
-
'Direct
|
|
23
|
+
'Direct CHP1-1 [W/m^2]': 'dni_chp1',
|
|
24
|
+
# NIP was mapped to dni for pvlib<=0.10.5
|
|
25
|
+
'Direct NIP [W/m^2]': 'dni_nip',
|
|
24
26
|
'Diffuse CM22-1 (vent/cor) [W/m^2]': 'dhi',
|
|
25
27
|
'Avg Wind Speed @ 6ft [m/s]': 'wind_speed',
|
|
26
28
|
'Tower Dry Bulb Temp [deg C]': 'temp_air',
|
|
27
29
|
'Tower RH [%]': 'relative_humidity'},
|
|
28
30
|
'UOSMRL': {
|
|
29
31
|
'Global CMP22 [W/m^2]': 'ghi',
|
|
30
|
-
'Direct
|
|
31
|
-
'Diffuse
|
|
32
|
+
'Direct CHP1 [W/m^2]': 'dni_chp1',
|
|
33
|
+
'Diffuse [W/m^2]': 'dhi',
|
|
34
|
+
# NIP was mapped to dni for pvlib<=0.10.5
|
|
35
|
+
'Direct NIP [W/m^2]': 'dni_nip',
|
|
36
|
+
# Schenk was mapped to dhi for pvlib<=0.10.5
|
|
37
|
+
# 'Diffuse Schenk [W/m^2]': 'dhi',
|
|
32
38
|
'Air Temperature [deg C]': 'temp_air',
|
|
33
39
|
'Relative Humidity [%]': 'relative_humidity',
|
|
34
40
|
'Avg Wind Speed @ 10m [m/s]': 'wind_speed'},
|
|
@@ -80,18 +86,17 @@ MIDC_VARIABLE_MAP = {
|
|
|
80
86
|
'Air Temperature [deg C]': 'temp_air',
|
|
81
87
|
'Rel Humidity [%]': 'relative_humidity',
|
|
82
88
|
'Avg Wind Speed @ 3m [m/s]': 'wind_speed'},
|
|
83
|
-
'
|
|
89
|
+
'NWTC': {
|
|
84
90
|
'Global Horizontal [W/m^2]': 'ghi',
|
|
85
91
|
'Direct Normal [W/m^2]': 'dni',
|
|
86
92
|
'Diffuse Horizontal [W/m^2]': 'dhi',
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
'
|
|
90
|
-
'NWTC': {
|
|
91
|
-
'Global PSP [W/m^2]': 'ghi',
|
|
93
|
+
# PSP instrument was removed Feb. 2021
|
|
94
|
+
# PSP was mapped to ghi for pvlib<=0.10.5
|
|
95
|
+
# 'Global PSP [W/m^2]': 'ghi',
|
|
92
96
|
'Temperature @ 2m [deg C]': 'temp_air',
|
|
93
97
|
'Avg Wind Speed @ 2m [m/s]': 'wind_speed',
|
|
94
|
-
'Relative Humidity [%]': 'relative_humidity'}
|
|
98
|
+
'Relative Humidity [%]': 'relative_humidity'},
|
|
99
|
+
}
|
|
95
100
|
|
|
96
101
|
|
|
97
102
|
# Maps problematic timezones to 'Etc/GMT' for parsing.
|
pvlib/iotools/psm3.py
CHANGED
|
@@ -62,8 +62,8 @@ REQUEST_VARIABLE_MAP = {
|
|
|
62
62
|
|
|
63
63
|
|
|
64
64
|
def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,
|
|
65
|
-
attributes=ATTRIBUTES, leap_day=
|
|
66
|
-
affiliation=PVLIB_PYTHON, map_variables=
|
|
65
|
+
attributes=ATTRIBUTES, leap_day=True, full_name=PVLIB_PYTHON,
|
|
66
|
+
affiliation=PVLIB_PYTHON, map_variables=True, url=None,
|
|
67
67
|
timeout=30):
|
|
68
68
|
"""
|
|
69
69
|
Retrieve NSRDB PSM3 timeseries weather data from the PSM3 API. The NSRDB
|
|
@@ -105,14 +105,14 @@ def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,
|
|
|
105
105
|
for lists of available fields. Alternatively, pvlib names may also be
|
|
106
106
|
used (e.g. 'ghi' rather than 'GHI'); see :const:`REQUEST_VARIABLE_MAP`.
|
|
107
107
|
To retrieve all available fields, set ``attributes=[]``.
|
|
108
|
-
leap_day :
|
|
108
|
+
leap_day : bool, default : True
|
|
109
109
|
include leap day in the results. Only used for single-year requests
|
|
110
110
|
(i.e., it is ignored for tmy/tgy/tdy requests).
|
|
111
111
|
full_name : str, default 'pvlib python'
|
|
112
112
|
optional
|
|
113
113
|
affiliation : str, default 'pvlib python'
|
|
114
114
|
optional
|
|
115
|
-
map_variables :
|
|
115
|
+
map_variables : bool, default True
|
|
116
116
|
When true, renames columns of the Dataframe to pvlib variable names
|
|
117
117
|
where applicable. See variable :const:`VARIABLE_MAP`.
|
|
118
118
|
url : str, optional
|
|
@@ -179,14 +179,6 @@ def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,
|
|
|
179
179
|
# convert pvlib names in attributes to psm3 convention
|
|
180
180
|
attributes = [REQUEST_VARIABLE_MAP.get(a, a) for a in attributes]
|
|
181
181
|
|
|
182
|
-
if (leap_day is None) and (not names.startswith('t')):
|
|
183
|
-
warnings.warn(
|
|
184
|
-
'The ``get_psm3`` function will default to leap_day=True '
|
|
185
|
-
'starting in pvlib 0.11.0. Specify leap_day=True '
|
|
186
|
-
'to enable this behavior now, or specify leap_day=False '
|
|
187
|
-
'to hide this warning.', pvlibDeprecationWarning)
|
|
188
|
-
leap_day = False
|
|
189
|
-
|
|
190
182
|
# required query-string parameters for request to PSM3 API
|
|
191
183
|
params = {
|
|
192
184
|
'api_key': api_key,
|
|
@@ -227,7 +219,7 @@ def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,
|
|
|
227
219
|
return parse_psm3(fbuf, map_variables)
|
|
228
220
|
|
|
229
221
|
|
|
230
|
-
def parse_psm3(fbuf, map_variables=
|
|
222
|
+
def parse_psm3(fbuf, map_variables=True):
|
|
231
223
|
"""
|
|
232
224
|
Parse an NSRDB PSM3 weather file (formatted as SAM CSV). The NSRDB
|
|
233
225
|
is described in [1]_ and the SAM CSV format is described in [2]_.
|
|
@@ -241,9 +233,9 @@ def parse_psm3(fbuf, map_variables=None):
|
|
|
241
233
|
----------
|
|
242
234
|
fbuf: file-like object
|
|
243
235
|
File-like object containing data to read.
|
|
244
|
-
map_variables: bool
|
|
236
|
+
map_variables: bool, default True
|
|
245
237
|
When true, renames columns of the Dataframe to pvlib variable names
|
|
246
|
-
where applicable. See variable VARIABLE_MAP
|
|
238
|
+
where applicable. See variable :const:`VARIABLE_MAP`.
|
|
247
239
|
|
|
248
240
|
Returns
|
|
249
241
|
-------
|
|
@@ -356,13 +348,6 @@ def parse_psm3(fbuf, map_variables=None):
|
|
|
356
348
|
tz = 'Etc/GMT%+d' % -metadata['Time Zone']
|
|
357
349
|
data.index = pd.DatetimeIndex(dtidx).tz_localize(tz)
|
|
358
350
|
|
|
359
|
-
if map_variables is None:
|
|
360
|
-
warnings.warn(
|
|
361
|
-
'PSM3 variable names will be renamed to pvlib conventions by '
|
|
362
|
-
'default starting in pvlib 0.11.0. Specify map_variables=True '
|
|
363
|
-
'to enable that behavior now, or specify map_variables=False '
|
|
364
|
-
'to hide this warning.', pvlibDeprecationWarning)
|
|
365
|
-
map_variables = False
|
|
366
351
|
if map_variables:
|
|
367
352
|
data = data.rename(columns=VARIABLE_MAP)
|
|
368
353
|
metadata['latitude'] = metadata.pop('Latitude')
|
|
@@ -372,7 +357,7 @@ def parse_psm3(fbuf, map_variables=None):
|
|
|
372
357
|
return data, metadata
|
|
373
358
|
|
|
374
359
|
|
|
375
|
-
def read_psm3(filename, map_variables=
|
|
360
|
+
def read_psm3(filename, map_variables=True):
|
|
376
361
|
"""
|
|
377
362
|
Read an NSRDB PSM3 weather file (formatted as SAM CSV). The NSRDB
|
|
378
363
|
is described in [1]_ and the SAM CSV format is described in [2]_.
|
|
@@ -386,9 +371,9 @@ def read_psm3(filename, map_variables=None):
|
|
|
386
371
|
----------
|
|
387
372
|
filename: str
|
|
388
373
|
Filename of a file containing data to read.
|
|
389
|
-
map_variables: bool
|
|
374
|
+
map_variables: bool, default True
|
|
390
375
|
When true, renames columns of the Dataframe to pvlib variable names
|
|
391
|
-
where applicable. See variable VARIABLE_MAP
|
|
376
|
+
where applicable. See variable :const:`VARIABLE_MAP`.
|
|
392
377
|
|
|
393
378
|
Returns
|
|
394
379
|
-------
|
pvlib/iotools/srml.py
CHANGED
|
@@ -6,8 +6,6 @@ import pandas as pd
|
|
|
6
6
|
import urllib
|
|
7
7
|
import warnings
|
|
8
8
|
|
|
9
|
-
from pvlib._deprecation import deprecated
|
|
10
|
-
|
|
11
9
|
# VARIABLE_MAP is a dictionary mapping SRML data element numbers to their
|
|
12
10
|
# pvlib names. For most variables, only the first three digits are used,
|
|
13
11
|
# the fourth indicating the instrument. Spectral data (7xxx) uses all
|
|
@@ -172,65 +170,6 @@ def _format_index(df):
|
|
|
172
170
|
return df
|
|
173
171
|
|
|
174
172
|
|
|
175
|
-
@deprecated('0.10.0', alternative='pvlib.iotools.get_srml', removal='0.11.0')
|
|
176
|
-
def read_srml_month_from_solardat(station, year, month, filetype='PO',
|
|
177
|
-
map_variables=True):
|
|
178
|
-
"""
|
|
179
|
-
Request a month of SRML data and read it into a Dataframe.
|
|
180
|
-
|
|
181
|
-
The SRML is described in [1]_.
|
|
182
|
-
|
|
183
|
-
Parameters
|
|
184
|
-
----------
|
|
185
|
-
station: str
|
|
186
|
-
The name of the SRML station to request.
|
|
187
|
-
year: int
|
|
188
|
-
Year to request data for
|
|
189
|
-
month: int
|
|
190
|
-
Month to request data for.
|
|
191
|
-
filetype: string
|
|
192
|
-
SRML file type to gather. See notes for explanation.
|
|
193
|
-
map_variables: bool, default: True
|
|
194
|
-
When true, renames columns of the DataFrame to pvlib variable names
|
|
195
|
-
where applicable. See variable :const:`VARIABLE_MAP`.
|
|
196
|
-
|
|
197
|
-
Returns
|
|
198
|
-
-------
|
|
199
|
-
data: pd.DataFrame
|
|
200
|
-
One month of data from SRML.
|
|
201
|
-
|
|
202
|
-
Notes
|
|
203
|
-
-----
|
|
204
|
-
File types designate the time interval of a file and if it contains
|
|
205
|
-
raw or processed data. For instance, `RO` designates raw, one minute
|
|
206
|
-
data and `PO` designates processed one minute data. The availability
|
|
207
|
-
of file types varies between sites. Below is a table of file types
|
|
208
|
-
and their time intervals. See [1] for site information.
|
|
209
|
-
|
|
210
|
-
============= ============ ==================
|
|
211
|
-
time interval raw filetype processed filetype
|
|
212
|
-
============= ============ ==================
|
|
213
|
-
1 minute RO PO
|
|
214
|
-
5 minute RF PF
|
|
215
|
-
15 minute RQ PQ
|
|
216
|
-
hourly RH PH
|
|
217
|
-
============= ============ ==================
|
|
218
|
-
|
|
219
|
-
References
|
|
220
|
-
----------
|
|
221
|
-
.. [1] University of Oregon Solar Radiation Measurement Laboratory
|
|
222
|
-
http://solardata.uoregon.edu/
|
|
223
|
-
"""
|
|
224
|
-
file_name = "{station}{filetype}{year:02d}{month:02d}.txt".format(
|
|
225
|
-
station=station,
|
|
226
|
-
filetype=filetype,
|
|
227
|
-
year=year % 100,
|
|
228
|
-
month=month)
|
|
229
|
-
url = "http://solardata.uoregon.edu/download/Archive/"
|
|
230
|
-
data = read_srml(url + file_name, map_variables=map_variables)
|
|
231
|
-
return data
|
|
232
|
-
|
|
233
|
-
|
|
234
173
|
def get_srml(station, start, end, filetype='PO', map_variables=True,
|
|
235
174
|
url="http://solardata.uoregon.edu/download/Archive/"):
|
|
236
175
|
"""Request data from UoO SRML and read it into a Dataframe.
|
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
|