|
|
(190 intermediate revisions by 5 users not shown) |
Line 1: |
Line 1: |
| = '''CSDMS Basic Modeling Interface (version 1.0)''' =
| | {{PageTitle| Basic Model Interface (BMI) }} |
| :
| |
| * In order to simplify conversion of an existing model to a reusable, plug-and-play model component, CSDMS has developed a simple interface called the '''''Basic Model Interface''''' or '''BMI'''. Recall that in this context an '''''interface''''' is a named set of functions with prescribed function names, argument types and return types.
| |
| :
| |
| * By design, the BMI functions are straightforward to implement in any of the languages supported by CSDMS, which include C, C++, Fortran (all years), Java and Python. Even though some of these languages are object-oriented and support user-defined types, the BMI functions use only simple (universal) data types.
| |
| :
| |
| * Also by design, the BMI functions are '''''noninvasive'''''. A BMI-compliant model is not required to use CSDMS data structures and does not make any calls to CSDMS components or tools. BMI therefore introduces no dependencies into a model and the model can still be used in a "stand-alone" manner.
| |
| :
| |
| * Any model that provides the BMI functions can be easily be converted to a CSDMS plug-and-play component with a CSDMS '''''Component Model Interface''''' or '''CMI'''. The BMI functions are called by the CMI, by the framework and by service components.
| |
|
| |
|
| <br/> | | <div class=AutoScaleImage>[[ File:Bmi-logo-below-lowercase.png | 325 px | right ]]</div> |
| <!-- ============================================= -->
| |
| == {{ Bar Heading| text=Fine-grained Control Functions}} ==
| |
| :
| |
| <syntaxhighlight lang=sidl> | |
| void initialize (in string config_file)
| |
| void update (in double dt) // Advance model variables by time interval, dt (dt=-1 means use model time step)
| |
| void finalize ()
| |
| void run_model (in string config_file) // Do a complete model run. Not needed for CMI.
| |
| </syntaxhighlight>
| |
| :
| |
| * These BMI functions are critical to plug-and-play modeling because they allow a calling component to bypass a model's own time loop. They also provide the caller with fine-grained control over the model, similar to a TV remote control.
| |
|
| |
|
| <br/>
| | '''Version 2.0''' |
| <!-- ============================================= -->
| |
| == {{ Bar Heading| text=Model Information Functions}} ==
| |
| :
| |
| <syntaxhighlight lang=sidl>
| |
| array<string> get_input_var_names()
| |
| array<string> get_output_var_names()
| |
| string get_attribute( in string att_name ) // (for model_name, mesh_type, time_step_type, etc.)
| |
| </syntaxhighlight>
| |
| :
| |
| * These BMI functions are called by the CSDMS framework in order to determine what input variables each model component needs and what output variables it can provide to other components.
| |
|
| |
|
| * Note that "long variable name" and "long_var_name" refer to standardized variable names from the [[CSDMS_Standard_Names | '''CSDMS Standard Names''']].
| | Automobiles benefit from a standard interface--regardless of whether you drive a pickup truck or an electric two-seater, |
| | you have an ignition, an accelerator, and steering wheel. |
| | Imagine spending weeks of study to switch from one type of automobile to another, |
| | or from one brand to another. |
| | At CSDMS, |
| | we believe that numerical models, and the sub-components that make up these models, should offer a similar kind of standardization. |
| | To this end, we have developed the Basic Model Interface (BMI): a set of standard query and control functions that, when added to a model code, make that model both easier to learn and easier to couple with other software. |
|
| |
|
| * The '''''get_input_var_names()''''' function returns a string array of the model's input variable names as "long variable names". Similarly, the '''''get_output_var_names()''''' function returns a string array of the models output variable names.
| | BMI is an element of the [[Workbench|CSDMS Workbench]], an integrated system of software tools, technologies, and standards for building and coupling models. |
|
| |
|
| * The '''''get_attribute()''''' function is passed an attribute name from the following list:
| | == Links == |
| model_name
| |
| author_name
| |
| mesh_type
| |
| time_step_type
| |
| :and returns a corresponding string. For the "mesh_type" attribute, the allowed return values are:
| |
| uniform, rectilinear, s_mesh and u_mesh
| |
| :as described below. For the "time_step_type" attribute, the allowed return values are:
| |
| fixed, adaptive, local
| |
|
| |
|
| <br/>
| | * The latest [http://bmi.readthedocs.io/ BMI documentation], including the [https://bmi.readthedocs.io/en/latest/bmi.getting_started.html Getting Started Guide] and [https://bmi.readthedocs.io/en/latest/bmi.best_practices.html BMI Best Practices]. |
| <!-- ============================================= -->
| | * The central BMI repository on [https://github.com/csdms/bmi GitHub]: Go here to contribute to BMI, ask a BMI-related question, or submit an issue. |
| == {{ Bar Heading| text=Variable Information Functions}} ==
| | * The BMI 2.0 language specifications for [https://github.com/csdms/bmi-c C], [https://github.com/csdms/bmi-cxx C++], [https://github.com/csdms/bmi-fortran Fortran], [https://github.com/csdms/bmi-java Java], and [https://github.com/csdms/bmi-python Python]. If you have a model in one of these supported languages, implement the corresponding spec to create a BMI. |
| : | | * Sample implementations in [https://github.com/csdms/bmi-example-c C], [https://github.com/csdms/bmi-example-cxx C++], [https://github.com/csdms/bmi-example-fortran Fortran], [https://github.com/csdms/bmi-example-java Java], and [https://github.com/csdms/bmi-example-python Python]. These examples demonstrate how to implement a BMI for a simple model. |
| <syntaxhighlight lang=sidl>
| | * The [http://www.sciencedirect.com/science/article/pii/S0098300412001252 Peckham et al. (2013) article] in ''Computers & Geosciences'' where the concept of BMI was proposed. |
| string get_var_type( in string long_var_name ) // ( returns type_string, e.g. ‘double’)
| | * The [https://joss.theoj.org/papers/10.21105/joss.02317 Hutton et al. (2020) article] in ''Journal of Open Source Software'' describing BMI 2.0. |
| string get_var_units( in string long_var_name ) // ( returns unit_string, e.g. ‘meters’ )
| |
| int get_var_rank( in string long_var_name ) // ( returns array rank or 0 for scalar)
| |
| string get_var_name( in string long_var_name ) // ( returns model’s internal, short name )
| |
|
| |
| double get_time_step() // (returns the model’s current timestep; adaptive or fixed.)
| |
| string get_time_units() // (returns unit string for model time, e.g. ‘seconds’, ‘years’)
| |
| double get_start_time()
| |
| double get_current_time()
| |
| double get_end_time()
| |
| </syntaxhighlight>
| |
|
| |
|
| :
| | == Citation == |
| * These BMI functions are called by the CSDMS framework to obtain information about a particular input or output variable. Based on this information, the framework can apply type or unit conversion when necessary.
| |
|
| |
|
| * Note that "long variable name" and "long_var_name" refer to standardized variable names from the [[CSDMS_Standard_Names | '''CSDMS Standard Names''']].
| | If you use BMI in your work, please cite: |
|
| |
|
| | * Hutton, E.W.H., Piper, M.D., and Tucker, G.E., 2020. The Basic Model Interface 2.0: A standard interface for coupling numerical models in the geosciences. ''Journal of Open Source Software'', '''5(51)''', 2317, https://doi.org/10.21105/joss.02317. |
|
| |
|
| '''GET_VAR_TYPE''': Return data type of a variable as a string. Some possible values are given in the following table.
| | * Peckham, S.D., Hutton, E.W., and Norris, B., 2013. A component-based approach to integrated modeling in the geosciences: The design of CSDMS. ''Computers & Geosciences'', '''53''', pp.3-12, http://dx.doi.org/10.1016/j.cageo.2012.04.002. |
| | |
| {|
| |
| ! align=left width=250 | BMI datatype
| |
| ! align=left width=150 | C datatype
| |
| |-
| |
| | BMI_CHAR
| |
| | <tt>char</tt>
| |
| |-
| |
| | BMI_UNSIGNED_CHAR
| |
| | <tt>unsigned char</tt>
| |
| |-
| |
| | BMI_INT
| |
| | <tt>signed int</tt>
| |
| |-
| |
| | BMI_LONG
| |
| | <tt>signed long int</tt>
| |
| |-
| |
| | BMI_UNSIGNED
| |
| | <tt>unsigned int</tt>
| |
| |-
| |
| | BMI_UNSIGNED_LONG
| |
| | <tt>unsigned long int</tt>
| |
| |-
| |
| | BMI_FLOAT
| |
| | <tt>float</tt>
| |
| |-
| |
| | BMI_DOUBLE
| |
| | <tt>double</tt>
| |
| |-
| |
| |}
| |
| | |
| <br/>
| |
| <!-- ============================================= -->
| |
| == {{ Bar Heading| text=Variable Getter and Setter Functions}} ==
| |
| :
| |
| <syntaxhighlight lang=sidl>
| |
| double get_0d_double( in string long_var_name )
| |
| array<double> get_1d_double( in string long_var_name )
| |
| array<double,2> get_2d_double( in string long_var_name )
| |
| array<double> get_2d_double_at_indices( in string long_var_name, array<int> indices )
| |
| void set_0d_double( in string long_var_name, in double scalar )
| |
| void set_1d_double( in string long_var_name, in array<double> array)
| |
| void set_2d_double( in string long_var_name, in array<double,2> array)
| |
| void set_2d_double_at_indices( in string long_var_name, in array<int> indices, in array<double,2> array)
| |
| </syntaxhighlight>
| |
| | |
| <br/>
| |
| <!-- ============================================= -->
| |
| == {{ Bar Heading| text=Grid Information Functions}} ==
| |
| : | |
| * The BMI function call get_attribute( 'mesh_type' ) should return one of the following strings:
| |
| | |
| uniform (for uniform rectilinear)
| |
| rectilinear
| |
| s_mesh (for structured mesh)
| |
| u_mesh (for unstructured mesh)
| |
| | |
| * Each of these strings corresponds to a particular type of model grid or mesh. In order to provide a complete and standardized description of a model's grid, there is a different set of BMI functions that are required for each model "mesh_type" as described in this section.
| |
| | |
| * Note that an "orthogonal curvilinear" coordinate system is a special case of a "structured mesh".
| |
| | |
| * Note that "uniform rectilinear", "rectilinear" and "structured mesh" all have the topology of a two-dimensional array.
| |
| | |
| === Uniform Rectilinear ===
| |
| | |
| [[Image:mesh_uniform_rectilinear.png|300px|wrap]]
| |
| <syntaxhighlight lang=sidl>
| |
| array<double, 1> get_grid_spacing (in string long_var_name)
| |
| array<double, 1> get_grid_lower_left_corner (in string long_var_name)
| |
| array<int, 1> get_grid_shape (in string long_var_name)
| |
| </syntaxhighlight>
| |
| | |
| === Rectilinear ===
| |
| [[Image:mesh_rectilinear.png|300px|wrap]]
| |
| <syntaxhighlight lang=sidl>
| |
| array<double, 1> get_grid_x (in string long_var_name)
| |
| array<double, 1> get_grid_y (in string long_var_name)
| |
| array<double, 1> get_grid_z (in string long_var_name)
| |
| array<int, 1> get_grid_shape (in string long_var_name)
| |
| </syntaxhighlight>
| |
| | |
| === Structured Mesh ===
| |
| [[Image:mesh_structured.png|300px|wrap]]
| |
| <syntaxhighlight lang=sidl>
| |
| array<double, 1> get_grid_x (in string long_var_name)
| |
| array<double, 1> get_grid_y (in string long_var_name)
| |
| array<int, 1> get_grid_shape (in string long_var_name)
| |
| </syntaxhighlight>
| |
| | |
| === Unstructured Mesh ===
| |
| [[Image:mesh_unstructured.png|300px|wrap]]
| |
| <syntaxhighlight lang=sidl>
| |
| array<double, 1> get_grid_x (in string long_var_name)
| |
| array<double, 1> get_grid_y (in string long_var_name)
| |
| array<int, 1> get_grid_connectivity (in string long_var_name)
| |
| array<int, 1> get_grid_offset (in string long_var_name)
| |
| </syntaxhighlight>
| |
| | |
| :
| |
| :
| |
| :
| |