/// <summary>Creates a list of temperature range factors used to estimate daily temperature from Min and Max temp</summary>
        /// <returns></returns>
        public List <double> SubDailyTemperatures()
        {
            double d      = MetData.CalculateDayLength(-6);
            double Tmin   = MetData.MinT;
            double Tmax   = MetData.MaxT;
            double TmaxB  = MetData.MaxT;
            double TminA  = MetData.MinT;
            double Hsrise = MetData.CalculateSunRise();
            double Hsset  = MetData.CalculateSunSet();


            List <double> sdts = new List <double>();

            for (int Th = 0; Th <= 23; Th++)
            {
                double Ta = 1.0;
                if (Th < Hsrise)
                {
                    //  Hour between midnight and sunrise
                    //  PERIOD A MaxTB is max. temperature, before day considered

                    //this is the sunset temperature of based on the previous day
                    double n = 24 - d;
                    Tsset = Tmin + (TmaxB - Tmin) *
                            Math.Sin(Math.PI * (d / (d + 2 * P)));

                    Ta = (Tmin - Tsset * Math.Exp(-n / TC) +
                          (Tsset - Tmin) * Math.Exp(-(Th + 24 - Hsset) / TC)) /
                         (1 - Math.Exp(-n / TC));
                }
                else if (Th >= Hsrise & Th < 12 + P)
                {
                    // PERIOD B Hour between sunrise and normal time of MaxT
                    Ta = Tmin + (Tmax - Tmin) *
                         Math.Sin(Math.PI * (Th - Hsrise) / (d + 2 * P));
                }
                else if (Th >= 12 + P & Th < Hsset)
                {
                    // PERIOD C Hour between normal time of MaxT and sunset
                    //  MinTA is min. temperature, after day considered

                    Ta = TminA + (Tmax - TminA) *
                         Math.Sin(Math.PI * (Th - Hsrise) / (d + 2 * P));
                }
                else
                {
                    // PERIOD D Hour between sunset and midnight
                    Tsset = TminA + (Tmax - TminA) * Math.Sin(Math.PI * (d / (d + 2 * P)));
                    double n = 24 - d;
                    Ta = (TminA - Tsset * Math.Exp(-n / TC) +
                          (Tsset - TminA) * Math.Exp(-(Th - Hsset) / TC)) /
                         (1 - Math.Exp(-n / TC));
                }
                sdts.Add(Ta);
            }
            return(sdts);
        }
 private void OnDoWeather(object sender, EventArgs e)
 {
     if (MetData != null)
     {
         DayLength = MetData.CalculateDayLength(Twilight);
     }
     else
     {
         DayLength = 0;
     }
 }
Beispiel #3
0
        // Calculates the ground solar incident radiation per hour and scales it to the actual radiation
        // Developed by Greg McLean and adapted/modified by Behnam (Ben) Ababaei.

        /// <summary>
        /// Hourly radiation estimation ported from https://github.com/BrianCollinss/ApsimX/blob/12a89f9981e2636f13251b0faa30200a98b713ce/Models/Functions/SupplyFunctions/MaximumHourlyTrModel.cs#L260
        /// by Hamish
        /// Note, this has not been tested and probably has errors as it is not a dirrect port
        /// </summary>
        /// <returns></returns>
        public List <double> SubDailyValues()
        {
            List <double> hourlyRad = new List <double>();

            double latR            = Math.PI / 180.0 * MetData.Latitude; // convert latitude (degrees) to radians
            double GlobalRadiation = MetData.Radn * 1e6;                 // solar radiation
            double PI  = Math.PI;
            double RAD = PI / 180.0;

            //Declination of the sun as function of Daynumber (vDay)
            double Dec = -Math.Asin(Math.Sin(23.45 * RAD) * Math.Cos(2.0 * PI * ((double)clock.Today.DayOfYear + 10.0) / 365.0));

            //vSin, vCos and vRsc are intermediate variables
            double Sin = Math.Sin(latR) * Math.Sin(Dec);
            double Cos = Math.Cos(latR) * Math.Cos(Dec);
            double Rsc = Sin / Cos;

            //Astronomical daylength (hr)
            double DayL      = MetData.CalculateDayLength(-6);
            double DailySinE = 3600.0 * (DayL * (Sin + 0.4 * (Sin * Sin + Cos * Cos * 0.5))
                                         + 12.0 * Cos * (2.0 + 3.0 * 0.4 * Sin) * Math.Sqrt(1.0 - Rsc * Rsc) / PI);

            double riseHour = MetData.CalculateSunRise();
            double setHour  = MetData.CalculateSunSet();

            for (int t = 0; t <= 23; t++)
            {
                double Hour1      = Math.Min(setHour, Math.Max(riseHour, t));
                double SinHeight1 = Math.Max(0.0, Sin + Cos * Math.Cos(2.0 * PI * (Hour1 - 12.0) / 24.0));
                double Hour2      = Math.Min(setHour, Math.Max(riseHour, t + 1));
                double SinHeight2 = Math.Max(0.0, Sin + Cos * Math.Cos(2.0 * PI * (Hour2 - 12.0) / 24.0));
                double SinHeight  = 0.5 * (SinHeight1 + SinHeight2);
                hourlyRad.Add(Math.Max(0, GlobalRadiation * SinHeight * (1.0 + 0.4 * SinHeight) / DailySinE));
                hourlyRad[t] *= HourlyWeight(t + 1, riseHour, setHour);
            }

            return(hourlyRad);
        }
Beispiel #4
0
 /// <summary>
 /// Gets the duration of the day in hours.
 /// </summary>
 /// <param name="Twilight">Angular distance between 90° and end of twilight - altitude of sun. +ve up, -ve down.</param>
 public double CalculateDayLength(double Twilight) => weather.CalculateDayLength(Twilight);