/// <summary>Document the model.</summary> public override IEnumerable <ITag> Document() { // Write description of this class. yield return(new Paragraph($"This phase goes from {Start.ToLower()} to {End.ToLower()} and simulates time to {End.ToLower()} as a function of sowing depth. The *ThermalTime Target* for ending this phase is given by:")); yield return(new Paragraph($"*Target* = *SowingDepth* x *ShootRate* + *ShootLag*")); yield return(new Paragraph($"Where:")); yield return(new Paragraph($"*ShootRate* = {ShootRate} (deg day/mm),")); yield return(new Paragraph($"*ShootLag* = {ShootLag} (deg day), ")); yield return(new Paragraph($"*SowingDepth* (mm) is sent from the manager with the sowing event.")); // Write memos. foreach (var tag in DocumentChildren <Memo>()) { yield return(tag); } IFunction thermalTime = FindChild <IFunction>("ThermalTime"); yield return(new Paragraph($"Progress toward emergence is driven by thermal time accumulation{(thermalTime == null ? "" : ", where thermal time is calculated as:")}")); if (thermalTime != null) { foreach (var tag in thermalTime.Document()) { yield return(tag); } } }
/// <summary> /// Document the model. /// </summary> public override IEnumerable <ITag> Document() { if (ChildFunctions == null) { ChildFunctions = FindAllChildren <IFunction>(); } foreach (IFunction child in ChildFunctions) { if (child != Lower && child != Upper) { yield return(new Paragraph($"{Name} is the value of {child.Name} bound between a lower and upper bound where:")); foreach (ITag tag in child.Document()) { yield return(tag); } break; } } if (Lower != null) { foreach (ITag tag in Lower.Document()) { yield return(tag); } } if (Upper != null) { foreach (ITag tag in Upper.Document()) { yield return(tag); } } }
/// <summary>Writes documentation for this function by adding to the list of documentation tags.</summary> public override IEnumerable <ITag> Document() { // Write description of this class. yield return(new Paragraph($"This phase goes from {Start.ToLower()} to {End.ToLower()}.")); // Write memos foreach (var tag in DocumentChildren <Memo>()) { yield return(tag); } yield return(new Paragraph($"The *Target* for completion is calculated as:")); // Write target foreach (var tag in target.Document()) { yield return(tag); } yield return(new Paragraph($"*Progression* through phase is calculated daily and accumulated until the *Target* is reached.")); // Write progression foreach (var tag in progression.Document()) { yield return(tag); } }
/// <summary> /// Document the model. /// </summary> /// <returns></returns> public override IEnumerable <ITag> Document() { yield return(new Paragraph($"Each time {SetStage} occurs, bud number on each main-stem is set to:")); yield return(new Paragraph($"*{FractionOfBudBurst.Name}* * *SowingData.BudNumber* (from manager at establishment)")); yield return(new Section(FractionOfBudBurst.Name, FractionOfBudBurst.Document())); }
private IEnumerable <ITag> DocumentNSupply() { if (nReallocationFactor is Constant nReallocConst) { if (nReallocConst.Value() == 0) { yield return(new Paragraph($"{Name} does not reallocate N when senescence of the organ occurs.")); } else { yield return(new Paragraph($"{Name} will reallocate {nReallocConst.Value() * 100}% of N that senesces each day.")); } } else { yield return(new Paragraph("The proportion of senescing N that is allocated each day is quantified by the NReallocationFactor.")); foreach (ITag tag in nReallocationFactor.Document()) { yield return(tag); } } IModel nRetransFactor = FindChild("NRetranslocationFactor"); if (nRetransFactor != null) { if (nRetransFactor is Constant nRetransConst) { if (nRetransConst.Value() == 0) { yield return(new Paragraph($"{Name} does not retranslocate non-structural N.")); } else { yield return(new Paragraph($"{Name} will retranslocate {nRetransConst.Value() * 100}% of non-structural N each day.")); } } else { yield return(new Paragraph("The proportion of non-structural N that is allocated each day is quantified by the NReallocationFactor.")); foreach (ITag tag in nRetransFactor.Document()) { yield return(tag); } } } }
/// <summary> /// Document the model. /// </summary> public override IEnumerable <ITag> Document() { yield return(new Paragraph($"If {PropertyName} = {StringValue} Then")); foreach (ITag tag in TrueValue.Document()) { yield return(tag); } yield return(new Paragraph("Else")); foreach (ITag tag in FalseValue.Document()) { yield return(tag); } }
/// <summary>Document this model.</summary> public override IEnumerable <ITag> Document() { yield return(new Paragraph("The structure model simulates morphological development of the plant to inform the Leaf class when and how many leaves and branches appear and provides an estimate of height.")); yield return(new Section("Plant and Main-Stem Population", new Paragraph( $"The *Plant.Population* is set at sowing with information sent from a manager script in the Sow method. " + $"The *PrimaryBudNumber* is also sent with the Sow method. The main-stem population (*MainStemPopn*) for {Parent.Name} is calculated as:\n\n" + $"*MainStemPopn* = *Plant.Population* x *PrimaryBudNumber*\n\n" + $"Primary bud number is > 1 for crops like potato and grape vine where there are more than one main-stem per plant" ))); var tags = new List <ITag>(); tags.Add(new Paragraph("Each day the number of main-stem leaf tips appeared (*LeafTipsAppeared*) is calculated as:")); tags.Add(new Paragraph("*LeafTipsAppeared* += *DeltaTips*")); tags.Add(new Paragraph("Where *DeltaTips* is calculated as:")); tags.Add(new Paragraph("*DeltaTips* = *ThermalTime* / *Phyllochron*")); tags.Add(new Paragraph("Where *Phyllochron* is the thermal time duration between the appearance of leaf tips given by:")); tags.AddRange(phyllochron.Document()); tags.Add(new Paragraph("*ThermalTime* is given by")); tags.AddRange(thermalTime.Document()); tags.Add(new Paragraph("*LeafTipsAppeared* continues to increase until *FinalLeafNumber* is reached where *FinalLeafNumber* is calculated as:")); tags.AddRange(finalLeafNumber.Document()); yield return(new Section("Main-Stem leaf appearance", tags)); var branchingTags = new List <ITag>(); branchingTags.Add(new Paragraph("The total population of stems (*TotalStemPopn*) is calculated as:")); branchingTags.Add(new Paragraph("*TotalStemPopn* = *MainStemPopn* + *NewBranches* - *NewlyDeadBranches*")); branchingTags.Add(new Paragraph("Where:")); branchingTags.Add(new Paragraph("*NewBranches* = *MainStemPopn* x *BranchingRate*")); branchingTags.Add(new Paragraph("*BranchingRate* is given by:")); branchingTags.AddRange(branchingRate.Document()); branchingTags.Add(new Paragraph("*NewlyDeadBranches* is calcualted as:")); branchingTags.Add(new Paragraph("*NewlyDeadBranches* = (*TotalStemPopn* - *MainStemPopn*) x *BranchMortality*")); branchingTags.Add(new Paragraph("where *BranchMortality* is given by:")); branchingTags.AddRange(branchMortality.Document()); yield return(new Section("Branching and Branch Mortality", branchingTags)); var heightTags = new List <ITag>(); heightTags.Add(new Paragraph("The height of the crop is calculated by the *HeightModel*")); heightTags.AddRange(heightModel.Document()); yield return(new Section("Height", heightTags)); }
/// <summary> /// Document the model. /// </summary> /// <returns></returns> public override IEnumerable <ITag> Document() { foreach (ITag tag in DocumentChildren <Memo>()) { yield return(tag); } List <ITag> initialisationTags = new List <ITag>(); initialisationTags.Add(new Paragraph("The initialisation of Carbon and Nutrient contents of this pool is described as follows:")); initialisationTags.AddRange(InitialCarbon.Document()); initialisationTags.AddRange(InitialNitrogen.Document()); // todo: include initial P in docs once soil P is released. // initialisationTags.AddRange(InitialPhosphorus.Document()); yield return(new Section("Initialisation", initialisationTags)); yield return(new Section("Organic Matter Flows", DocumentChildren <CarbonFlow>(true))); }
private IEnumerable <ITag> DocumentDMSupply() { if (dmReallocationFactor is Constant dmReallocConst) { if (dmReallocConst.Value() == 0) { yield return(new Paragraph($"{Name} does not reallocate DM when senescence of the organ occurs.")); } else { yield return(new Paragraph($"{Name} will reallocate {dmReallocConst.Value() * 100}% of DM that senesces each day.")); } } else { yield return(new Paragraph("The proportion of senescing DM that is allocated each day is quantified by the DMReallocationFactor.")); foreach (ITag tag in dmReallocationFactor.Document()) { yield return(tag); } } if (dmRetranslocationFactor is Constant dmRetransConst) { if (dmRetransConst.Value() == 0) { yield return(new Paragraph($"{Name} does not retranslocate non-structural DM.")); } else { yield return(new Paragraph($"{Name} will retranslocate {dmRetransConst.Value() * 100}% of non-structural DM each day.")); } } else { yield return(new Paragraph("The proportion of non-structural DM that is allocated each day is quantified by the DMReallocationFactor.")); foreach (ITag tag in dmRetranslocationFactor.Document()) { yield return(tag); } } }
private IEnumerable <ITag> DocumentSenescenceRate() { if (senescenceRate is Constant senescenceConst) { if (senescenceConst.Value() == 0) { yield return(new Paragraph($"{Name} has senescence parameterised to zero so all biomass in this organ will remain alive.")); } else { yield return(new Paragraph($"{Name} senesces {senescenceConst.Value() * 100}% of its live biomass each day, moving the corresponding amount of biomass from the live to the dead biomass pool.")); } } else { yield return(new Paragraph("The proportion of live biomass that senesces and moves into the dead pool each day is quantified by the SenescenceRate.")); foreach (ITag tag in senescenceRate.Document()) { yield return(tag); } } if (detachmentRateFunction is Constant detachmentConst) { if (detachmentConst.Value() == 0) { yield return(new Paragraph($"{Name} has detachment parameterised to zero so all biomass in this organ will remain with the plant until a defoliation or harvest event occurs.")); } else { yield return(new Paragraph($"{Name} detaches {detachmentConst.Value() * 100}% of its live biomass each day, passing it to the surface organic matter model for decomposition.")); } } else { yield return(new Paragraph("The proportion of Biomass that detaches and is passed to the surface organic matter model for decomposition is quantified by the DetachmentRateFunction.")); foreach (ITag tag in detachmentRateFunction.Document()) { yield return(tag); } } }
/// <summary> /// Document the model. /// </summary> public override IEnumerable <ITag> Document() { if (PreEventValue != null) { yield return(new Paragraph($"Before {SetEvent}")); foreach (ITag tag in PreEventValue.Document()) { yield return(tag); } } if (PostEventValue != null) { yield return(new Paragraph($"On {SetEvent} the value is set to:")); foreach (ITag tag in PostEventValue.Document()) { yield return(tag); } } }
/// <summary> /// Document the model. /// </summary> public override IEnumerable <ITag> Document() { yield return(new Paragraph($"{Name} is calcualted using a sigmoid function of the form y = Ymax * 1 / 1 + e^-(Xvalue - Xo) / b^.")); // Document Ymax. yield return(new Paragraph($"{nameof(Ymax)} is calculated as:")); foreach (ITag tag in Ymax.Document()) { yield return(tag); } // Document x0. yield return(new Paragraph($"{nameof(Xo)} is calculated as:")); foreach (ITag tag in Xo.Document()) { yield return(tag); } // Document b. yield return(new Paragraph($"{nameof(b)} is calculated as:")); foreach (ITag tag in b.Document()) { yield return(tag); } // Document x value. yield return(new Paragraph($"{nameof(XValue)} is calculated as:")); foreach (ITag tag in XValue.Document()) { yield return(tag); } }
/// <summary>Writes documentation for this function by adding to the list of documentation tags.</summary> public override IEnumerable <ITag> Document() { // Write description of this class from summary and remarks XML documentation. foreach (var tag in GetModelDescription()) { yield return(tag); } // Write memos. foreach (var tag in DocumentChildren <Memo>()) { yield return(tag); } // Document thermal time function. yield return(new Section("ThermalTime", thermalTime.Document())); // Write a table containing phase numers and start/end stages. yield return(new Paragraph("**List of stages and phases used in the simulation of crop phenological development**")); DataTable phaseTable = new DataTable(); phaseTable.Columns.Add("Phase Number", typeof(int)); phaseTable.Columns.Add("Phase Name", typeof(string)); phaseTable.Columns.Add("Initial Stage", typeof(string)); phaseTable.Columns.Add("Final Stage", typeof(string)); int n = 1; foreach (IPhase child in FindAllChildren <IPhase>()) { DataRow row = phaseTable.NewRow(); row[0] = n; row[1] = child.Name; row[2] = (child as IPhase).Start; row[3] = (child as IPhase).End; phaseTable.Rows.Add(row); n++; } yield return(new Table(phaseTable)); // Document Phases foreach (var phase in FindAllChildren <IPhase>()) { yield return(new Section(phase.Name, phase.Document())); } // Document Constants var constantTags = new List <ITag>(); foreach (var constant in FindAllChildren <Constant>()) { foreach (var tag in constant.Document()) { constantTags.Add(tag); } } yield return(new Section("Constants", constantTags)); // Document everything else. foreach (var phase in Children.Where(child => !(child is IPhase) && !(child is Memo) && !(child is Constant) && child != thermalTime)) { yield return(new Section(phase.Name, phase.Document())); } }
/// <summary>Writes documentation for this function by adding to the list of documentation tags.</summary> public override IEnumerable <ITag> Document() { foreach (var tag in GetModelDescription()) { yield return(tag); } // Document memos. foreach (var memo in FindAllChildren <Memo>()) { foreach (var tag in memo.Document()) { yield return(tag); } } // List the parameters, properties, and processes from this organ that need to be documented: yield return(new Section("Initial Dry Matter", initialWt.Document())); // document DM demands var dmDemandTags = new List <ITag>(); dmDemandTags.Add(new Paragraph("The dry matter demand for the organ is calculated as defined in DMDemands, based on the DMDemandFunction and partition fractions for each biomass pool.")); dmDemandTags.AddRange(dmDemands.Document()); yield return(new Section("Dry Matter Demand", dmDemandTags)); // document N demands var nDemandTags = new List <ITag>(); nDemandTags.Add(new Paragraph("The N demand is calculated as defined in NDemands, based on DM demand the N concentration of each biomass pool.")); nDemandTags.AddRange(nDemands.Document()); yield return(new Section("Nitrogen Demand", nDemandTags)); // document N demands var nConcTags = new List <ITag>(); nConcTags.AddRange(minimumNConc.Document()); nConcTags.AddRange(criticalNConc.Document()); nConcTags.AddRange(maximumNConc.Document()); yield return(new Section("Nitrogen Concentration Thresholds", nDemandTags)); // document DM supplies var dmSupplyTags = new List <ITag>(); dmSupplyTags.AddRange(dmReallocationFactor.Document()); dmSupplyTags.AddRange(dmRetranslocationFactor.Document()); yield return(new Section("Dry Matter Supply", dmSupplyTags)); // document photosynthesis yield return(new Section("Photosynthesis", photosynthesis.Document())); // document N supplies var nSupplyTags = new List <ITag>(); nSupplyTags.AddRange(nReallocationFactor.Document()); nSupplyTags.AddRange(nRetranslocationFactor.Document()); yield return(new Section("Nitrogen Supply", nSupplyTags)); // document canopy var canopyTags = new List <ITag>(); if (area != null) { canopyTags.Add(new Paragraph(Name + " has been defined with a LAIFunction, cover is calculated using the Beer-Lambert equation.")); canopyTags.AddRange(area.Document()); } if (cover != null) { canopyTags.Add(new Paragraph(Name + " has been defined with a CoverFunction. LAI is calculated using an inverted Beer-Lambert equation")); canopyTags.AddRange(cover.Document()); } canopyTags.AddRange(extinctionCoefficient.Document()); canopyTags.AddRange(tallness.Document()); yield return(new Section("Canopy Properties", canopyTags)); var stomatalConductanceTags = new List <ITag>(); stomatalConductanceTags.Add(new Paragraph("Stomatal Conductance (gs) is calculated for use within the micromet model by adjusting a value provided for an atmospheric CO2 concentration of 350 ppm. The impact of other stresses (e.g. Temperature, N) are captured through the modifier, Frgr.")); stomatalConductanceTags.Add(new Paragraph(" gs = Gsmax350 x FRGR x stomatalConductanceCO2Modifier")); stomatalConductanceTags.AddRange(stomatalConductanceCO2Modifier.Document()); yield return(new Section("StomatalConductance", stomatalConductanceTags)); // document senescence and detachment var senescenceTags = new List <ITag>(); if (senescenceRate is Constant senescenceRateConstant) { if (senescenceRateConstant.Value() == 0) { senescenceTags.Add(new Paragraph(Name + " has senescence parameterised to zero so all biomass in this organ will remain alive.")); } else { senescenceTags.Add(new Paragraph(Name + " senesces " + senescenceRateConstant.Value() * 100 + "% of its live biomass each day, moving the corresponding amount of biomass from the live to the dead biomass pool.")); } } else { senescenceTags.Add(new Paragraph("The proportion of live biomass that senesces and moves into the dead pool each day is quantified by the SenescenceRate.")); senescenceTags.AddRange(senescenceRate.Document()); } if (detachmentRate is Constant detachmentRateConstant) { if (detachmentRateConstant.Value() == 0) { senescenceTags.Add(new Paragraph(Name + " has detachment parameterised to zero so all biomass in this organ will remain with the plant until a defoliation or harvest event occurs.")); } else { senescenceTags.Add(new Paragraph(Name + " detaches " + detachmentRateConstant.Value() * 100 + "% of its dead biomass each day, passing it to the surface organic matter model for decomposition.")); } } else { senescenceTags.Add(new Paragraph("The proportion of Biomass that detaches and is passed to the surface organic matter model for decomposition is quantified by the DetachmentRateFunction.")); senescenceTags.AddRange(detachmentRate.Document()); } yield return(new Section("Senescence and Detachment", senescenceTags)); if (biomassRemovalModel != null) { yield return(new Section("Biomass removal", biomassRemovalModel.Document())); } }
/// <summary> /// Document the model. /// </summary> public override IEnumerable <ITag> Document() { foreach (ITag tag in GetModelDescription()) { yield return(tag); } // Document DM demands. yield return(new Section("Dry Matter Demand", DocumentDMDemands())); // Document N demands. yield return(new Section("Nitrogen Demand", DocumentNDemand())); // Document N concentration thresholds. // todo: Should these be in their own section? foreach (ITag tag in minimumNConc.Document()) { yield return(tag); } foreach (ITag tag in criticalNConc.Document()) { yield return(tag); } foreach (ITag tag in maximumNConc.Document()) { yield return(tag); } IModel nDemandSwitch = FindChild("NitrogenDemandSwitch"); if (nDemandSwitch != null) { if (nDemandSwitch is Constant nDemandConst) { if (nDemandConst.Value() == 1) { //Don't bother documenting as is does nothing } else { yield return(new Paragraph($"The demand for N is reduced by a factor of {nDemandConst.Value()} as specified by the NitrogenDemandSwitch")); } } else { yield return(new Paragraph("The demand for N is reduced by a factor specified by the NitrogenDemandSwitch.")); foreach (ITag tag in nDemandSwitch.Document()) { yield return(tag); } } } // document DM supplies yield return(new Section("Dry Matter Supply", DocumentDMSupply())); // Document N supplies. yield return(new Section("Nitrogen Supply", DocumentNSupply())); // Document N fixation. IModel fixationRate = FindChild("FixationRate"); if (fixationRate != null) { foreach (ITag tag in fixationRate.Document()) { yield return(tag); } } // Document senescence and detachment. yield return(new Section("Senescence and Detachment", DocumentSenescenceRate())); if (biomassRemovalModel != null) { foreach (ITag tag in biomassRemovalModel.Document()) { yield return(tag); } } }