Esempio n. 1
0
        /// <summary>
        /// Returns soil Nitrogen uptake from each zone by the static tree model
        /// </summary>
        /// <param name="soilstate"></param>
        /// <returns></returns>
        public List <Soils.Arbitrator.ZoneWaterAndN> GetNitrogenUptakeEstimates(Soils.Arbitrator.SoilState soilstate)
        {
            Zone treeZone = ZoneList.FirstOrDefault() as Zone;

            List <ZoneWaterAndN> Uptakes = new List <ZoneWaterAndN>();
            double PotNO3Supply          = 0; // Total N supply (kg)

            double NDemandkg = GetNDemandToday() * 10 * treeZone.Area;

            foreach (ZoneWaterAndN Z in soilstate.Zones)
            {
                foreach (Zone ZI in ZoneList)
                {
                    if (Z.Zone.Name == ZI.Name)
                    {
                        ZoneWaterAndN Uptake = new ZoneWaterAndN(ZI);
                        //Find the soil for this zone
                        Soils.Soil      ThisSoil     = null;
                        Soils.IPhysical soilPhysical = null;

                        foreach (Zone SearchZ in forestryZones)
                        {
                            if (SearchZ.Name == Z.Zone.Name)
                            {
                                ThisSoil     = SearchZ.FindInScope <Soils.Soil>();
                                soilPhysical = ThisSoil.FindChild <Soils.IPhysical>();
                                break;
                            }
                        }

                        double[] SW = Z.Water;

                        Uptake.NO3N  = new double[SW.Length];
                        Uptake.NH4N  = new double[SW.Length];
                        Uptake.Water = new double[SW.Length];
                        double[] LL15mm = MathUtilities.Multiply(soilPhysical.LL15, soilPhysical.Thickness);
                        double[] BD     = soilPhysical.BD;
                        double[] RLD    = GetRLD(ZI);

                        for (int i = 0; i <= SW.Length - 1; i++)
                        {
                            Uptake.NO3N[i]  = PotentialNO3Uptake(soilPhysical.Thickness[i], Z.NO3N[i], Z.Water[i], RLD[i], RootRadius, BD[i], Kd);
                            Uptake.NO3N[i] *= 10; // convert from g/m2 to kg/ha
                            PotNO3Supply   += Uptake.NO3N[i] * ZI.Area;
                        }
                        Uptakes.Add(Uptake);
                        break;
                    }
                }
            }
            // Now scale back uptakes if demand > supply
            double F = 0;  // Uptake scaling factor

            if (PotNO3Supply > 0)
            {
                F = NDemandkg / PotNO3Supply;
                if (F > 1)
                {
                    F = 1;
                }
            }
            else
            {
                F = 1;
            }
            NStress = Math.Min(1, Math.Max(0, PotNO3Supply / NDemandkg));

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

            foreach (ZoneWaterAndN Z in Uptakes)
            {
                Z.NO3N = MathUtilities.Multiply_Value(Z.NO3N, F);
                uptakeList.Add(Z.TotalNO3N);
            }

            NUptake = uptakeList.ToArray();
            return(Uptakes);
        }
Esempio n. 2
0
        /// <summary>
        /// Returns soil water uptake from each zone by the static tree model
        /// </summary>
        /// <param name="soilstate"></param>
        /// <returns></returns>
        public List <Soils.Arbitrator.ZoneWaterAndN> GetWaterUptakeEstimates(Soils.Arbitrator.SoilState soilstate)
        {
            double Etz = treeZoneWater.Eo; //Eo of Tree Zone

            SWDemand = 0;
            foreach (Zone ZI in ZoneList)
            {
                SWDemand += Etz * (GetShade(ZI) / 100) * (ZI.Area * 10000);    // 100 converts from %, 10000 converts from ha to m2
            }
            IndividualTreeWaterDemand = SWDemand / NumberOfTrees;

            List <ZoneWaterAndN> Uptakes = new List <ZoneWaterAndN>();
            double PotSWSupply           = 0; // Total water supply (L)

            foreach (ZoneWaterAndN Z in soilstate.Zones)
            {
                foreach (Zone ZI in ZoneList)
                {
                    if (Z.Zone.Name == ZI.Name)
                    {
                        ZoneWaterAndN Uptake = new ZoneWaterAndN(ZI);
                        //Find the soil for this zone
                        Soils.Soil      ThisSoil     = null;
                        Soils.IPhysical soilPhysical = null;

                        foreach (Zone SearchZ in forestryZones)
                        {
                            if (SearchZ.Name == Z.Zone.Name)
                            {
                                ThisSoil     = SearchZ.FindInScope <Soils.Soil>();
                                soilPhysical = ThisSoil.FindChild <Soils.IPhysical>();
                                break;
                            }
                        }

                        double[] SW = Z.Water;
                        Uptake.NO3N  = new double[SW.Length];
                        Uptake.NH4N  = new double[SW.Length];
                        Uptake.Water = new double[SW.Length];
                        double[] LL15mm = MathUtilities.Multiply(soilPhysical.LL15, soilPhysical.Thickness);
                        double[] RLD    = GetRLD(ZI);

                        for (int i = 0; i <= SW.Length - 1; i++)
                        {
                            Uptake.Water[i] = Math.Max(SW[i] - LL15mm[i], 0.0) * BaseKL * RLD[i];
                            PotSWSupply    += Uptake.Water[i] * ZI.Area * 10000;
                        }
                        Uptakes.Add(Uptake);
                        break;
                    }
                }
            }
            // Now scale back uptakes if supply > demand
            double F = 0;  // Uptake scaling factor

            if (PotSWSupply > 0)
            {
                F = SWDemand / PotSWSupply;
                if (F > 1)
                {
                    F = 1;
                }
            }
            else
            {
                F = 1;
            }
            WaterStress = Math.Min(1, Math.Max(0, PotSWSupply / SWDemand));

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

            foreach (ZoneWaterAndN Z in Uptakes)
            {
                Z.Water = MathUtilities.Multiply_Value(Z.Water, F);
                uptakeList.Add(Z.TotalWater);
            }

            WaterUptake = uptakeList.ToArray();
            return(Uptakes);
        }