PlantSimEngine includes models for learning and testing. Load them with:
using PlantSimEngine.ExamplesThese examples show how to write equations and connect models. Check their assumptions before using them in a scientific study. Start with your first simulation for a guided example.
PlantSimEngine.ExamplesPlantSimEngine.Examples.AbstractCarbon_AllocationModelPlantSimEngine.Examples.AbstractCarbon_AssimilationModelPlantSimEngine.Examples.AbstractCarbon_BiomassModelPlantSimEngine.Examples.AbstractCarbon_DemandModelPlantSimEngine.Examples.AbstractDegreedaysModelPlantSimEngine.Examples.AbstractGrowthModelPlantSimEngine.Examples.AbstractLai_DynamicModelPlantSimEngine.Examples.AbstractLeaf_SurfaceModelPlantSimEngine.Examples.AbstractLight_InterceptionModelPlantSimEngine.Examples.AbstractLight_PartitioningModelPlantSimEngine.Examples.AbstractMaintenance_RespirationModelPlantSimEngine.Examples.AbstractProcess1ModelPlantSimEngine.Examples.AbstractProcess2ModelPlantSimEngine.Examples.AbstractProcess3ModelPlantSimEngine.Examples.AbstractProcess4ModelPlantSimEngine.Examples.AbstractProcess5ModelPlantSimEngine.Examples.AbstractProcess6ModelPlantSimEngine.Examples.AbstractProcess7ModelPlantSimEngine.Examples.AbstractSoil_WaterModelPlantSimEngine.Examples.AbstractToy_Daily_DevelopmentModelPlantSimEngine.Examples.AbstractToy_DevelopmentModelPlantSimEngine.Examples.AbstractToy_Environment_ControllerModelPlantSimEngine.Examples.AbstractToy_Environment_ReaderModelPlantSimEngine.Examples.AbstractToy_Selective_Call_ControllerModelPlantSimEngine.Examples.AbstractToy_Stock_WriterModelPlantSimEngine.Examples.BeerPlantSimEngine.Examples.Process1ModelPlantSimEngine.Examples.Process2ModelPlantSimEngine.Examples.Process3ModelPlantSimEngine.Examples.Process4ModelPlantSimEngine.Examples.Process5ModelPlantSimEngine.Examples.Process6ModelPlantSimEngine.Examples.Process7ModelPlantSimEngine.Examples.ToyAssimGrowthModelPlantSimEngine.Examples.ToyAssimModelPlantSimEngine.Examples.ToyCAllocationModelPlantSimEngine.Examples.ToyCBiomassModelPlantSimEngine.Examples.ToyCDemandModelPlantSimEngine.Examples.ToyDailyDevelopmentModelPlantSimEngine.Examples.ToyDegreeDaysCumulModelPlantSimEngine.Examples.ToyDevelopmentModelPlantSimEngine.Examples.ToyEnvironmentControllerModelPlantSimEngine.Examples.ToyEnvironmentHandlePlantSimEngine.Examples.ToyEnvironmentReaderModelPlantSimEngine.Examples.ToyLAIModelPlantSimEngine.Examples.ToyLAIfromLeafAreaModelPlantSimEngine.Examples.ToyLeafSurfaceModelPlantSimEngine.Examples.ToyLightPartitioningModelPlantSimEngine.Examples.ToyMaintenanceRespirationModelPlantSimEngine.Examples.ToyPlantLeafSurfaceModelPlantSimEngine.Examples.ToyPlantRmModelPlantSimEngine.Examples.ToyRUEGrowthModelPlantSimEngine.Examples.ToySelectiveCallControllerModelPlantSimEngine.Examples.ToySoilWaterModelPlantSimEngine.Examples.ToySpatialEnvironmentPlantSimEngine.Examples.ToyStockWriterModelPlantSimEngine.Examples.import_mtg_examplePlantSimEngine.fitPlantSimEngine.run!A sub-module with example models.
Examples used in the documentation for a set of multiscale models. The models can be found in the examples folder of the package, and are stored in the following files:
ToyAssimModel.jl
ToyCDemandModel.jl
ToyCAllocationModel.jl
ToySoilModel.jl
Examples
using PlantSimEngine
using PlantSimEngine.Examples
ToyAssimModel()carbon_allocation process abstract model.
All models implemented to simulate the carbon_allocation process must be a subtype of this type, e.g. struct MyCarbon_AllocationModel <: AbstractCarbon_AllocationModel end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractCarbon_AllocationModel)carbon_assimilation process abstract model.
All models implemented to simulate the carbon_assimilation process must be a subtype of this type, e.g. struct MyCarbon_AssimilationModel <: AbstractCarbon_AssimilationModel end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractCarbon_AssimilationModel)carbon_biomass process abstract model.
All models implemented to simulate the carbon_biomass process must be a subtype of this type, e.g. struct MyCarbon_BiomassModel <: AbstractCarbon_BiomassModel end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractCarbon_BiomassModel)carbon_demand process abstract model.
All models implemented to simulate the carbon_demand process must be a subtype of this type, e.g. struct MyCarbon_DemandModel <: AbstractCarbon_DemandModel end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractCarbon_DemandModel)Degreedays process abstract model.
All models implemented to simulate the Degreedays process must be a subtype of this type, e.g. struct MyDegreedaysModel <: AbstractDegreedaysModel end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractDegreedaysModel)growth process abstract model.
All models implemented to simulate the growth process must be a subtype of this type, e.g. struct MyGrowthModel <: AbstractGrowthModel end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractGrowthModel)LAI_Dynamic process abstract model.
All models implemented to simulate the LAI_Dynamic process must be a subtype of this type, e.g. struct MyLai_DynamicModel <: AbstractLai_DynamicModel end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractLai_DynamicModel)leaf_surface process abstract model.
All models implemented to simulate the leaf_surface process must be a subtype of this type, e.g. struct MyLeaf_SurfaceModel <: AbstractLeaf_SurfaceModel end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractLeaf_SurfaceModel)light_interception process abstract model.
All models implemented to simulate the light_interception process must be a subtype of this type, e.g. struct MyLight_InterceptionModel <: AbstractLight_InterceptionModel end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractLight_InterceptionModel)light_partitioning process abstract model.
All models implemented to simulate the light_partitioning process must be a subtype of this type, e.g. struct MyLight_PartitioningModel <: AbstractLight_PartitioningModel end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractLight_PartitioningModel)maintenance_respiration process abstract model.
All models implemented to simulate the maintenance_respiration process must be a subtype of this type, e.g. struct MyMaintenance_RespirationModel <: AbstractMaintenance_RespirationModel end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractMaintenance_RespirationModel)process1 process abstract model.
All models implemented to simulate the process1 process must be a subtype of this type, e.g. struct MyProcess1Model <: AbstractProcess1Model end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractProcess1Model)process2 process abstract model.
All models implemented to simulate the process2 process must be a subtype of this type, e.g. struct MyProcess2Model <: AbstractProcess2Model end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractProcess2Model)process3 process abstract model.
All models implemented to simulate the process3 process must be a subtype of this type, e.g. struct MyProcess3Model <: AbstractProcess3Model end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractProcess3Model)process4 process abstract model.
All models implemented to simulate the process4 process must be a subtype of this type, e.g. struct MyProcess4Model <: AbstractProcess4Model end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractProcess4Model)process5 process abstract model.
All models implemented to simulate the process5 process must be a subtype of this type, e.g. struct MyProcess5Model <: AbstractProcess5Model end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractProcess5Model)process6 process abstract model.
All models implemented to simulate the process6 process must be a subtype of this type, e.g. struct MyProcess6Model <: AbstractProcess6Model end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractProcess6Model)process7 process abstract model.
All models implemented to simulate the process7 process must be a subtype of this type, e.g. struct MyProcess7Model <: AbstractProcess7Model end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractProcess7Model)soil_water process abstract model.
All models implemented to simulate the soil_water process must be a subtype of this type, e.g. struct MySoil_WaterModel <: AbstractSoil_WaterModel end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractSoil_WaterModel)toy_daily_development process abstract model.
All models implemented to simulate the toy_daily_development process must be a subtype of this type, e.g. struct MyToy_Daily_DevelopmentModel <: AbstractToy_Daily_DevelopmentModel end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractToy_Daily_DevelopmentModel)toy_development process abstract model.
All models implemented to simulate the toy_development process must be a subtype of this type, e.g. struct MyToy_DevelopmentModel <: AbstractToy_DevelopmentModel end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractToy_DevelopmentModel)toy_environment_controller process abstract model.
All models implemented to simulate the toy_environment_controller process must be a subtype of this type, e.g. struct MyToy_Environment_ControllerModel <: AbstractToy_Environment_ControllerModel end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractToy_Environment_ControllerModel)toy_environment_reader process abstract model.
All models implemented to simulate the toy_environment_reader process must be a subtype of this type, e.g. struct MyToy_Environment_ReaderModel <: AbstractToy_Environment_ReaderModel end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractToy_Environment_ReaderModel)toy_selective_call_controller process abstract model.
All models implemented to simulate the toy_selective_call_controller process must be a subtype of this type, e.g. struct MyToy_Selective_Call_ControllerModel <: AbstractToy_Selective_Call_ControllerModel end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractToy_Selective_Call_ControllerModel)toy_stock_writer process abstract model.
All models implemented to simulate the toy_stock_writer process must be a subtype of this type, e.g. struct MyToy_Stock_WriterModel <: AbstractToy_Stock_WriterModel end.
You can list all models implementing this process using subtypes:
Examples
subtypes(AbstractToy_Stock_WriterModel)Beer(k)Beer-Lambert law for light interception.
Required inputs: LAI in m[leaf]² m[ground]⁻². Required environment input: Ri_PAR_f, the incident flux of atmospheric radiation in the PAR, in W m[ground]⁻² (== J m[ground]⁻² s⁻¹).
Output: aPPFD, the canopy-absorbed Photosynthetic Photon Flux Density in μmol[PAR] m[ground]⁻² s⁻¹. It is not a mean leaf-area-basis PPFD.
Process4Model()A dummy model implementing a "process4" process for testing purposes. It computes the inputs needed for the coupled processes 1-2-3.
sourceProcess5Model()A dummy model implementing a "process5" process for testing purposes. It needs the outputs from the coupled processes 1-2-3.
sourceProcess6Model()A dummy model implementing a "process6" process for testing purposes. It needs the outputs from the coupled processes 1-2-3, but also from process 7 that is itself independant.
sourceProcess7Model()A dummy model implementing a "process7" process for testing purposes. It is independent (needs :var0 only as for Process4Model), but its outputs are used by Process6Model, so it is a soft-coupling.
sourceToyAssimGrowthModel(Rm_factor, Rg_cost)
ToyAssimGrowthModel(; LUE=0.2, Rm_factor = 0.5, Rg_cost = 1.2)Computes the biomass growth of a plant.
Arguments
LUE=0.2: the light use efficiency, in gC mol[PAR]⁻¹
Rm_factor=0.5: the fraction of assimilation that goes into maintenance respiration
Rg_cost=1.2: the cost of growth maintenance, in gram of carbon biomass per gram of assimilate
Inputs
aPPFD: the absorbed photosynthetic photon flux density, in mol[PAR] m⁻² time-step⁻¹
Outputs
carbon_assimilation: the assimilation, in gC m⁻² time-step⁻¹
Rm: the maintenance respiration, in gC m⁻² time-step⁻¹
Rg: the growth respiration, in gC m⁻² time-step⁻¹
biomass_increment: the daily biomass increment, in gC m⁻² time-step⁻¹
biomass: the plant biomass, in gC m⁻² time-step⁻¹
ToyAssimModel(LUE)Computes the assimilation of a plant (= photosynthesis).
Arguments
LUE=0.2: the light use efficiency, in gC mol[PAR]⁻¹
Inputs
aPPFD: the absorbed photosynthetic photon flux density, in mol[PAR] m⁻² time-step⁻¹
soil_water_content: the soil water content, in %
Outputs
carbon_assimilation: the assimilation or photosynthesis, also sometimes denoted A, in gC m⁻² time-step⁻¹
Details
The assimilation is computed as the product of the absorbed photosynthetic photon flux density (aPPFD) and the light use efficiency (LUE), so the units of the assimilation usually are in gC m⁻² time-step⁻¹, but they could be in another spatial or temporal unit depending on the unit of aPPFD, e.g. if aPPFD is in mol[PAR] plant⁻¹ time-step⁻¹, the assimilation will be in gC plant⁻¹ time-step⁻¹.
ToyCAllocationModel()Computes the carbon allocation to each organ of a plant based on the plant total carbon offer and individual organ demand. This model should be used at the plant scale, because it first computes the carbon availaible for allocation as the minimum between the total demand (sum of organs' demand) and total carbon offer (sum of organs' assimilation - total maintenance respiration), and then allocates the carbon relative to each organ's demand.
Inputs
carbon_assimilation: a vector of the assimilation of all photosynthetic organs, usually in gC m⁻² time-step⁻¹
Rm: the maintenance respiration of the plant, usually in gC m⁻² time-step⁻¹
carbon_demand: a vector of the carbon demand of the organs, usually in gC m⁻² time-step⁻¹
Outputs
carbon_assimilation: the carbon assimilation, usually in gC m⁻² time-step⁻¹
Details
The units usually are in gC m⁻² time-step⁻¹, but they could be in another spatial or temporal unit depending on the unit of the inputs, e.g. in gC plant⁻¹ time-step⁻¹.
sourceToyCBiomassModel(construction_cost)Computes the carbon biomass of an organ based on the carbon allocation and construction cost.
Arguments
construction_cost: the construction cost of the organ, usually in gC gC⁻¹. Should be understood as the amount of carbon needed to build 1g of carbon biomass.
Inputs
carbon_allocation: the carbon allocation to the organ for the time-step, usually in gC m⁻² time-step⁻¹
Outputs
carbon_biomass_increment: the increment of carbon biomass, usually in gC time-step⁻¹
carbon_biomass: the carbon biomass, usually in gC
growth_respiration: the growth respiration, usually in gC time-step⁻¹
ToyCDemandModel(optimal_biomass, development_duration)
ToyCDemandModel(; optimal_biomass, development_duration)Computes the carbon demand of an organ depending on its biomass under optimal conditions and the duration of its development in degree days. The model assumes that the carbon demand is linear througout the duration of the development.
Arguments
optimal_biomass: the biomass of the organ under optimal conditions, in gC
development_duration: the duration of the development of the organ, in degree days
Inputs
TT: the thermal time, in degree days
Outputs
carbon_demand: the carbon demand, in gC
ToyDailyDevelopmentModel(increment)Accumulate one configured growth increment every 24 simulation steps. The model declares this default cadence and hold-last output semantics.
sourceToyDegreeDaysCumulModel(;init_TT=0.0, T_base=10.0, T_max=43.0)Computes the thermal time in degree days and cumulated degree-days based on the average daily temperature (T), the initial cumulated degree days, the base temperature below which there is no growth, and the maximum temperature for growh.
ToyDevelopmentModel(efficiency)Compute one growth increment from required thermal time and an optional stress factor.
Inputs
TT: required thermal time for the current step.
stress: dimensionless stress factor, defaulting to 1.0.
Outputs
growth: growth increment for the current step.
ToyEnvironmentControllerModel(trial_temperature, accepted_temperature)Demonstrate a typed trial environment followed by one accepted environment commit and publication.
sourceToyLAIModel(;max_lai=8.0, dd_incslope=800, inc_slope=110, dd_decslope=1500, dec_slope=20)Computes the Leaf Area Index (LAI) based on a sigmoid function of thermal time.
Arguments
max_lai: the maximum LAI value
dd_incslope: the thermal time at which the LAI starts to increase
inc_slope: the slope of the increase
dd_decslope: the thermal time at which the LAI starts to decrease
dec_slope: the slope of the decrease
Inputs
TT_cu: the cumulated thermal time since the beginning of the simulation, usually in °C days
Outputs
LAI: the Leaf Area Index, usually in m² m⁻²
ToyLAIfromLeafAreaModel()Computes the Leaf Area Index (LAI) of the model based on the plants leaf area.
Arguments
scene_area: the area of the model, usually in m²
Inputs
surface: a vector of plant leaf surfaces, usually in m²
Outputs
LAI: the Leaf Area Index of the model, usually in m² m⁻²
total_surface: the total surface of the plants, usually in m²
ToyLeafSurfaceModel(SLA)Computes the individual leaf surface from its biomass using the SLA.
Arguments
SLA: the specific leaf area, usually in m² gC⁻¹. Should be understood as the surface area of a leaf per unit of carbon biomass.
Values typically range from 0.002 to 0.027 m² gC⁻¹.
Inputs
carbon_biomass: the carbon biomass of the leaf, usually in gC
Outputs
surface: the leaf surface, usually in m²
ToyLightPartitioningModel()Partitions absorbed light in proportion to organ surface. This is a teaching model, not a calculation of the light environment of an individual leaf.
Inputs
aPPFD_larger_scale: absorbed photosynthetic photon flux density at the larger scale, for example in μmol photons m⁻² ground s⁻¹.
surface: surface of the receiving organ, in m².
total_surface: sum of the organ surfaces sharing this light, in m²; must be positive.
Outputs
aPPFD: this organ's contribution, in the same units and on the same area basis as aPPFD_larger_scale. A ground-area input gives a ground-area contribution, not a photon flux density per unit leaf area.
The contributions sum to the supplied larger-scale value when total_surface equals the sum of receiving surfaces. Use an explicit area conversion before passing a contribution to a model that requires a leaf-area photon flux density.
RmQ10FixedN(Q10, Rm_base, T_ref, P_alive, nitrogen_content)Maintenance respiration based on a Q10 computation with fixed nitrogen values and proportion of living cells in the organs.
Arguments
Q10: Q10 factor (values should usually range between: 1.5 - 2.5, with 2.1 being the most common value)
Rm_base: Base maintenance respiration (gC gDM⁻¹ time-step⁻¹). Should be around 0.06.
T_ref: Reference temperature at which Q10 was measured (usually around 25.0°C)
P_alive: proportion of living cells in the organ
nitrogen_content: nitrogen content of the organ (gN gC⁻¹)
Inputs
carbon_biomass: the carbon biomass of the organ in gC
ToyPlantLeafSurfaceModel()Computes the leaf surface at plant scale by summing the individual leaf surfaces.
Inputs
leaf_surfaces: a vector of leaf surfaces, usually in m²
Outputs
surface: the leaf surface at plant scale, usually in m²
ToyPlantRmModel()Total plant maintenance respiration based on the sum of Rm_organs, the maintenance respiration of the organs.
Inputs
Rm_organs: a vector of maintenance respiration from all organs in the plant in gC time-step⁻¹
Outputs
Rm: the total plant maintenance respiration in gC time-step⁻¹
ToyRUEGrowthModel(efficiency)Computes the carbon biomass increment of a plant based on the radiation use efficiency principle.
Arguments
efficiency: the radiation use efficiency, in gC[biomass] mol[PAR]⁻¹
Inputs
aPPFD: the absorbed photosynthetic photon flux density, in mol[PAR] m⁻² time-step⁻¹
Outputs
biomass_increment: the daily biomass increment, in gC[biomass] m⁻² time-step⁻¹
biomass: the plant biomass, in gC[biomass] m⁻² time-step⁻¹
ToySelectiveCallControllerModel(
trial_temperatures,
accepted_temperature;
selected_object,
)Resolve several hard-call targets, run selected_object for several unpublished trials, then publish one accepted result.
ToySoilWaterModel(values=[0.5])A toy model to compute the soil water content. The model simply take a random value in the values range using rand.
Outputs
soil_water_content: the soil water content (%).
Arguments
values: a range of soil_water_content values to sample from. Can be a vector of values [0.5,0.6] or a range 0.1:0.1:1.0. Default is [0.5].
ToySpatialEnvironment(cells; step_seconds=3600.0)A minimal spatial environment for examples and tests.
cells maps cell ids to named tuples of environment variables. Objects select a cell with geometry such as (cell=:sun,). PlantSimEngine compiles that cell id into a ToyEnvironmentHandle, so sampling does not resolve geometry inside the model kernel loop. An application configured with sink=:cells may also commit an accepted named-tuple state to its bound cell.
ToyStockWriterModel(value)Write one configured stock value. Several named applications of this model can demonstrate canonical writer ordering and stream-only output routing.
sourceimport_mtg_example()Returns an example multiscale tree graph (MTG) with a model, a soil, and a plant with two internodes and two leaves.
Examples
julia> using PlantSimEngine.Examplesjulia> import_mtg_example()
/ 1: Scene
├─ / 2: Soil
└─ + 3: Plant
└─ / 4: Internode
├─ + 5: Leaf
└─ < 6: Internode
└─ + 7: Leaffit(::Type{Beer}, df; J_to_umol=PlantMeteo.Constants().J_to_umol)Compute the k parameter of the Beer-Lambert law from measurements.
Arguments
::Type{Beer}: the model type
df: a DataFrame with the following columns:
aPPFD: canopy-absorbed Photosynthetic Photon Flux Density in μmol[PAR] m[ground]⁻² s⁻¹
LAI: leaf area index in m[leaf]² m[ground]⁻²
Ri_PAR_f: incident PAR flux in W m[ground]⁻² (== J m[ground]⁻² s⁻¹)
aPPFD and Ri_PAR_f * J_to_umol must use the same ground-area basis. LAI and the converted incident flux must be finite and strictly positive, and the implied absorbed fraction must satisfy 0 ≤ f_abs < 1.
Examples
Import the example models defined in the Examples sub-module:
using PlantSimEngine, PlantMeteo, DataFrames
using PlantSimEngine.ExamplesCreate a CompositeModel with one canopy model on a plant object, then fit Beer to the data:
meteo = Atmosphere(
T=20.0,
Wind=1.0,
P=101.3,
Rh=0.65,
Ri_PAR_f=300.0,
)
model = CompositeModel(
Beer(0.6);
status=(LAI=2.0,),
id=:plant,
scale=:Plant,
environment=meteo,
)
simulation = run!(model)
plant = final_state(simulation, One(scale=:Plant))
df = DataFrame(
aPPFD=[plant.aPPFD],
LAI=[plant.LAI],
Ri_PAR_f=[meteo.Ri_PAR_f[1]],
)
Evaluation.fit(Beer, df)run!(model::Beer, status, environment, constants, context)Computes the canopy-absorbed photosynthetic photon flux density (aPPFD, µmol[PAR] m[ground]⁻² s⁻¹) from the incoming PAR radiation flux (Ri_PAR_f, W m[ground]⁻²) and the Beer-Lambert law of light extinction.
Arguments
model: the current Beer model instance.
status: the application-local view of the target Object status.
environment: sampled environment, such as an Atmosphere row.
constants: physical constants supplied by the CompositeModel run.
context: runtime context; this kernel does not use it.
Examples
model = CompositeModel(
Beer(0.5);
status=(LAI=2.0,),
id=:plant,
scale=:Plant,
environment=Atmosphere(
T=20.0,
Wind=1.0,
P=101.3,
Rh=0.65,
Ri_PAR_f=300.0,
duration=Hour(1),
),
)
run!(model)
only(model_objects(model; scale=:Plant)).status.aPPFD