Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow DCaPST AmbientCO2 value to be read from weather component. #9524

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
730430e
Change Sorghum/Wheat CO2Modifier to 420ppm.
joesaddigh Dec 9, 2024
86e4314
Add new AmbientCO2 value, that can be shared between Sorghum and DCaP…
joesaddigh Dec 10, 2024
64e45ab
Move assignment of ambientCO2 in DCaPST model.
joesaddigh Dec 10, 2024
b1218dc
Assign ambient CO2 in the correct place. Add CO2Value to the experime…
joesaddigh Dec 10, 2024
8582c6f
Move functions around to make the flow more logical. Remove redundant…
joesaddigh Dec 10, 2024
674fcc4
Add CO2Value to Sorghum validation file.
joesaddigh Dec 10, 2024
119327c
Set CO2Value to match original Sorghum value 350 rather than 363.
joesaddigh Dec 10, 2024
de4af17
Move initialisation of AmbientCO2Provider so that Weather has been in…
joesaddigh Dec 10, 2024
8f1a12f
Reinstate LinearInterpolationFunction for CO2Modifier but use "[Leaf]…
joesaddigh Dec 11, 2024
57c3957
Remove CO2 values from Weather components in Sorghum and DT validatio…
joesaddigh Dec 11, 2024
53e62aa
Poke CI.
joesaddigh Dec 11, 2024
5ce122b
Revert files.
joesaddigh Dec 11, 2024
054bb93
Move AmbientCO2Provider to DCaPST utilities folder.
joesaddigh Dec 12, 2024
6bf0dac
Test
joesaddigh Dec 12, 2024
319b054
Added CO2Value back into Weather.
joesaddigh Dec 12, 2024
09593bc
Hardcode the AmbientCO2 to see if this is effecting the POStats.
joesaddigh Dec 12, 2024
8ea3f8f
Use the Weather CO2 value correctly.
joesaddigh Dec 12, 2024
b40d588
Error if no CO2Value has been defined in DCaPST. Always use Weather.C…
joesaddigh Dec 13, 2024
d1c98f7
Merge branch 'master' into 9523_UpdateDefaultC02
joesaddigh Dec 15, 2024
caa3407
Wording change for exception if no CO2Value component exists.
joesaddigh Dec 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
203 changes: 103 additions & 100 deletions Models/DCaPST/DCaPSTModelNG.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Models.Climate;
using Models.Core;
using Models.DCAPST.Canopy;
using Models.DCAPST.Environment;
Expand Down Expand Up @@ -169,98 +170,6 @@ public double ElectronTransportLimitedModifier
/// </summary>
public static ICropParameterGenerator ParameterGenerator { get; set; } = new CropParameterGenerator();

/// <summary>
/// Creates the DCAPST Model.
/// </summary>
/// <param name="canopyParameters"></param>
/// <param name="pathwayParameters"></param>
/// <param name="DOY"></param>
/// <param name="latitude"></param>
/// <param name="maxT"></param>
/// <param name="minT"></param>
/// <param name="radn"></param>
/// <param name="rpar"></param>
/// <param name="biolimit"></param>
/// <param name="reduction"></param>
/// <returns>The model</returns>
public static DCAPSTModel SetUpModel(
ICanopyParameters canopyParameters,
IPathwayParameters pathwayParameters,
int DOY,
double latitude,
double maxT,
double minT,
double radn,
double rpar,
double biolimit,
double reduction
)
{
// Model the solar geometry
var solarGeometry = new SolarGeometry
{
Latitude = latitude.ToRadians(),
DayOfYear = DOY
};

// Model the solar radiation
var solarRadiation = new SolarRadiation(solarGeometry)
{
Daily = radn,
RPAR = rpar
};

// Model the environmental temperature
var temperature = new Temperature(solarGeometry)
{
MaxTemperature = maxT,
MinTemperature = minT,
AtmosphericPressure = 1.01325
};

// Model the pathways
var sunlitAc1 = new AssimilationPathway(canopyParameters, pathwayParameters);
var sunlitAc2 = new AssimilationPathway(canopyParameters, pathwayParameters);
var sunlitAj = new AssimilationPathway(canopyParameters, pathwayParameters);

var shadedAc1 = new AssimilationPathway(canopyParameters, pathwayParameters);
var shadedAc2 = new AssimilationPathway(canopyParameters, pathwayParameters);
var shadedAj = new AssimilationPathway(canopyParameters, pathwayParameters);

IAssimilation assimilation = canopyParameters.Type switch
{
CanopyType.C3 => new AssimilationC3(canopyParameters, pathwayParameters),
CanopyType.C4 => new AssimilationC4(canopyParameters, pathwayParameters),
_ => new AssimilationCCM(canopyParameters, pathwayParameters)
};

var sunlit = new AssimilationArea(sunlitAc1, sunlitAc2, sunlitAj, assimilation);
var shaded = new AssimilationArea(shadedAc1, shadedAc2, shadedAj, assimilation);
var canopyAttributes = new CanopyAttributes(canopyParameters, pathwayParameters, sunlit, shaded);

// Model the transpiration
var waterInteraction = new WaterInteraction(temperature);
var temperatureResponse = new TemperatureResponse(canopyParameters, pathwayParameters);
var transpiration = new Transpiration(canopyParameters, pathwayParameters, waterInteraction, temperatureResponse);

// Model the photosynthesis
return new DCAPSTModel(
solarGeometry,
solarRadiation,
temperature,
pathwayParameters,
canopyAttributes,
transpiration
)
{
// From here, we can set additional options,
// such as verbosity, BioLimit, Reduction, etc.
PrintIntervalValues = false,
Biolimit = biolimit,
Reduction = reduction,
};
}

/// <summary>
/// Reset the default DCaPST parameters according to the type of crop.
/// </summary>
Expand All @@ -278,13 +187,30 @@ public void Reset()
/// <param name="args"></param>
[EventSubscribe("StartOfSimulation")]
private void OnStartOfSimulation(object sender, EventArgs args)
{
EnsureCropSelected();
EnsureAmbientCO2Available();
}

private void EnsureCropSelected()
{
if (string.IsNullOrEmpty(CropName))
{
throw new ArgumentNullException(CropName, "No CropName was specified in DCaPST configuration");
}
}

private void EnsureAmbientCO2Available()
{
if (weather is null ||
weather is not Weather weatherModel ||
weatherModel.FindChild<CO2Value>() is null
)
{
throw new Exception($"Invalid DCaPST simulation. No {nameof(CO2Value)} model has been configured in {nameof(Weather)} model.");
}
}

/// <summary>
/// Called once per day when it's time for dcapst to run.
/// </summary>
Expand All @@ -305,10 +231,7 @@ private void OnDoDCaPST(object sender, EventArgs args)
Parameters.Canopy,
Parameters.Pathway,
clock.Today.DayOfYear,
weather.Latitude,
weather.MaxT,
weather.MinT,
weather.Radn,
weather,
Parameters.Rpar,
Biolimit,
Reduction
Expand All @@ -333,6 +256,86 @@ private void OnDoDCaPST(object sender, EventArgs args)
}
}

/// <summary>
/// Creates the DCAPST Model.
/// </summary>
private static DCAPSTModel SetUpModel(
ICanopyParameters canopyParameters,
IPathwayParameters pathwayParameters,
int DOY,
IWeather weather,
double rpar,
double biolimit,
double reduction
)
{
// Model the solar geometry
var solarGeometry = new SolarGeometry
{
Latitude = weather.Latitude.ToRadians(),
DayOfYear = DOY
};

// Model the solar radiation
var solarRadiation = new SolarRadiation(solarGeometry)
{
Daily = weather.Radn,
RPAR = rpar
};

// Model the environmental temperature
var temperature = new Temperature(solarGeometry)
{
MaxTemperature = weather.MaxT,
MinTemperature = weather.MinT,
AtmosphericPressure = 1.01325
};

var ambientCO2 = weather.CO2;

// Model the pathways
var sunlitAc1 = new AssimilationPathway(canopyParameters, pathwayParameters, ambientCO2);
var sunlitAc2 = new AssimilationPathway(canopyParameters, pathwayParameters, ambientCO2);
var sunlitAj = new AssimilationPathway(canopyParameters, pathwayParameters, ambientCO2);

var shadedAc1 = new AssimilationPathway(canopyParameters, pathwayParameters, ambientCO2);
var shadedAc2 = new AssimilationPathway(canopyParameters, pathwayParameters, ambientCO2);
var shadedAj = new AssimilationPathway(canopyParameters, pathwayParameters, ambientCO2);

IAssimilation assimilation = canopyParameters.Type switch
{
CanopyType.C3 => new AssimilationC3(canopyParameters, pathwayParameters, ambientCO2),
CanopyType.C4 => new AssimilationC4(canopyParameters, pathwayParameters, ambientCO2),
_ => new AssimilationCCM(canopyParameters, pathwayParameters, ambientCO2)
};

var sunlit = new AssimilationArea(sunlitAc1, sunlitAc2, sunlitAj, assimilation);
var shaded = new AssimilationArea(shadedAc1, shadedAc2, shadedAj, assimilation);
var canopyAttributes = new CanopyAttributes(canopyParameters, pathwayParameters, sunlit, shaded);

// Model the transpiration
var waterInteraction = new WaterInteraction(temperature);
var temperatureResponse = new TemperatureResponse(canopyParameters, pathwayParameters);
var transpiration = new Transpiration(canopyParameters, pathwayParameters, waterInteraction, temperatureResponse, ambientCO2);

// Model the photosynthesis
return new DCAPSTModel(
solarGeometry,
solarRadiation,
temperature,
pathwayParameters,
canopyAttributes,
transpiration
)
{
// From here, we can set additional options,
// such as verbosity, BioLimit, Reduction, etc.
PrintIntervalValues = false,
Biolimit = biolimit,
Reduction = reduction,
};
}

/// <summary>Event from sequencer telling us to do our potential growth.</summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
Expand Down Expand Up @@ -402,9 +405,9 @@ private void SetUpPlant()
private ICanopy GetLeaf()
{
if (plant == null) return null;
ICanopy leafFind = plant.FindChild<ICanopy>("Leaf");
if (leafFind == null) throw new ArgumentNullException(nameof(leafFind), "Cannot find leaf configuration");
return leafFind;
ICanopy find = plant.FindChild<ICanopy>("Leaf");
if (find == null) throw new ArgumentNullException(nameof(find), "Cannot find leaf configuration");
return find;
}

private IFunction GetRootShootRatioFunction()
Expand Down Expand Up @@ -490,4 +493,4 @@ private IEnumerable<string> GetPlantNames()
return plants;
}
}
}
}
10 changes: 0 additions & 10 deletions Models/DCaPST/Interfaces/Parameters/ICanopyParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,6 @@ public interface ICanopyParameters
/// </summary>
CanopyType Type { get; set; }

///// <summary>
///// Parameters used in modelling an assimilation pathway
///// </summary>
//IPathwayParameters Pathway { get; set; }

/// <summary>
/// Partial pressure of CO2 in air (microbar)
/// </summary>
double AirCO2 { get; set; }

/// <summary>
/// Partial pressure of O2 in air (microbar)
/// </summary>
Expand Down
11 changes: 9 additions & 2 deletions Models/DCaPST/Models/Assimilation/Assimilation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,21 @@ public abstract class Assimilation : IAssimilation
protected IPathwayParameters parameters;

/// <summary>
///
/// The amount of CO2 in the air.
/// </summary>
protected double ambientCO2;

/// <summary>
/// Constructor.
/// </summary>
/// <param name="canopy"></param>
/// <param name="parameters"></param>
public Assimilation(ICanopyParameters canopy, IPathwayParameters parameters)
/// <param name="ambientCO2"></param>
public Assimilation(ICanopyParameters canopy, IPathwayParameters parameters, double ambientCO2)
{
this.canopy = canopy;
this.parameters = parameters;
this.ambientCO2 = ambientCO2;
}

/// <summary>
Expand Down
11 changes: 9 additions & 2 deletions Models/DCaPST/Models/Assimilation/AssimilationPathway.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,22 @@ public class AssimilationPathway
/// </summary>
public double Vpr { get; private set; }

/// <summary>
/// The amount of CO2 in the air.
/// </summary>
private readonly double ambientCO2;

/// <summary>
///
/// </summary>
/// <param name="canopy"></param>
/// <param name="pathway"></param>
public AssimilationPathway(ICanopyParameters canopy, IPathwayParameters pathway)
/// <param name="ambientCO2"></param>
public AssimilationPathway(ICanopyParameters canopy, IPathwayParameters pathway, double ambientCO2)
{
Canopy = canopy;
Pathway = pathway;
this.ambientCO2 = ambientCO2;
}

/// <summary>
Expand All @@ -115,7 +122,7 @@ public void SetConditions(double temperature, double lai)
Gbs = Pathway.BundleSheathConductance * lai;
Vpr = Pathway.PEPRegeneration * lai;

MesophyllCO2 = Canopy.AirCO2 * Pathway.IntercellularToAirCO2Ratio;
MesophyllCO2 = ambientCO2 * Pathway.IntercellularToAirCO2Ratio;
ChloroplasticCO2 = 1000;
ChloroplasticO2 = 210000;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ public class AssimilationC3 : Assimilation
/// </summary>
/// <param name="canopy"></param>
/// <param name="parameters"></param>
/// <param name="ambientCO2"></param>
/// <returns></returns>
public AssimilationC3(ICanopyParameters canopy, IPathwayParameters parameters) : base(canopy, parameters)
public AssimilationC3(ICanopyParameters canopy, IPathwayParameters parameters, double ambientCO2) : base(canopy, parameters, ambientCO2)
{ }

/// <inheritdoc/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ public class AssimilationC4 : Assimilation
/// </summary>
/// <param name="canopy"></param>
/// <param name="parameters"></param>
/// <param name="ambientCO2"></param>
/// <returns></returns>
public AssimilationC4(ICanopyParameters canopy, IPathwayParameters parameters) : base(canopy, parameters)
public AssimilationC4(ICanopyParameters canopy, IPathwayParameters parameters, double ambientCO2) : base(canopy, parameters, ambientCO2)
{ }

/// <inheritdoc/>
public override void UpdateIntercellularCO2(AssimilationPathway pathway, double gt, double waterUseMolsSecond)
{
pathway.IntercellularCO2 = ((gt - waterUseMolsSecond / 2.0) * canopy.AirCO2 - pathway.CO2Rate) / (gt + waterUseMolsSecond / 2.0);
pathway.IntercellularCO2 = ((gt - waterUseMolsSecond / 2.0) * ambientCO2 - pathway.CO2Rate) / (gt + waterUseMolsSecond / 2.0);
}

/// <inheritdoc/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ public class AssimilationCCM : Assimilation
/// </summary>
/// <param name="canopy"></param>
/// <param name="parameters"></param>
/// <param name="ambientCO2"></param>
/// <returns></returns>
public AssimilationCCM(ICanopyParameters canopy, IPathwayParameters parameters) : base(canopy, parameters)
public AssimilationCCM(ICanopyParameters canopy, IPathwayParameters parameters, double ambientCO2) : base(canopy, parameters, ambientCO2)
{ }

/// <inheritdoc/>
public override void UpdateIntercellularCO2(AssimilationPathway pathway, double gt, double waterUseMolsSecond)
{
pathway.IntercellularCO2 = ((gt - waterUseMolsSecond / 2.0) * canopy.AirCO2 - pathway.CO2Rate) / (gt + waterUseMolsSecond / 2.0);
pathway.IntercellularCO2 = ((gt - waterUseMolsSecond / 2.0) * ambientCO2 - pathway.CO2Rate) / (gt + waterUseMolsSecond / 2.0);
}

/// <inheritdoc/>
Expand Down
Loading