Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion docs/sphinx/source/whatsnew/v0.15.2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ Bug fixes

Enhancements
~~~~~~~~~~~~

* Added the ``front_side_fraction`` parameter to
:py:func:`pvlib.snow.loss_townsend` to support bifacial Townsend snow-loss
workflows where the calculated loss is scaled by the front-side energy
fraction. (:pull:`2756`) (:ghuser:`shethkajal7`)

Documentation
~~~~~~~~~~~~~
Expand Down Expand Up @@ -53,3 +56,4 @@ Contributors
~~~~~~~~~~~~
* :ghuser:`Omesh37`
* Cliff Hansen (:ghuser:`cwhanse`)
* :ghuser:`shethkajal7`
15 changes: 14 additions & 1 deletion pvlib/snow.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,8 @@ def _townsend_effective_snow(snow_total, snow_events):

def loss_townsend(snow_total, snow_events, surface_tilt, relative_humidity,
temp_air, poa_global, slant_height, lower_edge_height,
string_factor=1.0, angle_of_repose=40):
string_factor=1.0, angle_of_repose=40,
front_side_fraction=1.0):
'''
Calculates monthly snow loss based on the Townsend monthly snow loss
model.
Expand Down Expand Up @@ -293,6 +294,12 @@ def loss_townsend(snow_total, snow_events, surface_tilt, relative_humidity,
Piled snow angle, assumed to stabilize at 40°, the midpoint of
25°-55° avalanching slope angles. [deg]

front_side_fraction : numeric or array-like, default 1.0
Fraction of monthly energy from front-side insolation (unitless).
Multiplies the calculated loss fraction. For example,
use 0.9 when 90% of monthly energy is from the front side
of a bifacial system and 10% is from the rear side.

Returns
-------
loss : array-like
Expand All @@ -310,6 +317,10 @@ def loss_townsend(snow_total, snow_events, surface_tilt, relative_humidity,
publication of [1]_, as described in [2]_.
The definition for snow events documented above is based on [3]_.

For bifacial systems, [2]_ recommends including both front-side and
rear-side insolation in ``poa_global``. The resulting loss is
scaled by the front-side energy fraction ``front_side_fraction``.

References
----------
.. [1] Townsend, Tim & Powers, Loren. (2011). Photovoltaics and snow: An
Expand Down Expand Up @@ -384,4 +395,6 @@ def loss_townsend(snow_total, snow_events, surface_tilt, relative_humidity,
* string_factor
)

loss_fraction = loss_fraction * front_side_fraction

return np.clip(loss_fraction, 0, 1)
24 changes: 24 additions & 0 deletions tests/test_snow.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,27 @@ def test_loss_townsend_cases(poa_global, surface_tilt, slant_height,
poa_global, slant_height, lower_edge_height, string_factor)
actual = np.around(actual * 100)
assert np.allclose(expected, actual)


def test_loss_townsend_front_side_fraction():
snow_total = np.array([25.4, 25.4, 12.7, 2.54, 0, 0, 0, 0, 0, 0, 12.7,
25.4])
snow_events = np.array([2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 2, 3])
surface_tilt = 20
relative_humidity = np.full(12, 80)
temp_air = np.full(12, 0)
poa_global = np.full(12, 350000)
slant_height = 2.54
lower_edge_height = 0.254
front_side_fraction = 0.9

unadjusted = snow.loss_townsend(
snow_total, snow_events, surface_tilt, relative_humidity, temp_air,
poa_global, slant_height, lower_edge_height)

adjusted = snow.loss_townsend(
snow_total, snow_events, surface_tilt, relative_humidity, temp_air,
poa_global, slant_height, lower_edge_height,
front_side_fraction=front_side_fraction)

np.testing.assert_allclose(adjusted, unadjusted * front_side_fraction)