SetupInterface (execute_on)

Most user-facing objects in MOOSE inherit from the SetupInterface class. This class provides two features to objects. Foremost, it provides the the "execute_on" parameter, which, as the name suggests, dictates when the object is to be executed. Secondly, it adds virtual setup methods that allow derived classes to perform setup applications prior to execution.

Execute On

Any object inheriting from the SetupInterface, that adds the SetupInterface::validParams() within its own parameters, will have an "execute_on" parameter that can be set to various flags, the most common (default) flags are listed below.

Execute FlagDescription
NONENever executed.
INITIALPrior to the first time step.
LINEARPrior to each residual evaluation.
NONLINEARPrior to each Jacobian evaluation.
TIMESTEP_ENDAfter the solve for each time step.
TIMESTEP_BEGINPrior to the solve for each time step.
FINALAt the end of the entire simulation.
CUSTOMAt user specified instants.
ALWAYSUnion of all the above flags.

The "execute_on" parameter can be set to a single flag or multiple flags. For example, it may be desirable to only execute an object initially because the state of the auxiliary computation does not vary. In the input file snippet below, the ElementLengthAux computation only needs to be computed initially, thus the "execute_on" parameter is set as such.

[AuxKernels]
  [./min]
    type = ElementLengthAux
    variable = min
    method = min
    execute_on = initial
  [../]
  [./max]
    type = ElementLengthAux
    variable = max
    method = max
    execute_on = initial
  [../]
[../]
(test/tests/auxkernels/element_length/element_length.i)

Alternatively, it is often desirable to run a computation with multiple execute flags. For example, in the input file snippet below a TimePeriod control object that is responsible for enabling in Damper object needs to be run initially and prior to each timestep to guarantee that the damper is enabled when desired.

[Controls]
  [./damping_control]
    type = TimePeriod
    disable_objects = '*::const_damp'
    start_time = 0.25
    execute_on = 'initial timestep_begin'
  [../]
[]
(test/tests/controls/time_periods/dampers/control.i)

Depending on the system these options or others will be available, since as discussed in Creating Custom Execute Flags custom flags may be added. The complete list of execution flags is provided by MOOSE are listed in the "registerExecFlags" function.


#ifdef HAVE_GPERFTOOLS
#include "gperftools/profiler.h"
#include "gperftools/heap-profiler.h"
#endif

// MOOSE includes
#include "MooseRevision.h"
#include "AppFactory.h"
#include "DisplacedProblem.h"
#include "NonlinearSystemBase.h"
#include "AuxiliarySystem.h"
#include "MooseSyntax.h"
#include "MooseInit.h"
#include "Executioner.h"
#include "Executor.h"
#include "PetscSupport.h"
#include "Conversion.h"
#include "CommandLine.h"
#include "InfixIterator.h"
#include "MultiApp.h"
#include "MooseUtils.h"
#include "MooseObjectAction.h"
#include "InputParameterWarehouse.h"
#include "SystemInfo.h"
#include "MooseMesh.h"
#include "FileOutput.h"
#include "ConsoleUtils.h"
#include "JsonSyntaxTree.h"
#include "JsonInputFileFormatter.h"
#include "SONDefinitionFormatter.h"
#include "RelationshipManager.h"
#include "ProxyRelationshipManager.h"
#include "Registry.h"
#include "SerializerGuard.h"
#include "PerfGraphInterface.h" // For TIME_SECTION
#include "SolutionInvalidInterface.h"
#include "Attributes.h"
#include "MooseApp.h"
#include "CommonOutputAction.h"
#include "CastUniquePointer.h"
#include "NullExecutor.h"
#include "ExecFlagRegistry.h"
#include "SolutionInvalidity.h"
#include "MooseServer.h"
#include "RestartableDataWriter.h"
#include "StringInputStream.h"
#include "MooseMain.h"

// Regular expression includes
#include "pcrecpp.h"

#include "libmesh/exodusII_io.h"
#include "libmesh/mesh_refinement.h"
#include "libmesh/string_to_enum.h"
#include "libmesh/checkpoint_io.h"
#include "libmesh/mesh_base.h"

// System include for dynamic library methods
#ifdef LIBMESH_HAVE_DLOPEN
#include <dlfcn.h>
#include <sys/utsname.h> // utsname
#endif

// C++ includes
#include <numeric> // std::accumulate
#include <fstream>
#include <sys/types.h>
#include <unistd.h>
#include <cstdlib> // for system()
#include <chrono>
#include <thread>

#define QUOTE(macro) stringifyName(macro)
(framework/src/base/MooseApp.C)

The default value of "execute_on" is linear for most of MOOSE objects with the exception of:

  • The auxiliary kernels have the default value of linear and timestep_end.

  • The postprocessors have default value of timestep_end.

  • The controls have default value of initial and timestep_end.

  • The multi-apps have default value of timestep_begin.

  • The user objects have default value of timestep_end.

  • The outputs have default value of initial and timestep_end.

  • The default value for a transfer is set to be the same as the execute_on value of its corresponding sub-application.

Several objects in the framework have custom or selected default "execute_on". The default value for all objects including objects in MOOSE modules and MOOSE-based applications can be found in their parameter list.

Modifying Execute On

When creating objects that inherit from SetupInterface it is possible to set, add, or remove available execute flags by retrieving and then modifying the ExecFlagEnum parameter. For example, consider the snippet below (see Output.C).

  ExecFlagEnum & exec_enum = params.set<ExecFlagEnum>("execute_on", true);
  exec_enum = Output::getDefaultExecFlagEnum();
  exec_enum = {EXEC_INITIAL, EXEC_TIMESTEP_END};
  params.setDocString("execute_on", exec_enum.getDocString());
(framework/src/outputs/Output.C)

First, the "execute_on" is retrieved for modification by using the "set" method. Notice, that a second boolean argument is passed to "set", this second flag enables "quiet mode". Quiet mode will modify the parameter silently as if the default was the modified parameter. In this case, the parameter will be listed as un-modified by the user. That is, InputParameters::isParamSetByUser returns false, if quiet mode is not enabled this method would return true.

Second, the two new execution flags are added (EXEC_FINAL and EXEC_FAILED), therefore these additional options are available to all classes (all Output objects in this case) that inherit from this object.

Third, the default active flags are set to EXEC_INITIAL and EXEC_TIMESTEP_END, which are the defaults for all Output objects.

Finally, the documentation string for the "execute_on" parameter for the Output objects is update to reflect the changes made to the parameter. The ExecFlagEnum has a convenience function that generates a documentation string that includes the available options in the string.

Virtual Setup Methods

The SetupInterface includes virtual methods that correspond to the primary execute flags with MOOSE, these methods are listed in the header as shown here.

/**
* Gets called at the beginning of the simulation before this object is asked to do its job
*/
virtual void initialSetup();
/**
* Gets called at the beginning of the timestep before this object is asked to do its job
*/
virtual void timestepSetup();
/**
* Gets called just before the Jacobian is computed and before this object is asked to do its job
*/
virtual void jacobianSetup();
/**
* Gets called just before the residual is computed and before this object is asked to do its job
*/
virtual void residualSetup();
/**
* Gets called when the subdomain changes (i.e. in a Jacobian or residual loop) and before this
* object is asked to do its job
*/
virtual void subdomainSetup();
/**
* Gets called in FEProblemBase::execute() for execute flags other than initial, timestep_begin,
* nonlinear, linear and subdomain
*/
virtual void customSetup(const ExecFlagType & /*exec_type*/) {}
(framework/include/interfaces/SetupInterface.h)

In general, these methods should be utilized to perform "setup" procedures prior to the calls to execute for the corresponding execute flag.

commentnote

A few of the methods were created prior to the execute flags, thus the names do not correspond but they remain as is to keep the API consistent: the "jacobianSetup" methods is called prior to the "NONLINEAR" execute flag and the "residualSetup" is called prior to the "LINEAR" execute flag.

There is also a generic setup function "customSetup" that takes an execute flag as the argument. This function is called by MOOSE when performing evaluations of objects on the custom execute flags in Creating Custom Execute Flags.

warningwarning:Note on the "customSetup" function

This function is not called on initial, timestep_begin, subdomain, nonlinear and linear. Setup operations for those execute flags should be implemented in initialSetup, timestepSetup, subdomainSetup, jacobianSetup and residualSetup functions respectively.

Creating Custom Execute Flags

It is possible to create custom execute flags for an application. To create at utilize a custom execute flag the following steps should be followed.

1. Register an Execute Flag

Within your application a new global const should be declared in a header file. For example, within the LevelSetApp within MOOSE modules, there is a header (LevelSetTypes.h) that declares a new flag (EXEC_ADAPT_MESH).


#pragma once

#include "Moose.h"

namespace LevelSet
{
extern const ExecFlagType EXEC_ADAPT_MESH;
extern const ExecFlagType EXEC_COMPUTE_MARKERS;
}
(modules/level_set/include/base/LevelSetTypes.h)

This new global must be registered, which occurs in the corresponding source file using the registerExecFlag() macro defined in ExecFlagRegistry.h.


// Level set includes
#include "LevelSetTypes.h"

// MOOSE includes
#include "ExecFlagRegistry.h"

const ExecFlagType LevelSet::EXEC_ADAPT_MESH = registerExecFlag("ADAPT_MESH");
const ExecFlagType LevelSet::EXEC_COMPUTE_MARKERS = registerExecFlag("COMPUTE_MARKERS");
(modules/level_set/src/base/LevelSetTypes.C)

2. Add the Execute Flag to InputParameters

After a flag is registered, it must be made available to the object(s) in which are desired to be executed with the custom flag. This is done by adding this new flag to an existing objects valid parameters. For example, the following adds the EXEC_ADAPT_MESH flag to a Transfer object.

ExecFlagEnum & exec = params.set<ExecFlagEnum>("execute_on");
exec.addAvailableFlags(LevelSet::EXEC_ADAPT_MESH, LevelSet::EXEC_COMPUTE_MARKERS);
exec = {LevelSet::EXEC_COMPUTE_MARKERS, LevelSet::EXEC_ADAPT_MESH};
(modules/level_set/src/transfers/LevelSetMeshRefinementTransfer.C)

3. Use the Execute Flag

Depending on what type of custom computation is desired, various MOOSE execution calls accept execution flags, which will spawn calculations. For example, the LevelSetProblem contains a custom method that uses the EXEC_ADAPT_MESH flag to perform an additional MultiAppTransfer execution.

execMultiAppTransfers(LevelSet::EXEC_ADAPT_MESH, MultiAppTransfer::TO_MULTIAPP);
(modules/level_set/src/base/LevelSetProblem.C)