https://mooseframework.inl.gov
FullSolveMultiApp.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 #include "FullSolveMultiApp.h"
12 #include "Executioner.h"
13 #include "TransientBase.h"
14 #include "FEProblemBase.h"
16 #include "Console.h"
17 
18 // libMesh
19 #include "libmesh/mesh_tools.h"
20 
22 
25 {
27  params.addClassDescription("Performs a complete simulation during each execution.");
28  params.addParam<bool>(
29  "keep_full_output_history",
30  false,
31  "Whether or not to keep the full output history when this multiapp has multiple entries");
32  params.addParam<bool>("ignore_solve_not_converge",
33  false,
34  "True to continue main app even if a sub app's solve does not converge.");
35  params.addParam<bool>("update_old_solution_when_keeping_solution_during_restore",
36  true,
37  "Whether to update the old solution vector (to the previous fixed point "
38  "iteration solution) when keeping the solution during restore.");
39  return params;
40 }
41 
43  : MultiApp(parameters),
44  _ignore_diverge(getParam<bool>("ignore_solve_not_converge")),
45  _update_old_state_when_keeping_solution_during_restore(
46  getParam<bool>("update_old_solution_when_keeping_solution_during_restore"))
47 {
48  // You could end up with some dirty hidden behavior if you do this. We could remove this check,
49  // but I don't think that it's sane to do so.
51  paramError("no_restore",
52  "The parent app is restarting or recovering, restoration cannot be disabled");
53  // Force the user to make a decision on updating or not the old state of variables
55  !isParamSetByUser("update_old_solution_when_keeping_solution_during_restore"))
56  paramError("update_old_solution_when_keeping_solution_during_restore",
57  "Due to 'keep_solution_during_restore' parameter being true, which is an "
58  "optimization for fixed point iterations, the "
59  "unrestored solution will be kept as the starting solution for the next solve "
60  "of the MultiApp. You must set this parameter to decide if this solution should "
61  "be copied as the old solution at the beginning of the next time step, "
62  "or not. If the MultiApp is running a transient, you likely want to set this to "
63  "true. If the MultiApp is a quasi-static simulation, you likely want to set "
64  "this to false. If you don't know what this error message means, please set "
65  "'keep_solution_during_restore' to false and no need to set "
66  "'update_old_solution_when_keeping_solution_during_restore'.");
67  if (isParamSetByUser("update_old_solution_when_keeping_solution_during_restore") &&
69  paramError("update_old_solution_when_keeping_solution_during_restore",
70  "Should not be set if not keeping the solution during restore "
71  "(keep_solution_during_restore=false)");
72 }
73 
74 void
76 {
77  if (!_no_restore)
78  MultiApp::restore(force);
79 }
80 
81 void
83 {
85 
86  if (_has_an_app)
87  {
89 
91 
92  // Grab Executioner from each app
93  for (unsigned int i = 0; i < _my_num_apps; i++)
94  {
95  auto & app = _apps[i];
96  Executioner * ex = app->getExecutioner();
97 
98  if (!ex)
99  mooseError("Executioner does not exist!");
100 
101  if (_ignore_diverge)
102  {
103  TransientBase * tex = dynamic_cast<TransientBase *>(ex);
104  if (tex && tex->parameters().get<bool>("error_on_dtmin"))
105  mooseError("Requesting to ignore failed solutions, but 'Executioner/error_on_dtmin' is "
106  "true in sub-application. Set this parameter to false in sub-application to "
107  "avoid an error if Transient solve fails.");
108  }
109 
110  ex->init();
111 
113  (appProblemBase(_first_local_app + i).getMaterialPropertyStorage().hasStatefulProperties()
114 #ifdef KOKKOS_ENABLED
116  .getKokkosMaterialPropertyStorage()
117  .hasStatefulProperties()
118 #endif
119  ))
120  paramError(
121  "update_old_solution_when_keeping_solution_during_restore",
122  "While we are updating old solutions using the solution from the previous fixed "
123  "point iteration, we are not updating the old stateful material properties as "
124  "well. This is not consistent. We recommend you consider using the 'no_restore' "
125  "parameter instead of 'keep_solution_during_restore', or stop using the latter.");
128  .hasSolutionState(2, Moose::SolutionIterationType::Time))
129  mooseDoOnce(paramWarning(
130  "keep_solution_during_restore",
131  "This FullSolveMultiApp simulation(s) uses older time step variable states (notably "
132  "from two time steps prior in transients). Due to 'keep_solution_during_restore' "
133  "parameter being true, which is an optimization for fixed point iterations, the "
134  "unrestored solution will be kept as the starting solution. It would normally be "
135  "copied onto the 'old' state at the beginning of the first time step. This copy can be "
136  "skipped using 'update_old_solution_when_keeping_solution_during_restore', while the "
137  "copy of the old state onto the 'older' state and the stateful material properties "
138  "state updates do not have such an option at this time. This warning relates to this "
139  "inconsistency. If you suspect this is a problem, please set "
140  "'keep_solution_during_restore' to false"));
141 
142  _executioners[i] = ex;
143  }
144  }
145 }
146 
147 bool
148 FullSolveMultiApp::solveStep(Real /*dt*/, Real /*target_time*/, bool auto_advance)
149 {
150  if (!auto_advance)
151  mooseError("FullSolveMultiApp is not compatible with auto_advance=false");
152 
153  if (!_has_an_app)
154  return true;
155 
156  TIME_SECTION(_solve_step_timer);
157 
159 
160  int rank;
161  int ierr;
162  ierr = MPI_Comm_rank(_communicator.get(), &rank);
163  mooseCheckMPIErr(ierr);
164 
165  bool last_solve_converged = true;
166  for (unsigned int i = 0; i < _my_num_apps; i++)
167  {
168  // reset output system if desired
169  if (!getParam<bool>("keep_full_output_history"))
170  _apps[i]->getOutputWarehouse().reset();
171  // Prevent the copy of the post-FP iteration solution state onto the old vector
174 
175  Executioner * ex = _executioners[i];
176  ex->execute();
177 
178  last_solve_converged = last_solve_converged && ex->lastSolveConverged();
179 
181  }
182 
183  return last_solve_converged || _ignore_diverge;
184 }
185 
186 void
188 {
189  if (!_fe_problem.verboseMultiApps() &&
190  _apps[i]->getOutputWarehouse().getOutputs<Console>().size() > 0)
191  return;
192  else if (!_executioners[i]->lastSolveConverged())
193  _console << COLOR_RED << "Subapp " << _apps[i]->name() << " solve Did NOT Converge!"
194  << COLOR_DEFAULT << std::endl;
195  else
196  _console << COLOR_GREEN << "Subapp " << _apps[i]->name() << " solve converged!" << COLOR_DEFAULT
197  << std::endl;
198 }
virtual void initialSetup() override
Method to be called in main-app initial setup for create sub-apps if using positions is false...
virtual void restore(bool force=true)
Restore the state of every Sub App.
Definition: MultiApp.C:774
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.
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
virtual void init()
Initialize the executioner.
Definition: Executioner.h:62
An output object for writing to the console (screen)
Definition: Console.h:18
const PerfID _solve_step_timer
Timers.
Definition: MultiApp.h:639
const InputParameters & parameters() const
Get the parameters of the object.
Definition: MooseBase.h:131
std::vector< std::shared_ptr< MooseApp > > _apps
Pointers to each of the Apps.
Definition: MultiApp.h:554
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const Parallel::Communicator & _communicator
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
void skipNextForwardSolutionCopyToOld()
Prevents the copy of the solution vector to the old solution vector in each system.
const bool _ignore_diverge
Switch to tell executioner to keep going despite app solve not converging.
virtual void execute()=0
Pure virtual execute function MUST be overridden by children classes.
const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:103
FullSolveMultiApp(const InputParameters &parameters)
bool _keep_solution_during_restore
Flag indicates if or not restart from the latest solution.
Definition: MultiApp.h:611
std::vector< Executioner * > _executioners
FEProblemBase & appProblemBase(unsigned int app)
Get the FEProblemBase for the global app desired.
Definition: MultiApp.C:1016
Executioners are objects that do the actual work of solving your problem.
Definition: Executioner.h:30
Base class for transient executioners that use a FixedPointSolve solve object for multiapp-main app i...
Definition: TransientBase.h:27
MooseApp & _app
The MOOSE application this is associated with.
Definition: MooseBase.h:385
static InputParameters validParams()
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
registerMooseObject("MooseApp", FullSolveMultiApp)
unsigned int _first_local_app
The number of the first app on this processor.
Definition: MultiApp.h:530
const bool _no_restore
Whether or not to skip restoring completely.
Definition: MultiApp.h:617
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
virtual void restore(bool force=true) override
Restore the state of every Sub App.
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
virtual void showStatusMessage(unsigned int i) const
This function is called after each sub-application solve and is meant to display information about th...
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...
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
void paramWarning(const std::string &param, Args... args) const
virtual bool lastSolveConverged() const =0
Whether or not the last solve converged.
static InputParameters validParams()
Definition: MultiApp.C:51
A MultiApp represents one or more MOOSE applications that are running simultaneously.
Definition: MultiApp.h:112
virtual bool solveStep(Real dt, Real target_time, bool auto_advance=true) override
Re-solve all of the Apps.
bool isRecovering() const
Whether or not this is a "recover" calculation.
Definition: MooseApp.C:1493
const bool _update_old_state_when_keeping_solution_during_restore
Switch to tell the systems or not to update the old solution using the unrestored solution (the one w...
bool isParamSetByUser(const std::string &name) const
Test if the supplied parameter is set by a user, as opposed to not set or set to default.
Definition: MooseBase.h:215
MPI_Comm & _my_comm
The MPI communicator this object is going to use.
Definition: MultiApp.h:539
This type of MultiApp will do a full solve when it is asked to take a step.