Skip to content

NREL bird clearsky #276

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
merged 35 commits into from
May 26, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
9d192ba
add requirements.txt to install into virtualenv and ignore venv/
mikofski Dec 3, 2016
457615d
add Bird clearsky model
mikofski Dec 3, 2016
048a837
move test_bird to test_clearsky and move bird to clearsky core module
mikofski Dec 15, 2016
1324267
revert api changes
mikofski Dec 15, 2016
f985b15
add spencer and pvcdron eot to solarposition, fix test and 2pi
mikofski Dec 17, 2016
3ace2a8
add equation of time test
mikofski Jan 7, 2017
850b604
addressing comments in PR 276
mikofski Jan 10, 2017
3b86fd8
add declination formulas to solarposition.py
mikofski Jan 10, 2017
dc4eba6
make bird function signature similar to other clearsky methods
mikofski Jan 11, 2017
ba7eb1e
add all parameters to docstring for bird clearsky
mikofski Jan 11, 2017
e6dcdac
add all parameters to docstring for bird clearsky
mikofski Jan 11, 2017
8877fb0
set night values to zero
mikofski Jan 11, 2017
de0eb33
calculate diffuse_horiz return value prior to return line
mikofski Jan 11, 2017
da8e292
update test_bird() with new function signature
mikofski Jan 14, 2017
b8d93cf
Merge branch 'master' into nrel_bird_clearsky
mikofski Jan 14, 2017
0e69eca
Merge branch 'master' into nrel_bird_clearsky
mikofski Jan 14, 2017
dd97ecc
update docs
mikofski Jan 14, 2017
96af6a7
add missing requirements
mikofski Jan 14, 2017
926c28b
add it to min build too
mikofski Jan 14, 2017
ca7649e
remove dependence on xlrd
mikofski Jan 21, 2017
f2fc729
move low precision solar position correlations to new api section
mikofski Jan 23, 2017
977bc8f
test keywords in bird clear sky model
mikofski Jan 23, 2017
09d0b7e
test scalars in bird model
mikofski Jan 23, 2017
cb562ef
add test data file
mikofski Jan 23, 2017
1976721
Merge branch 'master' into nrel_bird_clearsky
mikofski Feb 4, 2017
bc5eb18
lower case Spencer71 in docs and solarposition
mikofski Feb 4, 2017
a4b9edd
Merge branch 'master' into nrel_bird_clearsky
mikofski Feb 7, 2017
76db3c7
Merge branch 'master' into nrel_bird_clearsky
mikofski May 17, 2017
513cd95
fix lower case 's' in spencer71
mikofski May 17, 2017
dc528be
output OrderedDict or DataFrame
mikofski May 17, 2017
ca8adf8
fix link
mikofski May 17, 2017
1e14e5f
update docstring returns to OrderedDict/DataFrame
mikofski May 18, 2017
b4e5cce
provide note on solar vs apparent zenith and testing
mikofski May 18, 2017
2a0458a
quotes for 'direct_horizontal' in docstring returns
mikofski May 18, 2017
eafb9cd
add tests for solarposition low-accuracy formulas
mikofski May 25, 2017
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
15 changes: 15 additions & 0 deletions docs/sphinx/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ unless you know that you need a different function.
solarposition.pyephem
solarposition.spa_c


Additional functions for quantities closely related to solar position.

.. autosummary::
Expand All @@ -65,6 +66,19 @@ algorithm.
spa


Correlations and analytical expressions for low precision solar position
calculations.

.. autosummary::
:toctree: generated/

solarposition.solar_zenith_analytical
solarposition.declination_spencer71
solarposition.declination_cooper69
solarposition.equation_of_time_spencer71
solarposition.equation_of_time_pvcdrom
solarposition.hour_angle

Clear sky
=========

Expand All @@ -77,6 +91,7 @@ Clear sky
clearsky.simplified_solis
clearsky.haurwitz
clearsky.detect_clearsky
clearsky.bird


Airmass and atmospheric models
Expand Down
4 changes: 4 additions & 0 deletions docs/sphinx/source/whatsnew/v0.4.5.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ Bug fixes

* Fix pandas 0.20 incompatibilities in Location.get_clearsky,
solarposition.ephemeris (:issue:`325`)
* Added NREL Bird clear sky model. (:issue:`276`)
* Added lower accuracy formulas for equation of time, declination, hour angle
and solar zenith.


Contributors
~~~~~~~~~~~~

* Will Holmgren
* Mark Mikofski
143 changes: 132 additions & 11 deletions pvlib/clearsky.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import numpy as np
import pandas as pd

from pvlib import tools
from pvlib import tools, atmosphere, solarposition, irradiance


def ineichen(apparent_zenith, airmass_absolute, linke_turbidity,
Expand All @@ -31,19 +31,19 @@ def ineichen(apparent_zenith, airmass_absolute, linke_turbidity,

Parameters
-----------
apparent_zenith: numeric
apparent_zenith : numeric
Refraction corrected solar zenith angle in degrees.

airmass_absolute: numeric
airmass_absolute : numeric
Pressure corrected airmass.

linke_turbidity: numeric
linke_turbidity : numeric
Linke Turbidity.

altitude: numeric
altitude : numeric
Altitude above sea level in meters.

dni_extra: numeric
dni_extra : numeric
Extraterrestrial irradiance. The units of ``dni_extra``
determine the units of the output.

Expand Down Expand Up @@ -349,24 +349,24 @@ def simplified_solis(apparent_elevation, aod700=0.1, precipitable_water=1.,

Parameters
----------
apparent_elevation: numeric
apparent_elevation : numeric
The apparent elevation of the sun above the horizon (deg).

aod700: numeric
aod700 : numeric
The aerosol optical depth at 700 nm (unitless).
Algorithm derived for values between 0 and 0.45.

precipitable_water: numeric
precipitable_water : numeric
The precipitable water of the atmosphere (cm).
Algorithm derived for values between 0.2 and 10 cm.
Values less than 0.2 will be assumed to be equal to 0.2.

pressure: numeric
pressure : numeric
The atmospheric pressure (Pascals).
Algorithm derived for altitudes between sea level and 7000 m,
or 101325 and 41000 Pascals.

dni_extra: numeric
dni_extra : numeric
Extraterrestrial irradiance. The units of ``dni_extra``
determine the units of the output.

Expand Down Expand Up @@ -720,3 +720,124 @@ def rmse(alpha):
return clear_samples, components, alpha
else:
return clear_samples


def bird(zenith, airmass_relative, aod380, aod500, precipitable_water,
ozone=0.3, pressure=101325., dni_extra=1364., asymmetry=0.85,
albedo=0.2):
"""
Bird Simple Clear Sky Broadband Solar Radiation Model

Based on NREL Excel implementation by Daryl R. Myers [1, 2].

Bird and Hulstrom define the zenith as the "angle between a line to the sun
and the local zenith". There is no distinction in the paper between solar
zenith and apparent (or refracted) zenith, but the relative airmass is
defined using the Kasten 1966 expression, which requires apparent zenith.
Although the formulation for calculated zenith is never explicitly defined
in the report, since the purpose was to compare existing clear sky models
with "rigorous radiative transfer models" (RTM) it is possible that apparent
zenith was obtained as output from the RTM. However, the implentation
presented in PVLIB is tested against the NREL Excel implementation by Daryl
Myers which uses an analytical expression for solar zenith instead of
apparent zenith.

Parameters
----------
zenith : numeric
Solar or apparent zenith angle in degrees - see note above
airmass_relative : numeric
Relative airmass
aod380 : numeric
Aerosol optical depth [cm] measured at 380[nm]
aod500 : numeric
Aerosol optical depth [cm] measured at 500[nm]
precipitable_water : numeric
Precipitable water [cm]
ozone : numeric
Atmospheric ozone [cm], defaults to 0.3[cm]
pressure : numeric
Ambient pressure [Pa], defaults to 101325[Pa]
dni_extra : numeric
Extraterrestrial radiation [W/m^2], defaults to 1364[W/m^2]
asymmetry : numeric
Asymmetry factor, defaults to 0.85
albedo : numeric
Albedo, defaults to 0.2

Returns
-------
clearsky : DataFrame (if Series input) or OrderedDict of arrays
DataFrame/OrderedDict contains the columns/keys
``'dhi', 'dni', 'ghi', 'direct_horizontal'`` in [W/m^2].

See also
--------
pvlib.atmosphere.bird_hulstrom80_aod_bb
pvlib.atmosphere.relativeairmass

References
----------
[1] R. E. Bird and R. L Hulstrom, "A Simplified Clear Sky model for Direct
and Diffuse Insolation on Horizontal Surfaces" SERI Technical Report
SERI/TR-642-761, Feb 1981. Solar Energy Research Institute, Golden, CO.

[2] Daryl R. Myers, "Solar Radiation: Practical Modeling for Renewable
Energy Applications", pp. 46-51 CRC Press (2013)

`NREL Bird Clear Sky Model <http://rredc.nrel.gov/solar/models/clearsky/>`_

`SERI/TR-642-761 <http://rredc.nrel.gov/solar/pubs/pdfs/tr-642-761.pdf>`_

`Error Reports <http://rredc.nrel.gov/solar/models/clearsky/error_reports.html>`_
"""
etr = dni_extra # extraradiation
ze_rad = np.deg2rad(zenith) # zenith in radians
airmass = airmass_relative
# Bird clear sky model
am_press = atmosphere.absoluteairmass(airmass, pressure)
t_rayleigh = (
np.exp(-0.0903 * am_press ** 0.84 * (
1.0 + am_press - am_press ** 1.01
))
)
am_o3 = ozone*airmass
t_ozone = (
1.0 - 0.1611 * am_o3 * (1.0 + 139.48 * am_o3) ** -0.3034 -
0.002715 * am_o3 / (1.0 + 0.044 * am_o3 + 0.0003 * am_o3 ** 2.0)
)
t_gases = np.exp(-0.0127 * am_press ** 0.26)
am_h2o = airmass * precipitable_water
t_water = (
1.0 - 2.4959 * am_h2o / (
(1.0 + 79.034 * am_h2o) ** 0.6828 + 6.385 * am_h2o
)
)
bird_huldstrom = atmosphere.bird_hulstrom80_aod_bb(aod380, aod500)
t_aerosol = np.exp(
-(bird_huldstrom ** 0.873) *
(1.0 + bird_huldstrom - bird_huldstrom ** 0.7088) * airmass ** 0.9108
)
taa = 1.0 - 0.1 * (1.0 - airmass + airmass ** 1.06) * (1.0 - t_aerosol)
rs = 0.0685 + (1.0 - asymmetry) * (1.0 - t_aerosol / taa)
id_ = 0.9662 * etr * t_aerosol * t_water * t_gases * t_ozone * t_rayleigh
ze_cos = np.where(zenith < 90, np.cos(ze_rad), 0.0)
id_nh = id_ * ze_cos
ias = (
etr * ze_cos * 0.79 * t_ozone * t_gases * t_water * taa *
(0.5 * (1.0 - t_rayleigh) + asymmetry * (1.0 - (t_aerosol / taa))) / (
1.0 - airmass + airmass ** 1.02
)
)
gh = (id_nh + ias) / (1.0 - albedo * rs)
diffuse_horiz = gh - id_nh
# TODO: be DRY, use decorator to wrap methods that need to return either
# OrderedDict or DataFrame instead of repeating this boilerplate code
irrads = OrderedDict()
irrads['direct_horizontal'] = id_nh
irrads['ghi'] = gh
irrads['dni'] = id_
irrads['dhi'] = diffuse_horiz
if isinstance(irrads['dni'], pd.Series):
irrads = pd.DataFrame.from_dict(irrads)
return irrads
Loading