-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Agrivoltaics - PAR diffuse fraction model #2048
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
Changes from 28 commits
90dd1e0
8cc7ffc
ae63127
5880453
5af860a
bdc2303
aec7870
02ebe81
c5d133d
149961e
eff3a25
d18827e
18619a4
feded95
b9aa23e
1c6d416
899844c
9268a44
bce50b6
2825e2c
764bf8b
0e0f836
0d23fe0
a7c84b5
d1bb64b
eeef154
6082fe7
94df738
ac9d45c
77f3ba8
a6c3c6b
f5449d7
bafe63b
1a5d0d9
189efe5
7c28be6
59faee0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Agrivoltaic Systems Modelling | ||
----------------------------- |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,145 @@ | ||||||
""" | ||||||
Calculating the diffuse PAR using Spitter's relationship | ||||||
========================================================= | ||||||
|
||||||
This example demonstrates how to calculate the diffuse photosynthetically | ||||||
active radiation (PAR) from total PAR using Spitter's relationship. | ||||||
""" | ||||||
|
||||||
# %% | ||||||
# The photosynthetically active radiation (PAR) is a key component in the | ||||||
# photosynthesis process of plants. As in photovoltaic systems, PAR can be | ||||||
echedey-ls marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
# divided into direct and diffuse components. The diffuse fraction of PAR | ||||||
# with respect to the total PAR is important in agrivoltaic systems, where | ||||||
# crops are grown under solar panels. The diffuse fraction of PAR can be | ||||||
# calculated using the Spitter's relationship [1]_ implemented in | ||||||
# :py:func:`~pvlib.irradiance.diffuse_par_spitters`. | ||||||
# This model requires the solar zenith angle and the fraction of the broadband | ||||||
# radiation that is diffuse as inputs. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To (perhaps) head off a discussion of whether "radiation" or "irradiance" should be used here: radiation is usually used when referring to the source, and irradiance (or irradiation) when referring to the receiver. So the sun emits radiation, and a tilted plane on the earth's surface receives solar irradiation. Either perspective seems OK to me in the context of this PR. But mixing PAR (..."radiation") with "irradiance" may be confusing to some. |
||||||
# | ||||||
# .. note:: | ||||||
# Understanding the distinction between the broadband radiation and the PAR | ||||||
# is a key concept. The broadband radiation is the total amount of solar | ||||||
echedey-ls marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
# radiation that is usually accounted for in PV applications, while the PAR | ||||||
echedey-ls marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
# is a measurement of a narrower range of wavelengths that are used in | ||||||
# photosynthesis. See section on *Photosynthetically Active Radiation* in | ||||||
# pp. 222-223 of [1]_. | ||||||
# | ||||||
# The key function used in this example is | ||||||
# :py:func:`pvlib.irradiance.diffuse_par_spitters` to calculate the diffuse | ||||||
# PAR fraction, as a function of broadband diffuse fraction and solar zenith. | ||||||
echedey-ls marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
# | ||||||
# References | ||||||
# ---------- | ||||||
# .. [1] C. J. T. Spitters, H. A. J. M. Toussaint, and J. Goudriaan, | ||||||
# 'Separating the diffuse and direct component of global radiation and its | ||||||
# implications for modeling canopy photosynthesis Part I. Components of | ||||||
# incoming radiation', Agricultural and Forest Meteorology, vol. 38, | ||||||
# no. 1, pp. 217-229, Oct. 1986, :doi:`10.1016/0168-1923(86)90060-2`. | ||||||
# | ||||||
# Read some example data | ||||||
# ^^^^^^^^^^^^^^^^^^^^^^ | ||||||
|
||||||
import pvlib | ||||||
import pandas as pd | ||||||
import matplotlib.pyplot as plt | ||||||
from matplotlib.dates import DateFormatter | ||||||
from pathlib import Path | ||||||
|
||||||
# Read some sample data | ||||||
DATA_FILE = Path(pvlib.__path__[0]).joinpath("data", "723170TYA.CSV") | ||||||
|
||||||
tmy, metadata = pvlib.iotools.read_tmy3( | ||||||
DATA_FILE, coerce_year=1990, map_variables=True | ||||||
) | ||||||
tmy = tmy.filter( | ||||||
["ghi", "dhi", "dni", "pressure", "temp_air"] | ||||||
) # remaining data is not needed | ||||||
tmy = tmy[ | ||||||
"1990-04-11T06":"1990-04-11T22" | ||||||
] # select a single day for this example | ||||||
|
||||||
solar_position = pvlib.solarposition.get_solarposition( | ||||||
# TMY timestamp is at end of hour, so shift to center of interval | ||||||
tmy.index.shift(freq="-30T"), | ||||||
latitude=metadata["latitude"], | ||||||
longitude=metadata["longitude"], | ||||||
altitude=metadata["altitude"], | ||||||
pressure=tmy["pressure"] * 100, # convert from millibar to Pa | ||||||
temperature=tmy["temp_air"], | ||||||
) | ||||||
solar_position.index = tmy.index # reset index to end of the hour | ||||||
|
||||||
# %% | ||||||
# Calculate Photosynthetically Active Radiation | ||||||
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||||||
# The total PAR can be approximated as 0.50 times the broadband horizontal | ||||||
# irradiance (GHI) for solar elevation higher that 10°. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is PAR simply 0 at solar elevation angles less than 10 degrees? Seems odd |
||||||
# See section on *Photosynthetically Active Radiation* in pp. 222-223 of [1]_. | ||||||
|
||||||
par = pd.DataFrame({"total": 0.50 * tmy["ghi"]}, index=tmy.index) | ||||||
|
||||||
# Calculate broadband irradiance diffuse fraction, input of the Spitter's model | ||||||
tmy["diffuse_fraction"] = tmy["dhi"] / tmy["ghi"] | ||||||
|
||||||
# Calculate diffuse PAR fraction using Spitter's relationship | ||||||
par["diffuse_fraction"] = pvlib.irradiance.diffuse_par_spitters( | ||||||
solar_position["zenith"], tmy["diffuse_fraction"] | ||||||
) | ||||||
|
||||||
# Finally, calculate the diffuse PAR | ||||||
par["diffuse"] = par["total"] * par["diffuse_fraction"] | ||||||
par[solar_position["zenith"] > 80] = ( | ||||||
0 # set to zero for elevation < 10 degrees | ||||||
) | ||||||
|
||||||
# %% | ||||||
# Plot the results | ||||||
# ^^^^^^^^^^^^^^^^ | ||||||
# Irradiances on left axis, diffuse fractions on right axis | ||||||
|
||||||
fig, ax_l = plt.subplots(figsize=(12, 6)) | ||||||
ax_l.set( | ||||||
xlabel="Time", | ||||||
ylabel="Irradiance $[W/m^2]$", | ||||||
title="Diffuse PAR using Spitter's relationship", | ||||||
) | ||||||
ax_l.xaxis.set_major_formatter(DateFormatter("%H:%M", tz=tmy.index.tz)) | ||||||
ax_l.plot(tmy.index, tmy["ghi"], label="Broadband: total", color="deepskyblue") | ||||||
ax_l.plot( | ||||||
tmy.index, | ||||||
tmy["dhi"], | ||||||
label="Broadband: diffuse", | ||||||
color="skyblue", | ||||||
linestyle="-.", | ||||||
) | ||||||
ax_l.plot(tmy.index, par["total"], label="PAR: total", color="orangered") | ||||||
ax_l.plot( | ||||||
tmy.index, | ||||||
par["diffuse"], | ||||||
label="PAR: diffuse", | ||||||
color="coral", | ||||||
linestyle="-.", | ||||||
) | ||||||
ax_l.grid() | ||||||
ax_l.legend(loc="upper left") | ||||||
|
||||||
ax_r = ax_l.twinx() | ||||||
ax_r.set(ylabel="Diffuse fraction") | ||||||
ax_r.plot( | ||||||
tmy.index, | ||||||
tmy["diffuse_fraction"], | ||||||
label="Broadband diffuse fraction", | ||||||
color="plum", | ||||||
linestyle=":", | ||||||
) | ||||||
ax_r.plot( | ||||||
tmy.index, | ||||||
par["diffuse_fraction"], | ||||||
label="PAR diffuse fraction", | ||||||
color="chocolate", | ||||||
linestyle=":", | ||||||
) | ||||||
ax_r.legend(loc="upper right") | ||||||
|
||||||
plt.show() |
Uh oh!
There was an error while loading. Please reload this page.