Control flow
Model Creation
A YAML format configuration file defines both the model structure (spatial domains containing biogeochemical variables and reactions that operate on them) and model parameter values. Reactions (subtypes of AbstractReaction
) are identified by Type name (without module prefix) in the configuration file.
To create the model, the numerical solver or host should call create_model_from_config
which reads the configuration file, and then:
- creates model
Domain
s and Reactions (subtypes ofAbstractReaction
), applying anyParameter
s settings from theparameters:
sections in the config file. - calls
set_model_geometry
allowing Reactions to create and attach Grids (AbstractMesh
subtypes) definingDomain
sizes. - calls
register_methods!
on each Reaction, allowing Reactions to define localVariableReaction
s and registerReactionMethod
s.ReactionMethod
s can be added to one of three groups, by callingadd_method_setup!
(called during model setup),add_method_initialize!
(called at start of main loop)add_method_do!
(called during main loop). - links
VariableReaction
s toVariableDomain
s, applying any renaming from thevariable_links:
sections in the config file. - calls
register_dynamic_methods!
on each Reaction, allowing Reactions to createVariableReaction
s and registerReactionMethod
s that depend onVariableDomain
s created by other Reactions. - relinks
VariableReaction
s toVariableDomain
s to include these additionalVariableReaction
s - sorts each group of
ReactionMethod
s into dispatch order based on dependencies between Variables, storing the sorted lists in theModel
struct.
Model initialisation
To initialise the model, the numerical solver or host should then:
- call
create_modeldata
to create aModelData
struct that will store data Arrays for model Variables. A default Vector ofCellRange
s covering the whole model, generated bycreate_default_cellrange
, is also stored in thecellranges_all
field of theModelData
struct. - call
allocate_variables!
to allocate memory for model Variables, storing these Array references in theModelData
struct. - call
check_ready
to check that all Variables are allocated. - call
initialize_reactiondata!
to:- store sorted lists of
ReactionMethod
s and corresponding Variable array accessors in theModelData
struct. AReactionMethod
may include a prepare function to include additional buffers etc. - call
create_dispatch_methodlists
to compile default model-wide lists ofinitialize
anddo
methods + corresponding Variable array accessors andCellRange
s. This is stored as the in thedispatchlists_all
of theModelData
struct.
- store sorted lists of
- call
check_configuration
to call any optionalcheck_configuration
Reaction methods to validate the model configuration. - call
dispatch_setup
withattribute_name = :setup
, which calls Reaction setup methods (registered byadd_method_setup!
) to initialise any internal Reaction state and any non-state Variables (eg grid variables).
State Variable initialization
To initialise state Variables and perform any Reaction-specific initialisation, the numerical solver or host should:
- call
dispatch_setup
withattribute_name = :norm_value
. These Reaction setup methods should set state Variables according to the:norm_value
Variable attribute (which can be set in thevariable_attributes:
section of the config file). Reactions may also use these values internally.- optionally (if normalisation values are required by a numerical solver), copy the Variable normalisation values from the arrays in
ModelData
to the solver.
- optionally (if normalisation values are required by a numerical solver), copy the Variable normalisation values from the arrays in
- optionally call
dispatch_setup
withattribute_name = :initial_value
to set state Variables according to the:initial_value
Variable attribute (which can be set in thevariable_attributes:
section of the config file).
Main loop
To calculate the model derivative, the numerical solver or host should:
- call
do_deriv
to call lists ofinitialize
anddo
methods created bycreate_dispatch_methodlists
Additional notes
Operator splitting and Domain tiling: Reaction and Domain subsets
The default initialisation described above calculates the model derivative for all model Reactions for all Domains, using the cellranges_all
, and dispatchlists_all
fields of the ModelData
struct. A custom Vector of CellRange
s can be used to select a subset of ReactionMethod
s by Domain
and operatorID
, eg to implement operator splitting. Tiles within Domain
eg to implement Domain decomposition for a multithreaded model can be defined by specifying CellRange
s with a subset of cell indices within Domain
s.
The custom Vector of CellRange
s should then be supplied to
create_dispatch_methodlists
to create lists of methods + correspondingCellRange
s which can then be supplied todo_deriv
for the model main loop.- Optionally to
VariableAggregator
s to create subsets of Variables and tiles withinDomain
s for a numerical solver.
Multithreaded models
To use with a multithreaded solver eg for a spatially tiled model:
- Set the global parameter
threadsafe=true
in the YAML file before callingcreate_model_from_config
. This is used by Reactions that require special handling eg atomic operations to maintain thread safety (usually those with scalar accumulator variables for totals etc). - Supply a
method_barrier
implementing a thread barrier function toinitialize_reactiondata!
. Reactions are sorted into groups, where each group has no dependencies and later groups depend on earlier ones. Themethod_barrier
will be inserted between these groups of independent Reactions.
Automatic differentiation
- Set
eltype
when callingcreate_modeldata
to the appropriate dual number type for a (forward) automatic differentation implementation. All model arrays are held in the createdModelData
struct and multipleModelData
instances can be created, allowing a combination of eg AD Jacobian and standard derivative calculations with different array types.