66from pvlib import snow
77from pvlib .tools import sind
88
9+ import pytest
10+
911
1012def test_fully_covered_nrel ():
1113 dt = pd .date_range (start = "2019-1-1 12:00:00" , end = "2019-1-1 18:00:00" ,
@@ -108,6 +110,7 @@ def test__townsend_effective_snow():
108110
109111
110112def test_loss_townsend ():
113+ # hand-calculated solution
111114 snow_total = np .array ([25.4 , 25.4 , 12.7 , 2.54 , 0 , 0 , 0 , 0 , 0 , 0 , 12.7 ,
112115 25.4 ])
113116 snow_events = np .array ([2 , 2 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 2 , 3 ])
@@ -118,12 +121,92 @@ def test_loss_townsend():
118121 poa_global = np .array ([350000 , 350000 , 350000 , 350000 , 350000 , 350000 ,
119122 350000 , 350000 , 350000 , 350000 , 350000 , 350000 ])
120123 angle_of_repose = 40
124+ string_factor = 1.0
121125 slant_height = 2.54
122126 lower_edge_height = 0.254
123127 expected = np .array ([0.07696253 , 0.07992262 , 0.06216201 , 0.01715392 , 0 , 0 ,
124128 0 , 0 , 0 , 0 , 0.02643821 , 0.06068194 ])
125129 actual = snow .loss_townsend (snow_total , snow_events , surface_tilt ,
126130 relative_humidity , temp_air ,
127131 poa_global , slant_height ,
128- lower_edge_height , angle_of_repose )
132+ lower_edge_height , string_factor ,
133+ angle_of_repose )
129134 np .testing .assert_allclose (expected , actual , rtol = 1e-05 )
135+
136+
137+ @pytest .mark .parametrize (
138+ 'poa_global,surface_tilt,slant_height,lower_edge_height,string_factor,expected' , # noQA: E501
139+ [
140+ (np .asarray (
141+ [60. , 80. , 100. , 125. , 175. , 225. , 225. , 210. , 175. , 125. , 90. ,
142+ 60. ], dtype = float ) * 1000. ,
143+ 2. ,
144+ 79. / 39.37 ,
145+ 3. / 39.37 ,
146+ 1.0 ,
147+ np .asarray (
148+ [44 , 34 , 20 , 9 , 3 , 1 , 0 , 0 , 0 , 2 , 6 , 25 ], dtype = float )
149+ ),
150+ (np .asarray (
151+ [60. , 80. , 100. , 125. , 175. , 225. , 225. , 210. , 175. , 125. , 90. ,
152+ 60. ], dtype = float ) * 1000. ,
153+ 5. ,
154+ 316 / 39.37 ,
155+ 120. / 39.37 ,
156+ 0.75 ,
157+ np .asarray (
158+ [22 , 16 , 9 , 4 , 1 , 0 , 0 , 0 , 0 , 1 , 2 , 12 ], dtype = float )
159+ ),
160+ (np .asarray (
161+ [60. , 80. , 100. , 125. , 175. , 225. , 225. , 210. , 175. , 125. , 90. ,
162+ 60. ], dtype = float ) * 1000. ,
163+ 23. ,
164+ 158 / 39.27 ,
165+ 12 / 39.37 ,
166+ 0.75 ,
167+ np .asarray (
168+ [28 , 21 , 13 , 6 , 2 , 0 , 0 , 0 , 0 , 1 , 4 , 16 ], dtype = float )
169+ ),
170+ (np .asarray (
171+ [80. , 100. , 125. , 150. , 225. , 300. , 300. , 275. , 225. , 150. , 115. ,
172+ 80. ], dtype = float ) * 1000. ,
173+ 52. ,
174+ 39.5 / 39.37 ,
175+ 34. / 39.37 ,
176+ 0.75 ,
177+ np .asarray (
178+ [7 , 5 , 3 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 4 ], dtype = float )
179+ ),
180+ (np .asarray (
181+ [80. , 100. , 125. , 150. , 225. , 300. , 300. , 275. , 225. , 150. , 115. ,
182+ 80. ], dtype = float ) * 1000. ,
183+ 60. ,
184+ 39.5 / 39.37 ,
185+ 25. / 39.37 ,
186+ 1. ,
187+ np .asarray (
188+ [7 , 5 , 3 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 3 ], dtype = float )
189+ )
190+ ]
191+ )
192+ def test_loss_townsend_cases (poa_global , surface_tilt , slant_height ,
193+ lower_edge_height , string_factor , expected ):
194+ # test cases from Townsend, 1/27/2023, addeed by cwh
195+ # snow_total in inches, convert to cm for pvlib
196+ snow_total = np .asarray (
197+ [20 , 15 , 10 , 4 , 1.5 , 0 , 0 , 0 , 0 , 1.5 , 4 , 15 ], dtype = float ) * 2.54
198+ # snow events are an average for each month
199+ snow_events = np .asarray (
200+ [5 , 4.2 , 2.8 , 1.3 , 0.8 , 0 , 0 , 0 , 0 , 0.5 , 1.5 , 4.5 ], dtype = float )
201+ # air temperature in C
202+ temp_air = np .asarray (
203+ [- 6. , - 2. , 1. , 4. , 7. , 10. , 13. , 16. , 14. , 12. , 7. , - 3. ], dtype = float )
204+ # relative humidity in %
205+ relative_humidity = np .asarray (
206+ [78. , 80. , 75. , 65. , 60. , 55. , 55. , 55. , 50. , 55. , 60. , 70. ],
207+ dtype = float )
208+ actual = snow .loss_townsend (
209+ snow_total , snow_events , surface_tilt , relative_humidity , temp_air ,
210+ poa_global , slant_height , lower_edge_height , string_factor )
211+ actual = np .around (actual * 100 )
212+ assert np .allclose (expected , actual )
0 commit comments