/// <summary>Add dung to the soil surface.</summary> private void AddDungToSurface() { var SOMData = new BiomassRemovedType(); SOMData.crop_type = "RuminantDung_PastureFed"; SOMData.dm_type = new string[] { SOMData.crop_type }; SOMData.dlt_crop_dm = new float[] { (float)AmountDungWtReturned }; SOMData.dlt_dm_n = new float[] { (float)AmountDungNReturned }; SOMData.dlt_dm_p = new float[] { 0.0F }; SOMData.fraction_to_residue = new float[] { 1.0F }; BiomassRemoved.Invoke(SOMData); }
public void OnHarvest(HarvestType Harvest) { WriteHarvestReport(); // Tell the rest of the system we are about to harvest if (Harvesting != null) { Harvesting.Invoke(); } // Check some bounds if (Harvest.Remove < 0 || Harvest.Remove > 1.0) { throw new Exception("Harvest remove fraction needs to be between 0 and 1"); } if (Harvest.Height < 0 || Harvest.Height > 1000.0) { throw new Exception("Harvest height needs to be between 0 and 1000"); } // Set the population denisty if one was provided by user. if (Harvest.Plants != 0) { Population.Density = Harvest.Plants; } // Call each organ's OnHarvest. They fill a BiomassRemoved structure. We then publish a // BiomassRemoved event. BiomassRemovedType BiomassRemovedData = new BiomassRemovedType(); foreach (Organ1 Organ in Organ1s) { Organ.OnHarvest(Harvest, BiomassRemovedData); } BiomassRemovedData.crop_type = CropType; BiomassRemoved.Invoke(BiomassRemovedData); WriteBiomassRemovedReport(BiomassRemovedData); // now update new canopy covers PlantSpatial.Density = Population.Density; PlantSpatial.CanopyWidth = Leaf.width; foreach (Organ1 Organ in Organ1s) { Organ.DoCover(); } UpdateCanopy(); foreach (Organ1 Organ in Organ1s) { Organ.DoNConccentrationLimits(); } }
/// <summary>Called when [end crop].</summary> /// <param name="BiomassRemoved">The biomass removed.</param> public override void OnEndCrop(BiomassRemovedType BiomassRemoved) { int i = Util.IncreaseSizeOfBiomassRemoved(BiomassRemoved); BiomassRemoved.dm_type[i] = Name; BiomassRemoved.fraction_to_residue[i] = 1.0F; BiomassRemoved.dlt_crop_dm[i] = (float)((Live.Wt + Dead.Wt) * Conversions.gm2kg / Conversions.sm2ha); BiomassRemoved.dlt_dm_n[i] = (float)((Live.N + Dead.N) * Conversions.gm2kg / Conversions.sm2ha); //BiomassRemoved.dlt_dm_p[i] = (float)((Green.P + Senesced.P) * Conversions.gm2kg / Conversions.sm2ha); Dead.Clear(); Live.Clear(); }
public void OnEndCrop() { NewCropType Crop = new NewCropType(); Crop.crop_type = CropType; Crop.sender = Name; if (CropEnding != null) { CropEnding.Invoke(Crop); } BiomassRemovedType BiomassRemovedData = new BiomassRemovedType(); BiomassRemovedData.crop_type = CropType; BiomassRemovedData.dm_type = new string[Organs.Count]; BiomassRemovedData.dlt_crop_dm = new float[Organs.Count]; BiomassRemovedData.dlt_dm_n = new float[Organs.Count]; BiomassRemovedData.dlt_dm_p = new float[Organs.Count]; BiomassRemovedData.fraction_to_residue = new float[Organs.Count]; int i = 0; foreach (Organ O in Organs) { if (O is AboveGround) { BiomassRemovedData.dm_type[i] = O.Name; BiomassRemovedData.dlt_crop_dm[i] = (float)(O.Live.Wt + O.Dead.Wt) * 10f; BiomassRemovedData.dlt_dm_n[i] = (float)(O.Live.N + O.Dead.N) * 10f; BiomassRemovedData.dlt_dm_p[i] = 0f; BiomassRemovedData.fraction_to_residue[i] = 1f; } else { BiomassRemovedData.dm_type[i] = O.Name; BiomassRemovedData.dlt_crop_dm[i] = 0f; BiomassRemovedData.dlt_dm_n[i] = 0f; BiomassRemovedData.dlt_dm_p[i] = 0f; BiomassRemovedData.fraction_to_residue[i] = 0f; } i++; } BiomassRemoved.Invoke(BiomassRemovedData); // tell all our children about sow foreach (Organ Child in Organs) { Child.OnEndCrop(); } }
public override void OnHarvest(HarvestType Harvest, BiomassRemovedType BiomassRemoved) { Biomass Dead; Dead = Live * DieBackFraction; // however dead roots have a given N concentration Dead.StructuralN = Dead.Wt * NSenescenceConcentration; Live = Live - Dead; Dead = Dead + Dead; int i = Util.IncreaseSizeOfBiomassRemoved(BiomassRemoved); // Unlike above ground parts, no roots go to surface residue module. BiomassRemoved.dm_type[i] = Name; BiomassRemoved.fraction_to_residue[i] = 0.0F; BiomassRemoved.dlt_crop_dm[i] = 0.0F; BiomassRemoved.dlt_dm_n[i] = 0.0F; BiomassRemoved.dlt_dm_p[i] = 0.0F; }
public static int IncreaseSizeOfBiomassRemoved(BiomassRemovedType BiomassRemoved) { // Make sure the BiomassRemoved structure has enough elements in it. if (BiomassRemoved.dm_type == null) { BiomassRemoved.dm_type = new string[1]; BiomassRemoved.fraction_to_residue = new float[1]; BiomassRemoved.dlt_crop_dm = new float[1]; BiomassRemoved.dlt_dm_n = new float[1]; BiomassRemoved.dlt_dm_p = new float[1]; } else { int NewSize = BiomassRemoved.dm_type.Length + 1; Array.Resize(ref BiomassRemoved.dm_type, NewSize); Array.Resize(ref BiomassRemoved.fraction_to_residue, NewSize); Array.Resize(ref BiomassRemoved.dlt_crop_dm, NewSize); Array.Resize(ref BiomassRemoved.dlt_dm_n, NewSize); Array.Resize(ref BiomassRemoved.dlt_dm_p, NewSize); } return(BiomassRemoved.dm_type.Length - 1); }
/// <summary>Called when [harvest].</summary> /// <param name="Harvest">The harvest.</param> /// <param name="BiomassRemoved">The biomass removed.</param> public abstract void OnHarvest(HarvestType Harvest, BiomassRemovedType BiomassRemoved);
virtual public void DoActualGrowth(double TT) { if (IsAppeared) { //Acellerate thermal time accumulation if crop is water stressed. double _ThermalTime; if ((DroughtInducedSenAcceleration != null) && (IsFullyExpanded)) { _ThermalTime = TT * DroughtInducedSenAcceleration.Value; } else { _ThermalTime = TT; } //Growing leaf area after DM allocated double DeltaCarbonConstrainedArea = (StructuralDMAllocation + MetabolicDMAllocation) * SpecificLeafAreaMax; //Fixme. Live.Nonstructural should probably be included in DM supply for leaf growth also double DeltaActualArea = Math.Min(DeltaWaterConstrainedArea, DeltaCarbonConstrainedArea); LiveArea += DeltaActualArea; /// Integrates leaf area at each cohort? FIXME-EIT is this the one integrated at leaf.cs? //Senessing leaf area double AreaSenescing = LiveArea * SenescedFrac; double AreaSenescingN = 0; if ((Live.MetabolicNConc <= MinimumNConc) & ((MetabolicNRetranslocated - MetabolicNAllocation) > 0.0)) { AreaSenescingN = LeafStartArea * (MetabolicNRetranslocated - MetabolicNAllocation) / LiveStart.MetabolicN; } double LeafAreaLoss = Math.Max(AreaSenescing, AreaSenescingN); if (LeafAreaLoss > 0) { SenescedFrac = Math.Min(1.0, LeafAreaLoss / LeafStartArea); } /* RFZ why variation between using LiveStart and Live * double StructuralWtSenescing = SenescedFrac * Live.StructuralWt; * double StructuralNSenescing = SenescedFrac * Live.StructuralN; * double MetabolicWtSenescing = SenescedFrac * Live.MetabolicWt; * double MetabolicNSenescing = SenescedFrac * LiveStart.MetabolicN; * double NonStructuralWtSenescing = SenescedFrac * Live.NonStructuralWt; * double NonStructuralNSenescing = SenescedFrac * LiveStart.NonStructuralN; */ double StructuralWtSenescing = SenescedFrac * LiveStart.StructuralWt; double StructuralNSenescing = SenescedFrac * LiveStart.StructuralN; double MetabolicWtSenescing = SenescedFrac * LiveStart.MetabolicWt; double MetabolicNSenescing = SenescedFrac * LiveStart.MetabolicN; double NonStructuralWtSenescing = SenescedFrac * LiveStart.NonStructuralWt; double NonStructuralNSenescing = SenescedFrac * LiveStart.NonStructuralN; DeadArea = DeadArea + LeafAreaLoss; LiveArea = LiveArea - LeafAreaLoss; // Final leaf area of cohort that will be integrated in Leaf.cs? (FIXME-EIT) Live.StructuralWt -= StructuralWtSenescing; Dead.StructuralWt += StructuralWtSenescing; Live.StructuralN -= StructuralNSenescing; Dead.StructuralN += StructuralNSenescing; Live.MetabolicWt -= Math.Max(0.0, MetabolicWtSenescing - MetabolicWtReallocated); Dead.MetabolicWt += Math.Max(0.0, MetabolicWtSenescing - MetabolicWtReallocated); Live.MetabolicN -= Math.Max(0.0, (MetabolicNSenescing - MetabolicNReallocated - MetabolicNRetranslocated)); //Don't Seness todays N if it has been taken for reallocation Dead.MetabolicN += Math.Max(0.0, (MetabolicNSenescing - MetabolicNReallocated - MetabolicNRetranslocated)); Live.NonStructuralN -= Math.Max(0.0, NonStructuralNSenescing - NonStructuralNReallocated - NonStructuralNRetrasnlocated); //Dont Senesess todays NonStructural N if it was retranslocated or reallocated Dead.NonStructuralN += Math.Max(0.0, NonStructuralNSenescing - NonStructuralNReallocated - NonStructuralNRetrasnlocated); Live.NonStructuralWt -= Math.Max(0.0, NonStructuralWtSenescing - DMRetranslocated); Live.NonStructuralWt = Math.Max(0.0, Live.NonStructuralWt); //RFZ //Reallocated gos to to reallocation pool but not into dead pool. Dead.NonStructuralWt += Math.Max(0.0, NonStructuralWtSenescing - DMRetranslocated - NonStructuralWtReallocated); Age = Age + _ThermalTime; // Do Detachment of this Leaf Cohort // --------------------------------- DetachedFrac = FractionDetaching(_ThermalTime); if (DetachedFrac > 0.0) { double DetachedArea = DeadArea * DetachedFrac; double DetachedWt = Dead.Wt * DetachedFrac; double DetachedN = Dead.N * DetachedFrac; DeadArea *= (1 - DetachedFrac); Dead.StructuralWt *= (1 - DetachedFrac); Dead.StructuralN *= (1 - DetachedFrac); Dead.NonStructuralWt *= (1 - DetachedFrac); Dead.NonStructuralN *= (1 - DetachedFrac); Dead.MetabolicWt *= (1 - DetachedFrac); Dead.MetabolicN *= (1 - DetachedFrac); BiomassRemovedType BiomassRemovedData = new BiomassRemovedType(); BiomassRemovedData.crop_type = Plant.CropType; BiomassRemovedData.dm_type = new string[1]; BiomassRemovedData.dlt_crop_dm = new float[1]; BiomassRemovedData.dlt_dm_n = new float[1]; BiomassRemovedData.dlt_dm_p = new float[1]; BiomassRemovedData.fraction_to_residue = new float[1]; BiomassRemovedData.dm_type[0] = "leaf"; BiomassRemovedData.dlt_crop_dm[0] = (float)DetachedWt * 10f; BiomassRemovedData.dlt_dm_n[0] = (float)DetachedN * 10f; BiomassRemovedData.dlt_dm_p[0] = 0f; BiomassRemovedData.fraction_to_residue[0] = 1f; BiomassRemoved.Invoke(BiomassRemovedData); } } }
/// <summary> /// Write a biomass removed report. /// </summary> void WriteBiomassRemovedReport(BiomassRemovedType Data) { double dm_residue = 0.0; double dm_root_residue = 0.0; double n_residue = 0.0; double n_root_residue = 0.0; double p_residue = 0.0; double p_root_residue = 0.0; double dm_chopped = 0.0; double dm_root_chopped = 0.0; double n_chopped = 0.0; double n_root_chopped = 0.0; double p_chopped = 0.0; double p_root_chopped = 0.0; for (int part = 0; part < Data.dm_type.Length; part++) { dm_chopped += Data.dlt_crop_dm[part]; n_chopped += Data.dlt_dm_n[part]; p_chopped += Data.dlt_dm_p[part]; dm_residue += Data.dlt_crop_dm[part] * Data.fraction_to_residue[part]; n_residue += Data.dlt_dm_n[part] * Data.fraction_to_residue[part]; p_residue += Data.dlt_dm_p[part] * Data.fraction_to_residue[part]; if (Data.dm_type[part] == "root") { dm_root_residue += Data.dlt_crop_dm[part] * Data.fraction_to_residue[part]; n_root_residue += Data.dlt_dm_n[part] * Data.fraction_to_residue[part]; p_root_residue += Data.dlt_dm_p[part] * Data.fraction_to_residue[part]; dm_root_chopped += Data.dlt_crop_dm[part]; n_root_chopped += Data.dlt_dm_n[part]; p_root_chopped += Data.dlt_dm_p[part]; } } double dm_tops_chopped = dm_chopped - dm_root_chopped; double n_tops_chopped = n_chopped - n_root_chopped; double p_tops_chopped = p_chopped - p_root_chopped; double dm_tops_residue = dm_residue - dm_root_residue; double n_tops_residue = n_residue - n_root_residue; double p_tops_residue = p_residue - p_root_residue; Console.WriteLine("\r\nCrop harvested."); Console.WriteLine(" Organic matter from crop:- Tops to surface residue Roots to soil FOM"); Console.WriteLine(string.Format(" DM (kg/ha) = {0,21:F1}{1,24:F1}", dm_tops_residue, dm_root_residue)); Console.WriteLine(string.Format(" N (kg/ha) = {0,22:F2}{1,24:F2}", n_tops_residue, n_root_residue)); //Console.WriteLine(string.Format("{0,48}{1,55:F1}{2,24:F1}", "P (kg/ha) = ", p_tops_residue, p_root_residue)); Console.WriteLine(""); double dm_removed_tops = dm_tops_chopped - dm_tops_residue; double dm_removed_root = dm_root_chopped - dm_root_residue; double n_removed_tops = n_tops_chopped - n_tops_residue; double n_removed_root = n_root_chopped - n_root_residue; double p_removed_tops = p_tops_chopped - p_tops_residue; double p_removed_root = p_root_chopped - p_root_residue; Console.WriteLine(" Organic matter removed from system:- From Tops From Roots"); Console.WriteLine(string.Format(" DM (kg/ha) = {0,21:F1}{1,24:F1}", dm_removed_tops, dm_removed_root)); Console.WriteLine(string.Format(" N (kg/ha) = {0,22:F2}{1,24:F2}", n_removed_tops, n_removed_root)); //Console.WriteLine(string.Format("{0,48}{1,55:F3}{2,24:F1}", "DM (kg/ha) = ", p_removed_tops, p_removed_root)); Console.WriteLine(""); }
private void OnDoPlantGrowth(object sender, EventArgs e) { DoWaterBalance(); DoGrowth(); DoNBalance(); // Now add today's growth to the soil - ie assume plants are in steady state. BiomassRemovedType BiomassRemovedData = new BiomassRemovedType(); BiomassRemovedData.crop_type = Crop_Type; BiomassRemovedData.dm_type = new string[1] { "litter" }; BiomassRemovedData.dlt_crop_dm = new float[1] { (float)(DltDM * 10) }; BiomassRemovedData.dlt_dm_n = new float[1] { (float)(NFixation + MathUtilities.Sum(NUptake)) }; BiomassRemovedData.dlt_dm_p = new float[1] { 0 }; BiomassRemovedData.fraction_to_residue = new float[1] { 1 }; BiomassRemoved.Invoke(BiomassRemovedData); }
/// <summary>Does the biomass removed.</summary> private void DoBiomassRemoved() { List<Biomass> Detaching = new List<Biomass>(); List<string> OrganNames = new List<string>(); foreach (Organ1 Organ in Organ1s) { if (Organ is AboveGround && !Organ.Detaching.IsEmpty) { Detaching.Add(Organ.Detaching); OrganNames.Add(Organ.Name); } } BiomassRemovedType chopped = new BiomassRemovedType(); chopped.crop_type = CropType; chopped.dm_type = new string[Detaching.Count]; chopped.dlt_crop_dm = new float[Detaching.Count]; chopped.dlt_dm_n = new float[Detaching.Count]; chopped.dlt_dm_p = new float[Detaching.Count]; chopped.fraction_to_residue = new float[Detaching.Count]; for (int i = 0; i < Detaching.Count; i++) { chopped.dm_type[i] = OrganNames[i]; chopped.dlt_crop_dm[i] = (float)Detaching[i].Wt; chopped.dlt_dm_n[i] = (float)Detaching[i].N; //chopped.dlt_dm_p[i] = (float) Detaching[i].P; chopped.fraction_to_residue[i] = 1.0f; } BiomassRemoved.Invoke(chopped); }
/// <summary>Event handler for the Harvest event - normally comes from Manager.</summary> /// <param name="Harvest">The harvest.</param> /// <exception cref="System.Exception"> /// Harvest remove fraction needs to be between 0 and 1 /// or /// Harvest height needs to be between 0 and 1000 /// </exception> public void OnHarvest(HarvestType Harvest) { WriteHarvestReport(); // Tell the rest of the system we are about to harvest if (Harvesting != null) Harvesting.Invoke(this, new EventArgs()); // Check some bounds if (Harvest.Remove < 0 || Harvest.Remove > 1.0) throw new Exception("Harvest remove fraction needs to be between 0 and 1"); if (Harvest.Height < 0 || Harvest.Height > 1000.0) throw new Exception("Harvest height needs to be between 0 and 1000"); // Set the population denisty if one was provided by user. if (Harvest.Plants != 0) Population.Density = Harvest.Plants; // Call each organ's OnHarvest. They fill a BiomassRemoved structure. We then publish a // BiomassRemoved event. BiomassRemovedType BiomassRemovedData = new BiomassRemovedType(); foreach (Organ1 Organ in Organ1s) Organ.OnHarvest(Harvest, BiomassRemovedData); BiomassRemovedData.crop_type = CropType; BiomassRemoved.Invoke(BiomassRemovedData); WriteBiomassRemovedReport(BiomassRemovedData); // now update new canopy covers PlantSpatial.Density = Population.Density; PlantSpatial.CanopyWidth = Leaf.width; foreach (Organ1 Organ in Organ1s) Organ.DoCover(); foreach (Organ1 Organ in Organ1s) Organ.DoNConccentrationLimits(); foreach (Organ1 Organ in Organ1s) Organ.OnHarvest(Harvest, BiomassRemovedData); }
/// <summary>Does the development.</summary> private void DoDevelopment() { Age = Age + 1.0 / 365.0; //for (int i = 0; i < Frond.Length; i++) // Frond[i].Age += 1; foreach (FrondType F in Fronds) { F.Age += DeltaT; //F.Area = SizeFunction(F.Age); } if (Fronds[Fronds.Count - 1].Age >= FrondAppearanceRate.Value) { FrondType F = new FrondType(); Fronds.Add(F); CumulativeFrondNumber += 1; BunchType B = new BunchType(); B.FemaleFraction = FemaleFlowerFraction.Value; Bunches.Add(B); } //if (Fronds[0].Age >= (40 * FrondAppRate.Value)) if (FrondNumber > Math.Round(HarvestFrondNumber.Value)) { HarvestBunches = Bunches[0].FemaleFraction; double HarvestYield = Bunches[0].Mass * Population / (1.0 - RipeBunchWaterContent.Value); HarvestFFB = HarvestYield / 100; HarvestNRemoved = Bunches[0].N * Population * 10; HarvestBunchSize = Bunches[0].Mass / (1.0 - RipeBunchWaterContent.Value) / Bunches[0].FemaleFraction; if (Harvesting != null) Harvesting.Invoke(this, new EventArgs()); // Now rezero these outputs - they can only be output non-zero on harvesting event. HarvestBunches = 0.0; HarvestYield = 0.0; HarvestFFB = 0.0; HarvestBunchSize = 0.0; HarvestNRemoved = 0.0; CumulativeBunchNumber += Bunches[0].FemaleFraction; Bunches.RemoveAt(0); BiomassRemovedType BiomassRemovedData = new BiomassRemovedType(); BiomassRemovedData.crop_type = CanopyType; BiomassRemovedData.dm_type = new string[1] { "frond" }; BiomassRemovedData.dlt_crop_dm = new float[1] { (float)(Fronds[0].Mass * Population * 10) }; BiomassRemovedData.dlt_dm_n = new float[1] { (float)(Fronds[0].N * Population * 10) }; BiomassRemovedData.dlt_dm_p = new float[1] { 0 }; BiomassRemovedData.fraction_to_residue = new float[1] { 1 }; Fronds.RemoveAt(0); BiomassRemoved.Invoke(BiomassRemovedData); } }
/// <summary>Called when [end crop].</summary> /// <param name="BiomassRemoved">The biomass removed.</param> public abstract void OnEndCrop(BiomassRemovedType BiomassRemoved);
/// <summary>Called when [end crop].</summary> /// <param name="BiomassRemoved">The biomass removed.</param> public override void OnEndCrop(BiomassRemovedType BiomassRemoved) { int i = Util.IncreaseSizeOfBiomassRemoved(BiomassRemoved); BiomassRemoved.dm_type[i] = Name; BiomassRemoved.fraction_to_residue[i] = 1.0F; BiomassRemoved.dlt_crop_dm[i] = (float)((Live.Wt + Dead.Wt) * Conversions.gm2kg / Conversions.sm2ha); BiomassRemoved.dlt_dm_n[i] = (float)((Live.N + Dead.N) * Conversions.gm2kg / Conversions.sm2ha); //BiomassRemoved.dlt_dm_p[i] = (float)((Green.P + Senesced.P) * Conversions.gm2kg / Conversions.sm2ha); Dead.Clear(); Live.Clear(); PotentialEP = 0.0; sw_demand = 0; sw_demand_te = 0; NodeNo = 0; Util.ZeroArray(LeafNo); Util.ZeroArray(LeafNoSen); Util.ZeroArray(LeafArea); _LAI = 0.0; _SLAI = 0.0; maxLAI = 0.0; }
/// <summary>Called when [harvest].</summary> /// <param name="Harvest">The harvest.</param> /// <param name="BiomassRemoved">The biomass removed.</param> public override void OnHarvest(HarvestType Harvest, BiomassRemovedType BiomassRemoved) { Biomass Dead; Dead = Live * DieBackFraction; // however dead roots have a given N concentration Dead.StructuralN = Dead.Wt * NSenescenceConcentration; Live = Live - Dead; Dead = Dead + Dead; int i = Util.IncreaseSizeOfBiomassRemoved(BiomassRemoved); // Unlike above ground parts, no roots go to surface residue module. BiomassRemoved.dm_type[i] = Name; BiomassRemoved.fraction_to_residue[i] = 0.0F; BiomassRemoved.dlt_crop_dm[i] = 0.0F; BiomassRemoved.dlt_dm_n[i] = 0.0F; BiomassRemoved.dlt_dm_p[i] = 0.0F; }
/// <summary>Called when [end crop].</summary> /// <param name="BiomassRemoved">The biomass removed.</param> public override void OnEndCrop(BiomassRemovedType BiomassRemoved) { DisposeDetachedMaterial(Live, RootLength); DisposeDetachedMaterial(Dead, RootLengthSenesced); Dead.Clear(); Live.Clear(); OnPrepare(null, null); }
/// <summary>Does the understory.</summary> private void DoUnderstory() { DoUnderstoryWaterBalance(); DoUnderstoryGrowth(); DoUnderstoryNBalance(); // Now add today's growth to the soil - ie assume plants are in steady state. BiomassRemovedType BiomassRemovedData = new BiomassRemovedType(); BiomassRemovedData.crop_type = "OilPalmUnderstory"; BiomassRemovedData.dm_type = new string[1] { "litter" }; BiomassRemovedData.dlt_crop_dm = new float[1] { (float)(UnderstoryDltDM * 10) }; BiomassRemovedData.dlt_dm_n = new float[1] { (float)(UnderstoryNFixation + MathUtilities.Sum(UnderstoryNUptake)) }; BiomassRemovedData.dlt_dm_p = new float[1] { 0 }; BiomassRemovedData.fraction_to_residue = new float[1] { 1 }; BiomassRemoved.Invoke(BiomassRemovedData); }
/// <summary>Called when [harvest].</summary> /// <param name="Harvest">The harvest.</param> /// <param name="BiomassRemoved">The biomass removed.</param> public override void OnHarvest(HarvestType Harvest, BiomassRemovedType BiomassRemoved) { // Some biomass is removed according to harvest height FractionHeightRemoved = MathUtilities.Divide(Harvest.Height, Height, 0.0); double chop_fr_green = (1.0 - RetainFraction.Value); double chop_fr_sen = (1.0 - RetainFraction.Value); double dlt_dm_harvest = Live.Wt * chop_fr_green + Dead.Wt * chop_fr_sen; double dlt_n_harvest = Live.N * chop_fr_green + Dead.N * chop_fr_sen; //double dlt_p_harvest = Green.P * chop_fr_green // + Senesced.P * chop_fr_sen; Dead = Dead * RetainFraction.Value; Live = Live * RetainFraction.Value; Height = MathUtilities.Constrain(Harvest.Height, 1.0, double.MaxValue); int i = Util.IncreaseSizeOfBiomassRemoved(BiomassRemoved); BiomassRemoved.dm_type[i] = Name; BiomassRemoved.fraction_to_residue[i] = (float)(1.0 - Harvest.Remove); BiomassRemoved.dlt_crop_dm[i] = (float)(dlt_dm_harvest * Conversions.gm2kg / Conversions.sm2ha); BiomassRemoved.dlt_dm_n[i] = (float)(dlt_n_harvest * Conversions.gm2kg / Conversions.sm2ha); //BiomassRemoved.dlt_dm_p[i] = (float)(dlt_p_harvest * Conversions.gm2kg / Conversions.sm2ha); }
private void DoDevelopment() { Age = Age + 1.0 / 365.0; //for (int i = 0; i < Frond.Length; i++) // Frond[i].Age += 1; foreach (FrondType F in Fronds) { F.Age += DeltaT; //F.Area = SizeFunction(F.Age); } if (Fronds[Fronds.Count - 1].Age >= FrondAppRate.Value) { FrondType F = new FrondType(); Fronds.Add(F); CumulativeFrondNumber += 1; BunchType B = new BunchType(); B.FemaleFraction = FemaleFlowerFraction.Value; Bunches.Add(B); } //if (Fronds[0].Age >= (40 * FrondAppRate.Value)) if (FrondNumber > Math.Round(HarvestFrondNumber.Value)) { HarvestBunches = Bunches[0].FemaleFraction; HarvestYield = Bunches[0].Mass * Population / (1.0 - RipeBunchWaterContent.Value); HarvestFFB = HarvestYield / 100; HarvestNRemoved = Bunches[0].N * Population * 10; HarvestBunchSize = Bunches[0].Mass / (1.0 - RipeBunchWaterContent.Value) / Bunches[0].FemaleFraction; if (Harvesting != null) { Harvesting.Invoke(); } // Now rezero these outputs - they can only be output non-zero on harvesting event. HarvestBunches = 0.0; HarvestYield = 0.0; HarvestFFB = 0.0; HarvestBunchSize = 0.0; HarvestNRemoved = 0.0; CumulativeBunchNumber += Bunches[0].FemaleFraction; CumulativeYield += Bunches[0].Mass * Population / (1.0 - RipeBunchWaterContent.Value); Bunches.RemoveAt(0); BiomassRemovedType BiomassRemovedData = new BiomassRemovedType(); BiomassRemovedData.crop_type = Crop_Type; BiomassRemovedData.dm_type = new string[1] { "frond" }; BiomassRemovedData.dlt_crop_dm = new float[1] { (float)(Fronds[0].Mass * Population * 10) }; BiomassRemovedData.dlt_dm_n = new float[1] { (float)(Fronds[0].N * Population * 10) }; BiomassRemovedData.dlt_dm_p = new float[1] { 0 }; BiomassRemovedData.fraction_to_residue = new float[1] { 1 }; Fronds.RemoveAt(0); BiomassRemoved.Invoke(BiomassRemovedData); } }
/// <summary>Called when [harvest].</summary> /// <param name="Harvest">The harvest.</param> /// <param name="BiomassRemoved">The biomass removed.</param> public override void OnHarvest(HarvestType Harvest, BiomassRemovedType BiomassRemoved) { double dm_init = MathUtilities.Constrain(InitialWt * Population.Density, double.MinValue, Live.Wt); double n_init = MathUtilities.Constrain(dm_init * InitialNConcentration, double.MinValue, Live.N); //double p_init = MathUtilities.Constrain(dm_init * SimplePart::c.p_init_conc, double.MinValue, Green.P); double retain_fr_green = MathUtilities.Divide(dm_init, Live.Wt, 0.0); double retain_fr_sen = 0.0; double dlt_dm_harvest = Live.Wt + Dead.Wt - dm_init; double dlt_n_harvest = Live.N + Dead.N - n_init; //double dlt_p_harvest = Green.P + Senesced.P - p_init; Dead = Dead * retain_fr_sen; Live.StructuralWt = Live.Wt * retain_fr_green; Live.StructuralN = n_init; //Green.P = p_init; int i = Util.IncreaseSizeOfBiomassRemoved(BiomassRemoved); BiomassRemoved.dm_type[i] = Name; BiomassRemoved.fraction_to_residue[i] = (float)(1.0 - Harvest.Remove); BiomassRemoved.dlt_crop_dm[i] = (float)(dlt_dm_harvest * Conversions.gm2kg / Conversions.sm2ha); BiomassRemoved.dlt_dm_n[i] = (float)(dlt_n_harvest * Conversions.gm2kg / Conversions.sm2ha); //BiomassRemoved.dlt_dm_p[i] = (float)(dlt_p_harvest * Conversions.gm2kg / Conversions.sm2ha); InitialiseAreas(); }
/// <summary>Write a biomass removed report.</summary> /// <param name="Data">The data.</param> void WriteBiomassRemovedReport(BiomassRemovedType Data) { double dm_residue = 0.0; double dm_root_residue = 0.0; double n_residue = 0.0; double n_root_residue = 0.0; double p_residue = 0.0; double p_root_residue = 0.0; double dm_chopped = 0.0; double dm_root_chopped = 0.0; double n_chopped = 0.0; double n_root_chopped = 0.0; double p_chopped = 0.0; double p_root_chopped = 0.0; for (int part = 0; part < Data.dm_type.Length; part++) { dm_chopped += Data.dlt_crop_dm[part]; n_chopped += Data.dlt_dm_n[part]; p_chopped += Data.dlt_dm_p[part]; dm_residue += Data.dlt_crop_dm[part] * Data.fraction_to_residue[part]; n_residue += Data.dlt_dm_n[part] * Data.fraction_to_residue[part]; p_residue += Data.dlt_dm_p[part] * Data.fraction_to_residue[part]; if (Data.dm_type[part] == "root") { dm_root_residue += Data.dlt_crop_dm[part] * Data.fraction_to_residue[part]; n_root_residue += Data.dlt_dm_n[part] * Data.fraction_to_residue[part]; p_root_residue += Data.dlt_dm_p[part] * Data.fraction_to_residue[part]; dm_root_chopped += Data.dlt_crop_dm[part]; n_root_chopped += Data.dlt_dm_n[part]; p_root_chopped += Data.dlt_dm_p[part]; } } double dm_tops_chopped = dm_chopped - dm_root_chopped; double n_tops_chopped = n_chopped - n_root_chopped; double p_tops_chopped = p_chopped - p_root_chopped; double dm_tops_residue = dm_residue - dm_root_residue; double n_tops_residue = n_residue - n_root_residue; double p_tops_residue = p_residue - p_root_residue; Summary.WriteMessage(this, "Crop harvested."); Summary.WriteMessage(this, "Organic matter from crop:- Tops to surface residue Roots to soil FOM"); Summary.WriteMessage(this, string.Format(" DM (kg/ha) = {0,21:F1}{1,24:F1}", dm_tops_residue, dm_root_residue)); Summary.WriteMessage(this, string.Format(" N (kg/ha) = {0,22:F2}{1,24:F2}", n_tops_residue, n_root_residue)); double dm_removed_tops = dm_tops_chopped - dm_tops_residue; double dm_removed_root = dm_root_chopped - dm_root_residue; double n_removed_tops = n_tops_chopped - n_tops_residue; double n_removed_root = n_root_chopped - n_root_residue; double p_removed_tops = p_tops_chopped - p_tops_residue; double p_removed_root = p_root_chopped - p_root_residue; Summary.WriteMessage(this, " Organic matter removed from system:- From Tops From Roots"); Summary.WriteMessage(this, string.Format(" DM (kg/ha) = {0,21:F1}{1,24:F1}", dm_removed_tops, dm_removed_root)); Summary.WriteMessage(this, string.Format(" N (kg/ha) = {0,22:F2}{1,24:F2}", n_removed_tops, n_removed_root)); }
/// <summary>Called when [end crop].</summary> public void OnEndCrop() { NewCropType Crop = new NewCropType(); Crop.crop_type = CropType; Crop.sender = Name; if (CropEnding != null) CropEnding.Invoke(Crop); if (PlantEnding != null) PlantEnding.Invoke(this, new ModelArgs() { Model = this }); // Keep track of some variables for reporting. Biomass AboveGroundBiomass = new Biomass(AboveGround); Biomass BelowGroundBiomass = new Biomass(BelowGround); // Call each organ's OnHarvest. They fill a BiomassRemoved structure. We then publish a // BiomassRemoved event. BiomassRemovedType BiomassRemovedData = new BiomassRemovedType(); foreach (Organ1 Organ in Organ1s) Organ.OnEndCrop(BiomassRemovedData); BiomassRemovedData.crop_type = CropType; BiomassRemoved.Invoke(BiomassRemovedData); string message = string.Format("Organic matter from crop to surface organic matter:-\r\n" + " DM tops (kg/ha) = {0,10:F1}\r\n" + " DM roots (kg/ha) = {1,10:F1}\r\n" + " N tops (kg/ha) = {0,10:F2}\r\n" + " N roots (lh/ha) = {1,10:F2}", AboveGroundBiomass.Wt, BelowGroundBiomass.Wt, AboveGroundBiomass.N, BelowGroundBiomass.N); Summary.WriteMessage(this, message); cultivarDefinition.Unapply(); SowingData = null; }