-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Shaded Fraction on Sloped Terrains - PR1725 partial continuation #1962
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
kandersolar
merged 120 commits into
pvlib:main
from
echedey-ls:pr1725-continuation-shaded-fraction-mikofski
May 24, 2024
Merged
Changes from 119 commits
Commits
Show all changes
120 commits
Select commit
Hold shift + click to select a range
c87885c
Update shading.py
echedey-ls 4fc6cd8
Minimal test
echedey-ls 2a72f33
Implementation
echedey-ls d6e8067
Fix, fix, fix, fix & format
echedey-ls 13a56d4
Format issues
echedey-ls f012aae
Extend tests (compare with singleaxis) & format with ruff
echedey-ls 6dd9a3b
Format fixes
echedey-ls e8743db
Upgrade tests
echedey-ls 6030774
Array -> Axis
echedey-ls 6276382
type
echedey-ls 509699f
Whatsnew
echedey-ls 5ff8fd8
xd
echedey-ls 04126e0
bruh
echedey-ls 607a246
Minor Python optimization a la tracking.singleaxis
echedey-ls 240b551
Comment and minor optimizations
echedey-ls 997def6
Surface -> Axis
echedey-ls 7912055
Elevation -> Zenith
echedey-ls f068e3e
Elev -> Zenith
echedey-ls a5f4a85
Update shading.py
echedey-ls a854e27
Update docstring
echedey-ls 2d82375
Add comments from `tracking.singleaxis`
echedey-ls 5f24721
Singleaxis implementation port & test addition, based on old pvlib.tr…
echedey-ls 049a8cc
Update v0.10.4.rst
echedey-ls a3185df
Linter
echedey-ls b9f1a76
Code review
echedey-ls f7d1d80
Add Fig 5 [1] (still gotta check the built output)
echedey-ls 1880f6a
Add caption, change size and describe in alternate text
echedey-ls d9f242a
rST fixes ?
echedey-ls 379ca95
Figures have captions, images do not
echedey-ls 62e99ad
Flip arguments order
echedey-ls 4f584ea
I forgot :skull:
echedey-ls 238d123
Linter are you happy now?
echedey-ls 98a254d
Remove port test and add edge cases test
echedey-ls 4616175
Update test_shading.py
echedey-ls 33ffd28
Indentation xd
echedey-ls 8526bc6
Update test_shading.py
echedey-ls bde3656
I forgot how to code
echedey-ls 51e3750
Align data
echedey-ls 35738a4
Docstring suggestion from Kevin
echedey-ls 8d679c3
Update link to example?
echedey-ls 4a907c1
add linear shade loss for thin films
mikofski 234288d
add tests, update docs, what's new
mikofski fb0e5d1
fix what's new gh issue and pr links
mikofski aa4b6e8
fix trailing whitespace
mikofski 18b2187
responding to comments
mikofski 4163a72
update docstring for linear shade loss
mikofski 1ebf8ea
update example in linear_shade_loss
mikofski de2144f
add figure and formulas to shaded fraction
mikofski 6aa43f0
shaded fraction consistently
mikofski c34a2f6
Add alternative text to image
echedey-ls 6b9f478
Update implementation based on PSZ PR. See description.
echedey-ls c3a9569
Whatsnew entries
echedey-ls 4bb02ab
Linter
echedey-ls 78c481e
Clear things, convert Mark's reference to a reference
echedey-ls 0ce0d68
Linter
echedey-ls 74b4215
Update according to changes at PSZA PR
echedey-ls 909cc23
Another commit, another try
echedey-ls e3e73f6
Ahhh, I rebased too fast
echedey-ls cbb0b04
whatsnews
echedey-ls 96b61a8
Update v0.10.4.rst
echedey-ls d2b9291
Update v0.10.3.rst
echedey-ls 7ec4d64
Merge branch 'main' into pr1725-continuation-shaded-fraction-mikofski
echedey-ls bbc6115
Rename to `shaded_fraction1d`, change params to `surface_*` instead o…
echedey-ls 39a3ba9
Left this tracker refs behind
echedey-ls a3ccf3e
Change rename in rst entries
echedey-ls e5fffca
Add another testcase
echedey-ls 457d4b4
Improve docs references, clarify nomenclature
echedey-ls f11858e
Update test_shading.py
echedey-ls f321cc1
Merge branch 'main' into linear-shade-mikofski-pr-1725
echedey-ls 0ab3720
Remove linear_shade_loss
echedey-ls e6da6e8
First implementation of the new shaded fraction model (missing figure)
echedey-ls 4ce1655
Create Anderson_Jensen_2024_Fig3.png
echedey-ls 60b7e2e
Update shading.py
echedey-ls 2d23cb2
Update shading.py
echedey-ls 78a451c
Update shading.py
echedey-ls 28128f6
lintaaargggg
echedey-ls f4acf39
Fill reference
echedey-ls 104d185
Next release 0.10.5?
echedey-ls 894ff9f
Fix tests
echedey-ls f147881
Update test_shading.py
echedey-ls 4d11294
Little improvement to table definitions
echedey-ls 69c76cf
Change `l` to `\ell`
echedey-ls 758f5e7
`pvlib.tracking.projected_solar_zenith_angle` to `pvlib.shading.proje…
echedey-ls 6882dfa
pitch references to `pitch`
echedey-ls 4ef4567
`trackers_axis_azimuth` to `axis_azimuth`
echedey-ls 574a1a2
whatsnews
echedey-ls efac0b3
Update v0.10.5.rst
echedey-ls 3a726b8
Change `tilt`s to `rotation`s and add `axis_tilt`
echedey-ls 300b912
Forgot to update tests :skull:
echedey-ls 497a62e
Merge branch 'main' into terrain-slope-mikofski-pr-1725
echedey-ls 2a34f43
Merge branch 'main' into pr1725-continuation-shaded-fraction-mikofski
echedey-ls c1b3978
Add examples section
echedey-ls db8edd6
roles assumption messin w/ me docs :astonished:
echedey-ls d65e64d
roles assumption messin w/ me docs :astonished:
echedey-ls 51a2dfa
Merge branch 'pr1725-continuation-shaded-fraction-mikofski' of https:…
echedey-ls 9038097
Update shading.py
echedey-ls 5652801
Update shading.py
echedey-ls 31affba
Add gallery example
echedey-ls 80ab494
This was fixed in recent sphinx-gallery releases IIRC
echedey-ls facde21
Extra empty line or admonition type unsupported
echedey-ls 5a807b7
Fix example link (hopefully :pray: )
echedey-ls 25a0f19
Update shading.py
echedey-ls 8bdd469
Fix subsubsections?
echedey-ls a2e8be7
Nah, bulleted list didn't work
echedey-ls 9f1fa97
tilted -> tracker, only affects text
echedey-ls 37ab496
Typos and unreasonable physical values
echedey-ls 6303583
See the Examples section below, not the unlinkable link
echedey-ls e785292
tracker -> row, param names, code and docs
echedey-ls 9b98d9e
Fix broken example :wrench:
echedey-ls 3726e4d
Apply suggestions from code review
echedey-ls 4e7e36f
"the row axis/axes" instead of ``axis_azimuth``
echedey-ls 59465c8
Unnecessary math mode
echedey-ls 9fa2bb4
Example suggestions and text trimming
echedey-ls 1be1d3e
Merge branch 'main' into terrain-slope-mikofski-pr-1725
echedey-ls 0d521ee
whatsmes
echedey-ls f01bd6f
Add test to fix coverage issue
echedey-ls 946cca6
Apply suggestions from code review (Adam)
echedey-ls 5e4bc7d
Update docs/examples/shading/plot_shaded_fraction1d_ns_hsat_example.py
kandersolar 9a7d5b7
Merge branch 'main' into pr1725-continuation-shaded-fraction-mikofski
kandersolar 7f1d549
Update docs/examples/shading/plot_shaded_fraction1d_ns_hsat_example.py
kandersolar File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
181 changes: 181 additions & 0 deletions
181
docs/examples/shading/plot_shaded_fraction1d_ns_hsat_example.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
""" | ||
Shaded fraction of a horizontal single-axis tracker | ||
==================================================== | ||
|
||
This example illustrates how to calculate the 1D shaded fraction of three rows | ||
in a North-South horizontal single axis tracker (HSAT) configuration. | ||
""" | ||
|
||
# %% | ||
# :py:func:`pvlib.shading.shaded_fraction1d` exposes a useful method for the | ||
# calculation of the shaded fraction of the width of a solar collector. Here, | ||
# the width is defined as the dimension perpendicular to the axis of rotation. | ||
# This method for calculating the shaded fraction only requires minor | ||
# modifications to be applicable for fixed-tilt systems. | ||
# | ||
# It is highly recommended to read :py:func:`pvlib.shading.shaded_fraction1d` | ||
# documentation to understand the input parameters and the method's | ||
# capabilities. For more in-depth information, please see the journal paper | ||
# `10.1063/5.0202220 <https://doi.org/10.1063/5.0202220>`_ describing | ||
the methodology. | ||
# | ||
# Let's start by obtaining the true-tracking angles for each of the rows and | ||
# limiting the angles to the range of -50 to 50 degrees. This decision is | ||
# done to create an example scenario with significant shading. | ||
# | ||
# Key functions used in this example are: | ||
# | ||
# 1. :py:func:`pvlib.tracking.singleaxis` to calculate the tracking angles. | ||
# 2. :py:func:`pvlib.shading.projected_solar_zenith_angle` to calculate the | ||
# projected solar zenith angle. | ||
# 3. :py:func:`pvlib.shading.shaded_fraction1d` to calculate the shaded | ||
# fractions. | ||
# | ||
# .. sectionauthor:: Echedey Luis <echelual (at) gmail.com> | ||
|
||
import pvlib | ||
|
||
import numpy as np | ||
import pandas as pd | ||
import matplotlib.pyplot as plt | ||
from matplotlib.dates import DateFormatter | ||
|
||
# Define the solar system parameters | ||
latitude, longitude = 28.51, -13.89 | ||
altitude = pvlib.location.lookup_altitude(latitude, longitude) | ||
|
||
axis_tilt = 3 # degrees, positive is upwards in the axis_azimuth direction | ||
axis_azimuth = 180 # degrees, N-S tracking axis | ||
collector_width = 3.2 # m | ||
pitch = 4.15 # m | ||
gcr = collector_width / pitch | ||
cross_axis_slope = -5 # degrees | ||
AdamRJensen marked this conversation as resolved.
Show resolved
Hide resolved
|
||
surface_to_axis_offset = 0.07 # m | ||
|
||
# Generate a time range for the simulation | ||
times = pd.date_range( | ||
start="2024-01-01T05", | ||
end="2024-01-01T21", | ||
freq="5min", | ||
tz="Atlantic/Canary", | ||
) | ||
|
||
# Calculate the solar position | ||
solar_position = pvlib.solarposition.get_solarposition( | ||
times, latitude, longitude, altitude | ||
) | ||
solar_azimuth = solar_position["azimuth"] | ||
solar_zenith = solar_position["apparent_zenith"] | ||
|
||
# Calculate the tracking angles | ||
rotation_angle = pvlib.tracking.singleaxis( | ||
solar_zenith, | ||
solar_azimuth, | ||
axis_tilt, | ||
axis_azimuth, | ||
max_angle=(-50, 50), # (min, max) degrees | ||
backtrack=False, | ||
gcr=gcr, | ||
cross_axis_tilt=cross_axis_slope, | ||
)["tracker_theta"] | ||
|
||
# %% | ||
# Once the tracker angles have been obtained, the next step is to calculate | ||
# the shaded fraction. Special care must be taken | ||
# to ensure that the shaded or shading tracker roles are correctly assigned | ||
# depending on the solar position. | ||
# This means we will have a result for each row, ``eastmost_shaded_fraction``, | ||
# ``middle_shaded_fraction``, and ``westmost_shaded_fraction``. | ||
# Switching the parameters will be based on the | ||
# sign of :py:func:`pvlib.shading.projected_solar_zenith_angle`. | ||
# | ||
# The following code is verbose to make it easier to understand the process, | ||
# but with some effort you may be able to simplify it. This verbosity also | ||
# allows to change the premises easily per case, e.g., in case of a tracker | ||
# failure or with a different system configuration. | ||
|
||
psza = pvlib.shading.projected_solar_zenith_angle( | ||
solar_zenith, solar_azimuth, axis_tilt, axis_azimuth | ||
) | ||
|
||
# Calculate the shaded fraction for the eastmost row | ||
eastmost_shaded_fraction = np.where( | ||
psza < 0, | ||
0, # no shaded fraction in the morning | ||
# shaded fraction in the evening | ||
pvlib.shading.shaded_fraction1d( | ||
solar_zenith, | ||
solar_azimuth, | ||
axis_azimuth, | ||
shaded_row_rotation=rotation_angle, | ||
axis_tilt=axis_tilt, | ||
collector_width=collector_width, | ||
pitch=pitch, | ||
surface_to_axis_offset=surface_to_axis_offset, | ||
cross_axis_slope=cross_axis_slope, | ||
shading_row_rotation=rotation_angle, | ||
), | ||
) | ||
|
||
# Calculate the shaded fraction for the middle row | ||
middle_shaded_fraction = np.where( | ||
psza < 0, | ||
# shaded fraction in the morning | ||
pvlib.shading.shaded_fraction1d( | ||
solar_zenith, | ||
solar_azimuth, | ||
axis_azimuth, | ||
shaded_row_rotation=rotation_angle, | ||
axis_tilt=axis_tilt, | ||
collector_width=collector_width, | ||
pitch=pitch, | ||
surface_to_axis_offset=surface_to_axis_offset, | ||
cross_axis_slope=cross_axis_slope, | ||
shading_row_rotation=rotation_angle, | ||
), | ||
# shaded fraction in the evening | ||
pvlib.shading.shaded_fraction1d( | ||
solar_zenith, | ||
solar_azimuth, | ||
axis_azimuth, | ||
shaded_row_rotation=rotation_angle, | ||
axis_tilt=axis_tilt, | ||
collector_width=collector_width, | ||
pitch=pitch, | ||
surface_to_axis_offset=surface_to_axis_offset, | ||
cross_axis_slope=cross_axis_slope, | ||
shading_row_rotation=rotation_angle, | ||
), | ||
) | ||
|
||
# Calculate the shaded fraction for the westmost row | ||
westmost_shaded_fraction = np.where( | ||
psza < 0, | ||
# shaded fraction in the morning | ||
pvlib.shading.shaded_fraction1d( | ||
solar_zenith, | ||
solar_azimuth, | ||
axis_azimuth, | ||
shaded_row_rotation=rotation_angle, | ||
axis_tilt=axis_tilt, | ||
collector_width=collector_width, | ||
pitch=pitch, | ||
surface_to_axis_offset=surface_to_axis_offset, | ||
cross_axis_slope=cross_axis_slope, | ||
shading_row_rotation=rotation_angle, | ||
), | ||
0, # no shaded fraction in the evening | ||
) | ||
|
||
# %% | ||
# Plot the shaded fraction result for each row: | ||
plt.plot(times, eastmost_shaded_fraction, label="East-most", color="blue") | ||
plt.plot(times, middle_shaded_fraction, label="Middle", color="green", | ||
linewidth=3, linestyle="--") # fmt: skip | ||
plt.plot(times, westmost_shaded_fraction, label="West-most", color="red") | ||
plt.title(r"$shaded\_fraction1d$ of each row vs time") | ||
plt.xlabel("Time") | ||
plt.gca().xaxis.set_major_formatter(DateFormatter("%H:%M")) | ||
plt.ylabel("Shaded Fraction") | ||
plt.legend() | ||
plt.show() |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.