/*! * \brief Use this method to choose model for ET0 calculation automatically depending on available data. * * \param climate Parameter to relay to matching ET0 calculation model. * \param date Parameter to relay to matching ET0 calculation model. * \param location Parameter to relay to matching ET0 calculation model. * \param et0PmArgs Relayed to Et0CalcPm() * \param et0HgArgs Relayed to Et0CalcHg() * * \return An Et0Result structure. */ public static bool Et0Calc( Climate climate, DateTime date, Location location, Et0PmArgs et0PmArgs, Et0HgArgs et0HgArgs, ref Et0Result result ) { var climateSet = climate.getValues(date); //check availability of values if (climateSet == null) { return(false); } if ( climateSet.max_temp.HasValue && climateSet.min_temp.HasValue && climateSet.humidity.HasValue && (climateSet.Rs.HasValue || climateSet.sunshine_duration.HasValue) ) { //data sufficient for Penman-Monteith return(Et0CalcPm(climate, date, location, et0PmArgs, ref result)); } //use Hargreaves return(Et0CalcHg(climate, date, location, et0HgArgs, ref result)); }
/*! * \brief Calculate ET0 with Penman-Monteith method as described in FAO paper 56. * * \param climate Use this dataset with climate data. * \param date Date for ET0 calculation. * \param location The location for calculation, latitude and altitude are used. * \param et0Args Regression coefficients for Penman/Monteith calculation * \param [in,out] result Result of calculation * * \return true on success */ public static bool Et0CalcPm( Climate climate, DateTime date, Location location, Et0PmArgs et0Args, ref Et0Result result ) { var climateSet = climate.getValues(date); //check availability of values if (climateSet == null) { return(false); } if ( !climateSet.max_temp.HasValue || !climateSet.min_temp.HasValue || !climateSet.humidity.HasValue || (!climateSet.Rs.HasValue && !climateSet.sunshine_duration.HasValue) ) { return(false); } //initialize default values and replace missing ones if (!climateSet.mean_temp.HasValue) { climateSet.mean_temp = (climateSet.min_temp + climateSet.max_temp) / 2; } //FAO recommended value default of 2m/s if (!climateSet.windspeed.HasValue) { climateSet.windspeed = 2; } //copy altitude from climate, location cannot be null if (!location.alt.HasValue) { if (climate.location.alt.HasValue) { location.alt = climate.location.alt; } else { location.alt = 0; } } var raResult = Ra.RaCalc(date, location); result.ra = raResult.ra; if (result.ra == 0) { result.et0 = 0; return(true); } var g = 0; var e0Tmin = 0.6108 * Math.Exp(17.27 * (double)climateSet.min_temp / ((double)climateSet.min_temp + 237.3)); var e0Tmax = 0.6108 * Math.Exp(17.27 * (double)climateSet.max_temp / ((double)climateSet.max_temp + 237.3)); var es = (e0Tmin + e0Tmax) / 2; var ea = climateSet.humidity / 100 * es; var n = 24 / Math.PI * raResult.omegaS; var rs0 = (0.75 + 0.00002 * location.alt) * result.ra; var rs = climateSet.Rs; if (rs == null) { rs = (et0Args._as + et0Args._bs * climateSet.sunshine_duration / n) * result.ra; rs = Math.Min((double)rs, (double)rs0); } var rsDivRs0 = Math.Min((double)rs / (double)rs0, 1); var rnl = 4.903e-9 * ((Math.Pow((double)climateSet.max_temp + 273.16, 4) + Math.Pow((double)climateSet.min_temp + 273.16, 4)) / 2) * (0.34 - 0.14 * Math.Sqrt((double)ea)) * (1.35 * rsDivRs0 - 0.35); var rns = 0.77 * rs; var rn = rns - rnl; var p = 101.3 * Math.Pow((293 - 0.0065 * (double)location.alt) / 293, 5.26); var gamma = 0.000665 * p; var d = 4098 * (0.6108 * Math.Exp(17.27 * (double)climateSet.mean_temp / ((double)climateSet.mean_temp + 237.3))) / Math.Pow((double)climateSet.mean_temp + 237.2, 2); var et0x = (0.408 * d * (rn - g) + gamma * (900 / ((double)climateSet.mean_temp + 273)) * (double)climateSet.windspeed * (es - ea)) / (d + gamma * (1 + 0.34 * (double)climateSet.windspeed)); result.et0 = Math.Max(0, (double)et0x); return(true); }