Skip to content

Commit d4a6abd

Browse files
committed
Add bifacial scaling to Townsend snow loss
Add optional front_side_fraction argument to loss_townsend for bifacial snow loss adjustment. Includes test coverage for the scaling behavior.
1 parent 603ede0 commit d4a6abd

2 files changed

Lines changed: 43 additions & 1 deletion

File tree

pvlib/snow.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,8 @@ def _townsend_effective_snow(snow_total, snow_events):
248248

249249
def loss_townsend(snow_total, snow_events, surface_tilt, relative_humidity,
250250
temp_air, poa_global, slant_height, lower_edge_height,
251-
string_factor=1.0, angle_of_repose=40):
251+
string_factor=1.0, angle_of_repose=40,
252+
front_side_fraction=None):
252253
'''
253254
Calculates monthly snow loss based on the Townsend monthly snow loss
254255
model.
@@ -293,6 +294,13 @@ def loss_townsend(snow_total, snow_events, surface_tilt, relative_humidity,
293294
Piled snow angle, assumed to stabilize at 40°, the midpoint of
294295
25°-55° avalanching slope angles. [deg]
295296
297+
front_side_fraction : numeric or array-like, default None
298+
Optional multiplier applied to the calculated loss fraction. For
299+
bifacial systems, this can be used to scale the snow loss by the
300+
front-side energy fraction from a no-soiling simulation. For example,
301+
use 0.9 when 90% of monthly energy is from the front side and 10% is
302+
from the rear side. If None, no bifacial adjustment is applied. [-]
303+
296304
Returns
297305
-------
298306
loss : array-like
@@ -310,6 +318,10 @@ def loss_townsend(snow_total, snow_events, surface_tilt, relative_humidity,
310318
publication of [1]_, as described in [2]_.
311319
The definition for snow events documented above is based on [3]_.
312320
321+
For bifacial systems, [2]_ recommends including both front-side and
322+
rear-side insolation in ``poa_global``. The resulting loss may then be
323+
scaled by the front-side energy fraction using ``front_side_fraction``.
324+
313325
References
314326
----------
315327
.. [1] Townsend, Tim & Powers, Loren. (2011). Photovoltaics and snow: An
@@ -384,4 +396,8 @@ def loss_townsend(snow_total, snow_events, surface_tilt, relative_humidity,
384396
* string_factor
385397
)
386398

399+
if front_side_fraction is not None:
400+
front_side_fraction = np.asarray(front_side_fraction)
401+
loss_fraction = loss_fraction * front_side_fraction
402+
387403
return np.clip(loss_fraction, 0, 1)

tests/test_snow.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,29 @@ def test_loss_townsend_cases(poa_global, surface_tilt, slant_height,
247247
poa_global, slant_height, lower_edge_height, string_factor)
248248
actual = np.around(actual * 100)
249249
assert np.allclose(expected, actual)
250+
251+
252+
def test_loss_townsend_front_side_fraction():
253+
snow_total = np.array([25.4, 25.4, 12.7, 2.54, 0, 0, 0, 0, 0, 0, 12.7,
254+
25.4])
255+
snow_events = np.array([2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 2, 3])
256+
surface_tilt = 20
257+
relative_humidity = np.array([80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
258+
80, 80])
259+
temp_air = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
260+
poa_global = np.array([350000, 350000, 350000, 350000, 350000, 350000,
261+
350000, 350000, 350000, 350000, 350000, 350000])
262+
slant_height = 2.54
263+
lower_edge_height = 0.254
264+
front_side_fraction = 0.9
265+
266+
unadjusted = snow.loss_townsend(
267+
snow_total, snow_events, surface_tilt, relative_humidity, temp_air,
268+
poa_global, slant_height, lower_edge_height)
269+
270+
adjusted = snow.loss_townsend(
271+
snow_total, snow_events, surface_tilt, relative_humidity, temp_air,
272+
poa_global, slant_height, lower_edge_height,
273+
front_side_fraction=front_side_fraction)
274+
275+
np.testing.assert_allclose(adjusted, unadjusted * front_side_fraction)

0 commit comments

Comments
 (0)