******************
Creating Workflows
******************

This project uses three layers of SCons configuration files:

1. SConstruct: the project configuration
2. Workflow SConscript: named after the workflow or simulation, e.g. ``rectangle_compression``
3. Part/Assembly/Simulation SConscript: named after the re-usable task(s) purpose,
   e.g. when creating a part use the part name ``rectangle``

There is one, and only one, SConstruct file, which is located in the project root directory. Every SConscript file must
contain a module level docstring that describes the import/return requirements of that SConscript file. When updating or
adding a new workflow, be sure to update the SConscript docstring to match any requirement changes.

The SConscript files *must* be located in a single, flat source directory:  ``modsim_package``. All project files are
also located in the same ``modsim_package`` directory. These restrictions result from (1) the project design which
intends to produce a single, flat build directory for each workflow and (2) the use of Abaqus input file scanning to
determine implicit source/target dependencies. To achieve a single, flat build directory per workflow when re-using
SConscript files, every SConscript file must be co-located in the same directory due to SCons target path construction
behavior. Abaqus input files are scanned for implicit ``*INCLUDE`` statements, so the calling workflow SConscript files
must be co-located with the Abaqus input files to resolve relative include paths correctly. These restrictions result
in the requirement for a single, flat source directory. Because this directory will grow in proportion to the size of
the project, the ``modsim_package`` directory may become quite large. Users and developers are encouraged to become
comfortable sorting and finding files with ``grep`` and ``find`` in a bash command line terminal or seeking out the
advanced behaviors for file sorting in their preferred GUI file browser.

SConstruct
==========

The project configuration SConstruct file is responsible for configuring project wide variables, command line options,
construction environment(s), and workflows. The SConstruct file is reponsible for calling workflow SConscript files with
the workflow's construction environment, alias, and parameters under the variable names ``env``, ``alias``, and
``parameters``, respectively.

The workflow SConscript calls are constructed in the ``workflow_configurations`` variable as a list of tuples defining
the: (1) workflow SConscript file ``workflow``, (2) study name ``study_name``, and (3) study definition
``study_definition``.

.. admonition:: SConstruct

    .. literalinclude:: SConstruct.txt
       :language: Python
       :lineno-match:
       :start-after: workflow-configurations-start-do-not-remove
       :end-before: workflow-configurations-end-do-not-remove

The alias is constructed from the workflow Sconscript file name and the study name as ``f"{workflow}_{study_name}"`` and
used to construct a unique build directory name.  The workflow file name is assumed to be a base name for a file found
in the ``modsim_package`` directory.

.. admonition:: SConstruct

    .. literalinclude:: SConstruct.txt
       :language: Python
       :lineno-match:
       :start-after: workflow-naming-conventions-start-do-not-remove
       :end-before: workflow-naming-conventions-end-do-not-remove

To accommodate parameters defined by both `WAVES`_ parameter studies, which require iterative unpacking, and
dictionaries the `WAVES`_ ``ParameterStudySConscript`` construction environment method is used as

.. code-block::

   ParameterStudySConscript(..., exports={"env": env, "alias": alias}, study=study_definition, ...)

where the ``ParameterStudySConscript`` method will unpack the ``study_definition`` and pass along parameter sets using
the ``parameters`` variable name.

Workflow SConscript
===================

The workflow configuration SConscript files are named after the workflow, simulation, or assembly that they configure.
These files should call SConscript files defining the re-usable portions of the workflow, such as parts and assembly
configuration, and may optionally define workflow specific tasks. The workflow configuration files pass the ``env``, and
``parameters`` through to the part or assembly SConscript files and are responsible for adding targets to the workflow
alias(es). Any task definitions must unpack the workflow ``parameters`` variable.

.. code-block::

   Import("env", "alias", "parameters")

   SConscript(..., exports={"env": env, "parameters": parameters}, ...)

   env.Command(
       target=[...],
       source=[...],
       action=[...],
       **parameters,
   )

   env.Alias(alias, targets)

Part/Assembly/Simulation SConscript
===================================

The final layer of SConscript files consists of re-usable task definitions. Most commonly, these contain part (or
assembly) configuration files. This layer may also include any re-usable tasks if there are common simulation or
post-processing task definitions that can be shared between workflows. These configuration files should accept the
construction environment ``env`` and workflow ``parameters``. The parameters should be unpacked into the part task
definitions. These files may optionally return a list of target artifacts for the parent workflow SConscript file to use
in alias definitions.

.. code-block::

   Import("env", "parameters")

   env.Command(
       target=[...],
       source=[...],
       action=[...],
       **parameters,
   )

   Return("artifacts")
