///<summary>Check if the crop has reached a specified Haun stage</summary> ///<param name="stg">Haun stage to check for</param> ///<returns>return true if the crop has reached the specified Haun stage, false if not</returns> /* private bool HasReachedHaun(double stg) * { * var ret = false; * //pm, 17/04/09: the line below based the Zadocks stages on final leaf number and not on current leaf number, have added the next line * // if (Phytomers_.FinalLeafNumber >= stg) * if (LeafNumber >= stg) * ret = true; * * return ret; * }*/ #endregion #region Grow // #Andrea 26/11/2015 - added double double deltaTTRemobilization, deltaTTSenescence, double canopyTmin, double canopyTmax ///<summary>Ask to the crop compartments to modify their states depending to the current crop phase</summary> public double Grow(double radTopAtm, double[] cumulTT, double deltaTTShoot, double deltaTTPhenoMaize, double deltaTTRemobilization, double deltaTTSenescence, double canopyTmin, double canopyTmax, double rad, double PAR, double DBF, double soilDepth, double DEBF, double DGF, double dayLength, double FPAW, double VPDairCanopy, double[] deltaTTCanopyHourly, double[] VPDeq) { ///<Behnam (2015.10.28)> shoot.isUnlimitedWater = isUnlimitedWater; shoot.isUnlimitedNitrogen = isUnlimitedNitrogen; shoot.isUnlimitedTemperature = isUnlimitedTemperature; root.isUnlimitedWater = isUnlimitedWater; root.isUnlimitedNitrogen = isUnlimitedNitrogen; root.isUnlimitedTemperature = isUnlimitedTemperature; ///</Behnam> phenology_.EstimatePhenology(dayLength, deltaTTShoot, cumulTT, shoot.GrainCumulTT, GAI, shoot.getIsLatestLeafInternodeLengthPotPositive()); var oldCropTotalN = CropTotalN; //Quantity of Ni to remove from soil double soilNDec = 0; //excess dry matter after phytomers and stem growth double excessDM; if (phenology_.getPhaseValue() >= 0 && phenology_.getPhaseValue() < 1) { if (areRootsToBeGrown) { root.Grow(soilDepth, cumulTT[(int)Delta.Air]); } // #Andrea 13/01/2016 - Root growth based on Soil temperature //root.Grow(soilDepth, cumulTT[(int)Delta.Soil]); } else if (phenology_.getPhaseValue() >= 1 && phenology_.getPhaseValue() < 4) { // #Andrea 13/01/2016 - Root growth based on Soil temperature if (areRootsToBeGrown) { root.Grow(soilDepth, cumulTT[(int)Delta.Air]); } //root.Grow(soilDepth, cumulTT[(int)Delta.Soil]); double availableNfromSoilAfter; shoot.Grow(radTopAtm, cumulTT, deltaTTShoot, deltaTTSenescence, canopyTmin, canopyTmax, rad, PAR, RoundedFinalLeafNumber, phenology_.FinalLeafNumber, DBF, LeafNumber, IsBeforeEndGrainCellDivision(cumulTT, phenology_.previousCalendar), root.availableNfromSoil, out availableNfromSoilAfter, phenology_.BeforeUpdateLeafNumber, phenology_.Phyllochron, FPAW, ref VirtualNReq, VPDairCanopy, LER, (phenology_.calendar.IsMomentRegistred(GrowthStage.ZC_75_EndCellDivision) == 1)?true:false, phenology_.tilleringProfile, phenology_.leafTillerNumberArray, deltaTTPhenoMaize, phenology_.cumulTTPhenoMaizeAtEmergence, cumulTT[(int)Delta.PhenoMaize], DailyCO2, deltaTTCanopyHourly, VPDeq, out excessDM); ///</Behnam> /// Behnam (2016.02.15): On Anaelle's request. AccumPAR += shoot.TotalPAR; soilNDec = root.availableNfromSoil - availableNfromSoilAfter; root.availableNfromSoil = availableNfromSoilAfter;//not technically useful to update root.availableNfromSoil because it is not used after but we do it anyway to avoid confusion shoot.useSenescencePool(); // calculate ear dry weight if (HasReachedFlagLeaf(1)) { grainEarDW_.UpdateEarDW(shoot.DeltaShootDM, DEBF); } } else if (phenology_.getPhaseValue() == 4 || phenology_.getPhaseValue() == 4.5) { //AnthesisToEndCellDivision,EndCellDivisionToEndGrainFill if (phenology_.getPhaseValue() == 4.5 && switchEndCD) { nniEndCD = shoot.CalculateNNI(); switchEndCD = false; } if (phenology_.getPhaseValue() == 4 && switchAnthesis) //AnthesisToEndCellDivision { shoot.InitAtAnthesis(grainEarDW_.EarDW); switchAnthesis = false; } double availableNfromSoilAfter; shoot.Grow(radTopAtm, cumulTT, deltaTTShoot, deltaTTSenescence, canopyTmin, canopyTmax, rad, PAR, RoundedFinalLeafNumber, phenology_.FinalLeafNumber, DBF, LeafNumber, IsBeforeEndGrainCellDivision(cumulTT, phenology_.previousCalendar), root.availableNfromSoil, out availableNfromSoilAfter, phenology_.BeforeUpdateLeafNumber, phenology_.Phyllochron, FPAW, ref VirtualNReq, VPDairCanopy, LER, (phenology_.calendar.IsMomentRegistred(GrowthStage.ZC_75_EndCellDivision) == 1)?true:false, phenology_.tilleringProfile, phenology_.leafTillerNumberArray, deltaTTPhenoMaize, phenology_.cumulTTPhenoMaizeAtEmergence, cumulTT[(int)Delta.PhenoMaize], DailyCO2, deltaTTCanopyHourly, VPDeq, out excessDM); AccumPAR += shoot.TotalPAR; soilNDec = root.availableNfromSoil - availableNfromSoilAfter; root.availableNfromSoil = availableNfromSoilAfter;//not technically useful to update root.availableNfromSoil because it is not used after but we do it anyway to avoid confusion shoot.GrowGrain(IsBeforeEndGrainCellDivision(cumulTT, phenology_.previousCalendar), deltaTTShoot, deltaTTRemobilization, DGF, excessDM); shoot.useSenescencePool(); PostAnthesisNUptake += CropTotalN - oldCropTotalN; } else if (phenology_.getPhaseValue() >= 5 && phenology_.getPhaseValue() < 7)//EndGrainFillToMaturity,AllOver { PostAnthesisNUptake += CropTotalN - oldCropTotalN; } else if (phenology_.getPhaseValue() < 0) { throw new Exception("is running but the crop phase is BEFORE_SOWING"); } else { throw new Exception("current phase is unknown"); } return(soilNDec); }