Skip to content

Commit

Permalink
Merge pull request #818 from aldoherty/LeafInterface
Browse files Browse the repository at this point in the history
Leaf interface
  • Loading branch information
hol353 committed May 9, 2016
2 parents e539b51 + ff7c4a4 commit 0a323b6
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 36 deletions.
29 changes: 29 additions & 0 deletions Models/Interfaces/ILeaf.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// -----------------------------------------------------------------------
// <copyright file="ICanopy.cs" company="APSIM Initiative">
// Copyright (c) APSIM Initiative
// </copyright>
//-----------------------------------------------------------------------
namespace Models.Interfaces
{
using System;

/// <summary>This interface describes interface for leaf interaction with Structure.</summary>
public interface ILeaf
{
/// <summary>
///
/// </summary>
bool CohortsInitialised { get; }
/// <summary>
///
/// </summary>
double PlantAppearedLeafNo { get; }
/// <summary>
///
/// </summary>
/// <param name="ProportionRemoved"></param>
void DoThin(double ProportionRemoved);

}
}

1 change: 1 addition & 0 deletions Models/Models.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@
<Compile Include="Graph\Regression.cs" />
<Compile Include="Grazplan\Supplement.cs" />
<Compile Include="Grazplan\GrazSupp.cs" />
<Compile Include="Interfaces\ILeaf.cs" />
<Compile Include="Interfaces\ISurfaceOrganicMatter.cs" />
<Compile Include="Interfaces\ICanopy.cs" />
<Compile Include="Interfaces\IWeather.cs" />
Expand Down
2 changes: 1 addition & 1 deletion Models/Plant/Organs/Leaf.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ namespace Models.PMF.Organs
[Description("Leaf Class")]
[ViewName("UserInterface.Views.GridView")]
[PresenterName("UserInterface.Presenters.PropertyPresenter")]
public class Leaf : BaseOrgan, AboveGround, ICanopy
public class Leaf : BaseOrgan, AboveGround, ICanopy, ILeaf
{
#region Canopy interface

Expand Down
126 changes: 92 additions & 34 deletions Models/Plant/Organs/SimpleLeaf.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using System.Xml.Serialization;
using Models.PMF.Interfaces;
using Models.Interfaces;
using Models.PMF.Phen;
using APSIM.Shared.Utilities;

namespace Models.PMF.Organs
{
Expand Down Expand Up @@ -38,8 +40,24 @@ namespace Models.PMF.Organs
[Serializable]
[ViewName("UserInterface.Views.GridView")]
[PresenterName("UserInterface.Presenters.PropertyPresenter")]
public class SimpleLeaf : GenericOrgan, AboveGround, ICanopy
public class SimpleLeaf : GenericOrgan, AboveGround, ICanopy, ILeaf
{
#region Leaf Interface
/// <summary>
///
/// </summary>
public bool CohortsInitialised { get; set; }
/// <summary>
///
/// </summary>
public double PlantAppearedLeafNo { get; set; }
/// <summary>
///
/// </summary>
/// <param name="proprtionRemoved"></param>
public void DoThin(double proprtionRemoved) { }
#endregion

#region Canopy interface

/// <summary>Gets the canopy. Should return null if no canopy present.</summary>
Expand All @@ -59,7 +77,7 @@ public class SimpleLeaf : GenericOrgan, AboveGround, ICanopy

/// <summary>Gets the LAI</summary>
[Units("m^2/m^2")]
public double LAI {get; set;}
public double LAI { get; set; }

/// <summary>Gets the LAI live + dead (m^2/m^2)</summary>
public double LAITotal { get { return LAI + LAIDead; } }
Expand All @@ -70,9 +88,21 @@ public double CoverGreen
{
get
{
if (CoverFunction == null)
return 1.0 - Math.Exp((-1 * ExtinctionCoefficientFunction.Value) * LAI);
return Math.Min(Math.Max(CoverFunction.Value, 0), 1);
//if (CoverFunction == null)
// return 1.0 - Math.Exp((-1 * ExtinctionCoefficientFunction.Value) * LAI);
//return Math.Min(Math.Max(CoverFunction.Value, 0), 1);

if (Plant.IsAlive)
{
if (CoverFunction == null)
return 1.0 - Math.Exp((-1 * ExtinctionCoefficientFunction.Value) * LAI);
return Math.Min(Math.Max(CoverFunction.Value, 0), 1);
}
else
{
return 0;
}

}
}

Expand All @@ -82,7 +112,7 @@ public double CoverTotal
{
get { return 1.0 - (1 - CoverGreen) * (1 - CoverDead); }
}

/// <summary>Gets or sets the height.</summary>
[Units("mm")]
public double Height { get; set; }
Expand All @@ -93,7 +123,7 @@ public double CoverTotal
/// <summary>Gets or sets the FRGR.</summary>
[Units("mm")]
public double FRGR { get; set; }

/// <summary>Sets the potential evapotranspiration. Set by MICROCLIMATE.</summary>
public double PotentialEP { get; set; }

Expand Down Expand Up @@ -133,6 +163,20 @@ public double CoverTotal
/// <summary>The structural fraction</summary>
[Link(IsOptional = true)]
IFunction StructuralFraction = null;

/// <summary>The structure</summary>
[Link(IsOptional = true)]
public Structure Structure = null;
/// <summary>The phenology</summary>
[Link(IsOptional = true)]
public Phenology Phenology = null;
/// <summary>TE Function</summary>
[Link(IsOptional = true)]
IFunction TranspirationEfficiency = null;
/// <summary></summary>
[Link(IsOptional = true)]
IFunction SVPFrac = null;

#endregion

#region States and variables
Expand Down Expand Up @@ -162,6 +206,14 @@ public override double WaterDemand
{
get
{
if (SVPFrac != null && TranspirationEfficiency != null)
{
double svpMax = MetUtilities.svp(MetData.MaxT) * 0.1;
double svpMin = MetUtilities.svp(MetData.MinT) * 0.1;
double vpd = Math.Max(SVPFrac.Value * (svpMax - svpMin), 0.01);

return Photosynthesis.Value / (TranspirationEfficiency.Value / vpd / 0.001);
}
return PotentialEP;
}
//set
Expand Down Expand Up @@ -195,7 +247,7 @@ public double Fn
{
double MaxNContent = Live.Wt * MaximumNConc.Value;
return Live.N / MaxNContent;
}
}
}

/// <summary>Gets or sets the lai dead.</summary>
Expand Down Expand Up @@ -245,7 +297,7 @@ public override BiomassPoolType DMDemand
Demand = DMDemandFunction.Value;
else
Demand = 1;
if (Math.Round(Demand,8) < 0)
if (Math.Round(Demand, 8) < 0)
throw new Exception(this.Name + " organ is returning a negative DM demand. Check your parameterisation");
return new BiomassPoolType { Structural = Demand };
}
Expand All @@ -256,7 +308,7 @@ public override BiomassSupplyType DMSupply
{
get
{
if (Math.Round(Photosynthesis.Value,8) < 0)
if (Math.Round(Photosynthesis.Value, 8) < 0)
throw new Exception(this.Name + " organ is returning a negative DM supply. Check your parameterisation");
return new BiomassSupplyType { Fixation = Photosynthesis.Value, Retranslocation = 0, Reallocation = 0 };
}
Expand Down Expand Up @@ -295,9 +347,9 @@ public override BiomassPoolType NDemand
StructuralDemand = MaximumNConc.Value * DMDemandTot * _StructuralFraction;
NDeficit = Math.Max(0.0, MaximumNConc.Value * (Live.Wt + DMDemandTot) - Live.N) - StructuralDemand;
}
if (Math.Round(StructuralDemand,8) < 0)
if (Math.Round(StructuralDemand, 8) < 0)
throw new Exception(this.Name + " organ is returning a negative structural N Demand. Check your parameterisation");
if (Math.Round(NDeficit,8) < 0)
if (Math.Round(NDeficit, 8) < 0)
throw new Exception(this.Name + " organ is returning a negative Non structural N Demand. Check your parameterisation");
return new BiomassPoolType { Structural = StructuralDemand, NonStructural = NDeficit };
}
Expand Down Expand Up @@ -346,6 +398,12 @@ public override BiomassAllocationType NAllocation
[EventSubscribe("DoDailyInitialisation")]
private void OnDoDailyInitialisation(object sender, EventArgs e)
{
if (Phenology != null)
if (Phenology.OnDayOf("Emergence"))
{
if (Structure != null)
Structure.MainStemNodeNo = 1.0;
}

EP = 0;
}
Expand Down Expand Up @@ -450,12 +508,12 @@ public override void Document(List<AutoDocumentation.ITag> tags, int headingLeve
tags.Add(new AutoDocumentation.Heading("Dry Matter Supply", headingLevel + 1)); //FIXME, this will need to be changed to photoysnthesis rather that potential Biomass
if (Photosynthesis != null)
tags.Add(new AutoDocumentation.Paragraph("DryMatter Fixation Supply (Photosynthesis) provided to the Organ Arbitrator (for partitioning between organs) is calculated each day as the product of a unstressed potential and a series of stress factors.", indent));
foreach (IModel child in Apsim.Children(this, typeof(IModel)))
{
if (child.Name == "Photosynthesis")
child.Document(tags, headingLevel + 5, indent + 1);
}
foreach (IModel child in Apsim.Children(this, typeof(IModel)))
{
if (child.Name == "Photosynthesis")
child.Document(tags, headingLevel + 5, indent + 1);
}

tags.Add(new AutoDocumentation.Paragraph("DM is not retranslocated out of " + this.Name + " ", indent));

tags.Add(new AutoDocumentation.Heading("Dry Matter Demands", headingLevel + 1));
Expand Down Expand Up @@ -489,23 +547,23 @@ public override void Document(List<AutoDocumentation.ITag> tags, int headingLeve
tags.Add(new AutoDocumentation.Heading("Nitrogen Supplies", headingLevel + 1));
tags.Add(new AutoDocumentation.Paragraph("N is not reallocated from " + this.Name + " ", indent));
tags.Add(new AutoDocumentation.Paragraph("Non-structural N in " + this.Name + " is not available for re-translocation to other organs", indent));

tags.Add(new AutoDocumentation.Heading("Biomass Senescece and Detachment", headingLevel + 1));
tags.Add(new AutoDocumentation.Paragraph("No senescence occurs from " + Name, indent));
tags.Add(new AutoDocumentation.Paragraph("No Detachment occurs from " + Name, indent));

tags.Add(new AutoDocumentation.Heading("Canopy", headingLevel + 1));
if (CoverFunction != null)
{
tags.Add(new AutoDocumentation.Paragraph("The Green cover (proportion of ground cover comprising green leaf) and Leaf area index (LAI, the area of leaf per unit area of ground) estimations are calculated using a CoverFunction as folows" + " ", indent));
tags.Add(new AutoDocumentation.Paragraph("The Green cover (proportion of ground cover comprising green leaf) and Leaf area index (LAI, the area of leaf per unit area of ground) estimations are calculated using a CoverFunction as folows" + " ", indent));
foreach (IModel child in Apsim.Children(this, typeof(IModel)))
{
if (child.Name == "CoverFunction")
child.Document(tags, headingLevel + 5, indent + 1);
}
tags.Add(new AutoDocumentation.Paragraph("Then LAI is calculated using an inverted Beer Lamberts equation with the estimated Cover value:"
+ " <b>LAI = Log(1 - Cover) / (ExtinctionCoefficient * -1));", indent));
tags.Add(new AutoDocumentation.Paragraph("Where ExtinctionCoefficient has a value of " + ExtinctionCoefficientFunction.Value, indent+1));
tags.Add(new AutoDocumentation.Paragraph("Where ExtinctionCoefficient has a value of " + ExtinctionCoefficientFunction.Value, indent + 1));
}
if (LAIFunction != null)
{
Expand All @@ -519,7 +577,7 @@ public override void Document(List<AutoDocumentation.ITag> tags, int headingLeve
+ " <b>Cover = 1.0 - e<sup>((-1 * ExtinctionCoefficient) * LAI);", indent));
tags.Add(new AutoDocumentation.Paragraph("Where ExtinctionCoefficient has a value of " + ExtinctionCoefficientFunction.Value, indent + 1));
}
tags.Add(new AutoDocumentation.Paragraph("The canopies values of Cover and LAI are passed to the MicroClimate module which uses the Penman Monteith equation to calculate potential evapotranspiration for each canopy and passes the value back to the crop", indent ));
tags.Add(new AutoDocumentation.Paragraph("The canopies values of Cover and LAI are passed to the MicroClimate module which uses the Penman Monteith equation to calculate potential evapotranspiration for each canopy and passes the value back to the crop", indent));
tags.Add(new AutoDocumentation.Paragraph("The effect of growth rate on transpiration is captured using the Fractional Growth Rate (FRGR) function which is parameterised as a function of temperature for the simple leaf", indent));
foreach (IModel child in Apsim.Children(this, typeof(IModel)))
{
Expand All @@ -530,22 +588,22 @@ public override void Document(List<AutoDocumentation.ITag> tags, int headingLeve
bool NonStandardFunctions = false;
foreach (IModel child in Apsim.Children(this, typeof(IModel)))
{
if (((child.Name != "StructuralFraction")
| (child.Name != "DMDemandFunction")
| (child.Name != "NConc")
| (child.Name != "Photosynthesis")
if (((child.Name != "StructuralFraction")
| (child.Name != "DMDemandFunction")
| (child.Name != "NConc")
| (child.Name != "Photosynthesis")
| (child.Name != "Photosynthesis")
| (child.Name != "NReallocationFactor")
| (child.Name != "NReallocationFactor")
| (child.Name != "NRetranslocationFactor")
| (child.Name != "DMRetranslocationFactor")
| (child.Name != "SenescenceRateFunction")
| (child.Name != "DetachmentRateFunctionFunction")
| (child.Name != "LAIFunction")
| (child.Name != "CoverFunction")
| (child.Name != "DMRetranslocationFactor")
| (child.Name != "SenescenceRateFunction")
| (child.Name != "DetachmentRateFunctionFunction")
| (child.Name != "LAIFunction")
| (child.Name != "CoverFunction")
| (child.Name != "ExtinctionCoefficientFunction")
| (child.Name != "Live")
| (child.Name != "Live")
| (child.Name != "Dead")
| (child.Name != "FRGRFunction")
| (child.Name != "FRGRFunction")
| (child.Name != "NitrogenDemandSwitch"))
&& (child.GetType() != typeof(Memo)))
{
Expand Down
3 changes: 2 additions & 1 deletion Models/Plant/Structure.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Models.PMF.Phen;
using System.Xml.Serialization;
using Models.PMF.Functions.StructureFunctions;
using Models.Interfaces;

namespace Models.PMF
{
Expand Down Expand Up @@ -194,7 +195,7 @@ public class Structure : Model
Plant Plant = null;
/// <summary>The leaf</summary>
[Link]
Leaf Leaf = null;
ILeaf Leaf = null;
/// <summary>The phenology</summary>
[Link]
private Phenology Phenology = null;
Expand Down

0 comments on commit 0a323b6

Please sign in to comment.