Skip to content

InputSpecDocumentation

Ethan Coon edited this page Jun 7, 2024 · 8 revisions

The goal of Amanzi-ATS (native) input spec documentation is making maintainability as simple as possible. Anything more than placing documentation in exactly one location, in the same file as that input spec is used, is likely not to be maintained by developers. Therefore our goal is the following:

Any class that uses a ParameterList must document their use of that list in the corresponding .hh file inside a special spec comment block starting with /*! ... */ .

Beyond that, pulling the spec into a user's guide is fairly simple. The input spec documentation is built in two stages. First, there is template file which describes the broad layout of the document. This file is parsed, then formatted using python3's str.format(**kwargs) variant. The dictionary for that formatting is formed by parsing all Amanzi and ATS source, looking for special spec comment blocks, and creating a dictionary whose keys are the filename (or a special spec argument). This allows straightforward substitution to create a restructured text file which is then parsed via sphinx to generate the above html.

A simple example

Developer creates a new evaluator, MyEvalutor. Inside the file, they use a ParameterList, and document it as such:

/*
  Copyright, etc
  Author: Developer ([email protected])
*/
//! An evaluator for doing my special science.            <-- note this is a special one-line comment
/*!                                                       <-- note the special block comment
MyEvaluator solves all the cool science one could need.

.. math::                                                 <-- use math!  This is sphinx rst
    my\_answer = \alpha * p

.. _my-evaluator-spec:                                    <-- give your spec a name, used in templates
.. admonition:: my-evaluator-spec                         <-- makes your input spec pretty in the documentation
    * `"alpha [Pa^-1]`" ``[double]`` **1.0** My parameter :math:`\alpha`  
                                                          <-- All parameters have * in the first column.
                                                          <-- Where possible include units in brackets 
                                                          <-- in the name.
                                                          <-- Valid types are ParameterList types, 
                                                          <-- including Array(...)
                                                          <-- **1.0** is the default value, or 
                                                          <-- **optional** is ok too.  No entry means 
                                                          <-- it is required.
*/
... // code

Then, the developer edits the Native Spec template file and adds the lines:

My Evaluator
------------
{ MyEvaluator }

to the list of evaluators, in some useful subsection, with the appropriate level heading character (e.g. the same as those at the same level in the table of contents).

First, you must check out the documentation -- this creates a git linked working tree within your branch, that is simply "another branch of the same repository checked out in a subdirectory." Do this only once for each new clone of the code. It simply checks out the gh-pages branch and puts them at docs/documentation/build to make thing easier to work with sphinx:

cd docs/documentation
make worktree      # NOTE: once per clone only (extra calls will error but not break things)

Then, update the documentation:

cd docs/documentation
make input_file          # This runs the python parser which fills ATSNativeSpec_dev.rst.in to 
                         # generate ATSNativeSpec_dev.rst
make html                # This runs sphinx to create docs/documentation/
# Manually inspect the documentation by pointing your browser to your file system and looking at 
#   docs/documentation/build/html/index.html  
# Did it work?  Is it pretty?
make deploy              # this commits the documentation and pushes it to github's gh-pages remote

Documentation syntax

Work in progress uses this same documentation to create python dictionaries that can be populated in scripts, allowing us to generate input files via python. If you follow this syntax, your input spec can be generated automatically. Please do!

* `"parameter-name`" ``[type]`` **optional,default value** Description `[units]`

Note that indentation is finicky. Multi-line descriptions look like this:

* `"parameter-name`" ``[type]`` **optional,default value** This is a 
  long long description on two lines, with exactly two spaces starting
  all other lines past the first
* `"another-parameter`" ``[type]`` Can go on the following line though.

Also valid are the following constructs:

Either...or but not both

ONE OF

* `"parameter A`" ...

OR

* `"parameter B`" ...

OR

* `"parameter C`" ...

END

Evaluators

Including a list of evaluator dependencies allows us to check things dynamically while creating the input file.

KEYS:
- `"dependency1`"
- `"dependency2`"

Valid options

Include a list of valid options when the type is string and there are only a few working choices. This allows the python parser to error if another string is provided.

* `"permeability type`" ``[string]`` **scalar** This key is placed in
  state->field evaluators->permeability, and controls the number of values
  needed to specify the absolute permeability.  One of:

  - `"scalar`" Requires one scalar value.
  - `"horizontal and vertical`" Requires two values, horizontal then vertical.
  - `"diagonal tensor`" Requires dim values: {xx, yy} or {xx, yy, zz}
  - `"full tensor`". (Note symmetry is required.)  Either {xx, yy, xy} or {xx,yy,zz,xy,xz,yz}.

Typed lists

Often we use the construct that looks like:

<ParameterList name="object">
  <Parameter name="object type" type="string" value="my object type"/>
  <ParameterList name="my object type parameters">
    ...
  </ParameterList>
</ParameterList>

This should be documented as:

``[object-typed-spec]``
* `"object type`" ``[string]`` Type of object to be used
* `"_object_type_ parameters`" ``[_object_type_-spec]``

And further along possible types would look like:

``[object-type-mytypeA]``
* ... parameters in `"mytypeA parameters`" list

A list of such typed objects (e.g. "mesh" or "PKs" lists in "main") looks like:

* `"PKs`" ``[pk-typed-spec-list]`` List of PKs used in the PK tree

Includes

For classes that inherit from another class, and therefore also use their options, use includes:

INCLUDES:

* ``[io-event-spec]`` An IOEvent_ object

Example

Try to end each spec with an example:

Example:

.. code-block:: xml
    <ParameterList name="my name">
      <Parameter name="my parameter [m]" type="double" value="6.0"/>
    </ParameterList>

Build the documentation

Building the documentation requires a python with sphinx and a few different sphinx extensions. Then, one can:

cd $ATS_SRC_DIR/docs/documentation
make
# locally check that $ATS_SRC_DIR/docs/documentation/build/html looks right
make deploy_master
make deploy
# visit https://amanzi.github.io/ats/master/ to see your changes (may take a minute)