pvlib 0.11.2__py3-none-any.whl → 0.12.1a1__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 (147) hide show
  1. pvlib/__init__.py +1 -0
  2. pvlib/atmosphere.py +40 -40
  3. pvlib/bifacial/infinite_sheds.py +4 -3
  4. pvlib/bifacial/utils.py +2 -1
  5. pvlib/iotools/__init__.py +6 -0
  6. pvlib/iotools/psm3.py +1 -1
  7. pvlib/iotools/psm4.py +819 -0
  8. pvlib/iotools/pvgis.py +10 -2
  9. pvlib/iotools/tmy.py +3 -69
  10. pvlib/irradiance.py +38 -15
  11. pvlib/ivtools/sdm/__init__.py +20 -0
  12. pvlib/ivtools/sdm/_fit_desoto_pvsyst_sandia.py +585 -0
  13. pvlib/ivtools/sdm/cec.py +93 -0
  14. pvlib/ivtools/sdm/desoto.py +401 -0
  15. pvlib/ivtools/sdm/pvsyst.py +630 -0
  16. pvlib/location.py +73 -33
  17. pvlib/modelchain.py +19 -36
  18. pvlib/pvsystem.py +114 -65
  19. pvlib/snow.py +64 -28
  20. pvlib/spectrum/__init__.py +0 -1
  21. pvlib/spectrum/irradiance.py +2 -64
  22. pvlib/spectrum/mismatch.py +3 -3
  23. pvlib/tools.py +6 -5
  24. {pvlib-0.11.2.dist-info → pvlib-0.12.1a1.dist-info}/METADATA +6 -5
  25. pvlib-0.12.1a1.dist-info/RECORD +80 -0
  26. {pvlib-0.11.2.dist-info → pvlib-0.12.1a1.dist-info}/WHEEL +1 -1
  27. pvlib/data/BIRD_08_16_2012.csv +0 -8761
  28. pvlib/data/BIRD_08_16_2012_patm.csv +0 -8761
  29. pvlib/data/Burlington, United States SolarAnywhere Time Series 2021 Lat_44_465 Lon_-73_205 TMY3 format.csv +0 -8762
  30. pvlib/data/Burlington, United States SolarAnywhere Time Series 20210101 to 20210103 Lat_44_4675 Lon_-73_2075 SA format.csv +0 -578
  31. pvlib/data/Burlington, United States SolarAnywhere Typical GHI Year Lat_44_465 Lon_-73_205 SA format.csv +0 -74
  32. pvlib/data/CPS SCH275KTL-DO-US-800-250kW_275kVA_1.OND +0 -146
  33. pvlib/data/CRNS0101-05-2019-AZ_Tucson_11_W.txt +0 -4
  34. pvlib/data/CRN_with_problems.txt +0 -3
  35. pvlib/data/ET-M772BH550GL.PAN +0 -75
  36. pvlib/data/NLD_Amsterdam062400_IWEC.epw +0 -8768
  37. pvlib/data/PVsyst_demo.csv +0 -10757
  38. pvlib/data/PVsyst_demo_model.csv +0 -3588
  39. pvlib/data/SRML-day-EUPO1801.txt +0 -1441
  40. pvlib/data/abq19056.dat +0 -6
  41. pvlib/data/bishop88_numerical_precision.csv +0 -101
  42. pvlib/data/bsrn-lr0100-pay0616.dat +0 -86901
  43. pvlib/data/bsrn-pay0616.dat.gz +0 -0
  44. pvlib/data/cams_mcclear_1min_verbose.csv +0 -60
  45. pvlib/data/cams_mcclear_monthly.csv +0 -42
  46. pvlib/data/cams_radiation_1min_verbose.csv +0 -72
  47. pvlib/data/cams_radiation_monthly.csv +0 -47
  48. pvlib/data/detect_clearsky_data.csv +0 -35
  49. pvlib/data/detect_clearsky_threshold_data.csv +0 -126
  50. pvlib/data/greensboro_kimber_soil_manwash.dat +0 -8761
  51. pvlib/data/greensboro_kimber_soil_nowash.dat +0 -8761
  52. pvlib/data/inverter_fit_snl_meas.csv +0 -127
  53. pvlib/data/inverter_fit_snl_sim.csv +0 -19
  54. pvlib/data/ivtools_numdiff.csv +0 -52
  55. pvlib/data/midc_20181014.txt +0 -1441
  56. pvlib/data/midc_raw_20181018.txt +0 -1441
  57. pvlib/data/midc_raw_short_header_20191115.txt +0 -1441
  58. pvlib/data/msn19056.dat +0 -6
  59. pvlib/data/precise_iv_curves1.json +0 -10251
  60. pvlib/data/precise_iv_curves2.json +0 -10251
  61. pvlib/data/precise_iv_curves_parameter_sets1.csv +0 -33
  62. pvlib/data/precise_iv_curves_parameter_sets2.csv +0 -33
  63. pvlib/data/pvgis_hourly_Timeseries_45.000_8.000_SA2_10kWp_CIS_5_2a_2013_2014.json +0 -1
  64. pvlib/data/pvgis_hourly_Timeseries_45.000_8.000_SA_30deg_0deg_2016_2016.csv +0 -35
  65. pvlib/data/pvgis_tmy_meta.json +0 -32
  66. pvlib/data/pvgis_tmy_test.csv +0 -8761
  67. pvlib/data/pvwatts_8760_rackmount.csv +0 -8779
  68. pvlib/data/pvwatts_8760_roofmount.csv +0 -8779
  69. pvlib/data/singleaxis_tracker_wslope.csv +0 -8761
  70. pvlib/data/spectrl2_example_spectra.csv +0 -123
  71. pvlib/data/surfrad-slv16001.dat +0 -1442
  72. pvlib/data/test_psm3_2017.csv +0 -17521
  73. pvlib/data/test_psm3_2019_5min.csv +0 -289
  74. pvlib/data/test_psm3_tmy-2017.csv +0 -8761
  75. pvlib/data/test_read_psm3.csv +0 -17523
  76. pvlib/data/test_read_pvgis_horizon.csv +0 -49
  77. pvlib/data/tmy_45.000_8.000_2005_2023.csv +0 -8789
  78. pvlib/data/tmy_45.000_8.000_2005_2023.epw +0 -8768
  79. pvlib/data/tmy_45.000_8.000_2005_2023.json +0 -1
  80. pvlib/data/tmy_45.000_8.000_2005_2023.txt +0 -8761
  81. pvlib/data/tmy_45.000_8.000_userhorizon.json +0 -1
  82. pvlib/ivtools/sdm.py +0 -1379
  83. pvlib/spa_c_files/README.md +0 -81
  84. pvlib/spa_c_files/cspa_py.pxd +0 -43
  85. pvlib/spa_c_files/spa_py.pyx +0 -30
  86. pvlib/tests/__init__.py +0 -0
  87. pvlib/tests/bifacial/__init__.py +0 -0
  88. pvlib/tests/bifacial/test_infinite_sheds.py +0 -317
  89. pvlib/tests/bifacial/test_losses_models.py +0 -54
  90. pvlib/tests/bifacial/test_pvfactors.py +0 -82
  91. pvlib/tests/bifacial/test_utils.py +0 -192
  92. pvlib/tests/conftest.py +0 -476
  93. pvlib/tests/iotools/__init__.py +0 -0
  94. pvlib/tests/iotools/test_acis.py +0 -213
  95. pvlib/tests/iotools/test_bsrn.py +0 -131
  96. pvlib/tests/iotools/test_crn.py +0 -95
  97. pvlib/tests/iotools/test_epw.py +0 -23
  98. pvlib/tests/iotools/test_midc.py +0 -89
  99. pvlib/tests/iotools/test_panond.py +0 -32
  100. pvlib/tests/iotools/test_psm3.py +0 -198
  101. pvlib/tests/iotools/test_pvgis.py +0 -644
  102. pvlib/tests/iotools/test_sodapro.py +0 -298
  103. pvlib/tests/iotools/test_solaranywhere.py +0 -287
  104. pvlib/tests/iotools/test_solargis.py +0 -68
  105. pvlib/tests/iotools/test_solcast.py +0 -324
  106. pvlib/tests/iotools/test_solrad.py +0 -152
  107. pvlib/tests/iotools/test_srml.py +0 -124
  108. pvlib/tests/iotools/test_surfrad.py +0 -75
  109. pvlib/tests/iotools/test_tmy.py +0 -133
  110. pvlib/tests/ivtools/__init__.py +0 -0
  111. pvlib/tests/ivtools/test_sde.py +0 -230
  112. pvlib/tests/ivtools/test_sdm.py +0 -429
  113. pvlib/tests/ivtools/test_utils.py +0 -173
  114. pvlib/tests/spectrum/__init__.py +0 -0
  115. pvlib/tests/spectrum/conftest.py +0 -40
  116. pvlib/tests/spectrum/test_irradiance.py +0 -138
  117. pvlib/tests/spectrum/test_mismatch.py +0 -304
  118. pvlib/tests/spectrum/test_response.py +0 -124
  119. pvlib/tests/spectrum/test_spectrl2.py +0 -72
  120. pvlib/tests/test__deprecation.py +0 -97
  121. pvlib/tests/test_albedo.py +0 -84
  122. pvlib/tests/test_atmosphere.py +0 -351
  123. pvlib/tests/test_clearsky.py +0 -884
  124. pvlib/tests/test_conftest.py +0 -37
  125. pvlib/tests/test_iam.py +0 -555
  126. pvlib/tests/test_inverter.py +0 -213
  127. pvlib/tests/test_irradiance.py +0 -1487
  128. pvlib/tests/test_location.py +0 -356
  129. pvlib/tests/test_modelchain.py +0 -2020
  130. pvlib/tests/test_numerical_precision.py +0 -124
  131. pvlib/tests/test_pvarray.py +0 -71
  132. pvlib/tests/test_pvsystem.py +0 -2511
  133. pvlib/tests/test_scaling.py +0 -207
  134. pvlib/tests/test_shading.py +0 -391
  135. pvlib/tests/test_singlediode.py +0 -608
  136. pvlib/tests/test_snow.py +0 -212
  137. pvlib/tests/test_soiling.py +0 -230
  138. pvlib/tests/test_solarposition.py +0 -966
  139. pvlib/tests/test_spa.py +0 -454
  140. pvlib/tests/test_temperature.py +0 -470
  141. pvlib/tests/test_tools.py +0 -146
  142. pvlib/tests/test_tracking.py +0 -474
  143. pvlib/tests/test_transformer.py +0 -60
  144. pvlib-0.11.2.dist-info/RECORD +0 -191
  145. {pvlib-0.11.2.dist-info → pvlib-0.12.1a1.dist-info/licenses}/AUTHORS.md +0 -0
  146. {pvlib-0.11.2.dist-info → pvlib-0.12.1a1.dist-info/licenses}/LICENSE +0 -0
  147. {pvlib-0.11.2.dist-info → pvlib-0.12.1a1.dist-info}/top_level.txt +0 -0
@@ -1,81 +0,0 @@
1
- README
2
- ------
3
-
4
- NREL provides a C implementation of the solar position algorithm described in
5
- [Reda, I.; Andreas, A. (2003). Solar Position Algorithm for Solar Radiation Applications. 55 pp.; NREL Report No. TP-560-34302](http://www.nrel.gov/docs/fy08osti/34302.pdf).
6
-
7
- This folder contains the files required to make SPA C code accessible
8
- to the `pvlib-python` package. We use the Cython package to wrap the NREL SPA
9
- implementation.
10
-
11
- ** Due to licensing issues, the SPA C files can _not_ be distributed with
12
- `pvlib-python`. You must download the SPA C files from the
13
- [NREL website](https://midcdmz.nrel.gov/spa/). **
14
-
15
- Download the `spa.c` and `spa.h` files from NREL, and copy them into the
16
- `pvlib/spa_c_files` directory. When the extension is built, the ``timezone``
17
- field in the SPA C files is replaced with `time_zone` to avoid a nameclash
18
- with the function `__timezone` that is redefined by Python>=3.5. This issue
19
- is [Python bug 24643](https://bugs.python.org/issue24643).
20
-
21
- There are a total of 5 files needed to compile the C code, described below:
22
-
23
- * `spa.c`: original C code from NREL
24
- * `spa.h`: header file for spa.c
25
- * `cspa_py.pxd`: a cython header file which essentially tells cython which
26
- parts of the main header file to pay attention to
27
- * `spa_py.pyx`: the cython code used to define both functions in the python
28
- namespace. NOTE: It is possible to provide user access to other paramters of
29
- the SPA algorithm through modifying this file
30
- * `setup.py`: a distutils file which performs the compiling of the cython code
31
-
32
- The cython compilation process produces two files:
33
- * `spa_py.c`: an intermediate cython c file
34
- * `spa_py.so` or `spa_py.<cpyver-plat>.pyd`: the python module which
35
- can be imported into a namespace
36
-
37
- To create the SPA Python extension, use the following shell command inside this
38
- folder:
39
-
40
- $ python setup.py build_ext --inplace
41
-
42
- There are four optional keyword arguments `delta_ut1=0`, `slope=30.0`,
43
- `azm_rotation=-10`, `atmos_refract` that effect four optional return values
44
- `incidence`, `suntransit`, `sunrise`, and `sunset`. If not given, the defaults
45
- shown are used.
46
-
47
- There is an example in `spa_py_example.py` that contains a test function called
48
- `spa_calc_example` that users can use to check that the result is consistent
49
- with expected values:
50
-
51
- >>> from spa_py_example import spa_calc_example
52
- >>> r = spa_calc_example()
53
- {
54
- 'year': 2004,
55
- 'month': 10,
56
- 'day': 17,
57
- 'hour': 12,
58
- 'minute': 30,
59
- 'second': 30.0,
60
- 'delta_ut1': 0.0,
61
- 'delta_t': 67.0,
62
- 'time_zone': -7.0,
63
- 'longitude': -105.1786,
64
- 'latitude': 39.742476,
65
- 'elevation': 1830.14,
66
- 'pressure': 820.0,
67
- 'temperature': 11.0,
68
- 'slope': 30.0,
69
- 'azm_rotation': -10.0,
70
- 'atmos_refract': 0.5667,
71
- 'function': 3,
72
- 'e0': 39.59209464796398,
73
- 'e': 39.60858878898177,
74
- 'zenith': 50.39141121101823,
75
- 'azimuth_astro': 14.311961805946808,
76
- 'azimuth': 194.3119618059468,
77
- 'incidence': 25.42168493680471,
78
- 'suntransit': 11.765833793714224,
79
- 'sunrise': 6.22578372122376,
80
- 'sunset': 17.320379610556166
81
- }
@@ -1,43 +0,0 @@
1
- cdef extern from "spa.h":
2
- ctypedef enum:
3
- SPA_ZA, SPA_ZA_INC, SPA_ZA_RTS, SPA_ALL
4
-
5
- ctypedef struct spa_data:
6
- int year
7
- int month
8
- int day
9
- int hour
10
- int minute
11
- double second
12
- double delta_ut1
13
- double delta_t
14
- double time_zone
15
- double longitude
16
- double latitude
17
-
18
- double elevation
19
-
20
- double pressure
21
-
22
- double temperature
23
-
24
- double slope
25
-
26
- double azm_rotation
27
-
28
- double atmos_refract
29
-
30
- int function
31
-
32
- double e0
33
- double e
34
- double zenith
35
- double azimuth_astro
36
- double azimuth
37
- double incidence
38
-
39
- double suntransit
40
- double sunrise
41
- double sunset
42
-
43
- int spa_calculate(spa_data *spa)
@@ -1,30 +0,0 @@
1
- cimport cspa_py
2
-
3
- def spa_calc(year, month, day, hour, minute, second, time_zone, latitude,
4
- longitude, elevation, pressure, temperature, delta_t,
5
- delta_ut1=0, slope=30.0, azm_rotation=-10, atmos_refract=0.5667):
6
-
7
- cdef cspa_py.spa_data spa
8
-
9
- spa.year = year
10
- spa.month = month
11
- spa.day = day
12
- spa.hour = hour
13
- spa.minute = minute
14
- spa.second = second
15
- spa.time_zone = time_zone
16
- spa.delta_ut1 = delta_ut1
17
- spa.delta_t = delta_t
18
- spa.longitude = longitude
19
- spa.latitude = latitude
20
- spa.elevation = elevation
21
- spa.pressure = pressure
22
- spa.temperature = temperature
23
- spa.slope = slope
24
- spa.azm_rotation = azm_rotation
25
- spa.atmos_refract = atmos_refract
26
- spa.function = cspa_py.SPA_ALL
27
-
28
- err = cspa_py.spa_calculate(&spa)
29
-
30
- return spa
pvlib/tests/__init__.py DELETED
File without changes
File without changes
@@ -1,317 +0,0 @@
1
- """
2
- test infinite sheds
3
- """
4
-
5
- import numpy as np
6
- import pandas as pd
7
- from pvlib.bifacial import infinite_sheds
8
- from ..conftest import assert_series_equal
9
-
10
- import pytest
11
-
12
-
13
- @pytest.fixture
14
- def test_system():
15
- syst = {'height': 1.0,
16
- 'pitch': 2.,
17
- 'surface_tilt': 30.,
18
- 'surface_azimuth': 180.,
19
- 'rotation': -30.} # rotation of right edge relative to horizontal
20
- syst['gcr'] = 1.0 / syst['pitch']
21
- pts = np.linspace(0, 1, num=3)
22
- sqr3 = np.sqrt(3) / 4
23
- # c_i,j = cos(angle from point i to edge of row j), j=0 is row = -1
24
- # c_i,j = cos(angle from point i to edge of row j), j=0 is row = -1
25
- c00 = (-2 - sqr3) / np.sqrt(1.25**2 + (2 + sqr3)**2) # right edge row -1
26
- c01 = -sqr3 / np.sqrt(1.25**2 + sqr3**2) # right edge row 0
27
- c02 = sqr3 / np.sqrt(0.75**2 + sqr3**2) # left edge of row 0
28
- c03 = (2 - sqr3) / np.sqrt(1.25**2 + (2 - sqr3)**2) # right edge of row 1
29
- vf_0 = 0.5 * (c03 - c02 + c01 - c00) # vf at point 0
30
- c10 = (-3 - sqr3) / np.sqrt(1.25**2 + (3 + sqr3)**2) # right edge row -1
31
- c11 = (-1 - sqr3) / np.sqrt(1.25**2 + (1 + sqr3)**2) # right edge row 0
32
- c12 = (-1 + sqr3) / np.sqrt(0.75**2 + (-1 + sqr3)**2) # left edge row 0
33
- c13 = (1 - sqr3) / np.sqrt(1.25**2 + (1 - sqr3)**2) # right edge row
34
- vf_1 = 0.5 * (c13 - c12 + c11 - c10) # vf at point 1
35
- c20 = -(4 + sqr3) / np.sqrt(1.25**2 + (4 + sqr3)**2) # right edge row -1
36
- c21 = (-2 + sqr3) / np.sqrt(0.75**2 + (-2 + sqr3)**2) # left edge row 0
37
- c22 = (-2 - sqr3) / np.sqrt(1.25**2 + (2 + sqr3)**2) # right edge row 0
38
- c23 = (0 - sqr3) / np.sqrt(1.25**2 + (0 - sqr3)**2) # right edge row 1
39
- vf_2 = 0.5 * (c23 - c22 + c21 - c20) # vf at point 1
40
- vfs_ground_sky = np.array([vf_0, vf_1, vf_2])
41
- return syst, pts, vfs_ground_sky
42
-
43
-
44
- def test__poa_ground_shadows():
45
- poa_ground, f_gnd_beam, df, vf_gnd_sky = (300., 0.5, 0.5, 0.2)
46
- result = infinite_sheds._poa_ground_shadows(
47
- poa_ground, f_gnd_beam, df, vf_gnd_sky)
48
- expected = 300. * (0.5 * 0.5 + 0.5 * 0.2)
49
- assert np.isclose(result, expected)
50
- # vector inputs
51
- poa_ground = np.array([300., 300.])
52
- f_gnd_beam = np.array([0.5, 0.5])
53
- df = np.array([0.5, 0.])
54
- vf_gnd_sky = np.array([0.2, 0.2])
55
- result = infinite_sheds._poa_ground_shadows(
56
- poa_ground, f_gnd_beam, df, vf_gnd_sky)
57
- expected_vec = np.array([expected, 300. * 0.5])
58
- assert np.allclose(result, expected_vec)
59
-
60
-
61
- def test__shaded_fraction_floats():
62
- result = infinite_sheds._shaded_fraction(
63
- solar_zenith=60., solar_azimuth=180., surface_tilt=60.,
64
- surface_azimuth=180., gcr=1.0)
65
- assert np.isclose(result, 0.5)
66
-
67
-
68
- def test__shaded_fraction_array():
69
- solar_zenith = np.array([0., 60., 90., 60.])
70
- solar_azimuth = np.array([180., 180., 180., 180.])
71
- surface_azimuth = np.array([180., 180., 180., 210.])
72
- surface_tilt = np.array([30., 60., 0., 30.])
73
- gcr = 1.0
74
- result = infinite_sheds._shaded_fraction(
75
- solar_zenith, solar_azimuth, surface_tilt, surface_azimuth, gcr)
76
- x = 0.75 + np.sqrt(3) / 2
77
- expected = np.array([0.0, 0.5, 0., (x - 1) / x])
78
- assert np.allclose(result, expected)
79
-
80
-
81
- def test_get_irradiance_poa():
82
- # singleton inputs
83
- solar_zenith = 0.
84
- solar_azimuth = 180.
85
- surface_tilt = 0.
86
- surface_azimuth = 180.
87
- gcr = 0.5
88
- height = 1.
89
- pitch = 1
90
- ghi = 1000
91
- dhi = 300
92
- dni = 700
93
- albedo = 0
94
- iam = 1.0
95
- npoints = 100
96
- res = infinite_sheds.get_irradiance_poa(
97
- surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
98
- gcr, height, pitch, ghi, dhi, dni,
99
- albedo, iam=iam, npoints=npoints)
100
- expected_diffuse = np.array([300.])
101
- expected_direct = np.array([700.])
102
- expected_global = expected_diffuse + expected_direct
103
- expected_shaded_fraction = np.array([0.])
104
- assert np.isclose(res['poa_global'], expected_global)
105
- assert np.isclose(res['poa_diffuse'], expected_diffuse)
106
- assert np.isclose(res['poa_direct'], expected_direct)
107
- assert np.isclose(res['shaded_fraction'], expected_shaded_fraction)
108
- # vector inputs
109
- surface_tilt = np.array([0., 0., 0., 0.])
110
- height = 1.
111
- surface_azimuth = np.array([180., 180., 180., 180.])
112
- gcr = 0.5
113
- pitch = 1
114
- solar_zenith = np.array([0., 45., 45., 90.])
115
- solar_azimuth = np.array([180., 180., 135., 180.])
116
- expected_diffuse = np.array([300., 300., 300., 300.])
117
- expected_direct = np.array(
118
- [700., 350. * np.sqrt(2), 350. * np.sqrt(2), 0.])
119
- expected_global = expected_diffuse + expected_direct
120
- expected_shaded_fraction = np.array(
121
- [0., 0., 0., 0.])
122
- res = infinite_sheds.get_irradiance_poa(
123
- surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
124
- gcr, height, pitch, ghi, dhi, dni,
125
- albedo, iam=iam, npoints=npoints)
126
- assert np.allclose(res['poa_global'], expected_global)
127
- assert np.allclose(res['poa_diffuse'], expected_diffuse)
128
- assert np.allclose(res['poa_direct'], expected_direct)
129
- assert np.allclose(res['shaded_fraction'], expected_shaded_fraction)
130
- # series inputs
131
- surface_tilt = pd.Series(surface_tilt)
132
- surface_azimuth = pd.Series(data=surface_azimuth, index=surface_tilt.index)
133
- solar_zenith = pd.Series(solar_zenith, index=surface_tilt.index)
134
- solar_azimuth = pd.Series(data=solar_azimuth, index=surface_tilt.index)
135
- expected_diffuse = pd.Series(
136
- data=expected_diffuse, index=surface_tilt.index)
137
- expected_direct = pd.Series(
138
- data=expected_direct, index=surface_tilt.index)
139
- expected_global = expected_diffuse + expected_direct
140
- expected_global.name = 'poa_global' # to match output Series
141
- expected_shaded_fraction = pd.Series(
142
- data=expected_shaded_fraction, index=surface_tilt.index)
143
- expected_shaded_fraction.name = 'shaded_fraction' # to match output Series
144
- res = infinite_sheds.get_irradiance_poa(
145
- surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
146
- gcr, height, pitch, ghi, dhi, dni,
147
- albedo, iam=iam, npoints=npoints)
148
- assert isinstance(res, pd.DataFrame)
149
- assert_series_equal(res['poa_global'], expected_global)
150
- assert_series_equal(res['shaded_fraction'], expected_shaded_fraction)
151
- assert all(k in res.columns for k in [
152
- 'poa_global', 'poa_diffuse', 'poa_direct', 'poa_ground_diffuse',
153
- 'poa_sky_diffuse', 'shaded_fraction'])
154
-
155
-
156
- def test__backside_tilt():
157
- tilt = np.array([0., 30., 30., 180.])
158
- system_azimuth = np.array([180., 150., 270., 0.])
159
- back_tilt, back_az = infinite_sheds._backside(tilt, system_azimuth)
160
- assert np.allclose(back_tilt, np.array([180., 150., 150., 0.]))
161
- assert np.allclose(back_az, np.array([0., 330., 90., 180.]))
162
-
163
-
164
- @pytest.mark.parametrize("vectorize", [True, False])
165
- def test_get_irradiance(vectorize):
166
- # singleton inputs
167
- solar_zenith = 0.
168
- solar_azimuth = 180.
169
- surface_tilt = 0.
170
- surface_azimuth = 180.
171
- gcr = 0.5
172
- height = 1.
173
- pitch = 1.
174
- ghi = 1000.
175
- dhi = 300.
176
- dni = 700.
177
- albedo = 0.
178
- iam_front = 1.0
179
- iam_back = 1.0
180
- npoints = 100
181
- result = infinite_sheds.get_irradiance(
182
- surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
183
- gcr, height, pitch, ghi, dhi, dni, albedo, iam_front, iam_back,
184
- bifaciality=0.8, shade_factor=-0.02, transmission_factor=0,
185
- npoints=npoints, vectorize=vectorize)
186
- expected_front_diffuse = np.array([300.])
187
- expected_front_direct = np.array([700.])
188
- expected_front_global = expected_front_diffuse + expected_front_direct
189
- expected_shaded_fraction_front = np.array([0.])
190
- expected_shaded_fraction_back = np.array([0.])
191
- assert np.isclose(result['poa_front'], expected_front_global)
192
- assert np.isclose(result['poa_front_diffuse'], expected_front_diffuse)
193
- assert np.isclose(result['poa_front_direct'], expected_front_direct)
194
- assert np.isclose(result['poa_global'], result['poa_front'])
195
- assert np.isclose(result['shaded_fraction_front'],
196
- expected_shaded_fraction_front)
197
- assert np.isclose(result['shaded_fraction_back'],
198
- expected_shaded_fraction_back)
199
- # series inputs
200
- ghi = pd.Series([1000., 500., 500., np.nan])
201
- dhi = pd.Series([300., 500., 500., 500.], index=ghi.index)
202
- dni = pd.Series([700., 0., 0., 700.], index=ghi.index)
203
- solar_zenith = pd.Series([0., 0., 0., 135.], index=ghi.index)
204
- surface_tilt = pd.Series([0., 0., 90., 0.], index=ghi.index)
205
- result = infinite_sheds.get_irradiance(
206
- surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
207
- gcr, height, pitch, ghi, dhi, dni, albedo, iam_front, iam_back,
208
- bifaciality=0.8, shade_factor=-0.02, transmission_factor=0,
209
- npoints=npoints, vectorize=vectorize)
210
- result_front = infinite_sheds.get_irradiance_poa(
211
- surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
212
- gcr, height, pitch, ghi, dhi, dni,
213
- albedo, iam=iam_front, vectorize=vectorize)
214
- assert isinstance(result, pd.DataFrame)
215
- expected_poa_global = pd.Series(
216
- [1000., 500., result_front['poa_global'][2] * (1 + 0.8 * 0.98),
217
- np.nan], index=ghi.index, name='poa_global')
218
- expected_shaded_fraction = pd.Series(
219
- result_front['shaded_fraction'], index=ghi.index,
220
- name='shaded_fraction_front')
221
- assert_series_equal(result['poa_global'], expected_poa_global)
222
- assert_series_equal(result['shaded_fraction_front'],
223
- expected_shaded_fraction)
224
-
225
-
226
- def test_get_irradiance_limiting_gcr():
227
- # test confirms that irradiance on widely spaced rows is approximately
228
- # the same as for a single row array
229
- solar_zenith = 0.
230
- solar_azimuth = 180.
231
- surface_tilt = 90.
232
- surface_azimuth = 180.
233
- gcr = 0.00001
234
- height = 1.
235
- pitch = 100.
236
- ghi = 1000.
237
- dhi = 300.
238
- dni = 700.
239
- albedo = 1.
240
- iam_front = 1.0
241
- iam_back = 1.0
242
- npoints = 100
243
- result = infinite_sheds.get_irradiance(
244
- surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
245
- gcr, height, pitch, ghi, dhi, dni, albedo, iam_front, iam_back,
246
- bifaciality=1., shade_factor=-0.00, transmission_factor=0.,
247
- npoints=npoints)
248
- expected_ground_diffuse = np.array([500.])
249
- expected_sky_diffuse = np.array([150.])
250
- expected_direct = np.array([0.])
251
- expected_diffuse = expected_ground_diffuse + expected_sky_diffuse
252
- expected_poa = expected_diffuse + expected_direct
253
- expected_shaded_fraction_front = np.array([0.])
254
- expected_shaded_fraction_back = np.array([0.])
255
- assert np.isclose(result['poa_front'], expected_poa, rtol=0.01)
256
- assert np.isclose(result['poa_front_diffuse'], expected_diffuse, rtol=0.01)
257
- assert np.isclose(result['poa_front_direct'], expected_direct)
258
- assert np.isclose(result['poa_front_sky_diffuse'], expected_sky_diffuse,
259
- rtol=0.01)
260
- assert np.isclose(result['poa_front_ground_diffuse'],
261
- expected_ground_diffuse, rtol=0.01)
262
- assert np.isclose(result['poa_front'], result['poa_back'])
263
- assert np.isclose(result['poa_front_diffuse'], result['poa_back_diffuse'])
264
- assert np.isclose(result['poa_front_direct'], result['poa_back_direct'])
265
- assert np.isclose(result['poa_front_sky_diffuse'],
266
- result['poa_back_sky_diffuse'])
267
- assert np.isclose(result['poa_front_ground_diffuse'],
268
- result['poa_back_ground_diffuse'])
269
- assert np.isclose(result['shaded_fraction_front'],
270
- expected_shaded_fraction_front)
271
- assert np.isclose(result['shaded_fraction_back'],
272
- expected_shaded_fraction_back)
273
-
274
-
275
- def test_get_irradiance_with_haydavies():
276
- # singleton inputs
277
- solar_zenith = 0.
278
- solar_azimuth = 180.
279
- surface_tilt = 0.
280
- surface_azimuth = 180.
281
- gcr = 0.5
282
- height = 1.
283
- pitch = 1.
284
- ghi = 1000.
285
- dhi = 300.
286
- dni = 700.
287
- albedo = 0.
288
- dni_extra = 1413.
289
- model = 'haydavies'
290
- iam_front = 1.0
291
- iam_back = 1.0
292
- npoints = 100
293
- result = infinite_sheds.get_irradiance(
294
- surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
295
- gcr, height, pitch, ghi, dhi, dni, albedo, model, dni_extra,
296
- iam_front, iam_back, bifaciality=0.8, shade_factor=-0.02,
297
- transmission_factor=0, npoints=npoints)
298
- expected_front_diffuse = np.array([151.38])
299
- expected_front_direct = np.array([848.62])
300
- expected_front_global = expected_front_diffuse + expected_front_direct
301
- expected_shaded_fraction_front = np.array([0.])
302
- expected_shaded_fraction_back = np.array([0.])
303
- assert np.isclose(result['poa_front'], expected_front_global)
304
- assert np.isclose(result['poa_front_diffuse'], expected_front_diffuse)
305
- assert np.isclose(result['poa_front_direct'], expected_front_direct)
306
- assert np.isclose(result['poa_global'], result['poa_front'])
307
- assert np.isclose(result['shaded_fraction_front'],
308
- expected_shaded_fraction_front)
309
- assert np.isclose(result['shaded_fraction_back'],
310
- expected_shaded_fraction_back)
311
- # test for when dni_extra is not supplied
312
- with pytest.raises(ValueError, match='supply dni_extra for haydavies'):
313
- result = infinite_sheds.get_irradiance(
314
- surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
315
- gcr, height, pitch, ghi, dhi, dni, albedo, model, None,
316
- iam_front, iam_back, bifaciality=0.8, shade_factor=-0.02,
317
- transmission_factor=0, npoints=npoints)
@@ -1,54 +0,0 @@
1
- from pvlib import bifacial
2
-
3
- import pandas as pd
4
- import numpy as np
5
- from numpy.testing import assert_allclose
6
-
7
-
8
- def test_power_mismatch_deline():
9
- """tests bifacial.power_mismatch_deline"""
10
- premise_rmads = np.array([0.0, 0.05, 0.1, 0.15, 0.2, 0.25])
11
- # test default model is for fixed tilt
12
- expected_ft_mms = np.array([0.0, 0.0151, 0.0462, 0.0933, 0.1564, 0.2355])
13
- result_def_mms = bifacial.power_mismatch_deline(premise_rmads)
14
- assert_allclose(result_def_mms, expected_ft_mms, atol=1e-5)
15
- assert np.all(np.diff(result_def_mms) > 0) # higher RMADs => higher losses
16
-
17
- # test custom coefficients, set model to 1+1*RMAD
18
- # as Polynomial class
19
- polynomial = np.polynomial.Polynomial([1, 1, 0])
20
- result_custom_mms = bifacial.power_mismatch_deline(
21
- premise_rmads, coefficients=polynomial
22
- )
23
- assert_allclose(result_custom_mms, 1 + premise_rmads)
24
- # as list
25
- result_custom_mms = bifacial.power_mismatch_deline(
26
- premise_rmads, coefficients=[1, 1, 0]
27
- )
28
- assert_allclose(result_custom_mms, 1 + premise_rmads)
29
-
30
- # test datatypes IO with Series
31
- result_mms = bifacial.power_mismatch_deline(pd.Series(premise_rmads))
32
- assert isinstance(result_mms, pd.Series)
33
-
34
- # test fill_factor, fill_factor_reference
35
- # default model + default fill_factor_reference
36
- ff_ref_default = 0.79
37
- ff_of_interest = 0.65
38
- result_mms = bifacial.power_mismatch_deline(
39
- premise_rmads, fill_factor=ff_of_interest
40
- )
41
- assert_allclose(
42
- result_mms,
43
- expected_ft_mms * ff_of_interest / ff_ref_default,
44
- atol=1e-5,
45
- )
46
- # default model + custom fill_factor_reference
47
- ff_of_interest = 0.65
48
- ff_ref = 0.75
49
- result_mms = bifacial.power_mismatch_deline(
50
- premise_rmads, fill_factor=ff_of_interest, fill_factor_reference=ff_ref
51
- )
52
- assert_allclose(
53
- result_mms, expected_ft_mms * ff_of_interest / ff_ref, atol=1e-5
54
- )
@@ -1,82 +0,0 @@
1
- import pandas as pd
2
- from datetime import datetime
3
- from pvlib.bifacial.pvfactors import pvfactors_timeseries
4
- from ..conftest import requires_pvfactors, assert_series_equal
5
- import pytest
6
-
7
-
8
- @pytest.fixture
9
- def example_values():
10
- """
11
- Example values from the pvfactors github repo README file:
12
- https://github.com/SunPower/pvfactors/blob/master/README.rst#quick-start
13
- """
14
- inputs = dict(
15
- timestamps=pd.DatetimeIndex([datetime(2017, 8, 31, 11),
16
- datetime(2017, 8, 31, 12)]),
17
- solar_zenith=[20., 10.],
18
- solar_azimuth=[110., 140.],
19
- surface_tilt=[10., 0.],
20
- surface_azimuth=[90., 90.],
21
- axis_azimuth=0.,
22
- dni=[1000., 300.],
23
- dhi=[50., 500.],
24
- gcr=0.4,
25
- pvrow_height=1.75,
26
- pvrow_width=2.44,
27
- albedo=0.2,
28
- n_pvrows=3,
29
- index_observed_pvrow=1,
30
- rho_front_pvrow=0.03,
31
- rho_back_pvrow=0.05,
32
- horizon_band_angle=15.,
33
- )
34
- outputs = dict(
35
- expected_ipoa_front=pd.Series([1034.95474708997, 795.4423259036623],
36
- index=inputs['timestamps'],
37
- name=('total_inc_front')),
38
- expected_ipoa_back=pd.Series([92.12563846416197, 78.05831585685098],
39
- index=inputs['timestamps'],
40
- name=('total_inc_back')),
41
- )
42
- return inputs, outputs
43
-
44
-
45
- @requires_pvfactors
46
- def test_pvfactors_timeseries_list(example_values):
47
- """Test basic pvfactors functionality with list inputs"""
48
- inputs, outputs = example_values
49
- ipoa_inc_front, ipoa_inc_back, _, _ = pvfactors_timeseries(**inputs)
50
- assert_series_equal(ipoa_inc_front, outputs['expected_ipoa_front'])
51
- assert_series_equal(ipoa_inc_back, outputs['expected_ipoa_back'])
52
-
53
-
54
- @requires_pvfactors
55
- def test_pvfactors_timeseries_pandas(example_values):
56
- """Test basic pvfactors functionality with Series inputs"""
57
-
58
- inputs, outputs = example_values
59
- for key in ['solar_zenith', 'solar_azimuth', 'surface_tilt',
60
- 'surface_azimuth', 'dni', 'dhi']:
61
- inputs[key] = pd.Series(inputs[key], index=inputs['timestamps'])
62
-
63
- ipoa_inc_front, ipoa_inc_back, _, _ = pvfactors_timeseries(**inputs)
64
- assert_series_equal(ipoa_inc_front, outputs['expected_ipoa_front'])
65
- assert_series_equal(ipoa_inc_back, outputs['expected_ipoa_back'])
66
-
67
-
68
- @requires_pvfactors
69
- def test_pvfactors_scalar_orientation(example_values):
70
- """test that surface_tilt and surface_azimuth inputs can be scalars"""
71
- # GH 1127, GH 1332
72
- inputs, outputs = example_values
73
- inputs['surface_tilt'] = 10.
74
- inputs['surface_azimuth'] = 90.
75
- # the second tilt is supposed to be zero, so we need to
76
- # update the expected irradiances too:
77
- outputs['expected_ipoa_front'].iloc[1] = 800.6524022701132
78
- outputs['expected_ipoa_back'].iloc[1] = 81.72135884745822
79
-
80
- ipoa_inc_front, ipoa_inc_back, _, _ = pvfactors_timeseries(**inputs)
81
- assert_series_equal(ipoa_inc_front, outputs['expected_ipoa_front'])
82
- assert_series_equal(ipoa_inc_back, outputs['expected_ipoa_back'])