https://mooseframework.inl.gov
TransientMultiApp.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 // MOOSE includes
11 #include "TransientMultiApp.h"
12 
14 #include "AuxiliarySystem.h"
15 #include "Console.h"
17 #include "MooseMesh.h"
18 #include "Output.h"
19 #include "TimeStepper.h"
20 #include "TransientBase.h"
21 #include "NonlinearSystem.h"
22 
23 #include "libmesh/mesh_tools.h"
24 #include "libmesh/numeric_vector.h"
25 
27 
30 {
33  params.addClassDescription("MultiApp for performing coupled simulations with the parent and "
34  "sub-application both progressing in time.");
35 
36  params.addParam<bool>("sub_cycling",
37  false,
38  "Set to true to allow this MultiApp to take smaller "
39  "timesteps than the rest of the simulation. More "
40  "than one timestep will be performed for each "
41  "parent application timestep");
42 
43  params.addParam<bool>("interpolate_transfers",
44  false,
45  "Only valid when sub_cycling. This allows "
46  "transferred values to be interpolated "
47  "over the time frame the MultiApp is "
48  "executing over when sub_cycling");
49 
50  params.addParam<bool>("detect_steady_state",
51  false,
52  "If true, then if/while sub-cycling ('sub_cycling = true'), a steady-state "
53  "check will be performed for each child app, allowing them to skip to the "
54  "end of the parent time step if steady conditions are detected.");
55 
56  params.addParam<bool>("output_sub_cycles", false, "If true then every sub-cycle will be output.");
57  params.addParam<bool>(
58  "print_sub_cycles", true, "Toggle the display of sub-cycles on the screen.");
59 
60  params.addParam<unsigned int>(
61  "max_failures", 0, "Maximum number of solve failures tolerated while sub_cycling.");
62 
63  params.addParamNamesToGroup("sub_cycling interpolate_transfers detect_steady_state "
64  "output_sub_cycles print_sub_cycles max_failures",
65  "Sub cycling");
66 
67  params.addParam<bool>("tolerate_failure",
68  false,
69  "If true this MultiApp won't participate in dt "
70  "decisions and will always be fast-forwarded to "
71  "the current time.");
72 
73  params.addParam<bool>(
74  "catch_up",
75  false,
76  "If true this will allow failed solves to attempt to 'catch up' using smaller timesteps.");
77 
78  params.addParam<Real>("max_catch_up_steps",
79  2,
80  "Maximum number of steps to allow an app to take "
81  "when trying to catch back up after a failed "
82  "solve.");
83 
84  params.addParamNamesToGroup("catch_up max_catch_up_steps", "Recovering failed solutions");
85  params.addParamNamesToGroup("tolerate_failure", "Accepting failed solutions");
86 
87  return params;
88 }
89 
91  : MultiApp(parameters),
92  _sub_cycling(getParam<bool>("sub_cycling")),
93  _interpolate_transfers(getParam<bool>("interpolate_transfers")),
94  _detect_steady_state(getParam<bool>("detect_steady_state")),
95  _output_sub_cycles(getParam<bool>("output_sub_cycles")),
96  _max_failures(getParam<unsigned int>("max_failures")),
97  _tolerate_failure(getParam<bool>("tolerate_failure")),
98  _failures(0),
99  _catch_up(getParam<bool>("catch_up")),
100  _max_catch_up_steps(getParam<Real>("max_catch_up_steps")),
101  _first(declareRecoverableData<bool>("first", true)),
102  _auto_advance(false),
103  _print_sub_cycles(getParam<bool>("print_sub_cycles"))
104 {
105  // Transfer interpolation only makes sense for sub-cycling solves
107  paramError("interpolate_transfers",
108  "MultiApp ",
109  name(),
110  " is set to interpolate_transfers but is not sub_cycling! That is not valid!");
111 
112  // Subcycling overrides catch up, we don't want to confuse users by allowing them to set both.
113  if (_sub_cycling && _catch_up)
114  paramError("catch_up",
115  "MultiApp ",
116  name(),
117  " \"sub_cycling\" and \"catch_up\" cannot both be set to true simultaneously.");
118 
120  paramError("keep_solution_during_restore",
121  "In MultiApp ",
122  name(),
123  " it doesn't make any sense to keep a solution during restore when doing "
124  "sub_cycling. Consider trying \"catch_up\" steps instead");
125 
127  paramError("keep_solution_during_restore",
128  "In MultiApp ",
129  name(),
130  " \"keep_solution_during_restore\" requires \"catch_up = true\". Either disable "
131  "\"keep_solution_during_restart\" or set \"catch_up = true\"");
132 
134  paramInfo("tolerate_failure",
135  "In MultiApp ",
136  name(),
137  " both \"sub_cycling\" and \"tolerate_failure\" are set to true. \"tolerate_failure\""
138  " will be ignored.");
139 }
140 
142 TransientMultiApp::appTransferVector(unsigned int app, std::string var_name)
143 {
144  if (std::find(_transferred_vars.begin(), _transferred_vars.end(), var_name) ==
145  _transferred_vars.end())
146  _transferred_vars.push_back(var_name);
147 
149  return appProblemBase(app).getAuxiliarySystem().system().get_vector("transfer");
150 
152 }
153 
154 void
156 {
158 
159  if (!_has_an_app)
160  return;
161 
163 
164  if (_has_an_app)
165  {
167  // Grab Transient Executioners from each app
168  for (unsigned int i = 0; i < _my_num_apps; i++)
169  setupApp(i);
170  }
171 }
172 
173 bool
174 TransientMultiApp::solveStep(Real dt, Real target_time, bool auto_advance)
175 {
176  if (!_has_an_app)
177  return true;
178 
179  TIME_SECTION(_solve_step_timer);
180 
181  _auto_advance = auto_advance;
182 
184  _console << COLOR_CYAN << "Solving MultiApp '" << name() << "' with target time " << target_time
185  << " and dt " << dt << " with auto-advance " << (auto_advance ? "on" : "off")
186  << COLOR_DEFAULT << std::endl;
187 
188  // "target_time" must always be in global time
189  target_time += _app.getGlobalTimeOffset();
190 
192  bool return_value = true;
193 
194  // Make sure we swap back the communicator regardless of how this routine is exited
195  try
196  {
197  int rank;
198  int ierr;
199  ierr = MPI_Comm_rank(_communicator.get(), &rank);
200  mooseCheckMPIErr(ierr);
201 
202  for (unsigned int i = 0; i < _my_num_apps; i++)
203  {
205 
207 
208  // The App might have a different local time from the rest of the problem
209  Real app_time_offset = _apps[i]->getGlobalTimeOffset();
210 
211  // Maybe this MultiApp was already solved
212  if ((ex->getTime() + app_time_offset + ex->timestepTol() >= target_time) ||
213  (ex->getTime() >= ex->endTime()))
214  continue;
215 
216  // Examine global time synchronization
217  if (!_sub_cycling && !_reset_happened.size())
218  {
219  // The multi-app general offset is substracted to go into local time.
220  if (std::abs(target_time - _app.getGlobalTimeOffset() - ex->getTime() - dt) >
221  ex->timestepTol())
222  mooseDoOnce(mooseWarning(
223  "The target time (time a multiapp must reach at the end of the time step) "
224  "is desynchronized between this app and subapp ",
225  i,
226  ".\n If this is desired: use the 'global_time_offset' multiapp parameter to "
227  "declare a constant offset\n"
228  "If the apps should (eventually) be synchronized in time, please either: \n"
229  " - match the 'start_time' in the main app and the multiapp, in the Executioner "
230  "block\n"
231  " - set 'sub_cycling' to true in the multiapp parameters\n"
232  "This message will only print once for all apps and all time steps."));
233  }
234 
235  if (_sub_cycling)
236  {
237  Real time_old = ex->getTime() + app_time_offset;
238 
240  {
241  AuxiliarySystem & aux_system = problem.getAuxiliarySystem();
242  System & libmesh_aux_system = aux_system.system();
243 
244  NumericVector<Number> & solution = *libmesh_aux_system.solution;
245  NumericVector<Number> & transfer_old = libmesh_aux_system.get_vector("transfer_old");
246 
247  solution.close();
248 
249  // Save off the current auxiliary solution
250  transfer_old = solution;
251 
252  transfer_old.close();
253 
254  // Snag all of the local dof indices for all of these variables
256  ConstElemRange & elem_range = *problem.mesh().getActiveLocalElementRange();
257  Threads::parallel_reduce(elem_range, aldit);
258 
260  }
261 
262  // Disable/enable output for sub cycling
263  problem.allowOutput(_output_sub_cycles); // disables all outputs, including console
264  problem.allowOutput<Console>(_print_sub_cycles); // re-enables Console to print, if desired
265 
266  ex->setTargetTime(target_time - app_time_offset);
267 
268  // unsigned int failures = 0;
269 
270  bool at_steady = false;
271 
272  // ADL: During restart, there is already an FEProblemBase::advanceState that occurs at the
273  // end of TransientMultiApp::setupApp. advanceState, along with copying the solutions
274  // backwards in time/state, also *moves* (note it doesn't copy!) stateful material
275  // properties backwards (through swapping). So if restarting from a full-solve steady
276  // multi-app for example, then after one advance state, we will have good information in old
277  // and no information in current. But then if we advance again we no longer have good data
278  // in the old material properties, so don't advance here if we're restarting
279  if (_first && !_app.isRecovering() && !_app.isRestarting())
280  problem.advanceState();
281 
282  bool local_first = _first;
283 
284  // Now do all of the solves we need
285  while ((!at_steady && ex->getTime() + app_time_offset + ex->timestepTol() < target_time) ||
286  !ex->lastSolveConverged())
287  {
288  if (local_first != true)
289  ex->incrementStepOrReject();
290 
291  local_first = false;
292 
293  ex->preStep();
294  ex->computeDT();
295 
297  {
298  // See what time this executioner is going to go to.
299  Real future_time = ex->getTime() + app_time_offset + ex->getDT();
300 
301  // How far along we are towards the target time:
302  Real step_percent = (future_time - time_old) / (target_time - time_old);
303 
304  Real one_minus_step_percent = 1.0 - step_percent;
305 
306  // Do the interpolation for each variable that was transferred to
308  AuxiliarySystem & aux_system = problem.getAuxiliarySystem();
309  System & libmesh_aux_system = aux_system.system();
310 
311  NumericVector<Number> & solution = *libmesh_aux_system.solution;
312  NumericVector<Number> & transfer = libmesh_aux_system.get_vector("transfer");
313  NumericVector<Number> & transfer_old = libmesh_aux_system.get_vector("transfer_old");
314 
315  solution.close(); // Just to be sure
316  transfer.close();
317  transfer_old.close();
318 
319  for (const auto & dof : _transferred_dofs)
320  {
321  solution.set(dof,
322  (transfer_old(dof) * one_minus_step_percent) +
323  (transfer(dof) * step_percent));
324  // solution.set(dof, transfer_old(dof));
325  // solution.set(dof, transfer(dof));
326  // solution.set(dof, 1);
327  }
328 
329  solution.close();
330  }
331 
332  ex->takeStep();
333 
334  bool converged = ex->lastSolveConverged();
335 
336  if (!converged)
337  {
338  mooseWarning(
339  "While sub_cycling ", name(), _first_local_app + i, " failed to converge!\n");
340 
341  _failures++;
342 
343  if (_failures > _max_failures)
344  {
345  std::stringstream oss;
346  oss << "While sub_cycling " << name() << _first_local_app << i << " REALLY failed!";
347  throw MultiAppSolveFailure(oss.str());
348  }
349  }
350 
351  at_steady = ex->convergedToSteadyState();
352 
353  if (converged && _detect_steady_state && at_steady)
354  {
356  _console << "Detected Steady State! Fast-forwarding to " << target_time << std::endl;
357 
358  // Indicate that the next output call (occurs in ex->endStep()) should output,
359  // regardless of intervals etc...
360  problem.forceOutput();
361 
362  // Clean up the end
363  ex->endStep(target_time - app_time_offset);
364  ex->postStep();
365  }
366  else
367  {
368  ex->endStep();
369  ex->postStep();
370  }
371  }
372 
373  // If we were looking for a steady state, but didn't reach one, we still need to output one
374  // more time, regardless of interval
375  // Note: if we turn off the output for all time steps for sub-cycling, we still need to
376  // have one output at the end.
377  if ((!at_steady && _detect_steady_state) || !_output_sub_cycles)
378  problem.outputStep(EXEC_FORCED);
379 
380  } // sub_cycling
381  else if (_tolerate_failure)
382  {
383  ex->takeStep(dt);
384  ex->endStep(target_time - app_time_offset);
385  ex->postStep();
386  }
387  else
388  {
389  // ADL: During restart, there is already an FEProblemBase::advanceState that occurs at the
390  // end of TransientMultiApp::setupApp. advanceState, along with copying the solutions
391  // backwards in time/state, also *moves* (note it doesn't copy!) stateful material
392  // properties backwards (through swapping). So if restarting from a full-solve steady
393  // multi-app for example, then after one advance state, we will have good information in old
394  // and no information in current. But then if we advance again we no longer have good data
395  // in the old material properties, so don't advance here if we're restarting
396  if (_first && !_app.isRecovering() && !_app.isRestarting())
397  problem.advanceState();
398 
399  if (auto_advance)
400  problem.allowOutput(true);
401 
402  ex->takeStep(dt);
403 
404  if (auto_advance)
405  {
406  ex->endStep();
407  ex->postStep();
408 
409  if (!ex->lastSolveConverged())
410  {
411  mooseWarning(name(), _first_local_app + i, " failed to converge!\n");
412 
413  if (_catch_up)
414  {
416  _console << "Starting time step catch up!" << std::endl;
417 
418  bool caught_up = false;
419 
420  unsigned int catch_up_step = 0;
421 
422  // Cut the timestep in half to first try two half-step solves
423  Real catch_up_dt = dt / 2;
424  Real catch_up_time = 0;
425 
426  while (!caught_up && catch_up_step < _max_catch_up_steps)
427  {
429  _console << "Solving " << name() << " catch up step " << catch_up_step
430  << std::endl;
431  ex->incrementStepOrReject();
432 
433  // Avoid numerical precision errors on target time
434  if (catch_up_time + catch_up_dt > dt)
435  catch_up_dt = dt - catch_up_time;
436 
437  ex->computeDT();
438  ex->takeStep(catch_up_dt);
439  ex->endStep();
440 
441  if (ex->lastSolveConverged())
442  {
443  catch_up_time += catch_up_dt;
444  if (std::abs(catch_up_time - dt) <
445  (1 + std::abs(ex->getTime())) * ex->timestepTol())
446  {
447  problem.outputStep(EXEC_FORCED);
448  caught_up = true;
449  }
450  }
451  else
452  // Keep cutting time step in half until it converges
453  catch_up_dt /= 2.0;
454 
455  ex->postStep();
456 
457  catch_up_step++;
458  }
459 
460  if (!caught_up)
461  throw MultiAppSolveFailure(name() + " Failed to catch up!\n");
462  }
463  }
464  }
465  else // auto_advance == false
466  {
467  if (!ex->lastSolveConverged())
468  {
469  // Even if we don't allow auto_advance - we can still catch up to the current time if
470  // possible
471  if (_catch_up)
472  {
474  _console << "Starting Catch Up!" << std::endl;
475 
476  bool caught_up = false;
477 
478  unsigned int catch_up_step = 0;
479 
480  Real catch_up_dt = dt / 2;
481 
482  // Note: this loop will _break_ if target_time is satisfied
483  while (catch_up_step < _max_catch_up_steps)
484  {
486  _console << "Solving " << name() << " catch up step " << catch_up_step
487  << std::endl;
488  ex->incrementStepOrReject();
489 
490  ex->computeDT();
491  ex->takeStep(catch_up_dt); // Cut the timestep in half to try two half-step solves
492 
493  // This is required because we can't call endStep() yet
494  // (which normally increments time)
495  Real current_time = ex->getTime() + ex->getDT();
496 
497  if (ex->lastSolveConverged())
498  {
499  if (current_time + app_time_offset +
500  (ex->timestepTol() * std::abs(current_time)) >=
501  target_time)
502  {
503  caught_up = true;
504  break; // break here so that we don't run endStep() or postStep() since this
505  // MultiApp should NOT be auto_advanced
506  }
507  }
508  else
509  catch_up_dt /= 2.0;
510 
511  ex->endStep();
512  ex->postStep();
513 
514  catch_up_step++;
515  }
516 
517  if (!caught_up)
518  throw MultiAppSolveFailure(name() + " Failed to catch up!\n");
519  }
520  else
521  throw MultiAppSolveFailure(name() + " failed to converge");
522  }
523  }
524  }
525 
526  // Re-enable all output (it may of been disabled by sub-cycling)
527  problem.allowOutput(true);
528  }
529 
530  _first = false;
531 
533  _console << "Successfully Solved MultiApp " << name() << "." << std::endl;
534  }
535  catch (MultiAppSolveFailure & e)
536  {
537  mooseWarning(e.what());
538  _console << "Failed to Solve MultiApp " << name() << ", attempting to recover." << std::endl;
539  return_value = false;
540  }
541 
542  _transferred_vars.clear();
543 
544  return return_value;
545 }
546 
547 void
549 {
550  if (!_sub_cycling)
551  {
552  for (unsigned int i = 0; i < _my_num_apps; i++)
553  {
555 
556  // The App might have a different local time from the rest of the problem
557  Real app_time_offset = _apps[i]->getGlobalTimeOffset();
558 
559  // Only increment the step if we are after (target_time) the
560  // start_time (added to app_time_offset) of this sub_app.
561  if (_apps[i]->getStartTime() + app_time_offset < target_time)
562  ex->incrementStepOrReject();
563  }
564  }
565 }
566 
567 void
568 TransientMultiApp::finishStep(bool recurse_through_multiapp_levels)
569 {
570  if (!_sub_cycling)
571  {
572  for (unsigned int i = 0; i < _my_num_apps; i++)
573  {
575  ex->endStep();
576  ex->postStep();
577  if (recurse_through_multiapp_levels)
578  {
580  /*recurse_through_multiapp_levels=*/true);
582  /*recurse_through_multiapp_levels=*/true);
583  }
584  }
585  }
586 }
587 
588 Real
590 {
591  if (_sub_cycling) // Bow out of the timestep selection dance
593 
594  Real smallest_dt = std::numeric_limits<Real>::max();
595 
596  if (_has_an_app)
597  {
599 
600  for (unsigned int i = 0; i < _my_num_apps; i++)
601  {
603  ex->computeDT();
604  Real dt = ex->getDT();
605 
606  smallest_dt = std::min(dt, smallest_dt);
607  }
608  }
609 
610  if (_tolerate_failure) // Bow out of the timestep selection dance, we do this down here because we
611  // need to call computeConstrainedDT at least once for these
612  // executioners...
614 
615  _communicator.min(smallest_dt);
616  return smallest_dt;
617 }
618 
619 void
621  unsigned int global_app,
622  Real /*time*/) // FIXME: Note that we are passing in time but also grabbing it below
623 {
624  if (hasLocalApp(global_app))
625  {
626  unsigned int local_app = globalAppToLocal(global_app);
627 
628  // Grab the current time the App is at so we can start the new one at the same place
629  Real time =
630  _transient_executioners[local_app]->getTime() + _apps[local_app]->getGlobalTimeOffset();
631 
632  // Reset the Multiapp
633  MultiApp::resetApp(global_app, time);
634 
636 
637  // Setup the app, disable the output so that the initial condition does not output
638  // When an app is reset the initial condition was effectively already output before reset
639  FEProblemBase & problem = appProblemBase(local_app);
640  problem.allowOutput(false);
641  setupApp(local_app, time);
642  problem.allowOutput(true);
643  }
644 }
645 
646 void
647 TransientMultiApp::setupApp(unsigned int i, Real /*time*/) // FIXME: Should we be passing time?
648 {
649  auto & app = _apps[i];
650  TransientBase * ex = dynamic_cast<TransientBase *>(app->getExecutioner());
651  if (!ex)
652  mooseError("MultiApp ", name(), " is not using a Transient Executioner!");
653 
654  // Get the FEProblemBase for the current MultiApp
656 
657  // Update the file numbers for the outputs from the parent application
658  app->getOutputWarehouse().setFileNumbers(_app.getOutputFileNumbers());
659 
660  // Add these vectors before we call init on the executioner because that will try to restore these
661  // vectors in a restart context
663  {
664  AuxiliarySystem & aux_system = problem.getAuxiliarySystem();
665  System & libmesh_aux_system = aux_system.system();
666 
667  // We'll store a copy of the auxiliary system's solution at the old time in here
668  libmesh_aux_system.add_vector("transfer_old", false);
669 
670  // This will be where we'll transfer the value to for the "target" time
671  libmesh_aux_system.add_vector("transfer", false);
672  }
673 
674  // Call initialization method of Executioner (Note, this performs the output of the initial time
675  // step, if desired)
676  ex->init();
677 
678  ex->preExecute();
679  if (!_app.isRecovering())
680  {
681  problem.timeStep()++;
682  problem.advanceState();
683  }
684  _transient_executioners[i] = ex;
685 }
virtual void preExecute() override
Override this for actions that should take place before execution.
virtual NumericVector< Number > & appTransferVector(unsigned int app, std::string var_name) override
Get the vector to transfer to for this MultiApp.
bool hasLocalApp(unsigned int global_app) const
Whether or not the given global app number is on this processor.
Definition: MultiApp.C:1061
Utility class for catching solve failure errors so that MOOSE can recover state before continuing...
MetaPhysicL::DualNumber< V, D, asd > abs(const MetaPhysicL::DualNumber< V, D, asd > &a)
Definition: EigenADReal.h:42
libMesh::ConstElemRange * getActiveLocalElementRange()
Return pointers to range objects for various types of ranges (local nodes, boundary elems...
Definition: MooseMesh.C:1235
bool _print_sub_cycles
Flag for toggling console output on sub cycles.
bool verboseMultiApps() const
Whether or not to use verbose printing for MultiApps.
const ExecFlagType EXEC_FORCED
Definition: Moose.C:45
NumericVector< Number > & solution()
Definition: SystemBase.h:195
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...
Definition: MooseApp.h:569
static InputParameters validParams()
virtual void endStep(Real input_time=-1.0)
virtual void setTargetTime(Real target_time)
Can be used to set the next "target time" which is a time to nail perfectly.
An output object for writing to the console (screen)
Definition: Console.h:18
unsigned int _max_failures
const PerfID _solve_step_timer
Timers.
Definition: MultiApp.h:625
virtual void initialSetup() override
Method to be called in main-app initial setup for create sub-apps if using positions is false...
virtual void add_vector(const T *v, const std::vector< numeric_index_type > &dof_indices)
std::vector< std::shared_ptr< MooseApp > > _apps
Pointers to each of the Apps.
Definition: MultiApp.h:541
FEProblemBase & feProblem()
Return a reference to this Executioner&#39;s FEProblemBase instance.
Definition: Executioner.C:124
void setupApp(unsigned int i, Real time=0.0)
Setup the executioner for the local app.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
virtual void resetApp(unsigned int global_app, Real time) override
"Reset" the App corresponding to the global App number passed in.
virtual Real getDT()
NumericVector< Number > & add_vector(std::string_view vec_name, const bool projections=true, const ParallelType type=PARALLEL)
MultiApp Implementation for Transient Apps.
void finishMultiAppStep(ExecFlagType type, bool recurse_through_multiapp_levels=false)
Finish the MultiApp time step (endStep, postStep) associated with the ExecFlagType.
const Parallel::Communicator & _communicator
const ExecFlagType EXEC_TIMESTEP_END
Definition: Moose.C:34
static InputParameters validParams()
FEProblemBase & _fe_problem
The FEProblemBase this MultiApp is part of.
Definition: MultiApp.h:482
bool isRestarting() const
Whether or not this is a "restart" calculation.
Definition: MooseApp.C:1808
bool convergedToSteadyState() const
Determines whether the problem has converged to steady state.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
virtual const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:57
void mooseWarning(Args &&... args) const
Emits a warning prefixed with object name and type.
const std::set< dof_id_type > & getDofIndices() const
auto max(const L &left, const R &right)
Grab all the (possibly semi)local dof indices for the variables passed in, in the system passed in...
virtual void advanceState()
Advance all of the state holding vectors / datastructures so that we can move to the next timestep...
virtual void preStep()
bool _keep_solution_during_restore
Flag indicates if or not restart from the latest solution.
Definition: MultiApp.h:598
void min(const T &r, T &o, Request &req) const
const ExecFlagType EXEC_TIMESTEP_BEGIN
Definition: Moose.C:35
TransientMultiApp(const InputParameters &parameters)
std::set< dof_id_type > _transferred_dofs
The DoFs associated with all of the currently transferred variables.
virtual void takeStep(Real input_dt=-1.0)
Do whatever is necessary to advance one step.
FEProblemBase & appProblemBase(unsigned int app)
Get the FEProblemBase for the global app desired.
Definition: MultiApp.C:1007
virtual Real getTime() const
Get the current time.
Definition: TransientBase.h:91
std::vector< TransientBase * > _transient_executioners
virtual void postStep()
void forceOutput()
Indicates that the next call to outputStep should be forced.
Base class for transient executioners that use a FixedPointSolve solve object for multiapp-main app i...
Definition: TransientBase.h:27
bool & _first
Is it our first time through the execution loop?
MooseApp & _app
The MOOSE application this is associated with.
Definition: MooseBase.h:84
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
virtual void resetApp(unsigned int global_app, Real time=0.0)
"Reset" the App corresponding to the global App number passed in.
Definition: MultiApp.C:1078
std::vector< std::string > _transferred_vars
The variables that have been transferred to. Used when doing transfer interpolation. This will be cleared after each solve.
AuxiliarySystem & getAuxiliarySystem()
virtual void close()=0
virtual int & timeStep() const
unsigned int _my_num_apps
The number of apps this object is involved in simulating.
Definition: MultiApp.h:514
bool _has_an_app
Whether or not this processor as an App at all
Definition: MultiApp.h:589
Real computeDT()
Finds the smallest dt from among any of the apps.
unsigned int _first_local_app
The number of the first app on this processor.
Definition: MultiApp.h:517
virtual void init() override
Initialize the executioner.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Real & endTime()
Get a modifiable reference to the end time.
virtual void initialSetup() override
Method to be called in main-app initial setup for create sub-apps if using positions is false...
Definition: MultiApp.C:438
Real & timestepTol()
Get the timestep tolerance.
unsigned int _failures
virtual void incrementStepOrReject()
This is where the solve step is actually incremented.
virtual MooseMesh & mesh() override
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump...
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
virtual void set(const numeric_index_type i, const Number value)=0
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
virtual bool lastSolveConverged() const override
Whether or not the last solve converged.
virtual libMesh::System & system() override
Get the reference to the libMesh system.
static InputParameters validParams()
Definition: MultiApp.C:50
A MultiApp represents one or more MOOSE applications that are running simultaneously.
Definition: MultiApp.h:112
registerMooseObject("MooseApp", TransientMultiApp)
bool isRecovering() const
Whether or not this is a "recover" calculation.
Definition: MooseApp.C:1802
auto min(const L &left, const R &right)
Real getGlobalTimeOffset() const
Each App has it&#39;s own local time.
Definition: MooseApp.h:338
void paramInfo(const std::string &param, Args... args) const
Emits an informational message prefixed with the file and line number of the given param (from the in...
MPI_Comm & _my_comm
The MPI communicator this object is going to use.
Definition: MultiApp.h:526
A system that holds auxiliary variables.
void ErrorVector unsigned int
virtual void incrementTStep(Real target_time) override
Advances the multi-apps time step which is important for dt selection.
void allowOutput(bool state)
Ability to enable/disable all output calls.
virtual void outputStep(ExecFlagType type)
Output the current step.
const NumericVector< Number > & get_vector(std::string_view vec_name) const
virtual bool solveStep(Real dt, Real target_time, bool auto_advance=true) override
Re-solve all of the Apps.
unsigned int globalAppToLocal(unsigned int global_app)
Map a global App number to the local number.
Definition: MultiApp.C:1441
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
This method takes a space delimited list of parameter names and adds them to the specified group name...
std::vector< bool > _reset_happened
Whether or not apps have been reset at each time.
Definition: MultiApp.h:574
virtual void finishStep(bool recurse_through_multiapp_levels=false) override
Calls multi-apps executioners&#39; endStep and postStep methods which creates output and advances time (n...