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.
Files changed (86) hide show
  1. pvlib/__init__.py +3 -2
  2. pvlib/atmosphere.py +23 -173
  3. pvlib/bifacial/infinite_sheds.py +88 -277
  4. pvlib/bifacial/utils.py +270 -28
  5. pvlib/data/adr-library-cec-inverters-2019-03-05.csv +5009 -0
  6. pvlib/data/precise_iv_curves1.json +10251 -0
  7. pvlib/data/precise_iv_curves2.json +10251 -0
  8. pvlib/data/precise_iv_curves_parameter_sets1.csv +33 -0
  9. pvlib/data/precise_iv_curves_parameter_sets2.csv +33 -0
  10. pvlib/data/test_psm3_2017.csv +17521 -17521
  11. pvlib/data/test_psm3_2019_5min.csv +288 -288
  12. pvlib/data/test_read_psm3.csv +17522 -17522
  13. pvlib/data/test_read_pvgis_horizon.csv +49 -0
  14. pvlib/data/variables_style_rules.csv +3 -0
  15. pvlib/iam.py +207 -51
  16. pvlib/inverter.py +6 -1
  17. pvlib/iotools/__init__.py +7 -2
  18. pvlib/iotools/acis.py +516 -0
  19. pvlib/iotools/midc.py +4 -4
  20. pvlib/iotools/psm3.py +59 -42
  21. pvlib/iotools/pvgis.py +84 -28
  22. pvlib/iotools/sodapro.py +8 -6
  23. pvlib/iotools/srml.py +121 -18
  24. pvlib/iotools/surfrad.py +2 -2
  25. pvlib/iotools/tmy.py +146 -102
  26. pvlib/irradiance.py +270 -15
  27. pvlib/ivtools/sde.py +14 -20
  28. pvlib/ivtools/sdm.py +31 -20
  29. pvlib/ivtools/utils.py +127 -6
  30. pvlib/location.py +3 -2
  31. pvlib/modelchain.py +67 -70
  32. pvlib/pvarray.py +225 -0
  33. pvlib/pvsystem.py +169 -539
  34. pvlib/shading.py +43 -2
  35. pvlib/singlediode.py +216 -66
  36. pvlib/snow.py +36 -15
  37. pvlib/soiling.py +3 -3
  38. pvlib/spa.py +327 -368
  39. pvlib/spectrum/__init__.py +8 -2
  40. pvlib/spectrum/mismatch.py +335 -0
  41. pvlib/temperature.py +124 -13
  42. pvlib/tests/bifacial/test_infinite_sheds.py +44 -106
  43. pvlib/tests/bifacial/test_utils.py +102 -5
  44. pvlib/tests/conftest.py +0 -31
  45. pvlib/tests/iotools/test_acis.py +213 -0
  46. pvlib/tests/iotools/test_midc.py +6 -6
  47. pvlib/tests/iotools/test_psm3.py +7 -5
  48. pvlib/tests/iotools/test_pvgis.py +21 -14
  49. pvlib/tests/iotools/test_sodapro.py +1 -1
  50. pvlib/tests/iotools/test_srml.py +71 -6
  51. pvlib/tests/iotools/test_tmy.py +43 -8
  52. pvlib/tests/ivtools/test_sde.py +19 -17
  53. pvlib/tests/ivtools/test_sdm.py +9 -4
  54. pvlib/tests/ivtools/test_utils.py +96 -1
  55. pvlib/tests/test_atmosphere.py +8 -64
  56. pvlib/tests/test_clearsky.py +0 -1
  57. pvlib/tests/test_iam.py +74 -1
  58. pvlib/tests/test_irradiance.py +56 -2
  59. pvlib/tests/test_location.py +1 -1
  60. pvlib/tests/test_modelchain.py +33 -76
  61. pvlib/tests/test_pvarray.py +46 -0
  62. pvlib/tests/test_pvsystem.py +366 -201
  63. pvlib/tests/test_shading.py +35 -0
  64. pvlib/tests/test_singlediode.py +306 -29
  65. pvlib/tests/test_snow.py +84 -1
  66. pvlib/tests/test_soiling.py +8 -7
  67. pvlib/tests/test_solarposition.py +7 -7
  68. pvlib/tests/test_spa.py +6 -7
  69. pvlib/tests/test_spectrum.py +145 -1
  70. pvlib/tests/test_temperature.py +29 -11
  71. pvlib/tests/test_tools.py +41 -0
  72. pvlib/tests/test_tracking.py +0 -149
  73. pvlib/tools.py +49 -25
  74. pvlib/tracking.py +1 -269
  75. pvlib-0.10.0.dist-info/AUTHORS.md +35 -0
  76. {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/LICENSE +5 -2
  77. {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/METADATA +3 -13
  78. {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/RECORD +80 -75
  79. {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/WHEEL +1 -1
  80. pvlib/data/adr-library-2013-10-01.csv +0 -1762
  81. pvlib/forecast.py +0 -1211
  82. pvlib/iotools/ecmwf_macc.py +0 -312
  83. pvlib/tests/iotools/test_ecmwf_macc.py +0 -162
  84. pvlib/tests/test_forecast.py +0 -228
  85. pvlib-0.9.4a1.dist-info/AUTHORS.md +0 -32
  86. {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/top_level.txt +0 -0
pvlib/bifacial/utils.py CHANGED
@@ -90,7 +90,7 @@ def _unshaded_ground_fraction(surface_tilt, surface_azimuth, solar_zenith,
90
90
  return f_gnd_beam # 1 - min(1, abs()) < 1 always
91
91
 
92
92
 
93
- def _vf_ground_sky_2d(x, rotation, gcr, pitch, height, max_rows=10):
93
+ def vf_ground_sky_2d(rotation, gcr, x, pitch, height, max_rows=10):
94
94
  r"""
95
95
  Calculate the fraction of the sky dome visible from point x on the ground.
96
96
 
@@ -100,15 +100,15 @@ def _vf_ground_sky_2d(x, rotation, gcr, pitch, height, max_rows=10):
100
100
 
101
101
  Parameters
102
102
  ----------
103
- x : numeric
104
- Position on the ground between two rows, as a fraction of the pitch.
105
- x = 0 corresponds to the point on the ground directly below the
106
- center point of a row. Positive x is towards the right. [unitless]
107
- rotation : float
103
+ rotation : numeric
108
104
  Rotation angle of the row's right edge relative to row center.
109
105
  [degree]
110
106
  gcr : float
111
107
  Ratio of the row slant length to the row spacing (pitch). [unitless]
108
+ x : numeric
109
+ Position on the ground between two rows, as a fraction of the pitch.
110
+ x = 0 corresponds to the point on the ground directly below the
111
+ center point of a row. Positive x is towards the right. [unitless]
112
112
  height : float
113
113
  Height of the center point of the row above the ground; must be in the
114
114
  same units as ``pitch``.
@@ -120,30 +120,272 @@ def _vf_ground_sky_2d(x, rotation, gcr, pitch, height, max_rows=10):
120
120
 
121
121
  Returns
122
122
  -------
123
- vf : numeric
124
- Fraction of sky dome visible from each point on the ground. [unitless]
125
- wedge_angles : array
126
- Angles defining each wedge of sky that is blocked by a row. Shape is
127
- (2, len(x), 2*max_rows+1). ``wedge_angles[0,:,:]`` is the
128
- starting angle of each wedge, ``wedge_angles[1,:,:]`` is the end angle.
129
- [degree]
123
+ vf : array
124
+ Fraction of sky dome visible from each point on the ground.
125
+ Shape is (len(x), len(rotation)). [unitless]
130
126
  """
131
- x = np.atleast_1d(x) # handle float
127
+ # This function creates large float64 arrays of size
128
+ # (2*len(x)*len(rotation)*len(max_rows)) or ~100 MB for
129
+ # typical time series inputs. This function makes heavy
130
+ # use of numpy's out parameter to avoid allocating new
131
+ # memory. Unfortunately that comes at the cost of some
132
+ # readability: because arrays get reused to avoid new allocations,
133
+ # variable names don't always match what they hold.
134
+
135
+ # handle floats:
136
+ x = np.atleast_1d(x)[:, np.newaxis, np.newaxis]
137
+ rotation = np.atleast_1d(rotation)[np.newaxis, :, np.newaxis]
132
138
  all_k = np.arange(-max_rows, max_rows + 1)
133
139
  width = gcr * pitch / 2.
140
+ distance_to_row_centers = (all_k - x) * pitch
141
+ dy = width * sind(rotation)
142
+ dx = width * cosd(rotation)
143
+
144
+ phi = np.empty((2, x.shape[0], rotation.shape[1], len(all_k)))
145
+
134
146
  # angles from x to right edge of each row
135
- a1 = height + width * sind(rotation)
136
- b1 = (all_k - x[:, np.newaxis]) * pitch + width * cosd(rotation)
137
- phi_1 = np.degrees(np.arctan2(a1, b1))
147
+ a1 = height + dy
148
+ # temporarily store one leg of the triangle in phi:
149
+ np.add(distance_to_row_centers, dx, out=phi[0])
150
+ np.arctan2(a1, phi[0], out=phi[0])
151
+
138
152
  # angles from x to left edge of each row
139
- a2 = height - width * sind(rotation)
140
- b2 = (all_k - x[:, np.newaxis]) * pitch - width * cosd(rotation)
141
- phi_2 = np.degrees(np.arctan2(a2, b2))
142
- phi = np.stack([phi_1, phi_2])
143
- swap = phi[0, :, :] > phi[1, :, :]
144
- # swap where phi_1 > phi_2 so that phi_1[0,:,:] is the lesser angle
145
- phi = np.where(swap, phi[::-1], phi)
146
- # right edge of next row - left edge of previous row
147
- wedge_vfs = 0.5 * (cosd(phi[1, :, 1:]) - cosd(phi[0, :, :-1]))
148
- vf = np.sum(np.where(wedge_vfs > 0, wedge_vfs, 0.), axis=1)
149
- return vf, phi
153
+ a2 = height - dy
154
+ np.subtract(distance_to_row_centers, dx, out=phi[1])
155
+ np.arctan2(a2, phi[1], out=phi[1])
156
+
157
+ # swap angles so that phi[0,:,:,:] is the lesser angle
158
+ phi.sort(axis=0)
159
+
160
+ # now re-use phi's memory again, this time storing cos(phi).
161
+ next_edge = phi[1, :, :, 1:]
162
+ np.cos(next_edge, out=next_edge)
163
+ prev_edge = phi[0, :, :, :-1]
164
+ np.cos(prev_edge, out=prev_edge)
165
+ # right edge of next row - left edge of previous row, again
166
+ # reusing memory so that the difference is stored in next_edge.
167
+ # Note that the 0.5 view factor coefficient is applied after summing
168
+ # as a minor speed optimization.
169
+ np.subtract(next_edge, prev_edge, out=next_edge)
170
+ np.clip(next_edge, a_min=0., a_max=None, out=next_edge)
171
+ vf = np.sum(next_edge, axis=-1) / 2
172
+ return vf
173
+
174
+
175
+ def vf_ground_sky_2d_integ(surface_tilt, gcr, height, pitch, max_rows=10,
176
+ npoints=100, vectorize=False):
177
+ """
178
+ Integrated view factor to the sky from the ground underneath
179
+ interior rows of the array.
180
+
181
+ Parameters
182
+ ----------
183
+ surface_tilt : numeric
184
+ Surface tilt angle in degrees from horizontal, e.g., surface facing up
185
+ = 0, surface facing horizon = 90. [degree]
186
+ gcr : float
187
+ Ratio of row slant length to row spacing (pitch). [unitless]
188
+ height : float
189
+ Height of the center point of the row above the ground; must be in the
190
+ same units as ``pitch``.
191
+ pitch : float
192
+ Distance between two rows. Must be in the same units as ``height``.
193
+ max_rows : int, default 10
194
+ Maximum number of rows to consider in front and behind the current row.
195
+ npoints : int, default 100
196
+ Number of points used to discretize distance along the ground.
197
+ vectorize : bool, default False
198
+ If True, vectorize the view factor calculation across ``surface_tilt``.
199
+ This increases speed with the cost of increased memory usage.
200
+
201
+ Returns
202
+ -------
203
+ fgnd_sky : numeric
204
+ Integration of view factor over the length between adjacent, interior
205
+ rows. Shape matches that of ``surface_tilt``. [unitless]
206
+ """
207
+ # Abuse vf_ground_sky_2d by supplying surface_tilt in place
208
+ # of a signed rotation. This is OK because
209
+ # 1) z span the full distance between 2 rows, and
210
+ # 2) max_rows is set to be large upstream, and
211
+ # 3) _vf_ground_sky_2d considers [-max_rows, +max_rows]
212
+ # The VFs to the sky will thus be symmetric around z=0.5
213
+ z = np.linspace(0, 1, npoints)
214
+ rotation = np.atleast_1d(surface_tilt)
215
+ if vectorize:
216
+ fz_sky = vf_ground_sky_2d(rotation, gcr, z, pitch, height, max_rows)
217
+ else:
218
+ fz_sky = np.zeros((npoints, len(rotation)))
219
+ for k, r in enumerate(rotation):
220
+ vf = vf_ground_sky_2d(r, gcr, z, pitch, height, max_rows)
221
+ fz_sky[:, k] = vf[:, 0] # remove spurious rotation dimension
222
+ # calculate the integrated view factor for all of the ground between rows
223
+ return np.trapz(fz_sky, z, axis=0)
224
+
225
+
226
+ def _vf_poly(surface_tilt, gcr, x, delta):
227
+ r'''
228
+ A term common to many 2D view factor calculations
229
+
230
+ Parameters
231
+ ----------
232
+ surface_tilt : numeric
233
+ Surface tilt angle in degrees from horizontal, e.g., surface facing up
234
+ = 0, surface facing horizon = 90. [degree]
235
+ gcr : numeric
236
+ Ratio of the row slant length to the row spacing (pitch). [unitless]
237
+ x : numeric
238
+ Position on the row's slant length, as a fraction of the slant length.
239
+ x=0 corresponds to the bottom of the row. [unitless]
240
+ delta : -1 or +1
241
+ A sign indicator for the linear term of the polynomial
242
+
243
+ Returns
244
+ -------
245
+ numeric
246
+ '''
247
+ a = 1 / gcr
248
+ c = cosd(surface_tilt)
249
+ return np.sqrt(a*a + 2*delta*a*c*x + x*x)
250
+
251
+
252
+ def vf_row_sky_2d(surface_tilt, gcr, x):
253
+ r'''
254
+ Calculate the view factor to the sky from a point x on a row surface.
255
+
256
+ Assumes a PV system of infinitely long rows with uniform pitch on
257
+ horizontal ground. The view to the sky is restricted by the row's surface
258
+ tilt and the top of the adjacent row.
259
+
260
+ Parameters
261
+ ----------
262
+ surface_tilt : numeric
263
+ Surface tilt angle in degrees from horizontal, e.g., surface facing up
264
+ = 0, surface facing horizon = 90. [degree]
265
+ gcr : numeric
266
+ Ratio of the row slant length to the row spacing (pitch). [unitless]
267
+ x : numeric
268
+ Position on the row's slant length, as a fraction of the slant length.
269
+ x=0 corresponds to the bottom of the row. [unitless]
270
+
271
+ Returns
272
+ -------
273
+ vf : numeric
274
+ Fraction of the sky dome visible from the point x. [unitless]
275
+
276
+ '''
277
+ p = _vf_poly(surface_tilt, gcr, 1 - x, -1)
278
+ return 0.5*(1 + (1/gcr * cosd(surface_tilt) - (1 - x)) / p)
279
+
280
+
281
+ def vf_row_sky_2d_integ(surface_tilt, gcr, x0=0, x1=1):
282
+ r'''
283
+ Calculate the average view factor to the sky from a segment of the row
284
+ surface between x0 and x1.
285
+
286
+ Assumes a PV system of infinitely long rows with uniform pitch on
287
+ horizontal ground. The view to the sky is restricted by the row's surface
288
+ tilt and the top of the adjacent row.
289
+
290
+ Parameters
291
+ ----------
292
+ surface_tilt : numeric
293
+ Surface tilt angle in degrees from horizontal, e.g., surface facing up
294
+ = 0, surface facing horizon = 90. [degree]
295
+ gcr : numeric
296
+ Ratio of the row slant length to the row spacing (pitch). [unitless]
297
+ x0 : numeric, default 0
298
+ Position on the row's slant length, as a fraction of the slant length.
299
+ x0=0 corresponds to the bottom of the row. x0 should be less than x1.
300
+ [unitless]
301
+ x1 : numeric, default 1
302
+ Position on the row's slant length, as a fraction of the slant length.
303
+ x1 should be greater than x0. [unitless]
304
+
305
+ Returns
306
+ -------
307
+ vf : numeric
308
+ Average fraction of the sky dome visible from points in the segment
309
+ from x0 to x1. [unitless]
310
+
311
+ '''
312
+ u = np.abs(x1 - x0)
313
+ p0 = _vf_poly(surface_tilt, gcr, 1 - x0, -1)
314
+ p1 = _vf_poly(surface_tilt, gcr, 1 - x1, -1)
315
+ with np.errstate(divide='ignore'):
316
+ result = np.where(u < 1e-6,
317
+ vf_row_sky_2d(surface_tilt, gcr, x0),
318
+ 0.5*(1 + 1/u * (p1 - p0))
319
+ )
320
+ return result
321
+
322
+
323
+ def vf_row_ground_2d(surface_tilt, gcr, x):
324
+ r'''
325
+ Calculate the view factor to the ground from a point x on a row surface.
326
+
327
+ Assumes a PV system of infinitely long rows with uniform pitch on
328
+ horizontal ground. The view to the ground is restricted by the row's
329
+ tilt and the bottom of the facing row.
330
+
331
+ Parameters
332
+ ----------
333
+ surface_tilt : numeric
334
+ Surface tilt angle in degrees from horizontal, e.g., surface facing up
335
+ = 0, surface facing horizon = 90. [degree]
336
+ gcr : numeric
337
+ Ratio of the row slant length to the row spacing (pitch). [unitless]
338
+ x : numeric
339
+ Position on the row's slant length, as a fraction of the slant length.
340
+ x=0 corresponds to the bottom of the row. [unitless]
341
+
342
+ Returns
343
+ -------
344
+ vf : numeric
345
+ View factor to the visible ground from the point x. [unitless]
346
+
347
+ '''
348
+ p = _vf_poly(surface_tilt, gcr, x, 1)
349
+ return 0.5 * (1 - (1/gcr * cosd(surface_tilt) + x)/p)
350
+
351
+
352
+ def vf_row_ground_2d_integ(surface_tilt, gcr, x0=0, x1=1):
353
+ r'''
354
+ Calculate the average view factor to the ground from a segment of the row
355
+ surface between x0 and x1.
356
+
357
+ Assumes a PV system of infinitely long rows with uniform pitch on
358
+ horizontal ground. The view to the ground is restricted by the row's
359
+ tilt and the bottom of the facing row.
360
+
361
+ Parameters
362
+ ----------
363
+ surface_tilt : numeric
364
+ Surface tilt angle in degrees from horizontal, e.g., surface facing up
365
+ = 0, surface facing horizon = 90. [degree]
366
+ gcr : numeric
367
+ Ratio of the row slant length to the row spacing (pitch). [unitless]
368
+ x0 : numeric, default 0.
369
+ Position on the row's slant length, as a fraction of the slant length.
370
+ x0=0 corresponds to the bottom of the row. x0 should be less than x1.
371
+ [unitless]
372
+ x1 : numeric, default 1.
373
+ Position on the row's slant length, as a fraction of the slant length.
374
+ x1 should be greater than x0. [unitless]
375
+
376
+ Returns
377
+ -------
378
+ vf : numeric
379
+ Integrated view factor to the visible ground on the interval (x0, x1).
380
+ [unitless]
381
+
382
+ '''
383
+ u = np.abs(x1 - x0)
384
+ p0 = _vf_poly(surface_tilt, gcr, x0, 1)
385
+ p1 = _vf_poly(surface_tilt, gcr, x1, 1)
386
+ with np.errstate(divide='ignore'):
387
+ result = np.where(u < 1e-6,
388
+ vf_row_ground_2d(surface_tilt, gcr, x0),
389
+ 0.5*(1 - 1/u * (p1 - p0))
390
+ )
391
+ return result