public override void OnEndCrop() { FOMLayerLayerType[] FOMLayers = new FOMLayerLayerType[dlayer.Length]; for (int layer = 0; layer < dlayer.Length; layer++) { double DM = (LayerLive[layer].Wt + LayerDead[layer].Wt) * 10.0; double N = (LayerLive[layer].N + LayerDead[layer].N) * 10.0; FOMType fom = new FOMType(); fom.amount = (float)DM; fom.N = (float)N; fom.C = (float)(0.40 * DM); fom.P = 0; fom.AshAlk = 0; FOMLayerLayerType Layer = new FOMLayerLayerType(); Layer.FOM = fom; Layer.CNR = 0; Layer.LabileP = 0; FOMLayers[layer] = Layer; } FOMLayerType FomLayer = new FOMLayerType(); FomLayer.Type = Plant.CropType; FomLayer.Layer = FOMLayers; IncorpFOM.Invoke(FomLayer); }
private void OnPlantEnding(object sender, EventArgs e) { if (sender == Plant) { FOMLayerLayerType[] FOMLayers = new FOMLayerLayerType[Soil.Thickness.Length]; for (int layer = 0; layer < Soil.Thickness.Length; layer++) { double DM = (LayerLive[layer].Wt + LayerDead[layer].Wt) * 10.0; double N = (LayerLive[layer].N + LayerDead[layer].N) * 10.0; FOMType fom = new FOMType(); fom.amount = (float)DM; fom.N = (float)N; fom.C = (float)(0.40 * DM); fom.P = 0; fom.AshAlk = 0; FOMLayerLayerType Layer = new FOMLayerLayerType(); Layer.FOM = fom; Layer.CNR = 0; Layer.LabileP = 0; FOMLayers[layer] = Layer; } FOMLayerType FomLayer = new FOMLayerType(); FomLayer.Type = Plant.CropType; FomLayer.Layer = FOMLayers; IncorpFOM.Invoke(FomLayer); } }
public override void DoActualGrowth() { base.DoActualGrowth(); // Do Root Front Advance int RootLayer = LayerIndex(Depth); double TEM = (TemperatureEffect == null)? 1: TemperatureEffect.Value; Depth = Depth + RootFrontVelocity.Value * xf[RootLayer] * TEM; if (!(MaximumRootDepth == null)) { Depth = Math.Min(Depth, MaximumRootDepth.Value); } double MaxDepth = 0; for (int i = 0; i < dlayer.Length; i++) { if (xf[i] > 0) { MaxDepth += dlayer[i]; } } Depth = Math.Min(Depth, MaxDepth); // Do Root Senescence FOMLayerLayerType[] FOMLayers = new FOMLayerLayerType[dlayer.Length]; for (int layer = 0; layer < dlayer.Length; layer++) { double DM = LayerLive[layer].Wt * _SenescenceRate * 10.0; double N = LayerLive[layer].StructuralN * _SenescenceRate * 10.0; LayerLive[layer].StructuralWt *= (1.0 - _SenescenceRate); LayerLive[layer].NonStructuralWt *= (1.0 - _SenescenceRate); LayerLive[layer].StructuralN *= (1.0 - _SenescenceRate); LayerLive[layer].NonStructuralN *= (1.0 - _SenescenceRate); FOMType fom = new FOMType(); fom.amount = (float)DM; fom.N = (float)N; fom.C = (float)(0.40 * DM); fom.P = 0; fom.AshAlk = 0; FOMLayerLayerType Layer = new FOMLayerLayerType(); Layer.FOM = fom; Layer.CNR = 0; Layer.LabileP = 0; FOMLayers[layer] = Layer; } FOMLayerType FomLayer = new FOMLayerType(); FomLayer.Type = Plant.CropType; FomLayer.Layer = FOMLayers; IncorpFOM.Invoke(FomLayer); }
private void OnDoActualPlantGrowth(object sender, EventArgs e) { if (Plant.IsAlive) { // Do Root Front Advance int RootLayer = LayerIndex(Depth); double TEM = (TemperatureEffect == null) ? 1 : TemperatureEffect.Value; Depth = Depth + RootFrontVelocity.Value * soilCrop.XF[RootLayer] * TEM; double MaxDepth = 0; for (int i = 0; i < Soil.Thickness.Length; i++) { if (soilCrop.XF[i] > 0) { MaxDepth += Soil.Thickness[i]; } } Depth = Math.Min(Depth, MaxDepth); // Do Root Senescence FOMLayerLayerType[] FOMLayers = new FOMLayerLayerType[Soil.Thickness.Length]; for (int layer = 0; layer < Soil.Thickness.Length; layer++) { double DM = LayerLive[layer].Wt * _SenescenceRate * 10.0; double N = LayerLive[layer].StructuralN * _SenescenceRate * 10.0; LayerLive[layer].StructuralWt *= (1.0 - _SenescenceRate); LayerLive[layer].NonStructuralWt *= (1.0 - _SenescenceRate); LayerLive[layer].StructuralN *= (1.0 - _SenescenceRate); LayerLive[layer].NonStructuralN *= (1.0 - _SenescenceRate); FOMType fom = new FOMType(); fom.amount = (float)DM; fom.N = (float)N; fom.C = (float)(0.40 * DM); fom.P = 0; fom.AshAlk = 0; FOMLayerLayerType Layer = new FOMLayerLayerType(); Layer.FOM = fom; Layer.CNR = 0; Layer.LabileP = 0; FOMLayers[layer] = Layer; } FOMLayerType FomLayer = new FOMLayerType(); FomLayer.Type = Plant.CropType; FomLayer.Layer = FOMLayers; IncorpFOM.Invoke(FomLayer); } }
/// <summary>Removes biomass from live and dead biomass pools and send to soil</summary> /// <param name="biomassRemoveType">Name of event that triggered this biomass remove call.</param> /// <param name="removal">The fractions of biomass to remove</param> /// <param name="Live">Live biomass pool</param> /// <param name="Dead">Dead biomass pool</param> /// <param name="Removed">The removed pool to add to.</param> /// <param name="Detached">The detached pool to add to.</param> public void RemoveBiomassToSoil(string biomassRemoveType, OrganBiomassRemovalType removal, Biomass[] Live, Biomass[] Dead, Biomass Removed, Biomass Detached) { if (removal == null) { removal = FindDefault(biomassRemoveType); } //NOTE: roots don't have dead biomass double totalFractionToRemove = removal.FractionLiveToRemove + removal.FractionLiveToResidue; if (totalFractionToRemove > 0) { //NOTE: at the moment Root has no Dead pool FOMLayerLayerType[] FOMLayers = new FOMLayerLayerType[Live.Length]; double remainingFraction = 1.0 - (removal.FractionLiveToResidue + removal.FractionLiveToRemove); for (int layer = 0; layer < Live.Length; layer++) { Biomass removing; Biomass detaching; double remainingLiveFraction = RemoveBiomassFromLiveAndDead(removal, Live[layer], Dead[layer], out removing, out detaching); // Add the detaching biomass to total removed and detached Removed.Add(removing); Detached.Add(detaching); // Pass the detaching biomass to surface organic matter model. FOMType fom = new FOMType(); fom.amount = (float)(detaching.Wt * 10); fom.N = (float)(detaching.N * 10); fom.C = (float)(0.40 * detaching.Wt * 10); fom.P = 0.0; fom.AshAlk = 0.0; FOMLayerLayerType Layer = new FOMLayerLayerType(); Layer.FOM = fom; Layer.CNR = 0.0; Layer.LabileP = 0.0; FOMLayers[layer] = Layer; } FOMLayerType FomLayer = new FOMLayerType(); FomLayer.Type = plant.PlantType; FomLayer.Layer = FOMLayers; IncorpFOM.Invoke(FomLayer); } }
/// <summary> /// Dispose of detached material from dead & senesced roots into FOM pool /// </summary> private void DisposeDetachedMaterial(Biomass BiomassToDisposeOf, double[] RootLength) { if (BiomassToDisposeOf.Wt > 0.0) { // DM double[] dlt_dm_incorp = RootDist(BiomassToDisposeOf.Wt * Conversions.gm2kg / Conversions.sm2ha, RootLength); // Nitrogen double[] dlt_N_incorp = RootDist(BiomassToDisposeOf.N * Conversions.gm2kg / Conversions.sm2ha, RootLength); // Phosporous //double[] dlt_P_incorp = RootDist(BiomassToDisposeOf.P * Conversions.gm2kg / Conversions.sm2ha); FOMLayerType IncorpFOMData = new FOMLayerType(); IncorpFOMData.Type = Plant.CropType; Util.Debug("Root.IncorpFOM.Type=%s", IncorpFOMData.Type.ToLower()); IncorpFOMData.Layer = new FOMLayerLayerType[dlt_dm_incorp.Length]; for (int i = 0; i != dlt_dm_incorp.Length; i++) { IncorpFOMData.Layer[i] = new FOMLayerLayerType(); IncorpFOMData.Layer[i].FOM = new FOMType(); IncorpFOMData.Layer[i].FOM.amount = (float)dlt_dm_incorp[i]; IncorpFOMData.Layer[i].FOM.N = (float)dlt_N_incorp[i]; //IncorpFOMData.Layer[i].FOM.P = (float)dlt_P_incorp[i]; IncorpFOMData.Layer[i].FOM.C = (float)0.0; IncorpFOMData.Layer[i].FOM.AshAlk = (float)0.0; IncorpFOMData.Layer[i].CNR = 0; IncorpFOMData.Layer[i].LabileP = 0; Util.Debug("Root.IncorpFOM.FOM.amount=%f2", IncorpFOMData.Layer[i].FOM.amount); Util.Debug("Root.IncorpFOM.FOM.N=%f", IncorpFOMData.Layer[i].FOM.N); } IncorpFOM.Invoke(IncorpFOMData); } else { // no roots to incorporate } }
private void DoRootGrowth(double Allocation) { int RootLayer = LayerIndex(RootDepth); RootDepth = RootDepth + RootFrontVelocity.Value * xf[RootLayer]; RootDepth = Math.Min(MaximumRootDepth, RootDepth); RootDepth = Math.Min(MathUtility.Sum(dlayer), RootDepth); // Calculate Root Activity Values for water and nitrogen double[] RAw = new double[dlayer.Length]; double[] RAn = new double[dlayer.Length]; double TotalRAw = 0; double TotalRAn = 0; for (int layer = 0; layer < dlayer.Length; layer++) { if (layer <= LayerIndex(RootDepth)) { if (Roots[layer].Mass > 0) { RAw[layer] = SWUptake[layer] / Roots[layer].Mass * dlayer[layer] * RootProportion(layer, RootDepth); RAw[layer] = Math.Max(RAw[layer], 1e-20); // Make sure small numbers to avoid lack of info for partitioning RAn[layer] = NUptake[layer] / Roots[layer].Mass * dlayer[layer] * RootProportion(layer, RootDepth); RAn[layer] = Math.Max(RAw[layer], 1e-10); // Make sure small numbers to avoid lack of info for partitioning } else if (layer > 0) { RAw[layer] = RAw[layer - 1]; RAn[layer] = RAn[layer - 1]; } else { RAw[layer] = 0; RAn[layer] = 0; } } TotalRAw += RAw[layer]; TotalRAn += RAn[layer]; } double allocated = 0; for (int layer = 0; layer < dlayer.Length; layer++) { if (TotalRAw > 0) { Roots[layer].Mass += Allocation * RAw[layer] / TotalRAw; } else if (Allocation > 0) { throw new Exception("Error trying to partition root biomass"); } allocated += Allocation * RAw[layer] / TotalRAw; } // Do Root Senescence FOMLayerLayerType[] FOMLayers = new FOMLayerLayerType[dlayer.Length]; for (int layer = 0; layer < dlayer.Length; layer++) { double Fr = RootSenescenceRate.Value; double DM = Roots[layer].Mass * Fr * 10.0; double N = Roots[layer].N * Fr * 10.0; Roots[layer].Mass *= (1.0 - Fr); Roots[layer].N *= (1.0 - Fr); Roots[layer].Length *= (1.0 - Fr); FOMType fom = new FOMType(); fom.amount = (float)DM; fom.N = (float)N; fom.C = (float)(0.44 * DM); fom.P = 0; fom.AshAlk = 0; FOMLayerLayerType Layer = new FOMLayerLayerType(); Layer.FOM = fom; Layer.CNR = 0; Layer.LabileP = 0; FOMLayers[layer] = Layer; } FOMLayerType FomLayer = new FOMLayerType(); FomLayer.Type = Crop_Type; FomLayer.Layer = FOMLayers; IncorpFOM.Invoke(FomLayer); }