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  }
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  } // end of 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  // matched time steps (no subcycling)
388  else
389  {
390  // ADL: During restart, there is already an FEProblemBase::advanceState that occurs at the
391  // end of TransientMultiApp::setupApp. advanceState, along with copying the solutions
392  // backwards in time/state, also *moves* (note it doesn't copy!) stateful material
393  // properties backwards (through swapping). So if restarting from a full-solve steady
394  // multi-app for example, then after one advance state, we will have good information in old
395  // and no information in current. But then if we advance again we no longer have good data
396  // in the old material properties, so don't advance here if we're restarting
397  if (_first && !_app.isRecovering() && !_app.isRestarting())
398  problem.advanceState();
399 
400  if (auto_advance)
401  problem.allowOutput(true);
402 
403  ex->takeStep(dt);
404 
405  if (auto_advance)
406  {
407  ex->endStep();
408  ex->postStep();
409 
410  if (!ex->lastSolveConverged())
411  {
412  mooseWarning(name(), _first_local_app + i, " failed to converge!\n");
413 
414  if (_catch_up)
415  {
417  _console << "Starting time step catch up!" << std::endl;
418 
419  bool caught_up = false;
420 
421  unsigned int catch_up_step = 0;
422 
423  // Cut the timestep in half to first try two half-step solves
424  Real catch_up_dt = dt / 2;
425  Real catch_up_time = 0;
426 
427  while (!caught_up && catch_up_step < _max_catch_up_steps)
428  {
430  _console << "Solving " << name() << " catch up step " << catch_up_step
431  << std::endl;
432  ex->incrementStepOrReject();
433 
434  // Avoid numerical precision errors on target time
435  if (catch_up_time + catch_up_dt > dt)
436  catch_up_dt = dt - catch_up_time;
437 
438  ex->computeDT();
439  ex->takeStep(catch_up_dt);
440  ex->endStep();
441 
442  if (ex->lastSolveConverged())
443  {
444  catch_up_time += catch_up_dt;
445  if (std::abs(catch_up_time - dt) <
446  (1 + std::abs(ex->getTime())) * ex->timestepTol())
447  {
448  problem.outputStep(EXEC_FORCED);
449  caught_up = true;
450  }
451  }
452  else
453  // Keep cutting time step in half until it converges
454  catch_up_dt /= 2.0;
455 
456  ex->postStep();
457 
458  catch_up_step++;
459  }
460 
461  if (!caught_up)
462  throw MultiAppSolveFailure(name() + " Failed to catch up!\n");
463  }
464  }
465  }
466  else // auto_advance == false
467  {
468  if (!ex->lastSolveConverged())
469  {
470  // Even if we don't allow auto_advance - we can still catch up to the current time if
471  // possible
472  if (_catch_up)
473  {
475  _console << "Starting Catch Up!" << std::endl;
476 
477  bool caught_up = false;
478 
479  unsigned int catch_up_step = 0;
480 
481  Real catch_up_dt = dt / 2;
482 
483  // Note: this loop will _break_ if target_time is satisfied
484  while (catch_up_step < _max_catch_up_steps)
485  {
487  _console << "Solving " << name() << " catch up step " << catch_up_step
488  << std::endl;
489  ex->incrementStepOrReject();
490 
491  ex->computeDT();
492  ex->takeStep(catch_up_dt); // Cut the timestep in half to try two half-step solves
493 
494  // This is required because we can't call endStep() yet
495  // (which normally increments time)
496  Real current_time = ex->getTime() + ex->getDT();
497 
498  if (ex->lastSolveConverged())
499  {
500  if (current_time + app_time_offset +
501  (ex->timestepTol() * std::abs(current_time)) >=
502  target_time)
503  {
504  caught_up = true;
505  break; // break here so that we don't run endStep() or postStep() since this
506  // MultiApp should NOT be auto_advanced
507  }
508  }
509  else
510  catch_up_dt /= 2.0;
511 
512  ex->endStep();
513  ex->postStep();
514 
515  catch_up_step++;
516  }
517 
518  if (!caught_up)
519  throw MultiAppSolveFailure(name() + " Failed to catch up!\n");
520  }
521  else
522  throw MultiAppSolveFailure(name() + " failed to converge");
523  }
524  }
525  }
526 
527  // Re-enable all output (it may of been disabled by sub-cycling)
528  problem.allowOutput(true);
529  }
530 
531  _first = false;
532 
534  _console << "Successfully Solved MultiApp " << name() << "." << std::endl;
535  }
536  catch (MultiAppSolveFailure & e)
537  {
538  mooseWarning(e.what());
539  _console << "Failed to Solve MultiApp " << name() << ", attempting to recover." << std::endl;
540  return_value = false;
541  }
542 
543  _transferred_vars.clear();
544 
545  return return_value;
546 }
547 
548 void
550 {
551  if (!_sub_cycling)
552  {
553  for (unsigned int i = 0; i < _my_num_apps; i++)
554  {
556 
557  // The App might have a different local time from the rest of the problem
558  Real app_time_offset = _apps[i]->getGlobalTimeOffset();
559 
560  // Only increment the step if we are after (target_time) the
561  // start_time (added to app_time_offset) of this sub_app.
562  if (_apps[i]->getStartTime() + app_time_offset < target_time)
563  ex->incrementStepOrReject();
564  }
565  }
566 }
567 
568 void
569 TransientMultiApp::finishStep(bool recurse_through_multiapp_levels)
570 {
571  if (!_sub_cycling)
572  {
573  for (unsigned int i = 0; i < _my_num_apps; i++)
574  {
576  ex->endStep();
577  ex->postStep();
578  if (recurse_through_multiapp_levels)
579  {
581  /*recurse_through_multiapp_levels=*/true);
583  /*recurse_through_multiapp_levels=*/true);
584  }
585  }
586  }
587 }
588 
589 Real
591 {
592  if (_sub_cycling) // Bow out of the timestep selection dance
594 
595  Real smallest_dt = std::numeric_limits<Real>::max();
596 
597  if (_has_an_app)
598  {
600 
601  for (unsigned int i = 0; i < _my_num_apps; i++)
602  {
604  ex->computeDT();
605  Real dt = ex->getDT();
606 
607  smallest_dt = std::min(dt, smallest_dt);
608  }
609  }
610 
611  if (_tolerate_failure) // Bow out of the timestep selection dance, we do this down here because we
612  // need to call computeConstrainedDT at least once for these
613  // executioners...
615 
616  _communicator.min(smallest_dt);
617  return smallest_dt;
618 }
619 
620 void
622  unsigned int global_app,
623  Real /*time*/) // FIXME: Note that we are passing in time but also grabbing it below
624 {
625  if (hasLocalApp(global_app))
626  {
627  unsigned int local_app = globalAppToLocal(global_app);
628 
629  // Grab the current time the App is at so we can start the new one at the same place
630  Real time =
631  _transient_executioners[local_app]->getTime() + _apps[local_app]->getGlobalTimeOffset();
632 
633  // Reset the Multiapp
634  MultiApp::resetApp(global_app, time);
635 
637 
638  // Setup the app, disable the output so that the initial condition does not output
639  // When an app is reset the initial condition was effectively already output before reset
640  FEProblemBase & problem = appProblemBase(local_app);
641  problem.allowOutput(false);
642  setupApp(local_app, time);
643  problem.allowOutput(true);
644  }
645 }
646 
647 void
648 TransientMultiApp::setupApp(unsigned int i, Real /*time*/) // FIXME: Should we be passing time?
649 {
650  auto & app = _apps[i];
651  TransientBase * ex = dynamic_cast<TransientBase *>(app->getExecutioner());
652  if (!ex)
653  mooseError("MultiApp ", name(), " is not using a Transient Executioner!");
654 
655  // Get the FEProblemBase for the current MultiApp
657 
658  // Update the file numbers for the outputs from the parent application
659  app->getOutputWarehouse().setFileNumbers(_app.getOutputFileNumbers());
660 
661  // Add these vectors before we call init on the executioner because that will try to restore these
662  // vectors in a restart context
664  {
665  AuxiliarySystem & aux_system = problem.getAuxiliarySystem();
666  System & libmesh_aux_system = aux_system.system();
667 
668  // We'll store a copy of the auxiliary system's solution at the old time in here
669  libmesh_aux_system.add_vector("transfer_old", false);
670 
671  // This will be where we'll transfer the value to for the "target" time
672  libmesh_aux_system.add_vector("transfer", false);
673  }
674 
675  // Call initialization method of Executioner (Note, this performs the output of the initial time
676  // step, if desired)
677  ex->init();
678 
679  ex->preExecute();
680  if (!_app.isRecovering())
681  {
682  problem.timeStep()++;
683  problem.advanceState();
684  }
685  _transient_executioners[i] = ex;
686 }
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:1070
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:50
libMesh::ConstElemRange * getActiveLocalElementRange()
Return pointers to range objects for various types of ranges (local nodes, boundary elems...
Definition: MooseMesh.C:1261
KOKKOS_INLINE_FUNCTION const T * find(const T &target, const T *const begin, const T *const end)
Find a value in an array.
Definition: KokkosUtils.h:40
bool _print_sub_cycles
Flag for toggling console output on sub cycles.
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 ...
Definition: MooseBase.h:467
bool verboseMultiApps() const
Whether or not to use verbose printing for MultiApps.
const ExecFlagType EXEC_FORCED
Definition: Moose.C:47
NumericVector< Number > & solution()
Definition: SystemBase.h:197
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:551
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:639
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:554
FEProblemBase & feProblem()
Return a reference to this Executioner&#39;s FEProblemBase instance.
Definition: Executioner.C:120
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:36
static InputParameters validParams()
FEProblemBase & _fe_problem
The FEProblemBase this MultiApp is part of.
Definition: MultiApp.h:495
bool isRestarting() const
Whether or not this is a "restart" calculation.
Definition: MooseApp.C:1499
bool convergedToSteadyState() const
Determines whether the problem has converged to steady state.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
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...
void mooseWarning(Args &&... args) const
const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:103
virtual void preStep()
bool _keep_solution_during_restore
Flag indicates if or not restart from the latest solution.
Definition: MultiApp.h:611
void min(const T &r, T &o, Request &req) const
const ExecFlagType EXEC_TIMESTEP_BEGIN
Definition: Moose.C:37
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:1016
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:385
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:1087
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:527
bool _has_an_app
Whether or not this processor as an App at all
Definition: MultiApp.h:602
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:530
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:437
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 and optionally a file path to the top-level block p...
Definition: MooseBase.h:281
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:51
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:1493
auto min(const L &left, const R &right)
Real getGlobalTimeOffset() const
Each App has it&#39;s own local time.
Definition: MooseApp.h:317
MPI_Comm & _my_comm
The MPI communicator this object is going to use.
Definition: MultiApp.h:539
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:1472
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...
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...
Definition: MooseBase.h:481
std::vector< bool > _reset_happened
Whether or not apps have been reset at each time.
Definition: MultiApp.h:587
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...