Ejemplo n.º 1
0
        /*!
         * \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));
        }
Ejemplo n.º 2
0
        /*!
         * \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);
        }