Line data Source code
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 "FixedPointSolve.h"
11 :
12 : #include "FEProblem.h"
13 : #include "Executioner.h"
14 : #include "MooseMesh.h"
15 : #include "NonlinearSystem.h"
16 : #include "AllLocalDofIndicesThread.h"
17 : #include "Console.h"
18 : #include "EigenExecutionerBase.h"
19 : #include "Convergence.h"
20 : #include "ConvergenceIterationTypes.h"
21 :
22 : InputParameters
23 486630 : FixedPointSolve::fixedPointDefaultConvergenceParams()
24 : {
25 486630 : InputParameters params = emptyInputParameters();
26 :
27 1459890 : params.addParam<unsigned int>(
28 973260 : "fixed_point_min_its", 1, "Specifies the minimum number of fixed point iterations.");
29 1459890 : params.addParam<unsigned int>(
30 973260 : "fixed_point_max_its", 1, "Specifies the maximum number of fixed point iterations.");
31 1459890 : params.addParam<bool>("disable_fixed_point_residual_norm_check",
32 973260 : false,
33 : "Disable the residual norm evaluation thus the three parameters "
34 : "fixed_point_rel_tol, fixed_point_abs_tol and fixed_point_force_norms.");
35 1459890 : params.addParam<bool>(
36 : "fixed_point_force_norms",
37 973260 : false,
38 : "Force the evaluation of both the TIMESTEP_BEGIN and TIMESTEP_END norms regardless of the "
39 : "existence of active MultiApps with those execute_on flags, default: false.");
40 1459890 : params.addParam<bool>(
41 : "accept_on_max_fixed_point_iteration",
42 973260 : false,
43 : "True to treat reaching the maximum number of fixed point iterations as converged.");
44 1459890 : params.addRangeCheckedParam<Real>("fixed_point_rel_tol",
45 973260 : 1e-8,
46 : "fixed_point_rel_tol>0",
47 : "The relative nonlinear residual drop to shoot for "
48 : "during fixed point iterations. This check is "
49 : "performed based on the main app's nonlinear "
50 : "residual.");
51 1459890 : params.addRangeCheckedParam<Real>("fixed_point_abs_tol",
52 973260 : 1e-50,
53 : "fixed_point_abs_tol>0",
54 : "The absolute nonlinear residual to shoot for "
55 : "during fixed point iterations. This check is "
56 : "performed based on the main app's nonlinear "
57 : "residual.");
58 :
59 486630 : params.addParam<PostprocessorName>("custom_pp",
60 : "Postprocessor for custom fixed point convergence check.");
61 1459890 : params.addParam<bool>("direct_pp_value",
62 973260 : false,
63 : "True to use direct postprocessor value "
64 : "(scaled by value on first iteration). "
65 : "False (default) to use difference in postprocessor "
66 : "value between fixed point iterations.");
67 1459890 : params.addRangeCheckedParam<Real>("custom_rel_tol",
68 973260 : 1e-8,
69 : "custom_rel_tol>0",
70 : "The relative nonlinear residual drop to shoot for "
71 : "during fixed point iterations. This check is "
72 : "performed based on the postprocessor defined by "
73 : "custom_pp residual.");
74 1459890 : params.addRangeCheckedParam<Real>("custom_abs_tol",
75 973260 : 1e-50,
76 : "custom_abs_tol>0",
77 : "The absolute nonlinear residual to shoot for "
78 : "during fixed point iterations. This check is "
79 : "performed based on postprocessor defined by "
80 : "the custom_pp residual.");
81 :
82 486630 : params.addParamNamesToGroup(
83 : "fixed_point_min_its fixed_point_max_its disable_fixed_point_residual_norm_check "
84 : "accept_on_max_fixed_point_iteration fixed_point_rel_tol fixed_point_abs_tol "
85 : "fixed_point_force_norms custom_pp direct_pp_value custom_abs_tol custom_rel_tol",
86 : "Fixed point iterations");
87 :
88 486630 : return params;
89 0 : }
90 :
91 : InputParameters
92 342271 : FixedPointSolve::validParams()
93 : {
94 342271 : InputParameters params = emptyInputParameters();
95 342271 : params += FixedPointSolve::fixedPointDefaultConvergenceParams();
96 :
97 342271 : params.addParam<ConvergenceName>(
98 : "multiapp_fixed_point_convergence",
99 : "Name of the Convergence object to use to assess convergence of the "
100 : "MultiApp fixed point solve. If not provided, a default Convergence "
101 : "will be constructed internally from the executioner parameters.");
102 :
103 : // Parameters for relaxing the fixed point process
104 1026813 : params.addRangeCheckedParam<Real>("relaxation_factor",
105 684542 : 1.0,
106 : "relaxation_factor>0 & relaxation_factor<2",
107 : "Fraction of newly computed value to keep."
108 : "Set between 0 and 2.");
109 1026813 : params.addParam<std::vector<std::string>>(
110 : "transformed_variables",
111 684542 : std::vector<std::string>(),
112 : "List of main app variables to transform during fixed point iterations");
113 1026813 : params.addParam<std::vector<PostprocessorName>>(
114 : "transformed_postprocessors",
115 684542 : std::vector<PostprocessorName>(),
116 : "List of main app postprocessors to transform during fixed point iterations");
117 1026813 : params.addDeprecatedParam<std::vector<std::string>>(
118 : "relaxed_variables",
119 684542 : std::vector<std::string>(),
120 : "List of main app variables to relax during fixed point iterations",
121 : "Relaxed variables is deprecated, use transformed_variables instead.");
122 :
123 342271 : params.addParam<bool>("auto_advance",
124 : "Whether to automatically advance sub-applications regardless of whether "
125 : "their solve converges, for transient executioners only.");
126 :
127 342271 : params.addParamNamesToGroup(
128 : "multiapp_fixed_point_convergence "
129 : "relaxation_factor transformed_variables transformed_postprocessors auto_advance",
130 : "Fixed point iterations");
131 :
132 1026813 : params.addParam<unsigned int>(
133 : "max_xfem_update",
134 684542 : std::numeric_limits<unsigned int>::max(),
135 : "Maximum number of times to update XFEM crack topology in a step due to evolving cracks");
136 1026813 : params.addParam<bool>("update_xfem_at_timestep_begin",
137 684542 : false,
138 : "Should XFEM update the mesh at the beginning of the timestep");
139 :
140 342271 : params.addParamNamesToGroup("max_xfem_update update_xfem_at_timestep_begin",
141 : "XFEM fixed point iterations");
142 :
143 342271 : return params;
144 0 : }
145 :
146 62153 : FixedPointSolve::FixedPointSolve(Executioner & ex)
147 : : SolveObject(ex),
148 184894 : _has_fixed_point_its(getParam<unsigned int>("fixed_point_max_its") > 1 ||
149 122741 : isParamSetByUser("multiapp_fixed_point_convergence")),
150 62153 : _relax_factor(getParam<Real>("relaxation_factor")),
151 62153 : _transformed_vars(getParam<std::vector<std::string>>("transformed_variables")),
152 62153 : _transformed_pps(getParam<std::vector<PostprocessorName>>("transformed_postprocessors")),
153 : // this value will be set by MultiApp
154 62153 : _secondary_relaxation_factor(1.0),
155 62153 : _fixed_point_it(0),
156 62153 : _fixed_point_status(MooseFixedPointConvergenceReason::UNSOLVED),
157 62153 : _max_xfem_update(getParam<unsigned int>("max_xfem_update")),
158 62153 : _update_xfem_at_timestep_begin(getParam<bool>("update_xfem_at_timestep_begin")),
159 62153 : _xfem_update_count(0),
160 62153 : _xfem_repeat_step(false),
161 62153 : _old_entering_time(_problem.time() - 1),
162 62153 : _fail_step(false),
163 62153 : _auto_advance_set_by_user(isParamValid("auto_advance")),
164 186459 : _auto_advance_user_value(_auto_advance_set_by_user ? getParam<bool>("auto_advance") : true)
165 : {
166 : // Handle deprecated parameters
167 62153 : if (!parameters().isParamSetByAddParam("relaxed_variables"))
168 0 : _transformed_vars = getParam<std::vector<std::string>>("relaxed_variables");
169 :
170 62153 : if (_transformed_vars.size() > 0 && _transformed_pps.size() > 0)
171 0 : mooseWarning(
172 : "Both variable and postprocessor transformation are active. If the two share dofs, the "
173 : "transformation will not be correct.");
174 :
175 62153 : if (!_app.isUltimateMaster())
176 : {
177 12356 : _secondary_relaxation_factor = _app.fixedPointConfig().sub_relaxation_factor;
178 12356 : _secondary_transformed_variables = _app.fixedPointConfig().sub_transformed_vars;
179 12356 : _secondary_transformed_pps = _app.fixedPointConfig().sub_transformed_pps;
180 : }
181 :
182 62153 : if (isParamValid("multiapp_fixed_point_convergence"))
183 77 : _problem.setMultiAppFixedPointConvergenceName(
184 : getParam<ConvergenceName>("multiapp_fixed_point_convergence"));
185 : else
186 62076 : _problem.setNeedToAddDefaultMultiAppFixedPointConvergence();
187 62153 : }
188 :
189 : void
190 58467 : FixedPointSolve::initialSetup()
191 : {
192 58467 : SolveObject::initialSetup();
193 :
194 58467 : if (_has_fixed_point_its)
195 : {
196 1600 : auto & conv = _problem.getConvergence(_problem.getMultiAppFixedPointConvergenceName());
197 1600 : conv.checkIterationType(ConvergenceIterationTypes::MULTIAPP_FIXED_POINT);
198 : }
199 58463 : }
200 :
201 : bool
202 282622 : FixedPointSolve::solve()
203 : {
204 282622 : TIME_SECTION("PicardSolve", 1);
205 :
206 282622 : Real current_dt = _problem.dt();
207 :
208 282622 : bool converged = true;
209 :
210 : // need to back up multi-apps even when not doing fixed point iteration for recovering from failed
211 : // multiapp solve
212 282622 : _problem.backupMultiApps(EXEC_MULTIAPP_FIXED_POINT_BEGIN);
213 282622 : _problem.backupMultiApps(EXEC_TIMESTEP_BEGIN);
214 282622 : _problem.backupMultiApps(EXEC_TIMESTEP_END);
215 282622 : _problem.backupMultiApps(EXEC_MULTIAPP_FIXED_POINT_END);
216 :
217 : // Prepare to relax variables as a main app
218 282622 : std::set<dof_id_type> transformed_dofs;
219 282622 : if ((_relax_factor != 1.0 || !dynamic_cast<PicardSolve *>(this)) && _transformed_vars.size() > 0)
220 : {
221 : // Snag all of the local dof indices for all of these variables
222 1818 : AllLocalDofIndicesThread aldit(_problem, _transformed_vars);
223 1818 : libMesh::ConstElemRange & elem_range = *_problem.mesh().getActiveLocalElementRange();
224 1818 : Threads::parallel_reduce(elem_range, aldit);
225 :
226 1818 : transformed_dofs = aldit.getDofIndices();
227 1818 : }
228 :
229 : // Prepare to relax variables as a subapp
230 282622 : std::set<dof_id_type> secondary_transformed_dofs;
231 282622 : if (_secondary_relaxation_factor != 1.0 || !dynamic_cast<PicardSolve *>(this))
232 : {
233 36550 : if (_secondary_transformed_variables.size() > 0)
234 : {
235 : // Snag all of the local dof indices for all of these variables
236 6081 : AllLocalDofIndicesThread aldit(_problem, _secondary_transformed_variables);
237 6081 : libMesh::ConstElemRange & elem_range = *_problem.mesh().getActiveLocalElementRange();
238 6081 : Threads::parallel_reduce(elem_range, aldit);
239 :
240 6081 : secondary_transformed_dofs = aldit.getDofIndices();
241 6081 : }
242 :
243 : // To detect a new time step
244 59460 : if (_old_entering_time == _problem.time() &&
245 22910 : _fixed_point_status != MooseFixedPointConvergenceReason::UNSOLVED)
246 : {
247 : // Keep track of the iteration number of the main app
248 22866 : _main_fixed_point_it++;
249 :
250 : // Save variable values before the solve. Solving will provide new values
251 22866 : if (!_app.isUltimateMaster())
252 22823 : saveVariableValues(/*is parent app of this iteration=*/false);
253 : }
254 : else
255 13684 : _main_fixed_point_it = 0;
256 : }
257 :
258 282622 : if (_has_fixed_point_its)
259 : {
260 12225 : auto & convergence = _problem.getConvergence(_problem.getMultiAppFixedPointConvergenceName());
261 12225 : convergence.initialize();
262 : }
263 :
264 282622 : _fixed_point_it = 0;
265 : while (true)
266 : {
267 331422 : if (_has_fixed_point_its)
268 : {
269 61025 : if (_fixed_point_it != 0)
270 : {
271 : // For every iteration other than the first, we need to restore the state of the MultiApps
272 48800 : _problem.restoreMultiApps(EXEC_TIMESTEP_BEGIN);
273 48800 : _problem.restoreMultiApps(EXEC_TIMESTEP_END);
274 : }
275 :
276 61021 : _console << COLOR_MAGENTA << "Beginning fixed point iteration " << _fixed_point_it
277 61021 : << COLOR_DEFAULT << std::endl
278 61021 : << std::endl;
279 : }
280 :
281 : // Solve a single application for one time step
282 331418 : const bool solve_converged = solveStep(transformed_dofs);
283 :
284 331077 : if (solve_converged)
285 : {
286 326942 : if (_has_fixed_point_its)
287 : {
288 61000 : _problem.outputStep(EXEC_MULTIAPP_FIXED_POINT_ITERATION_END);
289 :
290 : // Examine convergence metrics & properties and set the convergence reason
291 61000 : bool break_out = examineFixedPointConvergence(converged);
292 :
293 61000 : if (break_out)
294 : {
295 : // Except DefaultMultiAppFixedPointConvergence, convergence objects will not
296 : // update _fixed_point_status, so we give those cases generic values:
297 12200 : if (_fixed_point_status == MooseFixedPointConvergenceReason::CONVERGED_NONLINEAR)
298 : {
299 36 : if (converged)
300 36 : _fixed_point_status = MooseFixedPointConvergenceReason::CONVERGED_OBJECT;
301 : else
302 0 : _fixed_point_status = MooseFixedPointConvergenceReason::DIVERGED_OBJECT;
303 : }
304 :
305 12200 : break;
306 : }
307 : }
308 : }
309 : else
310 : {
311 : // If the last solve didn't converge then we need to exit this step completely (even in the
312 : // case of coupling). So we can retry...
313 4135 : converged = false;
314 4135 : break;
315 : }
316 :
317 314742 : _problem.dt() =
318 : current_dt; // _dt might be smaller than this at this point for multistep methods
319 :
320 314742 : _fixed_point_it++;
321 :
322 314742 : if (!_has_fixed_point_its)
323 265942 : break;
324 48800 : }
325 :
326 282277 : if (converged)
327 : {
328 : // Fixed point iteration loop ends right above
329 277845 : _problem.execute(EXEC_MULTIAPP_FIXED_POINT_END);
330 277845 : _problem.execTransfers(EXEC_MULTIAPP_FIXED_POINT_END);
331 277845 : if (!_problem.execMultiApps(EXEC_MULTIAPP_FIXED_POINT_END, autoAdvance()))
332 : {
333 0 : _fixed_point_status = MooseFixedPointConvergenceReason::DIVERGED_FAILED_MULTIAPP;
334 0 : return false;
335 : }
336 277845 : _problem.outputStep(EXEC_MULTIAPP_FIXED_POINT_END);
337 : }
338 :
339 : // Save postprocessors after the solve and their potential timestep_end execution
340 : // The postprocessors could be overwritten at timestep_begin, which is why they are saved
341 : // after the solve. They could also be saved right after the transfers.
342 282277 : if (_old_entering_time == _problem.time())
343 47141 : savePostprocessorValues(false);
344 :
345 282277 : if (converged)
346 : {
347 : // Update the subapp using the fixed point algorithm
348 277845 : if (_secondary_transformed_variables.size() > 0 &&
349 277845 : useFixedPointAlgorithmUpdateInsteadOfPicard(false) && _old_entering_time == _problem.time())
350 3357 : transformVariables(secondary_transformed_dofs, false);
351 :
352 : // Update the entering time, used to detect failed solves
353 277845 : _old_entering_time = _problem.time();
354 : }
355 :
356 282277 : if (_has_fixed_point_its)
357 12221 : printFixedPointConvergenceReason();
358 :
359 282277 : return converged;
360 282277 : }
361 :
362 : void
363 331318 : FixedPointSolve::saveAllValues(const bool primary)
364 : {
365 331318 : saveVariableValues(primary);
366 331318 : savePostprocessorValues(primary);
367 331318 : }
368 :
369 : bool
370 331418 : FixedPointSolve::solveStep(const std::set<dof_id_type> & transformed_dofs)
371 : {
372 331418 : bool auto_advance = autoAdvance();
373 :
374 331418 : _executioner.preSolve();
375 331418 : _problem.execTransfers(EXEC_TIMESTEP_BEGIN);
376 :
377 331418 : if (_fixed_point_it == 0)
378 : {
379 282622 : _problem.execute(EXEC_MULTIAPP_FIXED_POINT_BEGIN);
380 282622 : _problem.execTransfers(EXEC_MULTIAPP_FIXED_POINT_BEGIN);
381 282622 : if (!_problem.execMultiApps(EXEC_MULTIAPP_FIXED_POINT_BEGIN, autoAdvance()))
382 : {
383 0 : _fixed_point_status = MooseFixedPointConvergenceReason::DIVERGED_FAILED_MULTIAPP;
384 0 : return false;
385 : }
386 282622 : _problem.outputStep(EXEC_MULTIAPP_FIXED_POINT_BEGIN);
387 : }
388 :
389 331418 : if (!_problem.execMultiApps(EXEC_TIMESTEP_BEGIN, auto_advance))
390 : {
391 21 : _fixed_point_status = MooseFixedPointConvergenceReason::DIVERGED_FAILED_MULTIAPP;
392 21 : return false;
393 : }
394 :
395 331326 : if (_problem.haveXFEM() && _update_xfem_at_timestep_begin)
396 0 : _problem.updateMeshXFEM();
397 :
398 331326 : _problem.execute(EXEC_TIMESTEP_BEGIN);
399 :
400 : // Transform the fixed point postprocessors before solving, but after the timestep_begin transfers
401 : // have been received
402 331322 : if (_transformed_pps.size() > 0 && useFixedPointAlgorithmUpdateInsteadOfPicard(true))
403 13781 : transformPostprocessors(true);
404 334959 : if (_secondary_transformed_pps.size() > 0 && useFixedPointAlgorithmUpdateInsteadOfPicard(false) &&
405 3637 : _problem.time() == _old_entering_time)
406 3637 : transformPostprocessors(false);
407 :
408 331322 : if (_has_fixed_point_its)
409 : {
410 61000 : auto & convergence = _problem.getConvergence(_problem.getMultiAppFixedPointConvergenceName());
411 61000 : convergence.preExecute();
412 : }
413 :
414 : // Perform output for timestep begin
415 331322 : _problem.outputStep(EXEC_TIMESTEP_BEGIN);
416 :
417 : // Update warehouse active objects
418 331318 : _problem.updateActiveObjects();
419 :
420 : // Save the current values of variables and postprocessors, before the solve
421 331318 : saveAllValues(true);
422 :
423 331318 : if (_has_fixed_point_its)
424 61000 : _console << COLOR_MAGENTA << "\nMain app solve:" << COLOR_DEFAULT << std::endl;
425 331318 : if (!_inner_solve->solve())
426 : {
427 3925 : _fixed_point_status = MooseFixedPointConvergenceReason::DIVERGED_NONLINEAR;
428 :
429 : // Perform the output of the current, failed time step (this only occurs if desired)
430 3925 : _problem.outputStep(EXEC_FAILED);
431 3925 : return false;
432 : }
433 : else
434 327312 : _fixed_point_status = MooseFixedPointConvergenceReason::CONVERGED_NONLINEAR;
435 :
436 : // Use the fixed point algorithm if the conditions (availability of values, etc) are met
437 327312 : if (_transformed_vars.size() > 0 && useFixedPointAlgorithmUpdateInsteadOfPicard(true))
438 6062 : transformVariables(transformed_dofs, true);
439 :
440 327312 : if (_problem.haveXFEM() && (_xfem_update_count < _max_xfem_update) && _problem.updateMeshXFEM())
441 : {
442 0 : _console << "\nXFEM modified mesh, repeating step" << std::endl;
443 0 : _xfem_repeat_step = true;
444 0 : ++_xfem_update_count;
445 : }
446 : else
447 : {
448 327312 : if (_problem.haveXFEM())
449 : {
450 0 : _xfem_repeat_step = false;
451 0 : _xfem_update_count = 0;
452 0 : _console << "\nXFEM did not modify mesh, continuing" << std::endl;
453 : }
454 :
455 327312 : _problem.onTimestepEnd();
456 327312 : _problem.execute(EXEC_TIMESTEP_END);
457 :
458 327191 : _problem.execTransfers(EXEC_TIMESTEP_END);
459 327191 : if (!_problem.execMultiApps(EXEC_TIMESTEP_END, auto_advance))
460 : {
461 84 : _fixed_point_status = MooseFixedPointConvergenceReason::DIVERGED_FAILED_MULTIAPP;
462 84 : return false;
463 : }
464 : }
465 :
466 327047 : if (_fail_step)
467 : {
468 105 : _fail_step = false;
469 105 : return false;
470 : }
471 :
472 326942 : _executioner.postSolve();
473 :
474 326942 : return true;
475 : }
476 :
477 : bool
478 61000 : FixedPointSolve::examineFixedPointConvergence(bool & converged)
479 : {
480 61000 : _problem.execute(EXEC_MULTIAPP_FIXED_POINT_CONVERGENCE);
481 :
482 61000 : auto & convergence = _problem.getConvergence(_problem.getMultiAppFixedPointConvergenceName());
483 61000 : const auto status = convergence.checkConvergence(_fixed_point_it);
484 61000 : switch (status)
485 : {
486 11903 : case Convergence::MooseConvergenceStatus::CONVERGED:
487 11903 : converged = true;
488 11903 : return true;
489 297 : case Convergence::MooseConvergenceStatus::DIVERGED:
490 297 : converged = false;
491 297 : return true;
492 48800 : case Convergence::MooseConvergenceStatus::ITERATING:
493 48800 : converged = false;
494 48800 : return false;
495 0 : default:
496 0 : mooseError("Should not reach here");
497 : }
498 : }
499 :
500 : void
501 12221 : FixedPointSolve::printFixedPointConvergenceReason()
502 : {
503 12221 : _console << "Fixed point convergence reason: ";
504 12221 : switch (_fixed_point_status)
505 : {
506 3703 : case MooseFixedPointConvergenceReason::CONVERGED_ABS:
507 3703 : _console << "CONVERGED_ABS";
508 3703 : break;
509 8039 : case MooseFixedPointConvergenceReason::CONVERGED_RELATIVE:
510 8039 : _console << "CONVERGED_RELATIVE";
511 8039 : break;
512 44 : case MooseFixedPointConvergenceReason::CONVERGED_PP:
513 44 : _console << "CONVERGED_PP";
514 44 : break;
515 81 : case MooseFixedPointConvergenceReason::REACH_MAX_ITS:
516 81 : _console << "REACH_MAX_ITS";
517 81 : break;
518 36 : case MooseFixedPointConvergenceReason::CONVERGED_OBJECT:
519 36 : _console << "CONVERGED_OBJECT (see Convergence object)";
520 36 : break;
521 297 : case MooseFixedPointConvergenceReason::DIVERGED_MAX_ITS:
522 297 : _console << "DIVERGED_MAX_ITS";
523 297 : break;
524 0 : case MooseFixedPointConvergenceReason::DIVERGED_NONLINEAR:
525 0 : _console << "DIVERGED_NONLINEAR";
526 0 : break;
527 21 : case MooseFixedPointConvergenceReason::DIVERGED_FAILED_MULTIAPP:
528 21 : _console << "DIVERGED_FAILED_MULTIAPP";
529 21 : break;
530 0 : case MooseFixedPointConvergenceReason::DIVERGED_OBJECT:
531 0 : _console << "DIVERGED_OBJECT (see Convergence object)";
532 0 : break;
533 0 : default:
534 : // UNSOLVED and CONVERGED_NONLINEAR should not be hit when coupling
535 : // iteration is not on here
536 0 : mooseError("Internal error: wrong fixed point status!");
537 : break;
538 : }
539 12221 : _console << std::endl;
540 12221 : }
541 :
542 : bool
543 1089823 : FixedPointSolve::autoAdvance() const
544 : {
545 1089823 : bool auto_advance = !(_has_fixed_point_its && _problem.isTransient());
546 :
547 1089823 : if (dynamic_cast<EigenExecutionerBase *>(&_executioner) && _has_fixed_point_its)
548 0 : auto_advance = true;
549 :
550 1089823 : if (_auto_advance_set_by_user)
551 194 : auto_advance = _auto_advance_user_value;
552 :
553 1089823 : return auto_advance;
554 : }
|