https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
141NumericVector<Number> &
142TransientMultiApp::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
154void
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
173bool
174TransientMultiApp::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 const 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)
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 {
339 "While sub_cycling ", name(), _first_local_app + i, " failed to converge!\n");
340
341 _failures++;
342
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;
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;
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
548void
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)
564 }
565 }
566}
567
568void
569TransientMultiApp::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
589Real
591{
592 if (_sub_cycling) // Bow out of the timestep selection dance
593 return std::numeric_limits<Real>::max();
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...
614 return std::numeric_limits<Real>::max();
615
616 _communicator.min(smallest_dt);
617 return smallest_dt;
618}
619
620void
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
647void
648TransientMultiApp::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 if (app->hasInitialBackupMesh())
676 {
677 app->restoreMeshFromInitialBackup(problem.mesh());
678 problem.mesh().prepare(/*mesh_to_clone=*/nullptr);
679 problem.meshChanged(/*intermediate_change=*/false,
680 /*contract_mesh=*/false,
681 /*clean_refinement_flags=*/false);
682 }
683
684 // Call initialization method of Executioner (Note, this performs the output of the initial time
685 // step, if desired)
686 ex->init();
687
688 ex->preExecute();
689 if (!_app.isRecovering())
690 {
691 problem.timeStep()++;
692 problem.advanceState();
693 }
695}
const ExecFlagType EXEC_FORCED
Definition Moose.C:49
const ExecFlagType EXEC_TIMESTEP_END
Definition Moose.C:36
const ExecFlagType EXEC_TIMESTEP_BEGIN
Definition Moose.C:37
registerMooseObject("MooseApp", TransientMultiApp)
void ErrorVector unsigned int
Grab all the (possibly semi)local dof indices for the variables passed in, in the system passed in.
const std::set< dof_id_type > & getDofIndices() const
A system that holds auxiliary variables.
virtual libMesh::System & system() override
Get the reference to the libMesh system.
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
An output object for writing to the console (screen)
Definition Console.h:19
FEProblemBase & feProblem()
Return a reference to this Executioner's FEProblemBase instance.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
bool verboseMultiApps() const
Whether or not to use verbose printing for MultiApps.
AuxiliarySystem & getAuxiliarySystem()
virtual void advanceState()
Advance all of the state holding vectors / datastructures so that we can move to the next timestep.
void forceOutput()
Indicates that the next call to outputStep should be forced.
virtual MooseMesh & mesh() override
void finishMultiAppStep(ExecFlagType type, bool recurse_through_multiapp_levels=false)
Finish the MultiApp time step (endStep, postStep) associated with the ExecFlagType.
void allowOutput(bool state)
Ability to enable/disable all output calls.
virtual int & timeStep() const
virtual void meshChanged(bool intermediate_change, bool contract_mesh, bool clean_refinement_flags)
Update data after a mesh change.
virtual void outputStep(ExecFlagType type)
Output the current step.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
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 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.
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.
bool isRestarting() const
Whether or not this is a "restart" calculation.
Definition MooseApp.C:1675
Real getGlobalTimeOffset() const
Each App has it's own local time.
Definition MooseApp.h:318
bool isRecovering() const
Whether or not this is a "recover" calculation.
Definition MooseApp.C:1669
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:552
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:471
const std::string & name() const
Get the name of the class.
Definition MooseBase.h:103
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:457
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:271
bool prepare(const MeshBase *mesh_to_clone)
Calls prepare_for_use() if the underlying MeshBase object isn't prepared, then communicates various b...
Definition MooseMesh.C:386
const libMesh::ConstElemRange * getActiveLocalElementRange()
Return pointers to range objects for various types of ranges (local nodes, boundary elems,...
Definition MooseMesh.C:1242
MooseApp & _app
The MOOSE application this is associated with.
Definition MooseBase.h:375
Utility class for catching solve failure errors so that MOOSE can recover state before continuing.
A MultiApp represents one or more MOOSE applications that are running simultaneously.
Definition MultiApp.h:116
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
FEProblemBase & appProblemBase(unsigned int app)
Get the FEProblemBase for the global app desired.
Definition MultiApp.C:1016
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
MPI_Comm & _my_comm
The MPI communicator this object is going to use.
Definition MultiApp.h:539
bool hasLocalApp(unsigned int global_app) const
Whether or not the given global app number is on this processor.
Definition MultiApp.C:1070
unsigned int _first_local_app
The number of the first app on this processor.
Definition MultiApp.h:530
bool _has_an_app
Whether or not this processor as an App at all
Definition MultiApp.h:602
const PerfID _solve_step_timer
Timers.
Definition MultiApp.h:639
bool _keep_solution_during_restore
Flag indicates if or not restart from the latest solution.
Definition MultiApp.h:611
static InputParameters validParams()
Definition MultiApp.C:51
FEProblemBase & _fe_problem
The FEProblemBase this MultiApp is part of.
Definition MultiApp.h:495
unsigned int globalAppToLocal(unsigned int global_app)
Map a global App number to the local number.
Definition MultiApp.C:1472
std::vector< std::shared_ptr< MooseApp > > _apps
Pointers to each of the Apps.
Definition MultiApp.h:554
std::vector< bool > _reset_happened
Whether or not apps have been reset at each time.
Definition MultiApp.h:587
unsigned int _my_num_apps
The number of apps this object is involved in simulating.
Definition MultiApp.h:527
void mooseWarning(Args &&... args) const
NumericVector< Number > & solution()
Definition SystemBase.h:203
void min(const T &r, T &o, Request &req) const
Base class for transient executioners that use a FixedPointSolve solve object for multiapp-main app i...
virtual void incrementStepOrReject()
This is where the solve step is actually incremented.
virtual void takeStep(Real input_dt=-1.0)
Do whatever is necessary to advance one step.
virtual void postStep()
virtual Real getTime() const
Get the current time.
virtual bool lastSolveConverged() const override
Whether or not the last solve converged.
virtual void endStep(Real input_time=-1.0)
bool convergedToSteadyState() const
Determines whether the problem has converged to steady state.
virtual void preExecute() override
Override this for actions that should take place before execution.
Real & timestepTol()
Get the timestep tolerance.
virtual Real getDT()
virtual void preStep()
Real & endTime()
Get a modifiable reference to the end time.
virtual void init() override
Initialize the executioner.
virtual void setTargetTime(Real target_time)
Can be used to set the next "target time" which is a time to nail perfectly.
static InputParameters validParams()
MultiApp Implementation for Transient Apps.
virtual NumericVector< Number > & appTransferVector(unsigned int app, std::string var_name) override
Get the vector to transfer to for this MultiApp.
TransientMultiApp(const InputParameters &parameters)
virtual void finishStep(bool recurse_through_multiapp_levels=false) override
Calls multi-apps executioners' endStep and postStep methods which creates output and advances time (n...
void setupApp(unsigned int i, Real time=0.0)
Setup the executioner for the local app.
virtual void initialSetup() override
Method to be called in main-app initial setup for create sub-apps if using positions is false.
virtual void incrementTStep(Real target_time) override
Advances the multi-apps time step which is important for dt selection.
bool _print_sub_cycles
Flag for toggling console output on sub cycles.
std::set< dof_id_type > _transferred_dofs
The DoFs associated with all of the currently transferred variables.
virtual void resetApp(unsigned int global_app, Real time) override
"Reset" the App corresponding to the global App number passed in.
Real computeDT()
Finds the smallest dt from among any of the apps.
virtual bool solveStep(Real dt, Real target_time, bool auto_advance=true) override
Re-solve all of the Apps.
unsigned int _max_failures
bool & _first
Is it our first time through the execution loop?
std::vector< std::string > _transferred_vars
The variables that have been transferred to. Used when doing transfer interpolation....
static InputParameters validParams()
std::vector< TransientBase * > _transient_executioners
virtual void add_vector(const T *v, const std::vector< numeric_index_type > &dof_indices)
const Parallel::Communicator & _communicator
NumericVector< Number > & add_vector(std::string_view vec_name, const bool projections=true, const ParallelType type=PARALLEL)
std::unique_ptr< NumericVector< Number > > solution
const NumericVector< Number > & get_vector(std::string_view vec_name) const
void parallel_reduce(const Range &range, Body &body, unsigned int n_threads=libMesh::n_threads())