Go to the documentation of this file.
23 #include "libmesh/mesh_tools.h"
24 #include "libmesh/numeric_vector.h"
35 params.
addClassDescription(
"MultiApp for performing coupled simulations with the master and "
36 "sub-application both progressing in time.");
40 "Set to true to allow this MultiApp to take smaller "
41 "timesteps than the rest of the simulation. More "
42 "than one timestep will be performed for each "
45 params.
addParam<
bool>(
"interpolate_transfers",
47 "Only valid when sub_cycling. This allows "
48 "transferred values to be interpolated "
49 "over the time frame the MultiApp is "
50 "executing over when sub_cycling");
52 params.
addParam<
bool>(
"detect_steady_state",
54 "If true then while sub_cycling a steady state check will be "
55 "done. In this mode output will only be done once the "
56 "MultiApp reaches the target time or steady state is reached");
58 params.
addParam<Real>(
"steady_state_tol",
60 "The relative difference between the new "
61 "solution and the old solution that will be "
62 "considered to be at steady state");
64 params.
addParam<
bool>(
"output_sub_cycles",
false,
"If true then every sub-cycle will be output.");
66 "print_sub_cycles",
true,
"Toggle the display of sub-cycles on the screen.");
69 "max_failures", 0,
"Maximum number of solve failures tolerated while sub_cycling.");
71 params.
addParam<
bool>(
"tolerate_failure",
73 "If true this MultiApp won't participate in dt "
74 "decisions and will always be fast-forwarded to "
80 "If true this will allow failed solves to attempt to 'catch up' using smaller timesteps.");
82 params.
addParam<
bool>(
"keep_solution_during_restore",
84 "This is useful when doing Picard with catch_up steps. It takes the "
85 "solution from the final catch_up step and re-uses it as the initial guess "
86 "for the next picard iteration");
88 params.
addParam<Real>(
"max_catch_up_steps",
90 "Maximum number of steps to allow an app to take "
91 "when trying to catch back up after a failed "
99 _sub_cycling(getParam<bool>(
"sub_cycling")),
100 _interpolate_transfers(getParam<bool>(
"interpolate_transfers")),
101 _detect_steady_state(getParam<bool>(
"detect_steady_state")),
102 _steady_state_tol(getParam<Real>(
"steady_state_tol")),
103 _output_sub_cycles(getParam<bool>(
"output_sub_cycles")),
104 _max_failures(getParam<unsigned int>(
"max_failures")),
105 _tolerate_failure(getParam<bool>(
"tolerate_failure")),
107 _catch_up(getParam<bool>(
"catch_up")),
108 _max_catch_up_steps(getParam<Real>(
"max_catch_up_steps")),
109 _keep_solution_during_restore(getParam<bool>(
"keep_solution_during_restore")),
110 _first(declareRecoverableData<bool>(
"first", true)),
111 _auto_advance(false),
112 _print_sub_cycles(getParam<bool>(
"print_sub_cycles"))
119 " is set to interpolate_transfers but is not sub_cycling! That is not valid!");
126 " \"sub_cycling\" and \"catch_up\" cannot both be set to true simultaneously.");
132 " it doesn't make any sense to keep a solution during restore when doing "
133 "sub_cycling. Consider trying \"catch_up\" steps instead");
139 " \"keep_solution_during_restore\" requires \"catch_up = true\". Either disable "
140 "\"keep_solution_during_restart\" or set \"catch_up = true\"");
146 " both \"sub_cycling\" and \"tolerate_failure\" are set to true. \"tolerate_failure\""
147 " will be ignored.");
150 NumericVector<Number> &
219 _console << COLOR_CYAN <<
"Solving MultiApp '" <<
name() <<
"' with target time " << target_time
220 <<
" and dt " << dt <<
" with auto-advance " << (auto_advance ?
"on" :
"off")
221 << COLOR_DEFAULT << std::endl;
227 bool return_value =
true;
234 ierr = MPI_Comm_rank(_communicator.get(), &rank);
235 mooseCheckMPIErr(
ierr);
244 Real app_time_offset =
_apps[i]->getGlobalTimeOffset();
247 if ((ex->
getTime() + app_time_offset + 2e-14 >= target_time) ||
253 Real time_old = ex->
getTime() + app_time_offset;
258 System & libmesh_aux_system = aux_system.
system();
260 NumericVector<Number> & solution = *libmesh_aux_system.solution;
261 NumericVector<Number> & transfer_old = libmesh_aux_system.get_vector(
"transfer_old");
266 transfer_old = solution;
268 transfer_old.close();
273 Threads::parallel_reduce(elem_range, aldit);
286 bool at_steady =
false;
291 bool local_first =
_first;
294 while ((!at_steady && ex->
getTime() + app_time_offset + 2e-14 < target_time) ||
297 if (local_first !=
true)
308 Real future_time = ex->
getTime() + app_time_offset + ex->
getDT();
311 Real step_percent = (future_time - time_old) / (target_time - time_old);
313 Real one_minus_step_percent = 1.0 - step_percent;
318 System & libmesh_aux_system = aux_system.
system();
320 NumericVector<Number> & solution = *libmesh_aux_system.solution;
321 NumericVector<Number> & transfer = libmesh_aux_system.get_vector(
"transfer");
322 NumericVector<Number> & transfer_old = libmesh_aux_system.get_vector(
"transfer_old");
326 transfer_old.close();
331 (transfer_old(dof) * one_minus_step_percent) +
332 (transfer(dof) * step_percent));
354 std::stringstream oss;
363 _console <<
"Solution change norm: " << solution_change_norm << std::endl;
367 _console <<
"Detected Steady State! Fast-forwarding to " << target_time << std::endl;
376 ex->
endStep(target_time - app_time_offset);
397 ex->
endStep(target_time - app_time_offset);
421 _console <<
"Starting Catch Up!" << std::endl;
423 bool caught_up =
false;
425 unsigned int catch_up_step = 0;
427 Real catch_up_dt = dt / 2;
431 _console <<
"Solving " <<
name() <<
" catch up step " << catch_up_step << std::endl;
440 if (ex->
getTime() + app_time_offset +
469 _console <<
"Starting Catch Up!" << std::endl;
471 bool caught_up =
false;
473 unsigned int catch_up_step = 0;
475 Real catch_up_dt = dt / 2;
480 _console <<
"Solving " <<
name() <<
" catch up step " << catch_up_step << std::endl;
492 if (current_time + app_time_offset +
525 _console <<
"Successfully Solved MultiApp " <<
name() <<
"." << std::endl;
530 _console <<
"Failed to Solve MultiApp " <<
name() <<
", attempting to recover." << std::endl;
531 return_value =
false;
549 Real app_time_offset =
_apps[i]->getGlobalTimeOffset();
553 if (app_time_offset < target_time)
583 return std::numeric_limits<Real>::max();
585 Real smallest_dt = std::numeric_limits<Real>::max();
595 Real dt = ex->
getDT();
597 smallest_dt = std::min(dt, smallest_dt);
604 return std::numeric_limits<Real>::max();
606 _communicator.min(smallest_dt);
611 unsigned int global_app,
638 auto & app =
_apps[i];
639 Transient * ex = dynamic_cast<Transient *>(app->getExecutioner());
641 mooseError(
"MultiApp ",
name(),
" is not using a Transient Executioner!");
656 System & libmesh_aux_system = aux_system.
system();
659 libmesh_aux_system.add_vector(
"transfer_old",
false);
662 libmesh_aux_system.add_vector(
"transfer",
false);
MPI_Comm & _my_comm
The MPI communicator this object is going to use.
virtual void incrementTStep(Real target_time) override
Advances the multi-apps time step which is important for dt selection.
Transient executioners usually loop through a number of timesteps...
bool _print_sub_cycles
Flag for toggling console output on sub cycles.
bool _interpolate_transfers
unsigned int _my_num_apps
The number of apps this object is involved in simulating.
virtual void restore() override
Restore the state of every Sub App.
virtual bool solveStep(Real dt, Real target_time, bool auto_advance=true) override
Re-solve all of the Apps.
FEProblemBase & appProblemBase(unsigned int app)
Get the FEProblemBase for the global app is part of.
NumericVector< Number > & solution() override
virtual void initialSetup() override
Gets called at the beginning of the simulation before this object is asked to do its job.
MultiApp Implementation for Transient Apps.
A system that holds auxiliary variables.
void mooseError(Args &&... args) const
virtual NonlinearSystem & getNonlinearSystem()
static InputParameters validParams()
static InputParameters validParams()
unsigned int _max_failures
ConstElemRange * getActiveLocalElementRange()
Return pointers to range objects for various types of ranges (local nodes, boundary elems,...
virtual int & timeStep() const
MetaPhysicL::DualNumber< T, D > abs(const MetaPhysicL::DualNumber< T, D > &in)
void allowOutput(bool state)
Ability to enable/disable all output calls.
const ExecFlagType EXEC_FORCED
static InputParameters validParams()
virtual Executioner * getExecutioner(unsigned int app)
virtual void preExecute() override
Override this for actions that should take place before execution.
virtual void advanceState()
Advance all of the state holding vectors / datastructures so that we can move to the next timestep.
FEProblemBase & feProblem()
Return a reference to this Executioner's FEProblemBase instance.
virtual void setTargetTime(Real target_time)
Can be used to set the next "target time" which is a time to nail perfectly.
bool hasLocalApp(unsigned int global_app)
Whether or not the given global app number is on this processor.
unsigned int globalAppToLocal(unsigned int global_app)
Map a global App number to the local number.
virtual void resetApp(unsigned int global_app, Real time) override
"Reset" the App corresponding to the global App number passed in.
Real & timestepTol()
Get the timestep tolerance.
bool _has_an_app
Whether or not this processor as an App at all
bool _keep_solution_during_restore
std::set< dof_id_type > _all_dof_indices
std::vector< std::unique_ptr< NumericVector< Real > > > _end_solutions
The solution from the end of the previous solve, this is cloned from the Nonlinear solution during re...
A MultiApp represents one or more MOOSE applications that are running simultaneously.
Real getSolutionChangeNorm()
Get the Relative L2 norm of the change in the solution.
NumericVector< Number > & solution() override
void paramError(const std::string ¶m, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
virtual void endStep(Real input_time=-1.0)
void setupApp(unsigned int i, Real time=0.0)
Setup the executioner for the local app.
std::vector< std::shared_ptr< MooseApp > > _apps
Pointers to each of the Apps.
virtual bool lastSolveConverged() const override
Whether or not the last solve converged.
registerMooseObject("MooseApp", TransientMultiApp)
virtual bool needsRestoration() override
Whether or not this MultiApp should be restored at the beginning of each Picard iteration.
bool _detect_steady_state
std::vector< Transient * > _transient_executioners
void forceOutput()
Indicates that the next call to outputStep should be forced.
Grab all the local dof indices for the variables passed in, in the system passed in.
std::set< dof_id_type > _transferred_dofs
The DoFs associated with all of the currently transferred variables.
Utility class for catching solve failure errors so that MOOSE can recover state before continuing.
virtual void init() override
Initialize the executioner.
const std::map< std::string, unsigned int > & getOutputFileNumbers() const
Store a map of outputter names and file numbers The MultiApp system requires this to get the file num...
virtual void restore()
Restore the state of every Sub App.
bool & _first
Is it our first time through the execution loop?
virtual void incrementStepOrReject()
This is where the solve step is actually incremented.
virtual void initialSetup() override
Gets called at the beginning of the simulation before this object is asked to do its job.
std::vector< std::string > _transferred_vars
The variables that have been transferred to. Used when doing transfer interpolation....
TransientMultiApp(const InputParameters ¶meters)
bool isRecovering() const
Whether or not this is a "recover" calculation.
Real computeDT()
Finds the smallest dt from among any of the apps.
Real & endTime()
Get the end time.
virtual Real getTime()
Get the current time.
AuxiliarySystem & getAuxiliarySystem()
virtual void resetApp(unsigned int global_app, Real time=0.0)
"Reset" the App corresponding to the global App number passed in.
virtual void takeStep(Real input_dt=-1.0)
Do whatever is necessary to advance one step.
unsigned int _first_local_app
The number of the first app on this processor.
virtual void finishStep() override
Calls multi-apps executioners' endStep and postStep methods which creates output and advances time (n...
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
An output object for writing to the console (screen)
virtual System & system() override
Get the reference to the libMesh system.
MooseApp & _app
The MooseApp this object is associated with.
defineLegacyParams(TransientMultiApp)
virtual NumericVector< Number > & appTransferVector(unsigned int app, std::string var_name) override
Get the vector to transfer to for this MultiApp.
virtual MooseMesh & mesh() override
void mooseWarning(Args &&... args) const
virtual const std::string & name() const
Get the name of the object.
Real getGlobalTimeOffset() const
Each App has it's own local time.
void paramInfo(const std::string ¶m, Args... args) const
Emits an informational message prefixed with the file and line number of the given param (from the in...
virtual void outputStep(ExecFlagType type)
Output the current step.