WSL/SLF GitLab Repository

GeneratorAlgorithms.h 17.8 KB
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 /***********************************************************************************/ /* Copyright 2013 WSL Institute for Snow and Avalanche Research SLF-DAVOS */ /***********************************************************************************/ /* This file is part of MeteoIO. MeteoIO is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. MeteoIO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with MeteoIO. If not, see . */ #ifndef __GENERATORALGORITHMS_H__ #define __GENERATORALGORITHMS_H__  21 22 #include #include  23 24 25 26 27  #include #include #include  28 #ifdef _MSC_VER  Mathias Bavay committed Oct 05, 2013 29 30 31  #pragma warning(disable:4512) //we don't need any = operator! #endif  32 33 34 35 36 37 38 39 40 41 42 namespace mio { /** * @page generators Data generators * Once the data has been read, filtered and resampled, it can be that some data points are still missing. * These are either a few isolated periods (a sensor was not functioning) that are too large for performing * a statistical temporal interpolation or that a meteorological parameter was not even measured. In such a case, * we generate data, generally relying on some parametrization using other meteorological parameters. In a few * cases, even fully arbitrary data might be helpful (replacing missing value by a given constant so a model can * run over the data gap). *  Mathias Bavay committed Apr 23, 2014 43 44  * Another usage scenario is to create new parameters fully based on parametrizations. In such a case, the "generator" is called * a "creator" and behaves the same way as a generator, except that it creates an additional parameter. It is declared as  45  * {new_parameter}::%create = {data generators}.  Mathias Bavay committed Apr 23, 2014 46  *  Mathias Bavay committed Mar 23, 2013 47 48 49 50  * @note it is generally not advised to use data generators in combination with spatial interpolations as this would * potentially mix measured and generated values in the resulting grid. It is therefore advised to turn the data generators * off and let the spatial interpolations algorithms adjust to the amount of measured data. *  51 52 53 54  * @section generators_section Data generators section * The data generators are defined per meteorological parameter. They are applied to all stations * (if using multiple meteorological stations). If multiple dat generators are specified for each parameter, * they would be used in the order of declaration, meaning that only the data points that could not be  Mathias Bavay committed Mar 23, 2013 55 56  * generated by the first generator would be tentatively generated by the second generator, etc. Please also keep * in mind that at this stage, all data must be in SI units!  57 58 59 60 61 62  * @code * [Generators] * RH::generators = CST * RH::Cst = .7 * * P::generators = STD_PRESS  63  *  Mathias Bavay committed Apr 22, 2014 64  * ILWR::generators = AllSky_LW ClearSky_LW  Mathias Bavay committed Apr 23, 2014 65 66 67  * * TAU_CLD::create = CST * TA_CLD::Cst = 0.5  68 69  * @endcode *  70  * @section generators_keywords Available generators  71 72  * The keywords defining the algorithms are the following: * - STD_PRESS: standard atmospheric pressure as a function of the elevation of each station (see StandardPressureGenerator)  73  * - RELHUM: relative humidity from other humidity measurements (see RhGenerator)  74  * - CST: constant value as provided in argument (see ConstGenerator)  Mathias Bavay committed Jul 17, 2013 75  * - SIN: sinusoidal variation (see SinGenerator)  Mathias Bavay committed Jul 08, 2014 76 77  * - CLEARSKY_LW: use a clear sky model to generate ILWR from TA, RH (see ClearSkyLWGenerator) * - ALLSKY_LW: use an all sky model to generate ILWR from TA, RH and cloudiness (see AllSkyLWGenerator)  Mathias Bavay committed May 23, 2013 78  * - POT_RADIATION: generate the potential incoming short wave radiation, corrected for cloudiness if possible (see PotRadGenerator)  79  *  80  * @section generators_biblio Bibliography  81  * The data generators have been inspired by the following papers:  Mathias Bavay committed Mar 17, 2014 82 83 84  * - Brutsaert -- "On a Derivable Formula for Long-Wave Radiation From Clear Skies", Journal of Water Resources * Research, 11, No. 5, October 1975, pp 742-744. * - Prata -- "A new long-wave formula for estimating downward clear-sky radiation at the surface", Q. J. R. Meteorolo. Soc., 122, 1996, pp 1127-1151.  Mathias Bavay committed Mar 26, 2014 85  * - Dilley and O'Brien -- "Estimating downward clear sky long-wave irradiance at the surface from screen temperature and precipitable water", Q. J. R. Meteorolo. Soc., Vol. 124, 1998, doi:10.1002/qj.49712454903  86 87  * - Clark & Allen -- "The estimation of atmospheric radiation for clear and cloudy skies", Proceedings of the second national passive solar conference, 2, 1978, p 676. * - Tang et al. -- "Estimates of clear night sky emissivity in the Negev Highlands, Israel", Energy Conversion and Management, 45.11, 2004, pp 1831-1843.  Mathias Bavay committed Apr 22, 2014 88  * - Idso -- "A set of equations for full spectrum and 8 to 14 um and 10.5 to 12.5 um thermal radiation from cloudless skies", Water Resources Research, 17, 1981, pp 295-304.  Mathias Bavay committed Mar 17, 2014 89 90 91 92 93 94 95  * - Kasten and Czeplak -- "Solar and terrestrial radiation dependent on the amount and type of cloud", 1980, Solar energy, 24.2, pp 177-189 * - Omstedt -- "A coupled one-dimensional sea ice-ocean model applied to a semi-enclosed basin", Tellus, 42 A, 568-582, 1990, DOI:10.1034/j.1600-0870.1990.t01-3-00007. * - Konzelmann et al. -- "Parameterization of global and longwave incoming radiation for the Greenland Ice Sheet." Global and Planetary change 9.1 (1994): 143-164. * - Crawford and Duchon -- "An Improved Parametrization for Estimating Effective Atmospheric Emissivity for Use in Calculating Daytime * Downwelling Longwave Radiation", Journal of Applied Meteorology, 38, 1999, pp 474-480 * - Unsworth and Monteith -- "Long-wave radiation at the ground", Q. J. R. Meteorolo. Soc., Vol. 101, 1975, pp 13-24 * - Meeus -- "Astronomical Algorithms", second edition, 1998, Willmann-Bell, Inc., Richmond, VA, USA  96 97  * *  98 99 100 101 102 103 104 105 106 107 108 109  * @author Mathias Bavay * @date 2013-03-20 */ /** * @class GeneratorAlgorithm * @brief Interface class for the generator models. * These models generate data for a specific parameter when all other options failed (the resampling could not help). * Therefore, there is nothing more that could be done with the temporal history of the data, we have to use * a totally different approach: either generic data (constant value, etc) or generate the data from other * meteorological parameters (relying on a parametrization, like clear sky for ILWR). *  110  * @ingroup meteoLaws  111 112 113 114 115 116 117 118 119  * @author Mathias Bavay * @date 2013-03-20 */ class GeneratorAlgorithm { public: GeneratorAlgorithm(const std::vector& /*vecArgs*/, const std::string& i_algo) : algo(i_algo) {}; virtual ~GeneratorAlgorithm() {} //fill one MeteoData, for one station  120  virtual bool generate(const size_t& param, MeteoData& md) = 0;  121  //fill one time series of MeteoData for one station  122  virtual bool generate(const size_t& param, std::vector& vecMeteo) = 0;  123 124  std::string getAlgo() const; protected:  125  virtual void parse_args(const std::vector& i_vecArgs);  126 127 128 129 130 131 132 133 134 135 136  const std::string algo; }; class GeneratorAlgorithmFactory { public: static GeneratorAlgorithm* getAlgorithm(const std::string& i_algoname, const std::vector& vecArgs); }; /** * @class ConstGenerator * @brief Constant value generator.  Mathias Bavay committed Mar 23, 2013 137  * Generate a constant value for this parameter, as provided in argument (please remember that it must be in SI units).  138 139 140 141 142 143 144 145 146  * @code * RH::generators = Cst * RH::Cst = .7 * @endcode */ class ConstGenerator : public GeneratorAlgorithm { public: ConstGenerator(const std::vector& vecArgs, const std::string& i_algo) : GeneratorAlgorithm(vecArgs, i_algo), constant(IOUtils::nodata) { parse_args(vecArgs); }  147 148  bool generate(const size_t& param, MeteoData& md); bool generate(const size_t& param, std::vector& vecMeteo);  149 150 151 152 153  private: void parse_args(const std::vector& vecArgs); double constant; };  Mathias Bavay committed Jun 05, 2013 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 /** * @class SinGenerator * @brief Sinusoid generator. * Generate a sinusoidal variation for this parameter, as provided in argument (please remember that it must be in SI units). * The arguments that must be provided are the following: the sinusoidal period (either "yearly" or "daily"), the minimum value, * the maximum value and the offset specifying when the minimum value should be reached, within one period (expressed as fraction of such period). * The example below generates a yearly sinusoidal variation for the air temperature, the minimum being 268.26 K and occuring at 1/12 * of the period (which practically means, at the end of the first month). * @code * TA::generators = Sin * TA::Sin = yearly 268.26 285.56 0.0833 * @endcode */ class SinGenerator : public GeneratorAlgorithm { public: SinGenerator(const std::vector& vecArgs, const std::string& i_algo) : GeneratorAlgorithm(vecArgs, i_algo), amplitude(IOUtils::nodata), offset(IOUtils::nodata), phase(IOUtils::nodata), type(' ') { parse_args(vecArgs); } bool generate(const size_t& param, MeteoData& md); bool generate(const size_t& param, std::vector& vecMeteo); private: void parse_args(const std::vector& vecArgs); double amplitude, offset, phase; char type; };  179 180 181 182 /** * @class StandardPressureGenerator * @brief Standard atmospheric pressure generator. * Generate a standard atmosphere's pressure, depending on the local elevation.  183  * @code  184 185  * P::generators = STD_PRESS * @endcode  186 187 188 189  */ class StandardPressureGenerator : public GeneratorAlgorithm { public: StandardPressureGenerator(const std::vector& vecArgs, const std::string& i_algo)  190 191 192 193 194  : GeneratorAlgorithm(vecArgs, i_algo) { parse_args(vecArgs); } bool generate(const size_t& param, MeteoData& md); bool generate(const size_t& param, std::vector& vecMeteo); };  195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 /** * @class RhGenerator * @brief Relative humidity generator. * Generate the relative humidity from either dew point temperature or specific humidity and air temperature. * The dew point temperature must be named "TD" and the specific humidity "SH" * @code * RH::generators = RELHUM * @endcode */ class RhGenerator : public GeneratorAlgorithm { public: RhGenerator(const std::vector& vecArgs, const std::string& i_algo) : GeneratorAlgorithm(vecArgs, i_algo) { parse_args(vecArgs); } bool generate(const size_t& param, MeteoData& md); bool generate(const size_t& param, std::vector& vecMeteo); };  Mathias Bavay committed Jan 29, 2014 213 /**  Mathias Bavay committed Apr 22, 2014 214  * @class ClearSkyLWGenerator  Mathias Bavay committed Mar 17, 2014 215 216  * @brief ILWR clear sky parametrization * Using air temperature (TA) and relative humidity (RH), this offers the choice of several clear sky parametrizations:  Mathias Bavay committed Mar 18, 2014 217  * - BRUTSAERT -- from Brutsaert, "On a Derivable Formula for Long-Wave Radiation From Clear Skies",  Mathias Bavay committed Jan 29, 2014 218  * Journal of Water Resources Research, 11, No. 5, October 1975, pp 742-744.  Mathias Bavay committed Mar 18, 2014 219  * - DILLEY -- from Dilley and O'Brien, "Estimating downward clear sky  Mathias Bavay committed Mar 17, 2014 220  * long-wave irradiance at the surface from screen temperature and precipitable water", Q. J. R. Meteorolo. Soc., 124, 1998, pp 1391-1401.  Mathias Bavay committed Mar 18, 2014 221  * - PRATA -- from Prata, "A new long-wave formula for estimating downward clear-sky radiation at the surface", Q. J. R. Meteorolo. Soc., 122, 1996, pp 1127-1151.  222 223 224 225  * - CLARK -- from Clark & Allen, "The estimation of atmospheric radiation for clear and * cloudy skies", Proceedings of the second national passive solar conference, 2, 1978, p 676. * - TANG -- from Tang et al., "Estimates of clear night sky emissivity in the * Negev Highlands, Israel", Energy Conversion and Management, 45.11, 2004, pp 1831-1843.  Mathias Bavay committed Apr 22, 2014 226 227 228  * - IDSO -- from Idso, "A set of equations for full spectrum and 8 to 14 um and * 10.5 to 12.5 um thermal radiation from cloudless skies", Water Resources Research, 17, 1981, pp 295-304. *  Mathias Bavay committed Jan 29, 2014 229 230  * Please keep in mind that for energy balance modeling, this significantly underestimate the ILWR input. * @code  Mathias Bavay committed Apr 22, 2014 231 232  * ILWR::generators = clearsky_LW * ILWR::clearsky_lw = Dilley  Mathias Bavay committed Jan 29, 2014 233 234 235  * @endcode * */  Mathias Bavay committed Apr 22, 2014 236 class ClearSkyLWGenerator : public GeneratorAlgorithm {  Mathias Bavay committed Jan 29, 2014 237  public:  Mathias Bavay committed Apr 22, 2014 238  ClearSkyLWGenerator(const std::vector& vecArgs, const std::string& i_algo)  Mathias Bavay committed Mar 17, 2014 239  : GeneratorAlgorithm(vecArgs, i_algo), model(BRUTSAERT) { parse_args(vecArgs); }  Mathias Bavay committed Jan 29, 2014 240 241  bool generate(const size_t& param, MeteoData& md); bool generate(const size_t& param, std::vector& vecMeteo);  Mathias Bavay committed Mar 17, 2014 242 243 244 245 246  private: void parse_args(const std::vector& vecArgs); typedef enum PARAMETRIZATION { BRUTSAERT, DILLEY,  247 248  PRATA, CLARK,  Mathias Bavay committed Apr 22, 2014 249 250  TANG, IDSO  Mathias Bavay committed Mar 17, 2014 251 252  } parametrization; parametrization model;  253 254 255 }; /**  Mathias Bavay committed Apr 22, 2014 256  * @class AllSkyLWGenerator  Mathias Bavay committed Mar 17, 2014 257  * @brief ILWR all sky parametrization  Mathias Bavay committed Aug 14, 2014 258  * Using air temperature (TA) and relative humidity (RH) and optionnally cloud fraction (TAU_CLD, but please note that this name is not definitive yet),  Mathias Bavay committed Mar 17, 2014 259  * this offers the choice of several all-sky parametrizations:  Mathias Bavay committed Mar 18, 2014 260  * - OMSTEDT -- from Omstedt, "A coupled one-dimensional sea ice-ocean model applied to a semi-enclosed basin",  Mathias Bavay committed Mar 17, 2014 261  * Tellus, 42 A, 568-582, 1990, DOI:10.1034/j.1600-0870.1990.t01-3-00007.  Mathias Bavay committed Mar 18, 2014 262  * - KONZELMANN -- from Konzelmann et al., "Parameterization of global and longwave incoming radiation  Mathias Bavay committed Mar 17, 2014 263  * for the Greenland Ice Sheet." Global and Planetary change 9.1 (1994): 143-164.  Mathias Bavay committed Mar 18, 2014 264 265 266  * - UNSWORTH -- from Unsworth and Monteith, "Long-wave radiation at the ground", * Q. J. R. Meteorolo. Soc., Vol. 101, 1975, pp 13-24 coupled with a clear sky emissivity following (Dilley, 1998). * - CRAWFORD -- from Crawford and Duchon, "An Improved Parametrization for Estimating Effective Atmospheric Emissivity for Use in Calculating Daytime  Mathias Bavay committed Mar 17, 2014 267  * Downwelling Longwave Radiation", Journal of Applied Meteorology, 38, 1999, pp 474-480  268  *  Mathias Bavay committed Mar 18, 2014 269 270 271 272 273 274 275 276 277 278  * If no cloudiness is provided in the data, it is calculated from the solar index (ratio of measured iswr to potential iswr, therefore using * the current location (lat, lon, altitude) and ISWR to parametrize the cloud cover). This relies on (Kasten and Czeplak, 1980) * except for Crawfor that provides its own parametrization. * The last evaluation of cloudiness is used all along during the times when no ISWR is available if such ratio * is not too old (ie. no more than 1 day old). * If only RSWR is measured, the measured snow height is used to determine if there is snow on the ground or not. * In case of snow, a snow albedo of 0.85 is used while in the abscence of snow, a grass albedo of 0.23 is used * in order to compute ISWR from RSWR. * Finally, it is recommended to also use a clear sky generator (declared after this one) * for the case of no available short wave measurement (by declaring the ClearSky generator \em after AllSky).  279  * @code  Mathias Bavay committed Apr 22, 2014 280 281  * ILWR::generators = allsky_LW * ILWR::allsky_lw = Omstedt  282 283 284  * @endcode * */  Mathias Bavay committed Apr 22, 2014 285 class AllSkyLWGenerator : public GeneratorAlgorithm {  286  public:  Mathias Bavay committed Apr 22, 2014 287  AllSkyLWGenerator(const std::vector& vecArgs, const std::string& i_algo)  288  : GeneratorAlgorithm(vecArgs, i_algo), model(OMSTEDT), clf_model(KASTEN),  Mathias Bavay committed Mar 18, 2014 289  last_cloudiness() { parse_args(vecArgs); }  290 291  bool generate(const size_t& param, MeteoData& md); bool generate(const size_t& param, std::vector& vecMeteo);  Mathias Bavay committed Mar 17, 2014 292 293  private: void parse_args(const std::vector& vecArgs);  294 295  double getCloudiness(const MeteoData& md, SunObject& sun, bool &is_night);  Mathias Bavay committed Mar 17, 2014 296 297 298 299 300 301 302  typedef enum PARAMETRIZATION { OMSTEDT, KONZELMANN, UNSWORTH, CRAWFORD } parametrization; parametrization model;  303 304 305 306 307 308 309  typedef enum CLF_PARAMETRIZATION { KASTEN, CLF_CRAWFORD } clf_parametrization; clf_parametrization clf_model;  Mathias Bavay committed Mar 18, 2014 310  std::map< std::string, std::pair > last_cloudiness; //as < station_hash, >  311 312  static const double soil_albedo, snow_albedo, snow_thresh; //to try using rswr if not iswr is given  313 314 };  Mathias Bavay committed Mar 22, 2013 315 316 317 318 319 /** * @class PotRadGenerator * @brief potential ISWR parametrization * This computes the potential incoming solar radiation, based on the position of the sun ine the sky * (as a function of the location and the date). Please note that although this is the radiation as perceived  Mathias Bavay committed May 23, 2013 320 321  * at ground level (on the horizontal). If an incoming long wave measurement is available, it corrects the * generated iswr for cloudiness (basically doing like UnsworthGenerator in reverse), otherwise this assumes  Mathias Bavay committed Jan 29, 2014 322 323  * clear sky! If no TA or RH is available, average values will be used (in order to get an average value * for the precipitable water vapor).  Mathias Bavay committed Jun 05, 2013 324  * @note This relies on SunObject to perform the heavy duty computation.  325 326 327  * @code * ISWR::generators = POT_RADIATION * @endcode  Mathias Bavay committed Mar 22, 2013 328 329 330 331 332 333 334 335 336  */ class PotRadGenerator : public GeneratorAlgorithm { public: PotRadGenerator(const std::vector& vecArgs, const std::string& i_algo) : GeneratorAlgorithm(vecArgs, i_algo), sun() { parse_args(vecArgs); } bool generate(const size_t& param, MeteoData& md); bool generate(const size_t& param, std::vector& vecMeteo); private: void parse_args(const std::vector& vecArgs);  Mathias Bavay committed Mar 22, 2013 337  double getSolarIndex(const double& ta, const double& rh, const double& ilwr);  Mathias Bavay committed Mar 22, 2013 338 339 340 341 342  SunObject sun; static const double soil_albedo, snow_albedo, snow_thresh; //to try using rswr if not iswr is given };  Mathias Bavay committed Oct 28, 2013 343 344 345 class HSSweGenerator : public GeneratorAlgorithm { public: HSSweGenerator(const std::vector& vecArgs, const std::string& i_algo)  346  : GeneratorAlgorithm(vecArgs, i_algo) { parse_args(vecArgs); }  Mathias Bavay committed Oct 28, 2013 347 348  bool generate(const size_t& param, MeteoData& md); bool generate(const size_t& param, std::vector& vecMeteo);  349   Mathias Bavay committed Oct 28, 2013 350 351 352 353 354 355 356  private: void parse_args(const std::vector& vecArgs); double newSnowDensity(const MeteoData& md) const; static const bool soft; };  357 358 359 } //end namespace mio #endif