WSL/SLF GitLab Repository

Commit 01af7bb0 authored by Mathias Bavay's avatar Mathias Bavay
Browse files

Some better documentation, a new method to project a radiation from the...

Some better documentation, a new method to project a radiation from the horizontal to a slope (as needed by Snowpack), a foolproof method for computing the splitting (it only gets one parameter, the measured radiation, and knows which potential radiation to use...). Now Snowpack can use a Sun object for computing its radiation!
parent 9293031a
......@@ -266,10 +266,12 @@ void SunObject::getSlopeRadiation(const double& slope_azi, const double& slope_e
/**
* @brief Evaluate the splitting coefficient between direct and diffuse components of the
* incoming short wave radiation. Splitting is based on "clearness of the sky", i.e. the ratio of
* measured incoming global radiation to top of the atmosphere radiation toa_h.g
* Erbs et al., Iqbal p.269e
* @param iswr_modeled modelled radiation, it should be Top Of Atmosphere Radiation (W/m²)
* incoming short wave radiation. Splitting is based on "clearness of the sky", ie. the ratio of
* measured incoming global radiation to top of the atmosphere radiation toa_h,
* see
* D. G. Erbs, S.A. Klein, J.A. Duffie, <i>"Estimation of the diffuse radiation fraction for hourly, daily and monthly-average global radiation"</i>, Solar Energy, <b>28</b>, 4, 1982, Pages 293-302 and
* M. Iqbal, <i>"An introduction to solar radiation"</i>, 1983, Academic Press, ISBN: 0-12-373750-8
* @param iswr_modeled modelled radiation, it should be beam Top Of Atmosphere Radiation (W/m²)
* @param iswr_measured measured Incoming Short Wave Radiation on the ground (W/m²)
* @return splitting coefficient (between 0 and 1, 1 being 100% diffuse radiation)
*/
......@@ -308,8 +310,14 @@ double SunObject::getSplitting(const double& iswr_modeled, const double& iswr_me
return (splitting_coef); // should be <=1.1; diff/toa should be <=0.8
}
double SunObject::getSplitting(const double& iswr_measured) const
{
return getSplitting(beam_toa, iswr_measured);
}
std::ostream& operator<<(std::ostream &os, const SunObject& data)
{
const std::streamsize old_prec = os.precision();
os << "<SunObject>\n";
os << data.position;
os << std::fixed << std::setprecision(4);
......@@ -335,7 +343,7 @@ std::ostream& operator<<(std::ostream &os, const SunObject& data)
os << std::fixed << std::setw(colw) << std::setprecision(1) << R_diffuse;
os << std::fixed << std::setw(colw) << std::setprecision(1) << R_direct+R_diffuse << "\n";
os << "</SunObject>\n";
os << "</SunObject>\n" << std::setprecision(old_prec);
return os;
}
......
......@@ -60,6 +60,7 @@ class SunObject {
double getElevationThresh() const;
double getSplitting(const double& iswr_modeled, const double& iswr_measured) const;
double getSplitting(const double& iswr_measured) const;
//SunTrajectory position;
SunMeeus position;
......
......@@ -50,7 +50,7 @@ double SunTrajectory::getAngleOfIncidence(const double& sun_azi, const double& s
double SunTrajectory::getRadiationOnHorizontal(const double& radiation) const
{ // Project a beam radiation (ie: perpendicular to the sun beam) to the horizontal
// Oke, T.R., Boundary Layer Climates. 2nd ed, 1987, Routledge, London, 435pp.
// Oke, T.R., Boundary Layer Climates. 2nd ed, 1987, Routledge, London, p345.
if(radiation==IOUtils::nodata) return IOUtils::nodata;
const double Z = (90.-SolarElevation)*Cst::to_rad;
......@@ -61,7 +61,7 @@ double SunTrajectory::getRadiationOnHorizontal(const double& radiation) const
double SunTrajectory::getRadiationOnSlope(const double& slope_azi, const double& slope_elev, const double& radiation) const
{ // Project a beam radiation (ie: perpendicular to the sun beam) to a given slope
// Oke, T.R., Boundary Layer Climates. 2nd ed, 1987, Routledge, London, 435pp.
// Oke, T.R., Boundary Layer Climates. 2nd ed, 1987, Routledge, London, p345.
if(radiation==IOUtils::nodata) return IOUtils::nodata;
const double Z = (90.-SolarElevation)*Cst::to_rad;
......@@ -73,10 +73,33 @@ double SunTrajectory::getRadiationOnSlope(const double& slope_azi, const double&
else return 0.;
}
/** @brief Project a given horizontal radiation to a given slope.
* The sun position is the current one, the radiation intensity is given as well as the slope parameters.
* This should be used after correcting the radiation on the horizontal (by applying atmospheric effects or
* special handling for dawn/dusk) in order to compute consistent radiation on slopes.
* @param slope_azi slope azimuth (compass orientation, in degrees)
* @param slope_elev slope angle (in degrees)
* @param H_radiation radiation intensity on the horizontal
* @param elev_threshold all solar elevations less than this threshold will be use this threshold (in degrees, default 5 degrees)
* @return radiation projected on the slope
*/
double SunTrajectory::getHorizontalOnSlope(const double& slope_azi, const double& slope_elev, const double& H_radiation, const double& elev_threshold) const
{// Project a given horizontal radiation to a given slope
// Oke, T.R., Boundary Layer Climates. 2nd ed, 1987, Routledge, London, p345.
const double Z = (SolarElevation>=elev_threshold)? (90.-SolarElevation)*Cst::to_rad : (90.-elev_threshold)*Cst::to_rad;
const double cosZ = cos(Z);
const double beta = slope_elev*Cst::to_rad;
const double cos_theta = cos(beta)*cosZ + sin(beta)*sin(Z)*cos((SolarAzimuthAngle-slope_azi)*Cst::to_rad);
const double on_slope = ( H_radiation/cosZ ) * cos_theta;
if(on_slope>0.) return on_slope;
return 0.;
}
//usefull static methods
double SunTrajectory::projectHorizontalToSlope(const double& sun_azi, const double& sun_elev, const double& slope_azi, const double& slope_elev, const double& H_radiation)
{// Project a horizontal radiation to a given slope
// Oke, T.R., Boundary Layer Climates. 2nd ed, 1987, Routledge, London, 435pp.
// Oke, T.R., Boundary Layer Climates. 2nd ed, 1987, Routledge, London, p345.
const double Z = (90.-sun_elev)*Cst::to_rad;
const double cosZ = cos(Z);
......@@ -93,7 +116,7 @@ double SunTrajectory::projectHorizontalToSlope(const double& sun_azi, const doub
double SunTrajectory::projectSlopeToHorizontal(const double& sun_azi, const double& sun_elev, const double& slope_azi, const double& slope_elev, const double& S_radiation)
{// Project a slope radiation to horizontal
// Oke, T.R., Boundary Layer Climates. 2nd ed, 1987, Routledge, London, 435pp.
// Oke, T.R., Boundary Layer Climates. 2nd ed, 1987, Routledge, London, p345.
const double Z = (90.-sun_elev)*Cst::to_rad;
const double beta = slope_elev*Cst::to_rad;
const double cos_theta = cos(beta)*cos(Z) + sin(beta)*sin(Z)*cos((sun_azi-slope_azi)*Cst::to_rad);
......@@ -108,7 +131,7 @@ double SunTrajectory::projectSlopeToHorizontal(const double& sun_azi, const doub
double SunTrajectory::projectHorizontalToBeam(const double& sun_elev, const double& H_radiation)
{ // Project a beam radiation (ie: perpendicular to the sun beam) to the horizontal
// Oke, T.R., Boundary Layer Climates. 2nd ed, 1987, Routledge, London, 435pp.
// Oke, T.R., Boundary Layer Climates. 2nd ed, 1987, Routledge, London, p345.
const double Z = (90.-sun_elev)*Cst::to_rad;
const double cosZ = cos(Z);
......
......@@ -18,11 +18,6 @@
#ifndef __SUNTAJECTORY_H__
#define __SUNTAJECTORY_H__
/*#include <ostream>
#include <iostream>
#include <iomanip>
#include <sstream>*/
#include <meteoio/IOUtils.h>
namespace mio {
......@@ -61,9 +56,10 @@ class SunTrajectory {
virtual void getEquatorialCoordinates(double& right_ascension, double& declination)=0;
///radiation projection methods
double getAngleOfIncidence(const double& slope_azi, const double& slope_elev) const;
double getRadiationOnHorizontal(const double& radiation) const;
double getRadiationOnSlope(const double& slope_azi, const double& slope_elev, const double& radiation) const;
double getAngleOfIncidence(const double& slope_azi, const double& slope_elev) const;
double getHorizontalOnSlope(const double& slope_azi, const double& slope_elev, const double& H_radiation, const double& elev_threshold=5.) const;
///static helper for radiation projection
static double getAngleOfIncidence(const double& sun_azi, const double& sun_elev,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment