Since version 1.7.6 - and in production since the version 1.9.0, BigDFT
uses YAML markup language to handle I/O of the code. For an overview of
**yaml** specifications see `this
page <http://www.yaml.org/spec/1.2/spec.html#id2759963>`__. This adds
much flexibility as new input variables might be added without altering
the format of the input files, in a transparent way for all the users.
Here we follow the steps needed to add such input file in the code.

Essentially, a new input variable shoudl correspond to a set of ultimate
components of the ``input_variables`` datatype, that is defined in the
module ``module_input_keys`` (file ``input_keys.f90``)in the directory
``src/modules``).

As an example, imagine we would like to insert a logical variable to
control the calculation of the stress tensor at the end of the SCF
cycle. Obviuosly, we should start by adding the component in the
``input_variables`` datatype:

.. code:: Fortran

    !> Structure of the variables read by input.* files
      type, public :: input_variables
         !>reference counter
         type(f_reference_counter) :: refcnt
         !> enumerator for the mode of the run
         type(f_enumerator) :: run_mode
         [...]
         !> boolean to activate the calculation of the stress tensor
         logical :: calculate_strten
         [...]
      end type input_variables

Note also the adding of the Doxygen documentation, for code review. This
variable should also be initialized in the ``default_input_variables``
routine, if default initialization is important.

Insert the variable in ``input_variables_definition.yaml`` file and associate a keyword
---------------------------------------------------------------------------------------

The input variables themselves are defined and parsed in YAML format
within the ``libbigdft-1.a`` library. This allows the code to have an
automatic determination of the allowed ranges and values of the
parameters, within the guidelines defined in the ``f_input_file`` module
of the ``flib`` utilities tool.

Coming back to our example, let us now insert the keyword associated to
this variable in the file ``input_variables_definition.yaml``, presently
in the ``src/`` directory. To do that, one should follow the
instructions written at the beginning of such file. Let us now add the
specification of the input variable (rigorously in lowercase format, to
avoid typing problems). In this example, we have

.. code:: yaml

       calculate_strten:
         COMMENT: Boolean to activate the calculation of the stress tensor. Might be set to No for performance reasons
         DESCRIPTION: In some cases, for example when doing MD for fixed volume systems, il might be useful to disable the
                        calculation of the stress tensor, to save computational time
         default: Yes

Again, see the instruction at the beginning of the file for all the
possible fields and descriptions.

Now that this variable has been inserted, a keyword has to be associated
to it. In other terms, we have to say the code that the string
``calculate_strten`` is important whilst parsing the input file. To do
that, simply add a new parameter in the ``public_keys.f90`` module
(directory ``/src/orbitals``):

.. code:: Fortran

         [...]
      character(len = *), parameter :: CALCULATE_STRTEN = "calculate_strten"
         [...]

To invoke the input variable, we will now use the ``CALCULATE_STRTEN``
parameter. This is much safer that using the string variable directly as
typos will be deteceted at compile time as we would refer to the
parameter.

Retrieve the value of the variable as parsed from the input file
----------------------------------------------------------------

One the above steps have been performed, the code is able to parse the
value of the ``calculate_strten`` variable. This means that, if now the
input file contains such keyword (that has been placed in the ``dft``
field for this example), no error is raised. Now we have to associate
the value of the variable as it is parsed from the input file into the
value of the ultimate component of the ``input_variables`` structure.
The point to do that is the ``input_set_dict`` routine, in the
``input_keys.f90`` file.

.. code:: Fortran

         [...]
      case(CALCULATE_STRTEN)
        in%calculate_strten=val
         [...]

The parsed value is stored in the variable ``val``, and it can be
affected to the ``calculate_strten`` utilmate component. Clearly the
assignment operator is understanding an overload which is taking care of
the fact that the two entities have different type. Then the input
variable is stored and the developer is able to invoke it from the
``input_variables`` datatype.
