diff --git a/docs/source/bmi.getter_setter.rst b/docs/source/bmi.getter_setter.rst index 9a832f8..311f04c 100644 --- a/docs/source/bmi.getter_setter.rst +++ b/docs/source/bmi.getter_setter.rst @@ -27,8 +27,8 @@ state variable can be changed or check the new data for validity. int get_value(in string name, in array<> dest); The `get_value` function takes a variable name and copies values into a -provided buffer. -The type and size of the buffer depend on the variable, +provided array parameter. +The type and size of the array parameter depend on the variable, and can be determined through :ref:`get_var_type`, :ref:`get_var_nbytes`, etc. Recall that arrays are always flattened in BMI, @@ -39,7 +39,7 @@ even if the model uses dimensional variables. * The *dest* argument must be defined and allocated before calling `get_value`. Whatever values it contains are overwritten in the call to `get_value`. -* In Python, the buffer is a :term:`numpy` array. +* In Python, the array parameter is a :term:`numpy` array. * In C++, `get_value` is a void function. * Depending on how a model is written, a variable may not be accessible until after the call to :ref:`initialize`. Likewise, the @@ -59,7 +59,7 @@ even if the model uses dimensional variables. The `get_value_ptr` function takes a variable name and returns a reference to a variable. -Unlike the buffer returned from :ref:`get_value`, +Unlike the array parameter returned from :ref:`get_value`, the reference always points to the current values of the variable, even if the model's state has changed. diff --git a/docs/source/bmi.grid_funcs.rst b/docs/source/bmi.grid_funcs.rst index 885082a..98b8958 100644 --- a/docs/source/bmi.grid_funcs.rst +++ b/docs/source/bmi.grid_funcs.rst @@ -49,7 +49,6 @@ is given in the :ref:`model_grids` section. **Implementation notes** -* This function is needed for every :ref:`grid type `. * In C++ and Python, the *type* argument is omitted and the grid type name is returned from the function. @@ -66,7 +65,8 @@ is given in the :ref:`model_grids` section. /* SIDL */ int get_grid_rank(in int grid, out int rank); -Given a :term:`grid identifier`, get the :term:`rank` of that grid as an integer. +Given a :term:`grid identifier`, get the :term:`rank` (the number of +dimensions) of that grid as an integer. A grid's rank determines the length of the return value of many of the following grid functions. diff --git a/docs/source/bmi.implementation.rst b/docs/source/bmi.implementation.rst index 0a51fd4..345f1ae 100644 --- a/docs/source/bmi.implementation.rst +++ b/docs/source/bmi.implementation.rst @@ -25,6 +25,18 @@ here are some tips to help when writing a BMI for a model. the BMI specifies are the names of the functions, their arguments, and their return values. +* :term:`Standard Names` are not required for naming a model's + :term:`exchange items `. However, the use of + standardized names makes it easier for a framework (or a human) to + match input and output variables between models. + +* Don't change the variable names you currently use within your model + to :term:`Standard Names`. Standard Names are too long and + cumbersome to be used within a model code. Instead, you find a + `matching`_ Standard Name for each variable in your model and then + write your BMI functions to accept the Standard Names and map them + to your model's internal names. + * Constructs and features that are natural for the language should be used when implementing a BMI. BMI strives to be developer-friendly. @@ -34,6 +46,11 @@ here are some tips to help when writing a BMI for a model. responsibility to ensure that array information is flattened/redimensionalized in the correct order. +* Recall that models can have mulitple grids. This can be particularly + useful for defining :term:`exchange items ` that + don't vary over the model domain; e.g., a diffusivity -- just define + the variable on a separate :ref:`scalar grid `. + * Avoid using global variables, if possible. This isn't strictly a BMI requirement, but if a model only uses local variables, its BMI will be self-contained. This may allow multiple instances of the model to @@ -73,3 +90,4 @@ here are some tips to help when writing a BMI for a model. .. _C++: https://github.com/csdms/bmi-example-cxx .. _Fortran: https://github.com/csdms/bmi-example-fortran .. _Python: https://github.com/csdms/bmi-example-python +.. _matching: https://github.com/csdms/standard_names_registry diff --git a/docs/source/bmi.info_funcs.rst b/docs/source/bmi.info_funcs.rst index 5ceab74..ed50df5 100644 --- a/docs/source/bmi.info_funcs.rst +++ b/docs/source/bmi.info_funcs.rst @@ -43,6 +43,7 @@ but it should be unique to prevent conflicts with other components. The number of variables the model can use from other models implementing a BMI. +Also the number of variables that can be set with :ref:`set_value`. **Implementation notes** @@ -64,6 +65,7 @@ implementing a BMI. The number of variables the model can provide other models implementing a BMI. +Also the number of variables that can be retrieved with :ref:`get_value`. **Implementation notes** @@ -101,7 +103,7 @@ Standard Names do not have to be used within the model. function in a vector, a standard container in the language. * In Python, the argument is omitted and the names are returned from the function in a tuple, a standard container in the language. -* A model may have no input variables. +* A model might have no input variables. [:ref:`info_funcs` | :ref:`basic_model_interface`] diff --git a/docs/source/bmi.spec.rst b/docs/source/bmi.spec.rst index 1e53744..9a471cb 100644 --- a/docs/source/bmi.spec.rst +++ b/docs/source/bmi.spec.rst @@ -59,6 +59,9 @@ Following the table is a detailed description of each function, including the function prototype in SIDL, grouped by functional category. +Be sure to check out the collected wisdom of our :ref:`best practices +document ` for tips on implementing a BMI. + .. table:: **Table 2:** Summary of BMI functions. :align: center :widths: 30, 70 diff --git a/docs/source/bmi.time_funcs.rst b/docs/source/bmi.time_funcs.rst index 9ce26a5..51d4d95 100644 --- a/docs/source/bmi.time_funcs.rst +++ b/docs/source/bmi.time_funcs.rst @@ -61,8 +61,9 @@ The end time of the model. **Implementation notes** -* If the model doesn't define an end time, a large number (e.g., - 1.0e6) is typically chosen. +* If the model doesn't define an end time, a large number (e.g., the + largest floating point number supported on a platform) is typically + chosen. * In C++ and Python, the argument is omitted and the time is returned from the function. @@ -87,7 +88,8 @@ It's recommended to use `time unit conventions`_ from Unidata's **Implementation notes** * Avoid using `years` as a unit, if possible, since a year is - difficult to define precisely. + difficult to define precisely. UDUNITS defines a year as 365.2422 + days or 31556926 seconds. * In C++ and Python, the argument is omitted and the units are returned from the function. diff --git a/docs/source/bmi.var_funcs.rst b/docs/source/bmi.var_funcs.rst index 6f42c2d..24c93b8 100644 --- a/docs/source/bmi.var_funcs.rst +++ b/docs/source/bmi.var_funcs.rst @@ -160,6 +160,9 @@ element the variable is defined. Valid return values are: * In C++ and Python, the *location* argument is omitted and the location is returned from the function. +* If the given variable is a scalar (i.e., defined on a :ref:`scalar + grid `), the return from this function is + ignored. [:ref:`var_funcs` | :ref:`basic_model_interface`] diff --git a/docs/source/csdms.rst b/docs/source/csdms.rst index 012d081..11e3a46 100644 --- a/docs/source/csdms.rst +++ b/docs/source/csdms.rst @@ -1,26 +1,24 @@ -.. _cmf: - -The CSDMS Modeling Framework -============================ - -Any model that provides the BMI functions can be easily converted -to a CSDMS plug-and-play component within the CSDMS Modeling -Framework (CMF). This conversion/wrapping process can be done -automatically using the CSDMS Babelizer tool, which generates -bindings for all of the CSDMS supported languages, so that the -model becomes a plug-in for within the CSDMS framework. - -.. - "becomes a plug-in for"? I don't understand. - -Any model that provides the BMI functions should also be -straightforward to ingest as a component into other component-based -modeling frameworks. For example, all model coupling frameworks -use Model Control Functions very similar to those of the BMI, -so providing them helps get a model ready for *plug-and-play* into -any framework. - -Within the CMF, a component automatically gains many +.. _pymt: + +The Python Modeling Toolkit (*pymt*) +==================================== + +Any model that provides the BMI functions can be converted +to a plug-and-play component +that runs in the CSDMS `Python Modeling Toolkit`_ (*pymt*). +This conversion process can be done +automatically with the CSDMS Babelizer tool, which generates +a Python package from any of the CSDMS supported languages +(currently C, C++, Fortran, and Python). +Some additional metadata is also required, +describes such things as: + +* the model author(s), license, description, web page, etc. +* how the model is built and how it can be linked +* template input files +* description of input parameters (description, units, ranges, etc.) + +Within *pymt*, a component automatically gains many new capabilities. This includes the ability to be coupled to other models even if their (1) programming language, (2) variable names, (3) variable units, (4) time-stepping scheme or (5) @@ -28,39 +26,18 @@ computational grid is different. It also gains: * the ability to write output variables to standardized NetCDF files, -* a graphical user interface (GUI), * unit conversion tools, -* time interpolation - - -CSDMS Standard Names --------------------- - -Note that the *name* parameter in many of the BMI functions -refers to a standardized variable name from the -`CSDMS_Standard_Names `_. -These names are not *required* by the BMI to be CSDMS Standard Names, -however, the use of standardized names makes it possible for a -framework (or a human) to more easily match components' input and -output variables. - -.. note: - - Note you **do not** change the variable names that you currently - use within your model. The standard names are too long to be - used within your model code. Instead, you find a matching CSDMS - Standard Name for each variable in your model and then write your - BMI functions to accept the standard names and map them to your - model's internal names. +* time interpolation, +* all the data analysis and visualization tools available in Python, +* the ability to run in a Jupyter Notebook +If you have a model with a BMI, +and would like to componentize it and add it to *pymt*, +please contact us through the `CSDMS Help Desk`_. +We'd be happy (and excited) to help! -Model metadata --------------- -For a model to be incorporated into the CSDMS framework, some additional -metadata is required. This metadata describes such things as: +.. Links: -* The model author(s), license, description, web page, etc. -* How the model is built and how it can be linked -* Template input files -* Description of input parameters (description, units, ranges, etc.) +.. _Python Modeling Toolkit: https://pymt.readthedocs.io +.. _CSDMS Help Desk: https://github.com/csdms/help-desk diff --git a/docs/source/index.rst b/docs/source/index.rst index 64b68e9..4ab6152 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -21,6 +21,16 @@ Additional Topics glossary references +Help +==== + +Adding a BMI to a model can be a daunting task. +If you'd like assistance, +CSDMS can help. +Depending on your need, we can provide advice or consulting services. +Feel free to contact us through the `CSDMS Help Desk`_. + + Project Information =================== @@ -31,3 +41,8 @@ Project Information contributing conduct credits + + +.. Links: + +.. _CSDMS Help Desk: https://github.com/csdms/help-desk diff --git a/docs/source/model_grids.rst b/docs/source/model_grids.rst index c4d422e..53045b5 100644 --- a/docs/source/model_grids.rst +++ b/docs/source/model_grids.rst @@ -33,10 +33,10 @@ its length would be listed first. .. note:: - The grid shape is the number of :term:`nodes ` in the - coordinate directions, not the number of cells or - elements. It is possible for grid values to be - associated with the nodes or with the cells. + The grid shape is the number of rows and columns of :term:`nodes + `, as opposed to other types of element (such as cells or + faces). It is possible for grid values to be associated with the + nodes or with the cells. .. _uniform_rectilinear: