-
Notifications
You must be signed in to change notification settings - Fork 45
FABM 1.0
FABM 1.0 is designed as the first long-term stable release: it standardises the application programming interfaces (APIs) that have been developed over the past 11 years and eliminates any inconsistencies and duplication of functionality. This affects the host API, that is, the set of routines that link FABM and its host (typically a hydrodynamic model). The FABM couplers developed for most hydrodynamic models will require small changes to become compatible with FABM 1.0. Biogeochemical models included in/linked to FABM do not require changes, provided they follow the coding conventions that have been in place since 2015. However, some functionality that has been deprecated for a long time (e.g., namelists-based configuration) is now removed. Biogeochemical models that rely on that will need an update.
FABM 1.0 drops support for reading its configuration from namelists (fabm.nml); this functionality has been superseded by a yaml-based system (fabm.yaml) in 2014. Biogeochemical models that exclusively support namelist-based configuration will need an update to use yaml. Without this update they will still compile but not be configurable (argument configunit
will always be -1).
In addition, FABM 1.0 drops a large number of long-deprecated aliases for preprocessor macros. This includes for instance _SET_ODE_BEN_
, which has been replaced by _SET_BOTTOM_ODE_
in 2013.
Most changes are name changes of existing variables and procedures. To facilitate migration to the new FABM version, a new fabm_v0_compatibility
module has been created that makes many host APIs available under their original names. By adding use fabm_v0_compatibility
you can minimize the changes needed to get your host working with FABM 1.0. However, this is not a long-term solution. The compatibility module will ultimately be removed. We therefore recommend you adopt the conventions outlined below as soon as possible.
You can detect which FABM version is used at compile time: preprocessor symbol _FABM_API_VERSION_
will be 1 for FABM 1.0, and 0 for earlier versions. Thus, after migrating your coupler to FABM 1.0, you can include something like this:
#include fabm_version.h
#if _FABM_API_VERSION_ < 1
# error You need FABM 1.0 or later
#endif
By placing that early in your source code, users with a pre-1.0 FABM version will be told about the need to upgrade to a new version, instead of getting a large number of errors about undefined symbols. The above code segment depends on fabm_version.h
, which has been provided with FABM since July 2019.
To guarantee that use fabm
does not import names that already exist in the host namespace, all public FABM types are prefixed with type_fabm_
, just like public methods and variables are prefixed with fabm_
. A few additional names are changed for consistency and simplicity.
Old name | New name |
---|---|
type_model | type_fabm_model |
type_external_variable | type_fabm_variable |
type_horizontal_state_variable_info | type_fabm_horizontal_state_variable |
type_bulk_variable_id | type_fabm_interior_variable_id |
type_horizontal_variable_id | type_fabm_horizontal_variable_id |
type_scalar_variable_id | type_fabm_scalar_variable_id |
standard_variables | fabm_standard_variables |
Note that fabm_standard_variables
in the above is the object with all of FABM's predefined standard variables (e.g, fabm_standard_variables%temperature
). fabm_standard_variables
is also the name of a module. However, all relevant variables in that module are exposed by the fabm
and fabm_types
modules, which means you should not need to use fabm_standard_variables
. Thus there is no risk of name clashes.
To improve the performance of object-oriented access to a FABM model, it needs to be declared as class pointer, for instance:
class (type_fabm_model), pointer :: model
At the same time, the name and syntax of the model creation function is changed from
call fabm_create_model_from_yaml_file(model, ...)
to
model => fabm_create_model(...)
The fabm_create_model
function is available from the main fabm
module. You no longer need to import fabm_config
.
As soon as the model object is created (by calling fabm_create_model
), FABM APIs should be accessed through the model's type-bound procedures. Typically, this means that calls such as call fabm_set_domain(model, ...)
need to be replaced by call model%set_domain(...)
.
Old syntax | New syntax |
---|---|
fabm_initialize(model, ...) | model%initialize(...) |
fabm_finalize(model, ...) | model%finalize(...) |
fabm_set_domain(model, ...) | model%set_domain(...) |
fabm_set_mask(model, ...) | model%set_mask(...) |
fabm_check_ready(model, ...) | model%start(...) |
fabm_initialize_state(model, ...) | model%initialize_interior_state(...) |
fabm_initialize_surface_state(model, ...) | model%initialize_surface_state(...) |
fabm_initialize_bottom_state(model, ...) | model%initialize_bottom_state(...) |
fabm_do(model, ...) | model%get_interior_sources(...) |
fabm_do_surface(model, ...) | model%get_surface_sources(...) |
fabm_do_bottom(model, ...) | model%get_bottom_sources(...) |
fabm_get_vertical_movement(model, ...) | model%get_vertical_movement(...) |
fabm_check_state(model, ...) | model%check_interior_state(...) |
fabm_check_surface_state(model, ...) | model%check_surface_state(...) |
fabm_check_bottom_state(model, ...) | model%check_bottom_state(...) |
fabm_get_conserved_quantities(model, ...) | model%get_interior_conserved_quantities(...) |
fabm_get_horizontal_conserved_quantities(model, ...) | model%get_horizontal_conserved_quantities(...) |
fabm_link_interior_data(model, ...) | model%link_interior_data(...) |
fabm_link_horizontal_data(model, ...) | model%link_horizontal_data(...) |
fabm_link_scalar(model, ...) | model%link_scalar(...) |
fabm_link_interior_state_data(model, ...) | model%link_interior_state_data(...) |
fabm_link_bottom_state_data(model, ...) | model%link_bottom_state_data(...) |
fabm_link_surface_state_data(model, ...) | model%link_surface_state_data(...) |
fabm_get_interior_data(model, ...) | model%get_interior_data(...) |
fabm_get_horizontal_data(model, ...) | model%get_horizontal_data(...) |
fabm_get_scalar_data(model, ...) | model%get_scalar_data(...) |
fabm_get_interior_diagnostic_data(model, ...) | model%get_interior_diagnostic_data(...) |
fabm_get_horizontal_diagnostic_data(model, ...) | model%get_horizontal_diagnostic_data(...) |
The following are removed altogether:
- fabm_get_light_extinction
- fabm_get_albedo
- fabm_get_drag
- fabm_get_light
- model%set_surface_index
- model%set_bottom_index (unless
_FABM_BOTTOM_INDEX_
is -1)
As before, the extents of the spatial domain are set with model%set_domain
. Optionally, you can now also set the active domain by calling model%set_domain_start
with the first active index for each dimension (default: 1) and calling model%set_domain_stop
with the last active index for each dimension (default: the dimension size provided to set_domain
). The extents of the active domain are used to infer the index of the surface and bottom layers, which is why model%set_surface_index
and model%set_bottom_index
have been removed (the latter only if FABM_BOTTOM_INDEX_
is not -1).
The full domain extents provided to set_domain
determine the shape of all arrays provided to the link_data
family of routines and the shape of all diagnostics provided by FABM. Conversely, the active domain determines for which grid cells FABM will compute biogeochemical properties (e.g., sources). This distinction can be useful: for instance, the full domain may include halo zones that need to be present for FABM diagnostics, but can be excluded from the active domain (i.e., from computation).
Calls to FABM within a single model time step must be encapsulated between a call to prepare_inputs
and a call to finalize_outputs
.
- Before you retrieve model source terms (
model%get_interior_sources
,model%get_bottom_sources
,model%get_surface_sources
), you must callmodel%prepare_inputs
. This ensures that all variables that the source routines depend on are computed. This replaces calls tofabm_update_time
,fabm_get_light_extinction
,fabm_get_light
, which together achieved the same in the past.model%prepare_inputs
optionally takes arguments for the current time, year, month, day, just likefabm_update_time
did before. - The routines that return sources (
model%get_interior_sources
,model%get_bottom_sources
,model%get_surface_sources
) can be called in any order. - After you retrieve model source terms, you must call
model%finalize_outputs
. This ensures that diagnostics unrelated to source routines are computed.
Both model%prepare_inputs
and model%finalize_outputs
operate on the entire active model domain. They therefore do not take spatial indices as argument and should be placed outside any spatial loops.
Before you can use any of these calls, you must call model%start
(previously fabm_check_ready
) at the start of the simulation. That was optional before, but now it is required.
For questions about FABM's use or development, visit Discussions. If you would like to cite FABM, please refer to its main publication and/or URLs.
Background
User guide
- Obtaining the source code
- Building and installing
- Setting up a simulation
- Available biogeochemical models
- Specific hosts
Developer guide
Updates
Tips and tricks
Support
How to cite
Licensing and copyright
Acknowledgements
Presentations
Workshops