/// <summary> /// Document the model. /// </summary> public override IEnumerable <ITag> Document() { // Add heading and description. foreach (ITag tag in base.Document()) { yield return(tag); } // List the parameters, properties, and processes from this organ that need to be documented: // Document DM demands. yield return(new Section("Dry Matter Demand", DocumentDMDemand(dmDemands))); // Document N demands. yield return(new Section("Nitrogen Demand", DocumentNDemand(FindChild("nDemands")))); // Document N concentration thresholds. yield return(new Section("N Concentration Thresholds", DocumentNConcentrationThresholds())); // todo: should this be in its own section? IModel nDemandSwitch = FindChild("NitrogenDemandSwitch"); if (nDemandSwitch is Constant nDemandConst) { if (nDemandConst.Value() == 1) { // Don't bother documenting as it 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 senescence and detachment. yield return(new Section("Senescence and Detachment", DocumentSenescence())); if (biomassRemovalModel != null) { foreach (ITag tag in biomassRemovalModel.Document()) { yield return(tag); } } }
/// <summary>Writes documentation for this function by adding to the list of documentation tags.</summary> /// <param name="tags">The list of tags to add to.</param> /// <param name="headingLevel">The level (e.g. H2) of the headings.</param> /// <param name="indent">The level of indentation 1, 2, 3 etc.</param> public void Document(List <AutoDocumentation.ITag> tags, int headingLevel, int indent) { if (IncludeInDocumentation) { // add a heading, the name of this organ tags.Add(new AutoDocumentation.Heading(Name, headingLevel)); // write the basic description of this class, given in the <summary> AutoDocumentation.DocumentModelSummary(this, tags, headingLevel, indent, false); // write the memos foreach (IModel memo in Apsim.Children(this, typeof(Memo))) { AutoDocumentation.DocumentModel(memo, tags, headingLevel + 1, indent); } //// List the parameters, properties, and processes from this organ that need to be documented: // document DM demands tags.Add(new AutoDocumentation.Heading("Dry Matter Demand", headingLevel + 1)); tags.Add(new AutoDocumentation.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.", indent)); IModel DMDemand = Apsim.Child(this, "dmDemands"); AutoDocumentation.DocumentModel(DMDemand, tags, headingLevel + 2, indent); // document N demands tags.Add(new AutoDocumentation.Heading("Nitrogen Demand", headingLevel + 1)); tags.Add(new AutoDocumentation.Paragraph("The N demand is calculated as defined in NDemands, based on DM demand the N concentration of each biomass pool.", indent)); IModel NDemand = Apsim.Child(this, "nDemands"); AutoDocumentation.DocumentModel(NDemand, tags, headingLevel + 2, indent); // document N concentration thresholds IModel MinN = Apsim.Child(this, "MinimumNConc"); AutoDocumentation.DocumentModel(MinN, tags, headingLevel + 2, indent); IModel CritN = Apsim.Child(this, "CriticalNConc"); AutoDocumentation.DocumentModel(CritN, tags, headingLevel + 2, indent); IModel MaxN = Apsim.Child(this, "MaximumNConc"); AutoDocumentation.DocumentModel(MaxN, tags, headingLevel + 2, indent); IModel NDemSwitch = Apsim.Child(this, "NitrogenDemandSwitch"); if (NDemSwitch is Constant) { if ((NDemSwitch as Constant).Value() == 1.0) { //Don't bother documenting as is does nothing } else { tags.Add(new AutoDocumentation.Paragraph("The demand for N is reduced by a factor of " + (NDemSwitch as Constant).Value() + " as specified by the NitrogenDemandSwitch", indent)); } } else { tags.Add(new AutoDocumentation.Paragraph("The demand for N is reduced by a factor specified by the NitrogenDemandSwitch.", indent)); AutoDocumentation.DocumentModel(NDemSwitch, tags, headingLevel + 2, indent); } // document DM supplies tags.Add(new AutoDocumentation.Heading("Dry Matter Supply", headingLevel + 1)); IModel DMReallocFac = Apsim.Child(this, "DMReallocationFactor"); if (DMReallocFac is Constant) { if ((DMReallocFac as Constant).Value() == 0) { tags.Add(new AutoDocumentation.Paragraph(Name + " does not reallocate DM when senescence of the organ occurs.", indent)); } else { tags.Add(new AutoDocumentation.Paragraph(Name + " will reallocate " + (DMReallocFac as Constant).Value() * 100 + "% of DM that senesces each day.", indent)); } } else { tags.Add(new AutoDocumentation.Paragraph("The proportion of senescing DM that is allocated each day is quantified by the DMReallocationFactor.", indent)); AutoDocumentation.DocumentModel(DMReallocFac, tags, headingLevel + 2, indent); } IModel DMRetransFac = Apsim.Child(this, "DMRetranslocationFactor"); if (DMRetransFac is Constant) { if ((DMRetransFac as Constant).Value() == 0) { tags.Add(new AutoDocumentation.Paragraph(Name + " does not retranslocate non-structural DM.", indent)); } else { tags.Add(new AutoDocumentation.Paragraph(Name + " will retranslocate " + (DMRetransFac as Constant).Value() * 100 + "% of non-structural DM each day.", indent)); } } else { tags.Add(new AutoDocumentation.Paragraph("The proportion of non-structural DM that is allocated each day is quantified by the DMReallocationFactor.", indent)); AutoDocumentation.DocumentModel(DMRetransFac, tags, headingLevel + 2, indent); } // document N supplies tags.Add(new AutoDocumentation.Heading("Nitrogen Supply", headingLevel + 1)); IModel NReallocFac = Apsim.Child(this, "NReallocationFactor"); if (NReallocFac is Constant) { if ((NReallocFac as Constant).Value() == 0) { tags.Add(new AutoDocumentation.Paragraph(Name + " does not reallocate N when senescence of the organ occurs.", indent)); } else { tags.Add(new AutoDocumentation.Paragraph(Name + " will reallocate " + (NReallocFac as Constant).Value() * 100 + "% of N that senesces each day.", indent)); } } else { tags.Add(new AutoDocumentation.Paragraph("The proportion of senescing N that is allocated each day is quantified by the NReallocationFactor.", indent)); AutoDocumentation.DocumentModel(NReallocFac, tags, headingLevel + 2, indent); } IModel NRetransFac = Apsim.Child(this, "NRetranslocationFactor"); if (NRetransFac is Constant) { if ((NRetransFac as Constant).Value() == 0) { tags.Add(new AutoDocumentation.Paragraph(Name + " does not retranslocate non-structural N.", indent)); } else { tags.Add(new AutoDocumentation.Paragraph(Name + " will retranslocate " + (NRetransFac as Constant).Value() * 100 + "% of non-structural N each day.", indent)); } } else { tags.Add(new AutoDocumentation.Paragraph("The proportion of non-structural N that is allocated each day is quantified by the NReallocationFactor.", indent)); AutoDocumentation.DocumentModel(NRetransFac, tags, headingLevel + 2, indent); } // document senescence and detachment tags.Add(new AutoDocumentation.Heading("Senescence and Detachment", headingLevel + 1)); IModel SenRate = Apsim.Child(this, "SenescenceRate"); if (SenRate is Constant) { if ((SenRate as Constant).Value() == 0) { tags.Add(new AutoDocumentation.Paragraph(Name + " has senescence parameterised to zero so all biomass in this organ will remain alive.", indent)); } else { tags.Add(new AutoDocumentation.Paragraph(Name + " senesces " + (SenRate as Constant).Value() * 100 + "% of its live biomass each day, moving the corresponding amount of biomass from the live to the dead biomass pool.", indent)); } } else { tags.Add(new AutoDocumentation.Paragraph("The proportion of live biomass that senesces and moves into the dead pool each day is quantified by the SenescenceRate.", indent)); AutoDocumentation.DocumentModel(SenRate, tags, headingLevel + 2, indent); } IModel DetRate = Apsim.Child(this, "DetachmentRateFunction"); if (DetRate is Constant) { if ((DetRate as Constant).Value() == 0) { tags.Add(new AutoDocumentation.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.", indent)); } else { tags.Add(new AutoDocumentation.Paragraph(Name + " detaches " + (DetRate as Constant).Value() * 100 + "% of its live biomass each day, passing it to the surface organic matter model for decomposition.", indent)); } } else { tags.Add(new AutoDocumentation.Paragraph("The proportion of Biomass that detaches and is passed to the surface organic matter model for decomposition is quantified by the DetachmentRateFunction.", indent)); AutoDocumentation.DocumentModel(DetRate, tags, headingLevel + 2, indent); } if (biomassRemovalModel != null) { biomassRemovalModel.Document(tags, headingLevel + 1, indent); } } }
/// <summary>Writes documentation for this function by adding to the list of documentation tags.</summary> /// <param name="tags">The list of tags to add to.</param> /// <param name="headingLevel">The level (e.g. H2) of the headings.</param> /// <param name="indent">The level of indentation 1, 2, 3 etc.</param> public override void Document(List <AutoDocumentation.ITag> tags, int headingLevel, int indent) { if (IncludeInDocumentation && StructuralFraction != null) { // add a heading. tags.Add(new AutoDocumentation.Heading(Name, headingLevel)); // write description of this class. AutoDocumentation.DocumentModel(this, tags, headingLevel, indent); // Documment DM demands. tags.Add(new AutoDocumentation.Heading("Dry Matter Demand", headingLevel + 1)); tags.Add(new AutoDocumentation.Paragraph("Total Dry matter demand is calculated by the DMDemandFunction", indent)); IModel DMDemand = Apsim.Child(this, "DMDemandFunction"); DMDemand.Document(tags, -1, indent); IModel StrucFrac = Apsim.Child(this, "StructuralFraction"); if (StrucFrac.GetType() == typeof(Constant)) { if (StructuralFraction.Value() == 1.0) { tags.Add(new AutoDocumentation.Paragraph("All demand is structural and this organ has no Non-structural demand", indent)); } else { double StrucPercent = StructuralFraction.Value() * 100; tags.Add(new AutoDocumentation.Paragraph("Of total biomass, " + StrucPercent + "% of this is structural and the remainder is non-structural demand", indent)); tags.Add(new AutoDocumentation.Paragraph("Any Non-structural Demand Capacity (StructuralWt/StructuralFraction) that is not currently occupied is also included in Non-structural DM Demand", indent)); } } else { tags.Add(new AutoDocumentation.Paragraph("The proportion of total biomass that is partitioned to structural is determined by the StructuralFraction", indent)); StrucFrac.Document(tags, -1, indent); tags.Add(new AutoDocumentation.Paragraph("Any Non-structural Demand Capacity (StructuralWt/StructuralFraction) that is not currently occupied is also included in Non-structural DM Demand", indent)); } // Document Nitrogen Demand tags.Add(new AutoDocumentation.Heading("Nitrogen Demand", headingLevel + 1)); tags.Add(new AutoDocumentation.Paragraph("The daily structural N demand is the product of Total DM demand and a Minimum N concentration", indent)); IModel MinN = Apsim.Child(this, "MinimumNConc"); MinN.Document(tags, -1, indent); tags.Add(new AutoDocumentation.Paragraph("The daily Storage N demand is the product of Total DM demand and a Maximum N concentration", indent)); IModel MaxN = Apsim.Child(this, "MaximumNConc"); MaxN.Document(tags, -1, indent); IModel NDemSwitch = Apsim.Child(this, "NitrogenDemandSwitch"); if (NDemSwitch.GetType() == typeof(Constant)) { if (NitrogenDemandSwitch.Value() == 1.0) { //Dont bother docummenting as is does nothing } else { tags.Add(new AutoDocumentation.Paragraph("The demand for N is reduced by a factor of " + NitrogenDemandSwitch.Value() + " as specified by the NitrogenDemandFactor", indent)); } } else { tags.Add(new AutoDocumentation.Paragraph("The demand for N is reduced by a factor specified by the NitrogenDemandFactor", indent)); NDemSwitch.Document(tags, -1, indent); } //Document DM supplies tags.Add(new AutoDocumentation.Heading("Dry Matter Supply", headingLevel + 1)); IModel DMReallocFac = Apsim.Child(this, "DMReallocationFactor"); if (DMReallocFac.GetType() == typeof(Constant)) { if (DMReallocationFactor.Value() == 0) { tags.Add(new AutoDocumentation.Paragraph(Name + " does not reallocate DM when senescence of the organ occurs", indent)); } else { tags.Add(new AutoDocumentation.Paragraph(Name + " will reallocate " + DMReallocationFactor.Value() * 100 + "% of DM that senesces each day", indent)); } } else { tags.Add(new AutoDocumentation.Paragraph("The proportion of senescing DM tha is allocated each day is quantified by the DMReallocationFactor", indent)); DMReallocFac.Document(tags, -1, indent); } IModel DMRetransFac = Apsim.Child(this, "DMRetranslocationFactor"); if (DMRetransFac.GetType() == typeof(Constant)) { if (DMRetranslocationFactor.Value() == 0) { tags.Add(new AutoDocumentation.Paragraph(Name + " does not retranslocate non-structural DM", indent)); } else { tags.Add(new AutoDocumentation.Paragraph(Name + " will retranslocate " + DMRetranslocationFactor.Value() * 100 + "% of non-structural DM each day", indent)); } } else { tags.Add(new AutoDocumentation.Paragraph("The proportion of non-structural DM tha is allocated each day is quantified by the DMReallocationFactor", indent)); DMRetransFac.Document(tags, -1, indent); } //Document N supplies tags.Add(new AutoDocumentation.Heading("Nitrogen Supply", headingLevel + 1)); IModel NReallocFac = Apsim.Child(this, "NReallocationFactor"); if (NReallocFac.GetType() == typeof(Constant)) { if (NReallocationFactor.Value() == 0) { tags.Add(new AutoDocumentation.Paragraph(Name + " does not reallocate N when senescence of the organ occurs", indent)); } else { tags.Add(new AutoDocumentation.Paragraph(Name + " will reallocate " + NReallocationFactor.Value() * 100 + "% of N that senesces each day", indent)); } } else { tags.Add(new AutoDocumentation.Paragraph("The proportion of senescing N tha is allocated each day is quantified by the NReallocationFactor", indent)); NReallocFac.Document(tags, -1, indent); } IModel NRetransFac = Apsim.Child(this, "NRetranslocationFactor"); if (NRetransFac.GetType() == typeof(Constant)) { if (NRetranslocationFactor.Value() == 0) { tags.Add(new AutoDocumentation.Paragraph(Name + " does not retranslocate non-structural N", indent)); } else { tags.Add(new AutoDocumentation.Paragraph(Name + " will retranslocate " + NRetranslocationFactor.Value() * 100 + "% of non-structural N each day", indent)); } } else { tags.Add(new AutoDocumentation.Paragraph("The proportion of non-structural N that is allocated each day is quantified by the NReallocationFactor", indent)); NRetransFac.Document(tags, -1, indent); } //Document Biomass Senescence and Detachment tags.Add(new AutoDocumentation.Heading("Senescence and Detachment", headingLevel + 1)); IModel Sen = Apsim.Child(this, "SenescenceRate"); if (Sen.GetType() == typeof(Constant)) { if (SenescenceRate.Value() == 0) { tags.Add(new AutoDocumentation.Paragraph(Name + " has senescence parameterised to zero so all biomss in this organ will remain live", indent)); } else { tags.Add(new AutoDocumentation.Paragraph(Name + " senesces " + SenescenceRate.Value() * 100 + "% of its live biomass each day, moving the corresponding amount of biomass from the live to the dead biomass pool", indent)); } } else { tags.Add(new AutoDocumentation.Paragraph("The proportion of live biomass that senesces and moves into the dead pool each day is quantified by the SenescenceFraction", indent)); Sen.Document(tags, -1, indent); } IModel Det = Apsim.Child(this, "DetachmentRateFunction"); if (Sen.GetType() == typeof(Constant)) { if (DetachmentRateFunction.Value() == 0) { tags.Add(new AutoDocumentation.Paragraph(Name + " has detachment parameterised to zero so all biomss in this organ will remain with the plant until a defoliation or harvest event occurs", indent)); } else { tags.Add(new AutoDocumentation.Paragraph(Name + " detaches " + DetachmentRateFunction.Value() * 100 + "% of its live biomass each day, passing it to the surface organic matter model for decomposition", indent)); } } else { tags.Add(new AutoDocumentation.Paragraph("The proportion of Biomass that detaches and is passed to the surface organic matter model for decomposition is quantified by the DetachmentRateFunction", indent)); Det.Document(tags, -1, indent); } if (biomassRemovalModel != null) { biomassRemovalModel.Document(tags, headingLevel + 1, indent); } } }
/// <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); } } }