********************
Solution Termination
********************

Solution termination is the capability to stop the execution when a computed  solution reaches some reference solution. This capability can be especially useful for users who want to terminate an analysis when a variable reaches a specific value, but they do not know a priori when this will occur. Solution termination may also be used in multi procedure or multi time period analysis to move on to the next solution procedure once some criteria is reached. The inputs are similar to those for solution verification (see  :numref:`output-verification`).

.. code-block:: sierrainput

   BEGIN SOLUTION TERMINATION
     TERMINATE GLOBAL <string>gVar {<|<=|=|>|>=} 
       <real>gVal [PLUS OR MINUS <real>Tol]
     TERMINATE GLOBAL <string>gVar {<|<=|=|>|>=} 
       GLOBAL <string>gVar2 [PLUS OR MINUS <real>Tol]
     TERMINATE GLOBAL <string>gVar {<|<=|=|>|>=} 
       FUNCTION <string>funcName
     TERMINATE NODAL <string>nVar 
       AT NODE <integer>nodeNum {<|<=|=|>|>=} 
       FUNCTION <string>funcName
     TERMINATE ELEMENT <string>eVar 
       AT ELEMENT <integer>elemNum {<|<=|=|>|>=} 
       <real>val
   
     TOLERANCE = <real>absTol  
     RELATIVE TOLERANCE = <real>relTol
     TIME TOLERANCE = <real>timeTol
   
     SKIP TIMES = <real>time0 TO <real>time1
     ACTIVE PERIODS = <string list>periodNames
     INACTIVE PERIODS = <string list>periodNames
   
     COMPLETION FILE = <string>fileName
   
     TERMINATE TYPE = ENTIRE_RUN|CURRENT_PROCEDURE|
       CURRENT_TIME_PERIOD(ENTIRE_RUN)
   
     # write results, history, and restart files
     WRITE OUTPUT = OFF|ON(ON)
   END

The various forms of the ``TERMINATE GLOBAL``, ``TERMINATE NODAL``, and  ``TERMINATE ELEMENT`` commands check that the named variable has achieved some relation to some defined constant, time history function, or other global  variable. Currently, the most thoroughly tested condition is for termination  based on a global variable, such as kinetic energy, reaching a constant target value. However, it should be possible to terminate for any variables (including element and nodal), and to allow the target solution to be a  user-defined, non-constant variable (e.g., defined via an analytic function  that depends on time or other field variables). The global variables  used in solution termination can be created via a ``USER OUTPUT`` based  command block. 

Tolerances of how close a solution needs to be to terminate  can be specified. The ``TOLERANCE`` and ``PLUS OR MINUS`` termination  option both specify absolute tolerances. For example the command:

.. code-block:: sierrainput

   TERMINATE GLOBAL disp1 = 1.0 PLUS OR MINUS 0.1 

will terminate the calculation at the first occurrence of disp1 being between  0.9 and 1.1.

The ``RELATIVE TOLERANCE`` command specifies an acceptable relative  difference between values for termination. Termination occurs if:

.. math::

   \frac{|\mathrm{gVal}-\mathrm{gVar}|}{\mathrm{max}(|\mathrm{gVal}|, |\mathrm{gVar}|)} < \mathrm{relTol}

The ``TIME TOLERANCE`` is used with the time history function based  termination commands. A termination will result if the ``gVar`` is within  tolerance to any value of the function that would be computed at the current  time plus or minus the ``timeTol``.

The ``SKIP TIMES`` command is used to skip evaluation of whether to terminate  over the defined time intervals. This enables solution-based termination to be  active only during certain time intervals. Similarly solution termination can be  made active only for one or more specified time periods defined in the time stepping block with use of the ``ACTIVE PERIODS`` and ``INACTIVE_PERIODS`` command lines  described in :numref:`commands-functionality` to activate and deactivate functionality during  specific time blocks.

The ``COMPLETION FILE`` command causes solution termination to output a  status file named ``fileName`` at successful completion of the code run. Existence of the status file indicates that the run was terminated  successfully. If the termination condition is never reached, the code should  run until the final time period.

The ``TERMINATE TYPE`` command defines what solution termination does when hitting the failure condition. The default ``ENTIRE_RUN`` option indicates that the entire run should exit when the termination condition is reached. The ``CURRENT_PROCEDURE`` option indicates that the current procedure will be stopped and the code will move on to the next defined procedure if there is one. If the subsequent procedure defines a start time the next procedure will start at that  time. If the subsequent procedure does not define a start time the next procedure will start at the time the current procedure was terminated. The ``CURRENT_TIME_PERIOD`` option indicates that the current time period (as defined in the time stepping block) will be ended. The Sierra/SM will then move onto the next defined time  period if there is one.

The ``WRITE OUTPUT`` option will write a new results, history, and restart files upon solution termination. 

.. warning::

   Multiple results will exist on the output files if output is already scheduled to be written and solution termination also triggers output to be written.

Solution Termination Examples
=============================

The following code is used to terminate a run when the global kinetic energy reaches some small value. This may be useful for ending an explicit analysis after a dynamic impact event has occurred and most of the dynamic energy of interest has been dissipated. 

.. code-block:: sierrainput

   BEGIN SOLUTION TERMINATION
     TERMINATE GLOBAL kinetic_energy < 1.5e+4
   END

The following example code could be used to end an implicit run immediately before some fracture criteria (eqps)  being reached. The fracture itself could then be evaluated in a subsequent explicit procedure.

.. code-block:: sierrainput

   BEGIN USER OUTPUT
     COMPUTE GLOBAL max_eqps AS MAX OF ELEMENT EQPS
     COMPUTE AT EVERY STEP
   END

   BEGIN SOLUTION TERMINATION
     TERMINATE GLOBAL max_eqps > 0.2
     TERMINATE TYPE = CURRENT_PROCEDURE
   END
