-
Notifications
You must be signed in to change notification settings - Fork 39
InputSpecDocumentation
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
ParameterListmust document their use of that list in the corresponding.hhfile 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.
Developer creates a new evaluator, MyScienceEvalutor. Inside the file, they use a ParameterList, and document it as such:
/*
Copyright, etc
Author: Developer (developer@ornl.gov)
*/
/*! <-- note the special block comment
My Science Evaluator solves all the cool science one could need.
.. math:: <-- use math! This is sphinx rst
my\_science = \alpha * p
`"evaluator type`" = `"my science`" <-- this name should be the same as what you "register" the
evaluator in the _reg.hh file
.. _evaluator-my-science-spec: <-- give your spec a name, used in templates. PKs should
start with pk-, evaluators with evaluator-, models
with their model name e.g. wrm-. Then the registered
name, e.g. evaluator type above (no spaces, only hyphens
here), followed by -spec
.. admonition:: evaluator-my-science-spec <-- makes your input spec pretty in the documentation
* `"alpha [Pa^-1]`" ``[double]`` **1.0** My parameter <-- All parameters have * in the first column.
:math:`\alpha` Where possible include units in brackets
in the name. 3 spaces before the *, 2 more for trailing
indent (standard for RST).
Valid types are ParameterList types,
including Array(...), or other `-spec` objects for sublists
**1.0** is the default value, or **optional** is ok too.
No entry means it is required.
DEPENDENCIES
- `"my science dependency`" **DOMAIN-my_sci_dep** <-- in a separate list, still in the "admonition", list out all
depedency keys, and their default. E.g. this would partner
with code in your evaluator:
dep_key_ = readKey(plist_, domain, "my science dependency", "my_sci_dep");
*/
... // code
Then, the developer edits the Native Spec template file and adds the lines:
My Science Evaluator
--------------------
{ MyScienceEvaluator }
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). Note that the quantity in the braces is the filename (minus the .hh part).
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_spec # 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
Note that to run make html make require a conda environment with the following packages:
conda create -n ats-docs -c conda-forge sphinx sphinxcontrib-jquery pydata-sphinx-theme myst-nb numpy matplotlib h5py
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:
ONE OF
* `"parameter A`" ...
OR
* `"parameter B`" ...
OR
* `"parameter C`" ...
END
Including a list of evaluator dependencies allows us to check things dynamically while creating the input file.
KEYS:
- `"dependency1`"
- `"dependency2`"
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}.
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
For classes that inherit from another class, and therefore also use their options, use includes:
INCLUDES:
* ``[io-event-spec]`` An IOEvent_ object
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>