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
Domains and Reactions (subtypes ofAbstractReaction), applying anyParameters settings from theparameters:sections in the config file. - calls
set_model_geometryallowing Reactions to create and attach Grids (AbstractMeshsubtypes) definingDomainsizes. - calls
register_methods!on each Reaction, allowing Reactions to define localVariableReactions and registerReactionMethods.ReactionMethods 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
VariableReactions toVariableDomains, applying any renaming from thevariable_links:sections in the config file. - calls
register_dynamic_methods!on each Reaction, allowing Reactions to createVariableReactions and registerReactionMethods that depend onVariableDomains created by other Reactions. - relinks
VariableReactions toVariableDomains to include these additionalVariableReactions - sorts each group of
ReactionMethods into dispatch order based on dependencies between Variables, storing the sorted lists in theModelstruct.
Model initialisation
To initialise the model, the numerical solver or host should then:
- call
create_modeldatato create aModelDatastruct that will store data Arrays for model Variables. A default Vector ofCellRanges covering the whole model, generated bycreate_default_cellrange, is also stored in thecellranges_allfield of theModelDatastruct. - call
allocate_variables!to allocate memory for model Variables, storing these Array references in theModelDatastruct. - call
check_readyto check that all Variables are allocated. - call
initialize_reactiondata!to:- store sorted lists of
ReactionMethods and corresponding Variable array accessors in theModelDatastruct. AReactionMethodmay include a prepare function to include additional buffers etc. - call
create_dispatch_methodliststo compile default model-wide lists ofinitializeanddomethods + corresponding Variable array accessors andCellRanges. This is stored as the in thedispatchlists_allof theModelDatastruct.
- store sorted lists of
- call
check_configurationto call any optionalcheck_configurationReaction methods to validate the model configuration. - call
dispatch_setupwithattribute_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_setupwithattribute_name = :norm_value. These Reaction setup methods should set state Variables according to the:norm_valueVariable 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
ModelDatato the solver.
- optionally (if normalisation values are required by a numerical solver), copy the Variable normalisation values from the arrays in
- optionally call
dispatch_setupwithattribute_name = :initial_valueto set state Variables according to the:initial_valueVariable 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_derivto call lists ofinitializeanddomethods 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 CellRanges can be used to select a subset of ReactionMethods 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 CellRanges with a subset of cell indices within Domains.
The custom Vector of CellRanges should then be supplied to
create_dispatch_methodliststo create lists of methods + correspondingCellRanges which can then be supplied todo_derivfor the model main loop.- Optionally to
VariableAggregators to create subsets of Variables and tiles withinDomains for a numerical solver.
Multithreaded models
To use with a multithreaded solver eg for a spatially tiled model:
- Set the global parameter
threadsafe=truein 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_barrierimplementing 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_barrierwill be inserted between these groups of independent Reactions.
Automatic differentiation
- Set
eltypewhen callingcreate_modeldatato the appropriate dual number type for a (forward) automatic differentation implementation. All model arrays are held in the createdModelDatastruct and multipleModelDatainstances can be created, allowing a combination of eg AD Jacobian and standard derivative calculations with different array types.