コード例 #1
0
ファイル: SoilArbitrator.cs プロジェクト: kiwiroy/ApsimX
        /// <summary>
        /// General soil arbitration method (water or nutrients) based upon Runge-Kutta method
        /// </summary>
        /// <param name="arbitrationType">Water or Nitrogen</param>
        private void DoArbitration(Estimate.CalcType arbitrationType)
        {
            SoilState InitialSoilState = new SoilState(this.Parent);
            InitialSoilState.Initialise();

            Estimate UptakeEstimate1 = new Estimate(this.Parent, arbitrationType, InitialSoilState);
            Estimate UptakeEstimate2 = new Estimate(this.Parent, arbitrationType, InitialSoilState - UptakeEstimate1 * 0.5);
            Estimate UptakeEstimate3 = new Estimate(this.Parent, arbitrationType, InitialSoilState - UptakeEstimate2 * 0.5);
            Estimate UptakeEstimate4 = new Estimate(this.Parent, arbitrationType, InitialSoilState - UptakeEstimate3);

            List<CropUptakes> UptakesFinal = new List<CropUptakes>();
            foreach (CropUptakes U in UptakeEstimate1.Values)
            {
                CropUptakes CWU = new CropUptakes();
                CWU.Crop = U.Crop;
                foreach (ZoneWaterAndN ZW1 in U.Zones)
                {
                    ZoneWaterAndN NewZ = UptakeEstimate1.UptakeZone(CWU.Crop, ZW1.Name) * (1.0 / 6.0)
                                       + UptakeEstimate2.UptakeZone(CWU.Crop, ZW1.Name) * (1.0 / 3.0)
                                       + UptakeEstimate3.UptakeZone(CWU.Crop, ZW1.Name) * (1.0 / 3.0)
                                       + UptakeEstimate4.UptakeZone(CWU.Crop, ZW1.Name) * (1.0 / 6.0);
                    CWU.Zones.Add(NewZ);
                }

                UptakesFinal.Add(CWU);
            }

            foreach (CropUptakes Uptake in UptakesFinal)
            {
                if (arbitrationType == Estimate.CalcType.Water)
                    Uptake.Crop.SetSWUptake(Uptake.Zones);
                else
                    Uptake.Crop.SetNUptake(Uptake.Zones);
            }
        }
コード例 #2
0
ファイル: Estimate.cs プロジェクト: hol353/ApsimX
        /// <summary>Initializes a new instance of the <see cref="Estimate"/> class.</summary>
        /// <param name="parent">The parent model</param>
        /// <param name="Type">The type of estimate</param>
        /// <param name="soilstate">The state of the soil</param>
        /// <param name="uptakeModels">A list of models that do uptake.</param>
        public Estimate(IModel parent, CalcType Type, SoilState soilstate, List<IModel> uptakeModels)
        {
            Values = new List<CropUptakes>();

            Parent = parent;
            foreach (IUptake crop in uptakeModels)
            {
                List<ZoneWaterAndN> uptake;
                if (Type == CalcType.Water)
                    uptake = crop.GetSWUptakes(soilstate);
                else
                    uptake = crop.GetNUptakes(soilstate);

                if (uptake != null)
                {
                    CropUptakes Uptake = new CropUptakes();
                    Uptake.Crop = crop;
                    Uptake.Zones = uptake;
                    Values.Add(Uptake);
                }
            }
        }
コード例 #3
0
ファイル: SoilState.cs プロジェクト: ykhorzon/ApsimX
        /// <summary>Implements the operator -.</summary>
        /// <param name="state">The soil state.</param>
        /// <param name="estimate">The estimate to subtract from the soil state.</param>
        /// <returns>The result of the operator.</returns>
        public static SoilState operator -(SoilState state, Estimate estimate)
        {
            SoilState NewState = new SoilState(state.Parent);
            foreach (ZoneWaterAndN Z in state.Zones)
            {
                ZoneWaterAndN NewZ = new ZoneWaterAndN();
                NewZ.Name = Z.Name;
                NewZ.Water = Z.Water;
                NewZ.NO3N = Z.NO3N;
                NewZ.NH4N = Z.NH4N;
                NewState.Zones.Add(NewZ);
            }

            foreach (CropUptakes C in estimate.Values)
                foreach (ZoneWaterAndN Z in C.Zones)
                    foreach (ZoneWaterAndN NewZ in NewState.Zones)
                        if (Z.Name == NewZ.Name)
                        {
                            NewZ.Water = MathUtilities.Subtract(NewZ.Water, Z.Water);
                            NewZ.NO3N = MathUtilities.Subtract(NewZ.NO3N, Z.NO3N);
                            NewZ.NH4N = MathUtilities.Subtract(NewZ.NH4N, Z.NH4N);
                        }
            return NewState;
        }
コード例 #4
0
ファイル: OrganArbitrator.cs プロジェクト: hol353/ApsimX
        /// <summary>
        /// Calculate the potential sw uptake for today. Should return null if crop is not in the ground.
        /// </summary>
        public List<Soils.Arbitrator.ZoneWaterAndN> GetNUptakes(SoilState soilstate)
        {
            if (Plant.IsAlive)
            {
                foreach (ZoneWaterAndN zone in soilstate.Zones)
                {
                    ZoneWaterAndN UptakeDemands = new ZoneWaterAndN();
                    if (Plant.Phenology != null)
                    {
                        if (Plant.Phenology.Emerged == true)
                        {
                            DoPotentialNutrientUptake(ref N, zone);  //Work out how much N the uptaking organs (roots) would take up in the absence of competition

                            //Pack results into uptake structure
                            UptakeDemands.NO3N = PotentialNO3NUptake;
                            UptakeDemands.NH4N = PotentialNH4NUptake;
                        }
                        else //Uptakes are zero
                        {
                            UptakeDemands.NO3N = new double[zone.NO3N.Length];
                            for (int i = 0; i < UptakeDemands.NO3N.Length; i++) { UptakeDemands.NO3N[i] = 0; }
                            UptakeDemands.NH4N = new double[zone.NH4N.Length];
                            for (int i = 0; i < UptakeDemands.NH4N.Length; i++) { UptakeDemands.NH4N[i] = 0; }
                        }
                    }
                    else
                    {
                        DoPotentialNutrientUptake(ref N, zone);  //Work out how much N the uptaking organs (roots) would take up in the absence of competition

                        //Pack results into uptake structure
                        UptakeDemands.NO3N = PotentialNO3NUptake;
                        UptakeDemands.NH4N = PotentialNH4NUptake;
                    }

                    UptakeDemands.Name = zone.Name;
                    UptakeDemands.Water = new double[UptakeDemands.NO3N.Length];

                    List<ZoneWaterAndN> zones = new List<ZoneWaterAndN>();
                    zones.Add(UptakeDemands);
                    return zones;
                }
            }

            return null;
        }
コード例 #5
0
ファイル: Plant15.cs プロジェクト: hol353/ApsimX
        /// <summary>Placeholder for SoilArbitrator</summary>
        /// <param name="soilstate">Soil state</param>
        /// <returns></returns>
        public List<ZoneWaterAndN> GetSWUptakes(SoilState soilstate)
        {
            if (IsAlive)
            {
                List<ZoneWaterAndN> Uptakes = new List<ZoneWaterAndN>();
                ZoneWaterAndN Uptake = new ZoneWaterAndN();

                ZoneWaterAndN MyZone = new ZoneWaterAndN();
                foreach (ZoneWaterAndN Z in soilstate.Zones)
                    if (Z.Name == this.Parent.Name)
                        MyZone = Z;

                double[] SW = MyZone.Water;
                OnPrepare(null, null);  //DEAN!!!

                Uptake.Name = this.Parent.Name;
                Uptake.Water = Root.CalculateWaterUptake(TopsSWDemand, SW);
                Uptake.NO3N = new double[SW.Length];
                Uptake.NH4N = new double[SW.Length];
                Uptakes.Add(Uptake);
                return Uptakes;
            }
            else
                return null;
        }
コード例 #6
0
ファイル: Plant15.cs プロジェクト: hol353/ApsimX
        /// <summary>Placeholder for SoilArbitrator</summary>
        /// <param name="soilstate">soil state</param>
        /// <returns></returns>
        public List<ZoneWaterAndN> GetNUptakes(SoilState soilstate)
        {
            if (IsAlive)
            {
                List<ZoneWaterAndN> Uptakes = new List<ZoneWaterAndN>();
                ZoneWaterAndN Uptake = new ZoneWaterAndN();

                ZoneWaterAndN MyZone = new ZoneWaterAndN();
                foreach (ZoneWaterAndN Z in soilstate.Zones)
                    if (Z.Name == this.Parent.Name)
                        MyZone = Z;

                double[] NO3N = MyZone.NO3N;
                double[] NH4N = MyZone.NH4N;

                double[] NO3NUp = new double[NO3N.Length];
                double[] NH4NUp = new double[NH4N.Length];

                Root.CalculateNUptake(NO3N, NH4N, ref NO3NUp, ref NH4NUp);
                Uptake.NO3N = NO3NUp;
                Uptake.NH4N = NH4NUp;
                Uptake.Water = new double[NO3N.Length];
                Uptake.Name = this.Parent.Name;

                Uptakes.Add(Uptake);
                return Uptakes;
            }
            else
                return null;
        }
コード例 #7
0
        /// <summary>Gets the potential plant water uptake for each layer (mm).</summary>
        /// <remarks>The model can only handle one root zone at present.</remarks>
        /// <param name="soilstate">Soil state (current water content)</param>
        /// <returns>Potential water uptake (mm)</returns>
        public List<ZoneWaterAndN> GetSWUptakes(SoilState soilstate)
        {
            if (IsAlive)
            {
                // Get the zone this plant is in
                ZoneWaterAndN myZone = new ZoneWaterAndN();
                Zone parentZone = Apsim.Parent(this, typeof (Zone)) as Zone;
                foreach (ZoneWaterAndN zone in soilstate.Zones)
                    if (zone.Name == parentZone.Name)
                        myZone = zone;

                // Get the amount of water available for this plant
                EvaluateSoilWaterAvailable(myZone);

                // Get the amount of water potentially taken up by this plant
                EvaluateSoilWaterUptake();

                // Pack potential uptake data for this plant
                ZoneWaterAndN myUptakeDemand = new ZoneWaterAndN();
                myUptakeDemand.Name = myZone.Name;
                myUptakeDemand.Water = mySoilWaterUptake;
                myUptakeDemand.NO3N = new double[nLayers];
                myUptakeDemand.NH4N = new double[nLayers];

                List<ZoneWaterAndN> zones = new List<ZoneWaterAndN>();
                zones.Add(myUptakeDemand);
                return zones;
            }
            else
                return null;
        }
コード例 #8
0
        /// <summary>Gets the potential plant N uptake for each layer (mm).</summary>
        /// <remarks>The model can only handle one root zone at present.</remarks>
        /// <param name="soilstate">Soil state (current N contents)</param>
        /// <returns>Potential N uptake (kg/ha)</returns>
        public List<ZoneWaterAndN> GetNUptakes(SoilState soilstate)
        {
            if (IsAlive)
            {
                // Get the zone this plant is in
                ZoneWaterAndN myZone = new ZoneWaterAndN();
                Zone parentZone = Apsim.Parent(this, typeof (Zone)) as Zone;
                foreach (ZoneWaterAndN Z in soilstate.Zones)
                    if (Z.Name == parentZone.Name)
                        myZone = Z;

                // Get the N amount available in the soil
                EvaluateSoilNitrogenAvailable(myZone);

                // Get the N amount fixed through symbiosis
                EvaluateNitrogenFixation();

                // Evaluate the use of N remobilised and get N amount demanded from soil
                EvaluateSoilNitrogenDemand();

                // Get N amount take up from the soil
                EvaluateSoilNitrogenUptake();

                //Pack results into uptake structure
                ZoneWaterAndN myUptakeDemand = new ZoneWaterAndN();
                myUptakeDemand.Name = myZone.Name;
                myUptakeDemand.NH4N = mySoilNH4Uptake;
                myUptakeDemand.NO3N = mySoilNO3Uptake;
                myUptakeDemand.Water = new double[nLayers];

                List<ZoneWaterAndN> zones = new List<ZoneWaterAndN>();
                zones.Add(myUptakeDemand);
                return zones;
            }
            else
                return null;
        }
コード例 #9
0
ファイル: OrganArbitrator.cs プロジェクト: kiwiroy/ApsimX
        /// <summary>
        /// Calculate the potential sw uptake for today
        /// </summary>
        public List<ZoneWaterAndN> GetSWUptakes(SoilState soilstate)
        {
            if (Plant.IsAlive)
            {
                double Supply = 0;
                double Demand = 0;
                double[] supply = null;
                foreach (IArbitration o in Organs)
                {
                    double[] organSupply = o.WaterSupply(soilstate.Zones);
                    if (organSupply != null)
                    {
                        supply = organSupply;
                        Supply += MathUtilities.Sum(organSupply);
                    }
                    Demand += o.WaterDemand;
                }

                double FractionUsed = 0;
                if (Supply > 0)
                    FractionUsed = Math.Min(1.0, Demand / Supply);

                ZoneWaterAndN uptake = new ZoneWaterAndN();
                uptake.Name = soilstate.Zones[0].Name;
                uptake.Water = MathUtilities.Multiply_Value(supply, FractionUsed);
                uptake.NO3N = new double[uptake.Water.Length];
                uptake.NH4N = new double[uptake.Water.Length];

                List<ZoneWaterAndN> zones = new List<ZoneWaterAndN>();
                zones.Add(uptake);
                return zones;
            }
            else
                return null;
        }
コード例 #10
0
ファイル: SimpleTree.cs プロジェクト: hol353/ApsimX
        /// <summary>Placeholder for SoilArbitrator</summary>
        /// <param name="soilstate">soil state</param>
        /// <returns></returns>
        public List<ZoneWaterAndN> GetNUptakes(SoilState soilstate)
        {
            ZoneWaterAndN MyZone = new ZoneWaterAndN();
            foreach (ZoneWaterAndN Z in soilstate.Zones)
                if (Z.Name == this.Parent.Name)
                    MyZone = Z;

            double[] PotNO3Uptake = new double[Soil.NO3N.Length];
            double[] PotNH4Uptake = new double[Soil.NH4N.Length];
            NO3Uptake = new double[Soil.NO3N.Length];
            NH4Uptake = new double[Soil.NH4N.Length];

            SoilCrop soilCrop = Soil.Crop(this.Name) as SoilCrop;

            for (int j = 0; j < Soil.SoilWater.LL15mm.Length; j++)
            {
                PotNO3Uptake[j] = Math.Max(0.0, RootProportion(j, RootDepth) * soilCrop.KL[j] * MyZone.NO3N[j]);
                PotNH4Uptake[j] = Math.Max(0.0, RootProportion(j, RootDepth) * soilCrop.KL[j] * MyZone.NH4N[j]);
            }
            double TotPotNUptake = MathUtilities.Sum(PotNO3Uptake) + MathUtilities.Sum(PotNH4Uptake);

            for (int j = 0; j < Soil.NO3N.Length; j++)
            {
                NO3Uptake[j] = PotNO3Uptake[j] * Math.Min(1.0, NDemand / TotPotNUptake);
                NH4Uptake[j] = PotNH4Uptake[j] * Math.Min(1.0, NDemand / TotPotNUptake);
            }
            List<ZoneWaterAndN> Uptakes = new List<ZoneWaterAndN>();
            ZoneWaterAndN Uptake = new ZoneWaterAndN();

            Uptake.Name = this.Parent.Name;
            Uptake.NO3N = NO3Uptake;
            Uptake.NH4N = NH4Uptake;
            Uptake.Water = new double[NO3Uptake.Length];
            Uptakes.Add(Uptake);
            return Uptakes;
        }
コード例 #11
0
ファイル: OrganArbitrator.cs プロジェクト: ykhorzon/ApsimX
        /// <summary>Does the uptake.</summary>
        /// <param name="Organs">The organs.</param>
        /// <param name="BAT">The bat.</param>
        /// <param name="soilstate">The soilstate.</param>
        public virtual void DoPotentialNutrientUptake(IArbitration[] Organs, ref BiomassArbitrationType BAT, SoilState soilstate)
        {
            // Model can only handle one root zone at present
            ZoneWaterAndN MyZone = new ZoneWaterAndN();
            Zone ParentZone = Apsim.Parent(this, typeof(Zone)) as Zone;
            foreach (ZoneWaterAndN Z in soilstate.Zones)
                if (Z.Name == ParentZone.Name)
                    MyZone = Z;

            PotentialNO3NUptake = new double[MyZone.NO3N.Length];
            PotentialNH4NUptake = new double[MyZone.NH4N.Length];

            //Get Nuptake supply from each organ and set the PotentialUptake parameters that are passed to the soil arbitrator
            for (int i = 0; i < Organs.Length; i++)
            {
                double[] organNO3Supply = Organs[i].NO3NSupply(soilstate.Zones);
                if (organNO3Supply != null)
                {
                    PotentialNO3NUptake = MathUtilities.Add(PotentialNO3NUptake, organNO3Supply); //Add uptake supply from each organ to the plants total to tell the Soil arbitrator
                    BAT.UptakeSupply[i] = MathUtilities.Sum(organNO3Supply) * kgha2gsm;    //Populate uptakeSupply for each organ for internal allocation routines
                }

                double[] organNH4Supply = Organs[i].NH4NSupply(soilstate.Zones);
                if (organNH4Supply != null)
                {
                    PotentialNH4NUptake = MathUtilities.Add(PotentialNH4NUptake, organNH4Supply);
                    BAT.UptakeSupply[i] += MathUtilities.Sum(organNH4Supply) * kgha2gsm;
                }
            }

            //Calculate plant level supply totals.
            BAT.TotalUptakeSupply = MathUtilities.Sum(BAT.UptakeSupply);
            BAT.TotalPlantSupply = BAT.TotalReallocationSupply + BAT.TotalUptakeSupply + BAT.TotalFixationSupply + BAT.TotalRetranslocationSupply;

            //If NUsupply is greater than uptake (total demand - reallocatio nsupply) reduce the PotentialUptakes that we pass to the soil arbitrator
            if (BAT.TotalUptakeSupply > (BAT.TotalPlantDemand - BAT.TotalReallocation))
            {
                double ratio = Math.Min(1.0, (BAT.TotalPlantDemand - BAT.TotalReallocation) / BAT.TotalUptakeSupply);
                PotentialNO3NUptake = MathUtilities.Multiply_Value(PotentialNO3NUptake, ratio);
                PotentialNH4NUptake = MathUtilities.Multiply_Value(PotentialNH4NUptake, ratio);
            }
        }
コード例 #12
0
ファイル: OrganArbitrator.cs プロジェクト: ykhorzon/ApsimX
 /// <summary>Calculates how much N the roots will take up in the absence of competition</summary>
 /// <param name="soilstate">The state of the soil.</param>
 public void DoNUptakeDemandCalculations(SoilState soilstate)
 {
     DoPotentialNutrientUptake(Organs, ref N, soilstate);  //Work out how much N the uptaking organs (roots) would take up in the absence of competition
 }
コード例 #13
0
ファイル: OrganArbitrator.cs プロジェクト: ykhorzon/ApsimX
        /// <summary>
        /// Calculate the potential sw uptake for today
        /// </summary>
        public List<ZoneWaterAndN> GetSWUptakes(SoilState soilstate)
        {
            if (Plant.IsAlive)
            {
                // Model can only handle one root zone at present
                ZoneWaterAndN MyZone = new ZoneWaterAndN();
                Zone ParentZone = Apsim.Parent(this, typeof(Zone)) as Zone;
                foreach (ZoneWaterAndN Z in soilstate.Zones)
                    if (Z.Name == ParentZone.Name)
                        MyZone = Z;

                double Supply = 0;
                double Demand = 0;
                double[] supply = null;
                foreach (IArbitration o in Organs)
                {
                    double[] organSupply = o.WaterSupply(soilstate.Zones);
                    if (organSupply != null)
                    {
                        supply = organSupply;
                        Supply += MathUtilities.Sum(organSupply);
                    }
                    Demand += o.WaterDemand;
                }

                double FractionUsed = 0;
                if (Supply > 0)
                    FractionUsed = Math.Min(1.0, Demand / Supply);

                // Just send uptake from my zone
                ZoneWaterAndN uptake = new ZoneWaterAndN();
                uptake.Name = MyZone.Name;
                uptake.Water = MathUtilities.Multiply_Value(supply, FractionUsed);
                uptake.NO3N = new double[uptake.Water.Length];
                uptake.NH4N = new double[uptake.Water.Length];

                List<ZoneWaterAndN> zones = new List<ZoneWaterAndN>();
                zones.Add(uptake);
                return zones;
            }
            else
                return null;
        }
コード例 #14
0
ファイル: OrganArbitrator.cs プロジェクト: ykhorzon/ApsimX
        /// <summary>
        /// Calculate the potential sw uptake for today. Should return null if crop is not in the ground.
        /// </summary>
        public List<Soils.Arbitrator.ZoneWaterAndN> GetNUptakes(SoilState soilstate)
        {
            if (Plant.IsAlive)
            {
                // Model can only handle one root zone at present
                ZoneWaterAndN MyZone = new ZoneWaterAndN();
                Zone ParentZone = Apsim.Parent(this, typeof(Zone)) as Zone;
                foreach (ZoneWaterAndN Z in soilstate.Zones)
                    if (Z.Name == ParentZone.Name)
                        MyZone = Z;

                ZoneWaterAndN UptakeDemands = new ZoneWaterAndN();
                if (Plant.Phenology != null)
                {
                    if (Plant.Phenology.Emerged == true)
                    {
                        DoNUptakeDemandCalculations(soilstate);

                        //Pack results into uptake structure
                        UptakeDemands.NO3N = PotentialNO3NUptake;
                        UptakeDemands.NH4N = PotentialNH4NUptake;
                    }
                    else //Uptakes are zero
                    {
                        UptakeDemands.NO3N = new double[MyZone.NO3N.Length];
                        for (int i = 0; i < UptakeDemands.NO3N.Length; i++) { UptakeDemands.NO3N[i] = 0; }
                        UptakeDemands.NH4N = new double[MyZone.NH4N.Length];
                        for (int i = 0; i < UptakeDemands.NH4N.Length; i++) { UptakeDemands.NH4N[i] = 0; }
                    }
                }
                else
                {
                    DoNUptakeDemandCalculations(soilstate);

                    //Pack results into uptake structure
                    UptakeDemands.NO3N = PotentialNO3NUptake;
                    UptakeDemands.NH4N = PotentialNH4NUptake;
                }

                UptakeDemands.Name = MyZone.Name;
                UptakeDemands.Water = new double[UptakeDemands.NO3N.Length];

                List<ZoneWaterAndN> zones = new List<ZoneWaterAndN>();
                zones.Add(UptakeDemands);
                return zones;
            }
            else
                return null;
        }
コード例 #15
0
ファイル: OrganArbitrator.cs プロジェクト: hol353/ApsimX
        /// <summary>
        /// Calculate the potential sw uptake for today
        /// </summary>
        public List<ZoneWaterAndN> GetSWUptakes(SoilState soilstate)
        {
            if (Plant.IsAlive)
            {
                // Get all water supplies.
                double waterSupply = 0;
                List<double[]> supplies = new List<double[]>();
                List<string> zoneNames = new List<string>();
                foreach (ZoneWaterAndN zone in soilstate.Zones)
                {
                    foreach (IArbitration o in Organs)
                    {
                        double[] organSupply = o.WaterSupply(zone);
                        if (organSupply != null)
                        {
                            supplies.Add(organSupply);
                            zoneNames.Add(zone.Name);
                            waterSupply += MathUtilities.Sum(organSupply);
                        }
                    }
                }

                // Calculate total water demand.
                double waterDemand = 0;
                foreach (IArbitration o in Organs)
                    waterDemand += o.WaterDemand;

                // Calculate demand / supply ratio.
                double fractionUsed = 0;
                if (waterSupply > 0)
                    fractionUsed = Math.Min(1.0, waterDemand / waterSupply);

                // Apply demand supply ratio to each zone and create a ZoneWaterAndN structure
                // to return to caller.
                List<ZoneWaterAndN> zones = new List<ZoneWaterAndN>();
                for (int i = 0; i < supplies.Count; i++)
                {
                    // Just send uptake from my zone
                    ZoneWaterAndN uptake = new ZoneWaterAndN();
                    uptake.Name = zoneNames[i];
                    uptake.Water = MathUtilities.Multiply_Value(supplies[i], fractionUsed);
                    uptake.NO3N = new double[uptake.Water.Length];
                    uptake.NH4N = new double[uptake.Water.Length];
                    zones.Add(uptake);
                }

                return zones;
            }
            else
                return null;
        }
コード例 #16
0
ファイル: SimpleTree.cs プロジェクト: hol353/ApsimX
        /// <summary>Calculate the potential sw uptake for today</summary>
        /// <param name="soilstate"></param>
        /// <returns>list of uptakes</returns>
        /// <exception cref="ApsimXException">Could not find root zone in Zone  + this.Parent.Name +  for SimpleTree</exception>
        public List<ZoneWaterAndN> GetSWUptakes(SoilState soilstate)
        {
            ZoneWaterAndN MyZone = new ZoneWaterAndN();
            foreach (ZoneWaterAndN Z in soilstate.Zones)
                if (Z.Name == this.Parent.Name)
                    MyZone = Z;

            double[] PotSWUptake = new double[Soil.LL15.Length];
            SWUptake = new double[Soil.LL15.Length];

            SoilCrop soilCrop = Soil.Crop(this.Name) as SoilCrop;

            for (int j = 0; j < Soil.SoilWater.LL15mm.Length; j++)
                PotSWUptake[j] = Math.Max(0.0, RootProportion(j, RootDepth) * soilCrop.KL[j] * (MyZone.Water[j] - Soil.SoilWater.LL15mm[j]));

            double TotPotSWUptake = MathUtilities.Sum(PotSWUptake);

            for (int j = 0; j < Soil.SoilWater.LL15mm.Length; j++)
                SWUptake[j] = PotSWUptake[j] * Math.Min(1.0, PotentialEP / TotPotSWUptake);

            List<ZoneWaterAndN> Uptakes = new List<ZoneWaterAndN>();
            ZoneWaterAndN Uptake = new ZoneWaterAndN();

            Uptake.Name = this.Parent.Name;
            Uptake.Water = SWUptake;
            Uptake.NO3N = new double[SWUptake.Length];
            Uptake.NH4N = new double[SWUptake.Length];
            Uptakes.Add(Uptake);
            return Uptakes;
        }
コード例 #17
0
ファイル: AgPasture1.Sward.cs プロジェクト: hut104/ApsimX
 /// <summary>Placeholder for SoilArbitrator</summary>
 /// <param name="soilstate">some info</param>
 /// <returns>soil info</returns>
 public List<ZoneWaterAndN> GetSWUptakes(SoilState soilstate)
 {
     throw new NotImplementedException();
 }
コード例 #18
0
ファイル: OrganArbitrator.cs プロジェクト: kiwiroy/ApsimX
        /// <summary>
        /// Calculate the potential sw uptake for today. Should return null if crop is not in the ground.
        /// </summary>
        public List<Soils.Arbitrator.ZoneWaterAndN> GetNUptakes(SoilState soilstate)
        {
            if (Plant.IsAlive)
            {
                ZoneWaterAndN UptakeDemands = new ZoneWaterAndN();
                if (Plant.Phenology != null)
                {
                    if (Plant.Phenology.Emerged == true)
                    {
                        DoNUptakeDemandCalculations(soilstate);

                        //Pack results into uptake structure
                        UptakeDemands.NO3N = PotentialNO3NUptake;
                        UptakeDemands.NH4N = PotentialNH4NUptake;
                    }
                    else //Uptakes are zero
                    {
                        UptakeDemands.NO3N = new double[soilstate.Zones[0].NO3N.Length];
                        for (int i = 0; i < UptakeDemands.NO3N.Length; i++) { UptakeDemands.NO3N[i] = 0; }
                        UptakeDemands.NH4N = new double[soilstate.Zones[0].NH4N.Length];
                        for (int i = 0; i < UptakeDemands.NH4N.Length; i++) { UptakeDemands.NH4N[i] = 0; }
                    }
                }
                else //Uptakes are zero
                {
                    UptakeDemands.NO3N = new double[soilstate.Zones[0].NO3N.Length];
                    for (int i = 0; i < UptakeDemands.NO3N.Length; i++) { UptakeDemands.NO3N[i] = 0; }
                    UptakeDemands.NH4N = new double[soilstate.Zones[0].NH4N.Length];
                    for (int i = 0; i < UptakeDemands.NH4N.Length; i++) { UptakeDemands.NH4N[i] = 0; }
                }

                UptakeDemands.Name = soilstate.Zones[0].Name;
                UptakeDemands.Water = new double[UptakeDemands.NO3N.Length];

                List<ZoneWaterAndN> zones = new List<ZoneWaterAndN>();
                zones.Add(UptakeDemands);
                return zones;
            }
            else
                return null;
        }