.. _types_files:

Types Files and the OpenFAST Registry
=====================================
Being a modern software project, OpenFAST has a complex system of custom data
types. In Fortran, these are known as "derived data types." Each module
contains a unique collection of derived types which may add on to but must
comply with the OpenFAST Framework. The module types are generally
auto-generated by an included program called *OpenFAST Registry*. The OpenFAST
Registry is written in C and adapted from a similar utility used in
`WRF <http://www.mmm.ucar.edu/wrf/WG2/software_2.0/registry_schaffer.pdf>`__.
Visit the `OpenFAST Registry README <https://github.com/OpenFAST/openfast/tree/main/modules/openfast-registry>`__
for more information.

The OpenFAST Registry requires an input file to describe the necessary types
for a given module. Generally, all module use a similar naming convention,
**<Module>_Registry.txt**, and resulting Fortran code will be in a file
called **<Module>_Types.f90**. For example, the AeroDyn OpenFAST Registry input
file is located at ``openfast/modules/aerodyn/src/AeroDyn_Registry.txt`` and
the resulting auto-generated Fortran source code is at
``openfast/modules/aerodyn/src/AeroDyn_Types.f90``.

Since the types-modules are autogenerated, any changes to the data types
directly should be expressed in the OpenFAST Registry input files so that the
changes are not subsequently overwritten.

Compiling the OpenFAST Registry
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The OpenFAST Registry is included
in the OpenFAST build system through CMake. However, the default is to
**not** compile the OpenFAST Registry executable and instead use the types
modules that are included in *git* while compiling OpenFAST. To include the
OpenFAST Registry in the build process and compile the Registry program,
configure CMake with the ``GENERATE_TYPES`` flag:

.. code-block:: bash

    cmake .. -DGENERATE_TYPES=ON

With ``GENERATE_TYPES`` enabled, CMake will configure the `openfast-registry`
target to compile as a dependency of all other targets. The OpenFAST Registry
executable will be found in
``openfast/build/modules/openfast-registry/openfast-registry``.

.. _regenerating_types:

Regenerating a types module
~~~~~~~~~~~~~~~~~~~~~~~~~~~
With the ``GENERATE_TYPES`` flag enabled, an additional step will be added to
modules that are configured can make use of the OpenFAST Registry. The
additional step will execute the OpenFAST Registry and regenerate the types
module overwriting the existing modules. Any changes to the types module will
be evident in *git*. For modules where the registry input file has not
changed, the resulting types module will not change. However, for registry
input files that have been modified, the output types module will be
recompiled.

Adding a new types module
~~~~~~~~~~~~~~~~~~~~~~~~~
The process for adding a new types module follows :ref:`regenerating_types`
closely. Here, an additional step is required to configure CMake to execute
the Registry on the new input file and include the resulting types module
in the compile step.

First, a new OpenFAST Registry input file must be created. Then, it must be
configured to pass through the Registry in the corresponding module's
``CMakeLists.txt``:

.. code-block:: cmake

    # This is the control statement for allowing the Registry to execute
    if (GENERATE_TYPES)

        # Here is the CMake wrapper-function to execute the Registry
        # syntax: generate_f90_types(<Registry input file> <output file location>)
        generate_f90_types(src/AeroDyn_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/AeroDyn_Types.f90)
        generate_f90_types(src/New_Registry.txt ${CMAKE_CURRENT_LIST_DIR}/src/New_Types.f90)
    endif()

Finally, the resulting types module must be added to the source files for the
corresponding module:

.. code-block:: cmake

    # AeroDyn lib
    set(AD_LIBS_SOURCES
        src/AeroDyn.f90
        src/AeroDyn_IO.f90
        src/AirfoilInfo.f90
        src/BEMT.f90
        src/DBEMT.f90
        src/BEMTUncoupled.f90
        src/UnsteadyAero.f90
        src/fmin_fcn.f90
        src/mod_root1dim.f90
        src/AeroDyn_Types.f90
        src/AirfoilInfo_Types.f90
        src/BEMT_Types.f90
        src/DBEMT_Types.f90
        src/UnsteadyAero_Types.f90

        # Add the new types module here
        src/New_Types.f90
    )

With CMake properly configured, a message will display during the build process
indicating that the OpenFAST Registry is executing:

.. code-block:: bash

    [ 64%] Generating ../../../modules/aerodyn/src/New_Types.f90

    ----- FAST Registry --------------
    ----------------------------------------------------------
    input file: /Users/rmudafor/Development/openfast/modules/aerodyn/src/New_Registry.txt
    # more build process output will follow

And finally there should be an indication that the resulting types module is
compiled:

.. code-block:: bash

    Scanning dependencies of target aerodynlib
    [ 70%] Building Fortran object modules/aerodyn/CMakeFiles/aerodynlib.dir/src/New_Types.f90.o
