Skip to content
Closed
Show file tree
Hide file tree
Changes from 6 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
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ Shading
shading.masking_angle_passias
shading.sky_diffuse_passias
shading.projected_solar_zenith_angle
shading.linear_shade_loss
4 changes: 4 additions & 0 deletions docs/sphinx/source/whatsnew/v0.10.5.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Deprecations

Enhancements
~~~~~~~~~~~~
* Added `pvlib.shading.linear_shade_loss` to apply linear shade loss for thin
film CdTe modules. (:issue:`1690`, :pull:`2004`)


Bug fixes
Expand All @@ -31,3 +33,5 @@ Requirements

Contributors
~~~~~~~~~~~~
* Mark Mikofski (:ghuser:`mikofski`)
* Echedey Luis (:ghuser:`echedey-ls`)
58 changes: 58 additions & 0 deletions pvlib/shading.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,3 +342,61 @@ def projected_solar_zenith_angle(solar_zenith, solar_azimuth,
# Eq. (5); angle between sun's beam and surface
theta_T = np.degrees(np.arctan2(sx_prime, sz_prime))
return theta_T


def linear_shade_loss(shaded_fraction, diffuse_fraction):
r"""
Fraction of power lost to linear shade loss applicable to monolithic thin
film modules like First Solar CdTe, where the shadow is perpendicular to
cell scribe lines.
Comment thread
echedey-ls marked this conversation as resolved.
Outdated

.. versionadded:: 0.10.5

Parameters
----------
shaded_fraction : numeric
The fraction of the collector width shaded by an adjacent row. A
value of 1 is completely shaded and zero is no shade.
Comment thread
echedey-ls marked this conversation as resolved.
Outdated
diffuse_fraction : numeric
The ratio of diffuse plane of array (poa) irradiance to global poa.
A value of 1 is completely diffuse and zero is no diffuse.
Comment thread
echedey-ls marked this conversation as resolved.
Outdated

Returns
-------
linear_shade_loss : numeric
The fraction of power lost due to linear shading. A value of 1 is all
power lost and zero is no loss.

Notes
-----
The reasoning behind this loss model is described in sections 4.2 and 4.3
of [1]_, page 8 of the manual.
Comment thread
echedey-ls marked this conversation as resolved.
Outdated

The loss is calculated as:

.. math::

\text{loss} = \text{shaded\_fraction}\cdot(1-\text{diffuse\_fraction})
Comment thread
echedey-ls marked this conversation as resolved.
Outdated

See also
--------
pvlib.shading.shaded_fraction1d : 1-dimensional shaded fraction calculation

Example
-------
>>> from pvlib import shading
>>> sf = shading.shaded_fraction1d(80, 180, 90, 25,
collector_width=0.5, row_pitch=1, surface_to_axis_offset=0,
cross_axis_slope=5.711, shading_tracker_tilt=50)
>>> loss = shading.linear_shade_loss(sf, diffuse_fraction=0.2)
>>> P_no_shade = 100 # [kWdc] DC output from modules
>>> P_linear_shade = P_no_shade * (1-loss) # [kWdc] output after loss
75.51797783654133

References
----------
.. [1] First Solar, “First Solar Series 4 Module.” [Online]. Available at: https://web.archive.org/web/20230512210902/https://www.firstsolar.com/-/media/First-Solar/Technical-Documents/User-Guides/Series-4-Module-User-Guide-North-America.ashx?la=en [accessed 2024-04-12]
.. [2] First Solar, “Diffuse Irradiance and Tracker Simulations,” May
01-02, 2013. http://web.archive.org/web/20170127080529/https://energy.sandia.gov/wp-content/gallery/uploads/26-Littmann-Tracking-and-Diffuse-Shading.pdf0_.pdf [accessed 2024-04-12]
Comment thread
echedey-ls marked this conversation as resolved.
Outdated
"""
return shaded_fraction * (1 - diffuse_fraction)
16 changes: 16 additions & 0 deletions pvlib/tests/test_shading.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,19 @@ def test_projected_solar_zenith_angle_datatypes(
)
psz = psz_func(sun_apparent_zenith, axis_azimuth, axis_tilt, axis_azimuth)
assert isinstance(psz, cast_type)


def test_linear_shade_loss():
test_data = pd.DataFrame(
columns=["shaded_fraction", "diffuse_ratio", "expected_loss"],
data=[
[0.11611, 0.2, 0.09289],
[0.11611, 0.0, 0.11611], # no diffuse, shade fraction is the loss
[0.11611, 1.0, 0.00000], # all diffuse, no shade loss
[0.16667, 0.2, 0.13333],
[0.03775, 0.2, 0.03019],
]
)
loss = shading.linear_shade_loss(test_data["shaded_fraction"],
test_data["diffuse_ratio"])
assert_allclose(loss, test_data["expected_loss"], atol=1e-5)