/// <summary> /// Accepts the actual soil Nitrogen uptake from the soil arbitrator. /// </summary> /// <param name="info"></param> public void SetNUptake(List <Soils.Arbitrator.ZoneWaterAndN> info) { foreach (ZoneWaterAndN ZI in info) { foreach (Zone SearchZ in forestryZones) { Soils.Soil ThisSoil = null; if (SearchZ.Name == ZI.Zone.Name) { ThisSoil = Apsim.Find(SearchZ, typeof(Soils.Soil)) as Soils.Soil; double[] NewNO3 = new double[ZI.NO3N.Length]; for (int i = 0; i <= ZI.NO3N.Length - 1; i++) { NewNO3[i] = ThisSoil.NO3N[i] - ZI.NO3N[i]; } ThisSoil.NO3N = NewNO3; } } } }
/// <summary> /// Accepts the actual soil water uptake from the soil arbitrator. /// </summary> /// <param name="info"></param> public void SetSWUptake(List<Soils.Arbitrator.ZoneWaterAndN> info) { int i = 0; foreach (Zone SearchZ in forestryZones) { foreach (ZoneWaterAndN ZI in info) { Soils.Soil ThisSoil = null; if (SearchZ.Name == ZI.Zone.Name) { ThisSoil = Apsim.Find(SearchZ, typeof(Soils.Soil)) as Soils.Soil; ThisSoil.SoilWater.dlt_sw_dep = MathUtilities.Multiply_Value(ZI.Water, -1); ; TreeWaterUptake[i] = MathUtilities.Sum(ZI.Water); if (TreeWaterUptake[i] < 0) { } i++; } } } }
/// <summary> /// Accepts the actual soil water uptake from the soil arbitrator. /// </summary> /// <param name="info"></param> public void SetActualWaterUptake(List <Soils.Arbitrator.ZoneWaterAndN> info) { int i = 0; foreach (Zone SearchZ in forestryZones) { foreach (ZoneWaterAndN ZI in info) { Soils.Soil ThisSoil = null; if (SearchZ.Name == ZI.Zone.Name) { ThisSoil = Apsim.Find(SearchZ, typeof(Soils.Soil)) as Soils.Soil; ThisSoil.SoilWater.RemoveWater(ZI.Water); TreeWaterUptake[i] = MathUtilities.Sum(ZI.Water); if (TreeWaterUptake[i] < 0) { } i++; } } } }
/// <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> GetNUptakes(Soils.Arbitrator.SoilState soilstate) { List <ZoneWaterAndN> Uptakes = new List <ZoneWaterAndN>(); foreach (ZoneWaterAndN Z in soilstate.Zones) { foreach (ZoneInfo ZI in ZoneInfoList) { if (Z.Name == ZI.zone.Name) { ZoneWaterAndN Uptake = new ZoneWaterAndN(); //Find the soil for this zone Zone ThisZone = new Zone(); Soils.Soil ThisSoil = new Soils.Soil(); foreach (Zone SearchZ in Apsim.ChildrenRecursively(Parent, typeof(Zone))) { if (SearchZ.Name == Z.Name) { ThisSoil = Apsim.Find(SearchZ, typeof(Soils.Soil)) as Soils.Soil; } } Uptake.Name = Z.Name; double[] SW = Z.Water; Uptake.NO3N = new double[SW.Length]; Uptake.NH4N = new double[SW.Length]; Uptake.Water = new double[SW.Length]; //for (int i = 0; i <= SW.Length-1; i++) // Uptake.NO3N[i] = Z.NO3N[i] * ZI.RLD[i]; Uptakes.Add(Uptake); } } } return(Uptakes); }
/// <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); }
/// <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); }
/// <summary> /// Accepts the actual soil water uptake from the soil arbitrator. /// </summary> /// <param name="info"></param> public void SetSWUptake(List<Soils.Arbitrator.ZoneWaterAndN> info) { foreach (ZoneWaterAndN ZI in info) { foreach (Zone SearchZ in Apsim.ChildrenRecursively(Parent, typeof(Zone))) { Soils.Soil ThisSoil = new Soils.Soil(); if (SearchZ.Name == ZI.Name) { ThisSoil = Apsim.Find(SearchZ, typeof(Soils.Soil)) as Soils.Soil; ThisSoil.SoilWater.dlt_sw_dep = MathUtilities.Multiply_Value(ZI.Water, -1); ; } } } }
/// <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> GetSWUptakes(Soils.Arbitrator.SoilState soilstate) { double SWDemand = 0; // Tree water demand (L) double PotSWSupply = 0; // Total water supply (L) foreach (ZoneInfo ZI in ZoneInfoList) { Soils.SoilWater S = Apsim.Find(ZI.zone, typeof(Soils.SoilWater)) as Soils.SoilWater; SWDemand += S.Eo * (1 / (1 - ZI.Shade / 100) - 1) * ZI.zone.Area * 10000; } List<ZoneWaterAndN> Uptakes = new List<ZoneWaterAndN>(); foreach (ZoneWaterAndN Z in soilstate.Zones) { foreach (ZoneInfo ZI in ZoneInfoList) { if (Z.Name == ZI.zone.Name) { ZoneWaterAndN Uptake = new ZoneWaterAndN(); //Find the soil for this zone Zone ThisZone = new Zone(); Soils.Soil ThisSoil = new Soils.Soil(); foreach (Zone SearchZ in Apsim.ChildrenRecursively(Parent, typeof(Zone))) if (SearchZ.Name == Z.Name) ThisSoil = Apsim.Find(SearchZ, typeof(Soils.Soil)) as Soils.Soil; Uptake.Name = Z.Name; double[] SW = Z.Water; Uptake.NO3N = new double[SW.Length]; Uptake.NH4N = new double[SW.Length]; Uptake.Water = new double[SW.Length]; for (int i = 0; i <= SW.Length - 1; i++) { double[] LL15mm = MathUtilities.Multiply(ThisSoil.LL15,ThisSoil.Thickness); Uptake.Water[i] = (SW[i] - LL15mm[i]) * ZI.RLD[i]; PotSWSupply += Uptake.Water[i] * ZI.zone.Area * 10000; } Uptakes.Add(Uptake); } } } // 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; foreach (ZoneWaterAndN Z in Uptakes) Z.Water = MathUtilities.Multiply_Value(Z.Water, F); return Uptakes; }
/// <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> GetNUptakes(Soils.Arbitrator.SoilState soilstate) { List<ZoneWaterAndN> Uptakes = new List<ZoneWaterAndN>(); foreach (ZoneWaterAndN Z in soilstate.Zones) { foreach (ZoneInfo ZI in ZoneInfoList) { if (Z.Name == ZI.zone.Name) { ZoneWaterAndN Uptake = new ZoneWaterAndN(); //Find the soil for this zone Zone ThisZone = new Zone(); Soils.Soil ThisSoil = new Soils.Soil(); foreach (Zone SearchZ in Apsim.ChildrenRecursively(Parent, typeof(Zone))) if (SearchZ.Name == Z.Name) ThisSoil = Apsim.Find(SearchZ, typeof(Soils.Soil)) as Soils.Soil; Uptake.Name = Z.Name; double[] SW = Z.Water; Uptake.NO3N = new double[SW.Length]; Uptake.NH4N = new double[SW.Length]; Uptake.Water = new double[SW.Length]; //for (int i = 0; i <= SW.Length-1; i++) // Uptake.NO3N[i] = Z.NO3N[i] * ZI.RLD[i]; Uptakes.Add(Uptake); } } } return Uptakes; }
/// <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> GetNUptakes(Soils.Arbitrator.SoilState soilstate) { Zone treeZone = ZoneList[0] as Zone; List <ZoneWaterAndN> Uptakes = new List <ZoneWaterAndN>(); double PotNO3Supply = 0; // Total N supply (kg) double NDemandkg = GetNDemandToday() * 10 * treeZone.Area * 10000; 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; foreach (Zone SearchZ in forestryZones) { if (SearchZ.Name == Z.Zone.Name) { ThisSoil = Apsim.Find(SearchZ, typeof(Soils.Soil)) as Soils.Soil; 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(ThisSoil.LL15, ThisSoil.Thickness); double[] BD = ThisSoil.BD; double[] RLD = GetRLD(ZI); for (int i = 0; i <= SW.Length - 1; i++) { Uptake.NO3N[i] = PotentialNO3Uptake(ThisSoil.Thickness[i], Z.NO3N[i], Z.Water[i], RLD[i], RootRadius, BD[i], Kd); PotNO3Supply += Uptake.NO3N[i] * ZI.Area * 10000; } Uptakes.Add(Uptake); break; } } } // Now scale back uptakes if supply > demand 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); }
/// <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> GetSWUptakes(Soils.Arbitrator.SoilState soilstate) { double SWDemand = 0; // Tree water demand (L) double PotSWSupply = 0; // Total water supply (L) foreach (ZoneInfo ZI in ZoneInfoList) { Soils.SoilWater S = Apsim.Find(ZI.zone, typeof(Soils.SoilWater)) as Soils.SoilWater; SWDemand += S.Eo * (1 / (1 - ZI.Shade / 100) - 1) * ZI.zone.Area * 10000; } List <ZoneWaterAndN> Uptakes = new List <ZoneWaterAndN>(); foreach (ZoneWaterAndN Z in soilstate.Zones) { foreach (ZoneInfo ZI in ZoneInfoList) { if (Z.Name == ZI.zone.Name) { ZoneWaterAndN Uptake = new ZoneWaterAndN(); //Find the soil for this zone Zone ThisZone = new Zone(); Soils.Soil ThisSoil = new Soils.Soil(); foreach (Zone SearchZ in Apsim.ChildrenRecursively(Parent, typeof(Zone))) { if (SearchZ.Name == Z.Name) { ThisSoil = Apsim.Find(SearchZ, typeof(Soils.Soil)) as Soils.Soil; } } Uptake.Name = Z.Name; double[] SW = Z.Water; Uptake.NO3N = new double[SW.Length]; Uptake.NH4N = new double[SW.Length]; Uptake.Water = new double[SW.Length]; for (int i = 0; i <= SW.Length - 1; i++) { double[] LL15mm = MathUtilities.Multiply(ThisSoil.LL15, ThisSoil.Thickness); Uptake.Water[i] = (SW[i] - LL15mm[i]) * ZI.RLD[i]; PotSWSupply += Uptake.Water[i] * ZI.zone.Area * 10000; } Uptakes.Add(Uptake); } } } // 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; } foreach (ZoneWaterAndN Z in Uptakes) { Z.Water = MathUtilities.Multiply_Value(Z.Water, F); } return(Uptakes); }