Beispiel #1
0
        public double ApplyResources_ByDate(double TotalNApplied, ref double TotalWApplied)
        {
            double NApplied      = 0;
            double NNIThreshold  = Run.ManagementDef.NNIThreshold;
            double NNIMultiplier = Run.ManagementDef.NNIMultiplier;

            var dateApp = Run.ManagementDef[CurrentDate];

            ///<Behnam (2015.10.20)>
            ///<Comment>To enable using total N fertisation and application shares at each event.
            ///<Behnam (2016.01.11)>
            ///Also a trend is applied, if applicable.</Comment>

            if (dateApp != null)
            {
                //if (!isUnlimitedWater) Soil_.Irrigate(dateApp.Water);
                Soil_.Irrigate(dateApp.Water);
                TotalWApplied += dateApp.Water;

                if (!isUnlimitedNitrogen)
                {
                    if (Run.ManagementDef.IsTotalNitrogen)
                    {
                        NApplied = NFertChange * dateApp.Nitrogen * Run.ManagementDef.TotalNApplication / 100;
                    }
                    else
                    {
                        NApplied = NFertChange * dateApp.Nitrogen;
                    }

                    ///<Comment>If NNI is to be used, the amount of N application is calculated by CalcNFertilisation</Comment>
                    if (Run.ManagementDef.IsNNIUsed && !isUnlimitedNitrogen)
                    {
                        NApplied = CalcNFertilisation(NNIThreshold, NNIMultiplier, TotalNApplied, NApplied);
                    }

                    /// Behnam (2016.05.14): Adding WaterAppWithNApp mm of water for each N application, if needed.
                    if (NApplied > 0 && TotalWApplied < WaterAppWithNApp * Run.MMwaterToGwater)
                    {
                        var WaterNeeded = WaterAppWithNApp * Run.MMwaterToGwater - TotalWApplied;
                        Soil_.Irrigate(WaterNeeded);
                        TotalWApplied += WaterNeeded;
                    }
                    NAdded = NApplied;
                    Soil_.Fertilize(NApplied);
                }
                TotalNApplied += NApplied;
            }
            return(TotalNApplied);
            ///</Behnam>
        }
Beispiel #2
0
        ///</Behnam>

        public override void Dispose()
        {
            base.Dispose();

            if (Crop_ != null)
            {
                Crop_.Dispose();
                Crop_ = null;
            }
            if (Soil_ != null)
            {
                Soil_.Dispose();
                Soil_ = null;
            }
        }
Beispiel #3
0
        public double ApplyResources_ByGrowthStage(double TotalNApplied, ref double TotalWApplied)
        {
            var gs = 0;

            foreach (var growthStageApp in Run.ManagementDef.GrowthStageApplications)
            {
                ///<Behnam (2015.10.22)>
                ///<Comment>
                ///Keep in mind, N and irrigation are triggered at least one day after the specified
                ///growth stage, but as they are applied at the begining of the simulation of each day,
                ///it is like they are applied one day earlier.
                ///</Comment>

                double NApplied      = 0;
                double NNIThreshold  = Run.ManagementDef.NNIThreshold;
                double NNIMultiplier = Run.ManagementDef.NNIMultiplier;

                gs += 1;
                var dateMoment = Run.CurrentUniverse.Crop_.getDateOfStage(growthStageApp.GrowthStage);

                ///<Comment>Don't apply irrigation if this irrigation event has already been triggered</Comment>
                if (PrevAppliedStagesIrr == gs)
                {
                    if (dateMoment.HasValue && dateMoment.Value.AddDays(1) == CurrentDate)
                    {
                        //if (!isUnlimitedWater) Soil_.Irrigate(growthStageApp.Water);
                        Soil_.Irrigate(growthStageApp.Water);
                        PrevAppliedStagesIrr += 1;
                        TotalWApplied        += growthStageApp.Water;
                    }
                }

                ///<Comment>Don't apply N if this N application event has already been triggered</Comment>
                if (PrevAppliedStagesN == gs)
                {
                    if (dateMoment.HasValue)
                    {
                        bool apply = true;
                        if (Run.ManagementDef.IsCheckPcpN)
                        {
                            ///<Comment>Check for cumulative precipitation over CheckDaysPcpN coming days, if applicable</Comment>
                            double cumpcp = Weather_.CumRainMM(CurrentDate, Run.ManagementDef.CheckDaysPcpN, false);

                            ///<Comment>Apply N if precipitation criterion is met or MaxPostponeN is reached</Comment>
                            apply = (cumpcp >= Run.ManagementDef.CumPcpThrN ||
                                     dateMoment.Value.AddDays(Run.ManagementDef.MaxPostponeN) <= CurrentDate);
                        }

                        if (apply)
                        {
                            if (!isUnlimitedNitrogen)
                            {
                                ///<Comment>To enable using total N fertisation and application shares at each event</Comment>
                                if (Run.ManagementDef.IsTotalNitrogen)
                                {
                                    NApplied = NFertChange * growthStageApp.Nitrogen * Run.ManagementDef.TotalNApplication / 100;
                                }
                                else
                                {
                                    NApplied = NFertChange * growthStageApp.Nitrogen;
                                }

                                ///<Comment>If NNI is to be used, the amount of N application is calculated by CalcNFertilisation</Comment>
                                if (Run.ManagementDef.IsNNIUsed && !isUnlimitedNitrogen)
                                {
                                    NApplied = CalcNFertilisation(NNIThreshold, NNIMultiplier, TotalNApplied, NApplied);
                                }

                                /// Behnam (2016.05.14): Adding WaterAppWithNApp mm of water for each N application, if needed.
                                if (NApplied > 0 && TotalWApplied < WaterAppWithNApp * Run.MMwaterToGwater)
                                {
                                    var WaterNeeded = WaterAppWithNApp * Run.MMwaterToGwater - TotalWApplied;
                                    Soil_.Irrigate(WaterNeeded);
                                    TotalWApplied += WaterNeeded;
                                }
                                NAdded = NApplied;
                                Soil_.Fertilize(NApplied);
                            }
                            TotalNApplied      += NApplied;
                            PrevAppliedStagesN += 1;
                        }
                    }
                }
            }
            return(TotalNApplied);
            ///</Behnam>
        }
Beispiel #4
0
        /// <summary>
        /// Element a day step on this universe.
        /// </summary>
        ///

        public void RunDayStep()
        {
            ///<Behnam (2016.01.07)>
            ///<Comment>To apply air temperature cut only on canopy temperature, instead of air temperature.
            ///Old setting will be preserved, just in case in the future it is required to work on air temperature.
            ///But the Boolean flag is now applied on canopy temperature.
            ///Weather_.isUnlimitedTemperature = isUnlimitedTemperature;
            Weather_.isUnlimitedTemperature = false;
            ///</Behnam>
            Soil_.isUnlimitedWater       = Crop_.isUnlimitedWater = isUnlimitedWater;
            Soil_.isUnlimitedNitrogen    = Crop_.isUnlimitedNitrogen = isUnlimitedNitrogen;
            Soil_.isUnlimitedTemperature = Crop_.isUnlimitedTemperature = isUnlimitedTemperature;

            ///<Comment>Cumulative air temperature from sowing (to calculate mean air temperature for different periods)</Comment>
            if (GrowthDay > 0)
            {
                CumAirTempFromSowing = GrowthDay * Weather_.MeanTemp(CurrentDate, GrowthDay);
            }
            ///</Behnam>
            ///Loic, Cumulative maximum air temperature from sowing
            if (GrowthDay > 0)
            {
                CumMaxAirTempFromSowing += Weather_.MaxTemp(CurrentDate);
            }
            ///Loic, Cumulative maximum canopy temperature from sowing
            if (GrowthDay > 0)
            {
                CumMaxCanopyTempFromSowing += Soil_.MaximumCanopyTemperature;
            }

            Soil_.InitDayStep(Crop_.RootLength);
            Soil_.MeanAirTemperature = Weather_.MeanTemp(CurrentDate);

            ///<Behnam (2016.01.19)>
            ///<Comment>Trying to organize the Universe class, contents were moved to two new methods
            ///With each application of N, WaterAppWithNApp mm of water is added, if needed</Comment>
            double TotalWApplied = 0;

            Soil_.Irrigate(Weather_.Rain(CurrentDate));
            TotalWApplied = Weather_.Rain(CurrentDate);

            NAdded = 0;

            double TotalNApplied = 0;

            TotalNApplied = ApplyResources_ByDate(TotalNApplied, ref TotalWApplied);
            TotalNApplied = ApplyResources_ByGrowthStage(TotalNApplied, ref TotalWApplied);

            ///</Behnam>

            Crop_.InitDayStep(thermalTimeWrapper_.getDeltaTT(Delta.Remobilization));

            double vp;

            if (!Weather_.IsWindAndVpDefined())
            {
                // from the formulation of Murray 1967, Journal of Aplplied Meteorology 1:203-204
                // The minimum air temperature is used as a proxy for dew temperature
                vp = (0.6108 * Math.Exp((17.27 * Weather_.MinTemp(CurrentDate)) / (Weather_.MinTemp(CurrentDate) + 237.3))) * 10; // multiplied by 10 to convert kPa to hPa
            }
            else
            {
                vp = Weather_.Vp(CurrentDate);
            }


            // Energy Balance
            // Boundary layer conductance
            // OUTPUT UNIT: m d-1
            double wind;

            if (Weather_.IsWindAndVpDefined() == false)
            {
                wind = 240 * 1000;                          // Assumes wind = 240 km/day converted to m/day
            }
            else
            {
                const double minWind = 100.0;
                wind = Math.Max(Weather_.Wind(CurrentDate), minWind) * 1000;
            }
            //

            meteorologyWrapper_.EstimateMeteo(Weather_.MeanTemp(CurrentDate), Weather_.MinTemp(CurrentDate), Weather_.MinTemp(CurrentDate.AddDays(1)), Weather_.MaxTemp(CurrentDate), Weather_.MinTemp(CurrentDate.AddDays(-1)), ShootTemperature_.MinShootTemperature, ShootTemperature_.MaxShootTemperature, vp, Weather_.Rad(CurrentDate), wind);

            Soil_.RunDayStep(meteorologyWrapper_.RadTopAtm,
                             Weather_.IsWindAndVpDefined(),
                             vp,
                             Weather_.Rad(CurrentDate),
                             Weather_.MinTemp(CurrentDate),
                             Weather_.MaxTemp(CurrentDate),
                             Weather_.MeanTemp(CurrentDate),
                             meteorologyWrapper_.HourlyAirTemperature,
                             wind,
                             Weather_.WeekTemp(CurrentDate),
                             meteorologyWrapper_.HSlope,
                             meteorologyWrapper_.VPDair,
                             Crop_.Tau,
                             Crop_.SumInternodesLength,
                             Crop_.PotentialWaterOnLeaves,
                             Crop_.RootLength,
                             Crop_.LeafNumber,
                             meteorologyWrapper_.HourlyVPDAir,
                             meteorologyWrapper_.HourlyRadiation,
                             Crop_.Ntip,
                             meteorologyWrapper_.RH
                             );


            ShootTemperature_.isUnlimitedTemperature = isUnlimitedTemperature;
            ShootTemperature_.Estimate(Crop_.LeafNumber, Soil_.MinimumCanopyTemperature, Soil_.MaximumCanopyTemperature, Soil_.HourlyCanopyTemperature,
                                       Soil_.SoilMinTemperature, Soil_.SoilMaxTemperature, Soil_.HourlySoilTemperature);

            Crop_.InitDayStepRoot(thermalTimeWrapper_.getCumulTT(Delta.Remobilization), Soil_.NavForRoot);

            //Quantity of Ni to remove from soil
            double soilNinc = 0;

            ///<Behnam (2016.01.08)>
            ///<Comment>Directly using shoot temperature instead of checking leaf number
            /// and selecting between soil and canopy temperature</Comment>
            ///
            thermalTimeWrapper_.EstimateDailyThermalTime(Weather_.MinTemp(CurrentDate), Weather_.MaxTemp(CurrentDate),
                                                         Soil_.SoilMinTemperature, Soil_.SoilMaxTemperature, ShootTemperature_.MinShootTemperature,
                                                         ShootTemperature_.MaxShootTemperature, ShootTemperature_.ShootHourlyTemperature, meteorologyWrapper_.HourlyAirTemperature, Crop_.getPhaseValue());
            ///</Behnam>

            soilNinc = Crop_.Grow(meteorologyWrapper_.RadTopAtm,
                                  thermalTimeWrapper_.CumulTT,
                                  thermalTimeWrapper_.getDeltaTT(Delta.Shoot),
                                  thermalTimeWrapper_.getDeltaTT(Delta.PhenoMaize),
                                  thermalTimeWrapper_.getDeltaTT(Delta.Remobilization),
                                  thermalTimeWrapper_.getDeltaTT(Delta.LeafSenescence),
                                  ShootTemperature_.MinShootTemperature,
                                  ShootTemperature_.MaxShootTemperature,
                                  Weather_.Rad(CurrentDate),
                                  Weather_.PAR(CurrentDate),
                                  Soil_.DBF,
                                  Soil_.SoilDepth,
                                  Soil_.DEBF,
                                  Soil_.DGF,
                                  meteorologyWrapper_.DayLength,
                                  Soil_.FPAW, meteorologyWrapper_.VPDairCanopy, Soil_.HourlyCanopyTemperature, Soil_.VPDeq);

            if (!isUnlimitedNitrogen)
            {
                Soil_.RemoveN(soilNinc);
            }

            Soil_.FinishDayStep();
        }