/// <summary>Does the Nitrogen uptake.</summary> /// <param name="zonesFromSoilArbitrator">List of zones from soil arbitrator</param> public void DoNitrogenUptake(List <ZoneWaterAndN> zonesFromSoilArbitrator) { foreach (ZoneWaterAndN thisZone in zonesFromSoilArbitrator) { ZoneState zone = Zones.Find(z => z.Name == thisZone.Zone.Name); if (zone != null) { zone.solutes.Subtract("NO3", SoluteManager.SoluteSetterType.Plant, thisZone.NO3N); zone.solutes.Subtract("NH4", SoluteManager.SoluteSetterType.Plant, thisZone.NH4N); zone.NitUptake = MathUtilities.Multiply_Value(MathUtilities.Add(thisZone.NO3N, thisZone.NH4N), -1); } } }
private new void OnSimulationCommencing(object sender, EventArgs e) { Soil soil = Apsim.Find(this, typeof(Soil)) as Soil; if (soil == null) { throw new Exception("Cannot find soil"); } if (soil.Crop(Plant.Name) == null && soil.Weirdo == null) { throw new Exception("Cannot find a soil crop parameterisation for " + Plant.Name); } PlantZone = new ZoneState(Plant, this, soil, 0, InitialDM.Value(), Plant.Population, MaximumNConc.Value()); Zones = new List <ZoneState>(); base.OnSimulationCommencing(sender, e); }
/// <summary>Does the Nitrogen uptake.</summary> /// <param name="zonesFromSoilArbitrator">List of zones from soil arbitrator</param> public void DoNitrogenUptake(List <ZoneWaterAndN> zonesFromSoilArbitrator) { foreach (ZoneWaterAndN thisZone in zonesFromSoilArbitrator) { ZoneState zone = Zones.Find(z => z.Name == thisZone.Zone.Name); if (zone != null) { // Send the delta water back to SoilN that we're going to uptake. NitrogenChangedType NitrogenUptake = new NitrogenChangedType(); NitrogenUptake.DeltaNO3 = MathUtilities.Multiply_Value(thisZone.NO3N, -1.0); NitrogenUptake.DeltaNH4 = MathUtilities.Multiply_Value(thisZone.NH4N, -1.0); zone.NitUptake = MathUtilities.Add(NitrogenUptake.DeltaNO3, NitrogenUptake.DeltaNH4); zone.soil.SoilNitrogen.SetNitrogenChanged(NitrogenUptake); } } }
/// <summary>Gets the nitrogen supply from the specified zone.</summary> /// <param name="zone">The zone.</param> /// <param name="NO3Supply">The returned NO3 supply</param> /// <param name="NH4Supply">The returned NH4 supply</param> public void CalculateNitrogenSupply(ZoneWaterAndN zone, ref double[] NO3Supply, ref double[] NH4Supply) { ZoneState myZone = Zones.Find(z => z.Name == zone.Zone.Name); if (myZone != null) { if (RWC == null || RWC.Length != myZone.soil.Thickness.Length) { RWC = new double[myZone.soil.Thickness.Length]; } double NO3Uptake = 0; double NH4Uptake = 0; double[] thickness = myZone.soil.Thickness; double[] water = myZone.soil.Water; double[] ll15mm = myZone.soil.LL15mm; double[] dulmm = myZone.soil.DULmm; double[] bd = myZone.soil.BD; double accuDepth = 0; for (int layer = 0; layer < thickness.Length; layer++) { accuDepth += thickness[layer]; if (myZone.LayerLive[layer].Wt > 0) { double factorRootDepth = Math.Max(0, Math.Min(1, 1 - (accuDepth - Depth) / thickness[layer])); RWC[layer] = (water[layer] - ll15mm[layer]) / (dulmm[layer] - ll15mm[layer]); RWC[layer] = Math.Max(0.0, Math.Min(RWC[layer], 1.0)); double SWAF = nUptakeSWFactor.Value(layer); double kno3 = this.kno3.Value(layer); double NO3ppm = zone.NO3N[layer] * (100.0 / (bd[layer] * thickness[layer])); NO3Supply[layer] = Math.Min(zone.NO3N[layer] * kno3 * NO3ppm * SWAF * factorRootDepth, (maxDailyNUptake.Value() - NO3Uptake)); NO3Uptake += NO3Supply[layer]; double knh4 = this.knh4.Value(layer); double NH4ppm = zone.NH4N[layer] * (100.0 / (bd[layer] * thickness[layer])); NH4Supply[layer] = Math.Min(zone.NH4N[layer] * knh4 * NH4ppm * SWAF * factorRootDepth, (maxDailyNUptake.Value() - NH4Uptake)); NH4Uptake += NH4Supply[layer]; } } } }
private void OnSimulationCommencing(object sender, EventArgs e) { Soil soil = Apsim.Find(this, typeof(Soil)) as Soil; if (soil == null) { throw new Exception("Cannot find soil"); } if (soil.Crop(Plant.Name) == null && soil.Weirdo == null) { throw new Exception("Cannot find a soil crop parameterisation for " + Plant.Name); } PlantZone = new ZoneState(Plant, this, soil, 0, initialDM.Value(), Plant.Population, maximumNConc.Value(), rootFrontVelocity, maximumRootDepth, remobilisationCost); Zones = new List <ZoneState>(); Allocated = new PMF.Biomass(); Senesced = new Biomass(); Detached = new Biomass(); Removed = new Biomass(); }
/// <summary>Gets or sets the water supply.</summary> /// <param name="zone">The zone.</param> public double[] CalculateWaterSupply(ZoneWaterAndN zone) { ZoneState myZone = Zones.Find(z => z.Name == zone.Zone.Name); if (myZone == null) { return(null); } SoilCrop crop = myZone.soil.Crop(Plant.Name) as SoilCrop; double[] supply = new double[myZone.soil.Thickness.Length]; double[] layerMidPoints = Soil.ToMidPoints(myZone.soil.Thickness); for (int layer = 0; layer < myZone.soil.Thickness.Length; layer++) { if (layer <= Soil.LayerIndexOfDepth(myZone.Depth, myZone.soil.Thickness)) { supply[layer] = Math.Max(0.0, crop.KL[layer] * KLModifier.ValueForX(layerMidPoints[layer]) * (zone.Water[layer] - crop.LL[layer] * myZone.soil.Thickness[layer]) * Soil.ProportionThroughLayer(layer, myZone.Depth, myZone.soil.Thickness)); } } return(supply); }