.. _subroutines-file:

************
Command File
************

In addition to the actual user subroutine, you will need to add command  lines to your input file to make use of your user subroutine. This section  describes the command lines that are used in conjunction with user  subroutines. This section also describes two additional command blocks, ``TIME  STEP INITIALIZATION`` and ``USER VARIABLE``. The ``TIME STEP INITIALIZATION`` command  block lets you execute a user subroutine at the beginning of a time step as  opposed to some later time. The ``USER VARIABLE`` command block can be used in  conjunction with user subroutines or for user-defined output. 

.. _use-subid:

Subroutine Identification
=========================

As described in :numref:`commands-scope-subroutines`, there is one command line associated with the user subroutine functionality that must be provided in the SIERRA scope:

.. code-block:: sierrainput

   USER SUBROUTINE FILE = <string>file_name
 
The named file may contain one or more user subroutines. The file must have an extension of ".F", as in blast.F.

.. _use-comlines:

User Subroutine Command Lines
=============================

.. code-block:: sierrainput

   {\{}begin command block{\}}
     NODE SET SUBROUTINE = <string>subroutine name |
       SURFACE SUBROUTINE = <string>subroutine_name |
       ELEMENT BLOCK SUBROUTINE = <string>subroutine_name
     SUBROUTINE DEBUGGING OFF | SUBROUTINE DEBUGGING ON
     SUBROUTINE REAL PARAMETER: <string>param_name
         = <real>param_value
     SUBROUTINE INTEGER PARAMETER: <string>param_name
         = <integer>param_value
     SUBROUTINE STRING PARAMETER: <string>param_name
         = <string>param_value
   {\{}end command block{\}}

A number of user subroutine command lines will appear in some Sierra/SM command block. User subroutine commands can appear in boundary condition, element death (only for explicit dynamics), user output, and state initialization command blocks. The possible command lines are shown above. The following sections describe the command lines related to user subroutines.

Type

User subroutines are currently available in three general types: node set, surface, and element.

Node set subroutines operate on groups of nodes. The command line for defining a node set subroutine is:

.. code-block:: sierrainput

   NODE SET SUBROUTINE = <string>subroutine_name

where ``subroutine_name`` is the name of the user subroutine. The name is case sensitive. A node set subroutine will operate on all nodes contained in an associated mechanics instance.

Surface subroutines work on groups of surfaces. A surface may be an external face of a solid element or the face of a shell element associated with either the positive or negative normal for the surface of the shell. The command line for defining a surface subroutine is:

.. code-block:: sierrainput

   SURFACE SUBROUTINE = <string>subroutine_name

Element block subroutines work on groups of elements. The command line for defining an element block subroutine is:

.. code-block:: sierrainput

   ELEMENT BLOCK SUBROUTINE = <string>subroutine_name

An element may be a solid element such as a hexahedron or a two-dimensional element such as a shell.

Different Sierra/SM features may accept one or more types of user subroutines. Only one subroutine is allowed per command block.

.. _use-debug:

Debugging
---------

Subroutines may be run in a special debugging mode to help catch memory errors. For example, there is a potential for a user subroutine to write outside of its allotted data space by writing beyond the bounds of an input or output array. Generally, this causes Sierra/SM to crash, but it also has the potential to introduce other hard-to-trace bugs into the Sierra/SM analysis. Subroutines run in debug mode require more memory and more processing time than subroutines not run in debug mode.

Subroutine debugging is on by default in debug executables. It can be turned off with the following command line:

.. code-block:: sierrainput

   SUBROUTINE DEBUGGING OFF

Subroutine debugging is off by default in optimized executables. It can be turned on with the following command line:

.. code-block:: sierrainput

   SUBROUTINE DEBUGGING ON

.. _use-param:

Parameters
----------

All user subroutines have the ability to use parameters. Parameters are defined in the input file and are quickly accessible by the user subroutine during run time. Parameters are a way of making a single user subroutine much more versatile. For example, a user subroutine could be written to define a periodic loading on a structure. A parameter for the subroutine could be defined specifying the frequency of the function. In this way, the same subroutine can be used in different parts of the model, and the subroutine behavior can be modified without recompiling the program. These command lines are placed within the scope of the command block in which the user subroutine is specified.

Real-valued parameters can be stored with the following command line:

.. code-block:: sierrainput

   SUBROUTINE REAL PARAMETER: <string>param_name
     = <real>param_value

Integer-valued parameters can be stored with the following command line:

.. code-block:: sierrainput

   SUBROUTINE INTEGER PARAMETER: <string>param_name
     = <integer>param_value

String-valued parameters can be stored with the following command line:

.. code-block:: sierrainput

   SUBROUTINE STRING PARAMETER: <string>param_name
     = <string>param_value

Any number of subroutine parameters may be defined. The subroutine parameters may be defined in any order within the command block. The user subroutine may request the values of the parameters but is not required to use them or even have any knowledge of their existence. An example of subroutine usage with parameters is as follows:

.. code-block:: sierrainput

   BEGIN PRESSURE
     SURFACE = surface_1
     SURFACE SUBROUTINE = blast_pressure
     SUBROUTINE REAL PARAMETER: blast_time = 1.2
     SUBROUTINE REAL PARAMETER: blast_power = 1.3e+07
     SUBROUTINE STRING PARAMETER: formulation = alpha
     SUBROUTINE INTEGER PARAMETER: decay_exponent = 2
     SUBROUTINE DEBUGGING ON
   END PRESSURE

In the above example, four parameters are associated with the subroutine ``blast_pressure``. Two of the parameters are real (``blast_time`` and ``blast_power``), one of the parameters is a string (``formulation``), and one of the parameters is an integer (``decay_exponent``). To access the parameters in the usersubroutine, the user will need to include interface calls described in previous sections. 

.. _use-tstepint:

Time Step Initialization
========================

.. code-block:: sierrainput

   BEGIN TIME STEP INITIALIZATION
     # mesh-entity set commands
     NODE SET|NODESET = <string list>nodelist_names
     SURFACE = <string list>surface_names
     BLOCK = <string list>block_names
     ASSEMBLY = <string list>assembly_names
     INCLUDE ALL BLOCKS
     REMOVE NODE SET = <string list>nodelist_names
     REMOVE SURFACE = <string list> surface_names
     REMOVE BLOCK = <string list>block_names
     #
     # external database commands
     READ VARIABLE = <string> mesh_var_name
     COPY VARIABLE = <string>var_name [FROM MODEL <string>model_name]
       MAP_BY_PROXIMITY|MAP_BY_ID(MAP_BY_PROXIMITY)
     TYPE = <string>NODE|ELEMENT
       [<string>REAL|INTEGER LENGTH = <integer>length]|
       [<string>SYM_TENSOR|FULL_TENSOR|VECTOR]
     #
     # user subroutine commands
     NODE SET SUBROUTINE = <string>subroutine_name |
       SURFACE SUBROUTINE = <string>sub_name |
       ELEMENT BLOCK SUBROUTINE = <string>sub_name
     SUBROUTINE DEBUGGING OFF | SUBROUTINE DEBUGGING ON
     SUBROUTINE REAL PARAMETER: <string>param_name
       = <real>param_value
     SUBROUTINE INTEGER PARAMETER: <string>param_name
       = <integer>param_value
     SUBROUTINE STRING PARAMETER: <string>param_name
       = <string>param_value            
     #
     # additional command
     ACTIVE PERIODS = <string list>period_names
     INACTIVE PERIODS = <string list>period_names
   
   END TIME STEP INITIALIZATION

The ``TIME STEP INITIALIZATION`` command block, which appears in the region scope, is used to control variables while an analysis is running. This can be done by reading a variable from a separate mesh file or by running a user subroutine.These variables can then be used to compute quantities used by other command types. For example, if the traction on a surface was dependent on the area, the time step initialization subroutine could be used to calculate the area, and that area could be stored and later read when calculating the traction. The user initialization subroutine will pass the specified mesh objects to the subroutine for use in calculating some value.

The ``TIME STEP INITIALIZATION`` command block contains two groups of commands---mesh entity set and user subroutine. In addition to the command lines in the these command groups, there is an additional command line: ``ACTIVE PERIODS`` or ``INACTIVE PERIODS``. Following are descriptions of the different command groups and the ``ACTIVE PERIODS`` or ``INACTIVE PERIODS`` command line. 

.. _use-mentcom:

Mesh-Entity Set Commands
------------------------

The ``mesh-entity set commands`` portion of the ``TIME STEP INITIALIZATION`` command block specifies the nodes, element faces, or elements associated with the particular subroutine run at the beginning of the applicable time steps. This portion of the command block can include some combination of the following command lines:

.. code-block:: sierrainput

   NODE SET|NODESET = <string list>nodelist_names
   SURFACE = <string list>surface_names
   BLOCK = <string list>block_names
   ASSEMBLY = <string list>assembly_names
   INCLUDE ALL BLOCKS
   REMOVE NODE SET = <string list>nodelist_names
   REMOVE SURFACE = <string list> surface_names
   REMOVE BLOCK = <string list>block_names

These command lines, taken collectively, constitute a set of Boolean operators for constructing a set of nodes, element faces, or elements. See :numref:`elements-fem` for more information about the use of these command lines for mesh entities. There must be at least one ``NODE SET|NODESET``, ``SURFACE``, ``BLOCK``, ``ASSEMBLY``, or ``INCLUDE ALL BLOCKS`` command line in the command block. Assemblies may contain blocks, surfaces, nodesets or assemblies of these.

External Mesh Database Commands
-------------------------------

.. code-block:: sierrainput

   READ VARIABLE = <string>var_name
   COPY VARIABLE = <string>var_name [FROM MODEL <string>model_name]
     MAP_BY_PROXIMITY|MAP_BY_ID(MAP_BY_PROXIMITY)
   TYPE = <string>NODE|ELEMENT
       [<string>REAL|INTEGER LENGTH = <integer>length]|
       [<string>SYM_TENSOR|FULL_TENSOR|VECTOR]

.. warning::

   At this time the ``COPY VARIABLE`` command can only be used with nodal variables. Neither the ``COPY VARIABLE`` nor ``READ VARIABLE`` commands are compatible with global variables.

If the external database option is used, the requested variable is read from an external mesh database. The variables are read from a finite element model defined via the ``FINITE ELEMENT MODEL`` command block described in :numref:`elements-fem`. The finite element model can either be the model used by the region for its mesh definition as specified with the ``USE FINITE ELEMENT MODEL`` command (see :numref:`commands-fem`), or it can be a different (but compatible) model.The ``TYPE`` command specifies the type of data the field is associated with. Once ``TYPE`` and one of the other commands are specified, the variable will show up on the new exodus mesh with the same name.

See :numref:`conditions-variable-extmesh` for more details.

.. _use-usesubcom:

User Subroutine Commands
------------------------

The following command lines are related to the user subroutine specification:

.. code-block:: sierrainput

   NODE SET SUBROUTINE = <string>subroutine_name |
     SURFACE SUBROUTINE = <string>subroutine_name |
     ELEMENT BLOCK SUBROUTINE = <string>subroutine_name
   SUBROUTINE DEBUGGING OFF | SUBROUTINE DEBUGGING ON
   SUBROUTINE REAL PARAMETER: <string>param_name
     = <real>param_value
   SUBROUTINE INTEGER PARAMETER: <string>param_name
     = <integer>param_value
   SUBROUTINE STRING PARAMETER: <string>param_name
     = <string>param_value   

Only one of the first three command lines listed above can be specified in the command block. The particular command line selected depends on the  mesh-entity type of the variable being initialized. For example, variables  associated with nodes would be initialized if you are using the ``NODE SET  SUBROUTINE`` command line, variables associated with faces if you are using  the ``SURFACE SUBROUTINE`` command line, and variables associated with elements  if you are using the ``ELEMENT BLOCK SUBROUTINE`` command line. The string  ``subroutine_name`` is the name of a FORTRAN subroutine that is written by  the user.

Following the selected subroutine command line are other command lines that may be used to implement the user subroutine option. These command lines are described in :numref:`use-comlines` and consist of ``SUBROUTINE DEBUGGING OFF``, ``SUBROUTINE DEBUGGING ON``, ``SUBROUTINE REAL PARAMETER``, ``SUBROUTINE INTEGER PARAMETER``, and ``SUBROUTINE STRING PARAMETER``. Examples of  using these command lines are provided throughout :numref:`subroutines`.

.. _use-addcom:

Additional Command
------------------

The ``ACTIVE PERIODS`` or ``INACTIVE PERIODS`` command line can optionally appear in the ``TIME STEP INITIALIZATION`` command block:

.. code-block:: sierrainput

   ACTIVE PERIODS = <string list>period_names

.. code-block:: sierrainput

   INACTIVE PERIODS = <string list>period_names

The ``ACTIVE PERIODS`` or ``INACTIVE PERIODS`` command line is used to activate or deactivate the running of the user subroutine at the beginning of every time step for certain time periods.  See :numref:`commands-functionality` for more information about this optional command line.

.. _subroutines-file-variables:

User Variables
==============

.. code-block:: sierrainput

   BEGIN USER VARIABLE <string>var_name
     BLOCK = <string list>block_names
     ASSEMBLY = <string list>assembly_names
     TYPE = <string>NODE|ELEMENT|GLOBAL
       [<string>REAL|INTEGER LENGTH = <integer>length]|
       [<string>SYM_TENSOR|FULL_TENSOR|VECTOR]
     GLOBAL OPERATOR = <string>SUM|MIN|MAX
     INITIAL VALUE = <real list>values
     INITIAL VARIATION = <real list>values LINEAR DISTRIBUTION
     USE WITH RESTART
   END [USER VARIABLE <string>var_name]

The ``USER VARIABLE`` command block is used to create a user-defined variable. This kind of variable may be used for scratch space in a user subroutine or for some user-defined output.  A user-defined variable may be output to the results file or the history file just like any other defined variable; i.e., a user-defined variable once defined by the ``USER VARIABLE`` command block can be specified in a ``USER OUTPUT`` command block, a ``RESULTS OUTPUT`` command block, and a ``HISTORY OUTPUT`` command block.

User-defined variables are associated with mesh entities: a node variable will exist on the nodes, an element variable will exist on the elements, and a global variable will have a single value for the entire model.  By default, the variable is registered on the entire model, but the ``BLOCK|ASSEMBLY`` command can be used to register the variable on a subset of the model.  The ``BLOCK|ASSEMBLY`` command enables registering a variable with different numbers of components between blocks, such as an element variable with ``LENGTH = 1`` on a block with mean-quadrature linear hexahedra and ``LENGTH = 8`` on another block with fully-integrated linear hexahedra. Assemblies may contain blocks, or assemblies of these.

If the user-defined variable functionality is used in conjunction with restart, the ``USE WITH RESTART`` command line must be included.

The ``USER VARIABLE`` command block is placed within a Sierra/SM region. The command block begins with the input line:

.. code-block:: sierrainput

   BEGIN USER VARIABLE <string>var_name

and ends with the input line:

.. code-block:: sierrainput

   END [USER VARIABLE <string>var_name]

where ``var_name`` is a user-selected name for the variable.

In the above command block:

- A user-defined variable has an associated type that is specified by the ``TYPE`` command line, which itself contains several parameters. The ``TYPE`` command line is required.

- The variable must be a nodal quantity, an element quantity, or a global quantity. The options ``NODE``, ``ELEMENT``, and ``GLOBAL`` determine whether the variable will be a nodal, element, or global quantity. One of these options must appear on the ``TYPE`` command line.

- The user-defined variable can be either an integer or a real, as specified by the ``INTEGER`` or ``REAL`` option.

-  The length of the variable must be set by using one of the options ``SYM_TENSOR``, ``FULL_TENSOR``, ``VECTOR``, or ``LENGTH = <integer>length``. If the ``LENGTH`` option is used, the user must specify whether the variable is an integer number or a real number by using the ``INTEGER`` or ``REAL`` option. If the ``SYM_TENSOR`` option is used, the variable has six real components. If the ``FULL_TENSOR`` is used, the variable has nine real components. If the ``VECTOR`` option is used, the variable has three real components. The three options ``SYM_TENSOR``, ``FULL_TENSOR``, and ``VECTOR`` all imply real numbers, and thus the ``REAL`` option need not be included in the command line when one of these three options is specified. 

Some examples of the ``TYPE`` command line follow: 

.. code-block:: sierrainput

   type = global real length = 1
   type = element tensor
   type = element real length = 3
   type = node sym_tensor
   type = node vector

-  If you use the ``GLOBAL`` option on the ``TYPE`` command line, a global variable is created, and this global variable must be given an associated reduction type, which is specified by the ``GLOBAL OPERATOR`` command line. The reduction type tells Sierra/SM how to reduce the individual values stored on each processor to a mesh global value. Global reductions are performed at the end of each time step. The ``SUM`` operator sums all processor variable contributions. The ``MAX`` operator takes the maximum value among all processor variable contributions. The ``MIN`` operator takes the minimum value among all processor variable contributions. 

- One or more initial values may be specified for the user-defined variable in the ``INITIAL VALUE`` command line. The number of initial values specified should be the same as the length of the variable, as specified in the ``TYPE`` command line either explicitly via the ``LENGTH`` option or implicitly via the ``SYM_TENSOR``, ``FULL_TENSOR``, or ``VECTOR`` option. The initial values will be copied to the variable space on every mesh object on which the variable is defined. Only real type variables may be given initial values at this time.

- The initial value of the user variable can be given some random distribution by use of the ``INITIAL VARIATION`` command line.  If the ``INITIAL VARIATION`` command is used the ``INITIAL VALUE`` command must also be used.  In addition the number of values specified in the initial variation command must exactly match the number of values specified in the initial value command.  When the initial variation command is used the initial values of the variable will be set as initial value plus or minus some random factor times the initial variation.  Currently the only random distribution supported is the linear distribution.  With linear distribution the random values will be distributed evenly from initial value minus variation to initial value plus variation.

- All intrinsic type options such as ``REAL``, ``INTEGER``, ``SYM_TENSOR``, ``FULL_TENSOR``, ``VECTOR`` and the ``LENGTH`` option can be used with any of the  mesh entity options (``NODE``, ``ELEMENT``, ``GLOBAL``).

- As indicated previously, if the user-defined variable functionality is used in conjunction with restart, the ``USE WITH RESTART`` command line must be included.
