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 "FEProblemSolve.h"
11 :
12 : #include "FEProblem.h"
13 : #include "NonlinearSystemBase.h"
14 : #include "LinearSystem.h"
15 : #include "Convergence.h"
16 : #include "Executioner.h"
17 : #include "ConvergenceIterationTypes.h"
18 :
19 : std::set<std::string> const FEProblemSolve::_moose_line_searches = {"contact", "project"};
20 :
21 : const std::set<std::string> &
22 307047 : FEProblemSolve::mooseLineSearches()
23 : {
24 307047 : return _moose_line_searches;
25 : }
26 :
27 : InputParameters
28 469395 : FEProblemSolve::feProblemDefaultConvergenceParams()
29 : {
30 469395 : InputParameters params = emptyInputParameters();
31 :
32 1877580 : params.addParam<unsigned int>("nl_max_its", 50, "Max Nonlinear Iterations");
33 1877580 : params.addParam<unsigned int>("nl_forced_its", 0, "The Number of Forced Nonlinear Iterations");
34 1877580 : params.addParam<unsigned int>("nl_max_funcs", 10000, "Max Nonlinear solver function evaluations");
35 1877580 : params.addParam<Real>("nl_abs_tol", 1.0e-50, "Nonlinear Absolute Tolerance");
36 1877580 : params.addParam<Real>("nl_rel_tol", 1.0e-8, "Nonlinear Relative Tolerance");
37 1408185 : params.addParam<Real>(
38 : "nl_div_tol",
39 938790 : 1.0e10,
40 : "Nonlinear Relative Divergence Tolerance. A negative value disables this check.");
41 1408185 : params.addParam<Real>(
42 : "nl_abs_div_tol",
43 938790 : 1.0e50,
44 : "Nonlinear Absolute Divergence Tolerance. A negative value disables this check.");
45 1877580 : params.addParam<Real>("nl_abs_step_tol", 0., "Nonlinear Absolute step Tolerance");
46 1877580 : params.addParam<Real>("nl_rel_step_tol", 0., "Nonlinear Relative step Tolerance");
47 1408185 : params.addParam<unsigned int>("n_max_nonlinear_pingpong",
48 938790 : 100,
49 : "The maximum number of times the nonlinear residual can ping pong "
50 : "before requesting halting the current evaluation and requesting "
51 : "timestep cut for transient simulations");
52 :
53 1408185 : params.addParamNamesToGroup(
54 : "nl_max_its nl_forced_its nl_max_funcs nl_abs_tol nl_rel_tol "
55 : "nl_rel_step_tol nl_abs_step_tol nl_div_tol nl_abs_div_tol n_max_nonlinear_pingpong",
56 : "Nonlinear Solver");
57 :
58 469395 : return params;
59 0 : }
60 :
61 : InputParameters
62 307047 : FEProblemSolve::validParams()
63 : {
64 307047 : InputParameters params = MultiSystemSolveObject::validParams();
65 307047 : params += FEProblemSolve::feProblemDefaultConvergenceParams();
66 :
67 307047 : std::set<std::string> line_searches = mooseLineSearches();
68 :
69 307047 : std::set<std::string> alias_line_searches = {"default", "none", "basic"};
70 307047 : line_searches.insert(alias_line_searches.begin(), alias_line_searches.end());
71 307047 : std::set<std::string> petsc_line_searches = Moose::PetscSupport::getPetscValidLineSearches();
72 307047 : line_searches.insert(petsc_line_searches.begin(), petsc_line_searches.end());
73 1228188 : std::string line_search_string = Moose::stringify(line_searches, " ");
74 614094 : MooseEnum line_search(line_search_string, "default");
75 307047 : std::string addtl_doc_str(" (Note: none = basic)");
76 307047 : params.addParam<MooseEnum>(
77 614094 : "line_search", line_search, "Specifies the line search type" + addtl_doc_str);
78 1228188 : MooseEnum line_search_package("petsc moose", "petsc");
79 1228188 : params.addParam<MooseEnum>("line_search_package",
80 : line_search_package,
81 : "The solver package to use to conduct the line-search");
82 :
83 921141 : params.addParam<unsigned>("contact_line_search_allowed_lambda_cuts",
84 614094 : 2,
85 : "The number of times lambda is allowed to be cut in half in the "
86 : "contact line search. We recommend this number be roughly bounded by 0 "
87 : "<= allowed_lambda_cuts <= 3");
88 921141 : params.addParam<Real>("contact_line_search_ltol",
89 : "The linear relative tolerance to be used while the contact state is "
90 : "changing between non-linear iterations. We recommend that this tolerance "
91 : "be looser than the standard linear tolerance");
92 :
93 307047 : params += Moose::PetscSupport::getPetscValidParams();
94 1228188 : params.addParam<Real>("l_tol", 1.0e-5, "Linear Relative Tolerance");
95 1228188 : params.addParam<Real>("l_abs_tol", 1.0e-50, "Linear Absolute Tolerance");
96 1228188 : params.addParam<unsigned int>("l_max_its", 10000, "Max Linear Iterations");
97 1228188 : params.addParam<std::vector<ConvergenceName>>(
98 : "nonlinear_convergence",
99 : "Name of the Convergence object(s) to use to assess convergence of the "
100 : "nonlinear system(s) solve. If not provided, the default Convergence "
101 : "associated with the Problem will be constructed internally.");
102 1228188 : params.addParam<std::vector<ConvergenceName>>(
103 : "linear_convergence",
104 : "Name of the Convergence object(s) to use to assess convergence of the "
105 : "linear system(s) solve. If not provided, the linear solver tolerance parameters are used");
106 921141 : params.addParam<bool>(
107 : "snesmf_reuse_base",
108 614094 : true,
109 : "Specifies whether or not to reuse the base vector for matrix-free calculation");
110 921141 : params.addParam<bool>(
111 614094 : "skip_exception_check", false, "Specifies whether or not to skip exception check");
112 921141 : params.addParam<bool>(
113 : "use_pre_SMO_residual",
114 614094 : false,
115 : "Compute the pre-SMO residual norm and use it in the relative convergence check. The "
116 : "pre-SMO residual is computed at the begining of the time step before solution-modifying "
117 : "objects are executed. Solution-modifying objects include preset BCs, constraints, "
118 : "predictors, etc.");
119 1228188 : params.addParam<bool>("automatic_scaling", "Whether to use automatic scaling for the variables.");
120 1228188 : params.addParam<std::vector<bool>>(
121 : "compute_scaling_once",
122 : {true},
123 : "Whether the scaling factors should only be computed once at the beginning of the simulation "
124 : "through an extra Jacobian evaluation. If this is set to false, then the scaling factors "
125 : "will be computed during an extra Jacobian evaluation at the beginning of every time step. "
126 : "Vector entries correspond to each nonlinear system.");
127 1228188 : params.addParam<std::vector<bool>>(
128 : "off_diagonals_in_auto_scaling",
129 : {false},
130 : "Whether to consider off-diagonals when determining automatic scaling factors. Vector "
131 : "entries correspond to each nonlinear system.");
132 2456376 : params.addRangeCheckedParam<std::vector<Real>>(
133 : "resid_vs_jac_scaling_param",
134 : {0},
135 : "0<=resid_vs_jac_scaling_param<=1",
136 : "A parameter that indicates the weighting of the residual vs the Jacobian in determining "
137 : "variable scaling parameters. A value of 1 indicates pure residual-based scaling. A value of "
138 : "0 indicates pure Jacobian-based scaling. Vector entries correspond to each nonlinear "
139 : "system.");
140 1228188 : params.addParam<std::vector<std::vector<std::vector<std::string>>>>(
141 : "scaling_group_variables",
142 : "Name of variables that are grouped together for determining scale factors. (Multiple "
143 : "groups can be provided, separated by semicolon). Vector entries correspond to each "
144 : "nonlinear system.");
145 1228188 : params.addParam<std::vector<std::vector<std::string>>>(
146 : "ignore_variables_for_autoscaling",
147 : "List of variables that do not participate in autoscaling. Vector entries correspond to each "
148 : "nonlinear system.");
149 1535235 : params.addRangeCheckedParam<unsigned int>(
150 : "num_grids",
151 614094 : 1,
152 : "num_grids>0",
153 : "The number of grids to use for a grid sequencing algorithm. This includes the final grid, "
154 : "so num_grids = 1 indicates just one solve in a time-step");
155 1228188 : params.addParam<std::vector<bool>>("residual_and_jacobian_together",
156 : {false},
157 : "Whether to compute the residual and Jacobian together. "
158 : "Vector entries correspond to each nonlinear system.");
159 :
160 921141 : params.addParam<bool>("reuse_preconditioner",
161 614094 : false,
162 : "If true reuse the previously calculated "
163 : "preconditioner for the linearized "
164 : "system across multiple solves "
165 : "spanning nonlinear iterations and time steps. "
166 : "The preconditioner resets as controlled by "
167 : "reuse_preconditioner_max_linear_its");
168 921141 : params.addParam<unsigned int>("reuse_preconditioner_max_linear_its",
169 614094 : 25,
170 : "Reuse the previously calculated "
171 : "preconditioner for the linear system "
172 : "until the number of linear iterations "
173 : "exceeds this number");
174 :
175 : // Multi-system fixed point
176 : // Defaults to false because of the difficulty of defining a good multi-system convergence
177 : // criterion, unless we add a default one to the simulation?
178 921141 : params.addParam<bool>(
179 : "multi_system_fixed_point",
180 614094 : false,
181 : "Whether to perform fixed point (Picard) iterations between the nonlinear systems.");
182 1228188 : params.addParam<ConvergenceName>(
183 : "multi_system_fixed_point_convergence",
184 : "Convergence object to determine the convergence of the multi-system fixed point iteration. "
185 : "If unspecified, defaults to checking that every system is converged (based on their own "
186 : "convergence criterion)");
187 :
188 1228188 : params.addParamNamesToGroup("l_tol l_abs_tol l_max_its reuse_preconditioner "
189 : "reuse_preconditioner_max_linear_its",
190 : "Linear Solver");
191 1228188 : params.addParamNamesToGroup(
192 : "solve_type snesmf_reuse_base use_pre_SMO_residual "
193 : "num_grids residual_and_jacobian_together nonlinear_convergence linear_convergence",
194 : "Nonlinear Solver");
195 1228188 : params.addParamNamesToGroup(
196 : "automatic_scaling compute_scaling_once off_diagonals_in_auto_scaling "
197 : "scaling_group_variables resid_vs_jac_scaling_param ignore_variables_for_autoscaling",
198 : "Solver variable scaling");
199 1228188 : params.addParamNamesToGroup("line_search line_search_package contact_line_search_ltol "
200 : "contact_line_search_allowed_lambda_cuts",
201 : "Solver line search");
202 1228188 : params.addParamNamesToGroup("multi_system_fixed_point multi_system_fixed_point_convergence",
203 : "Multiple solver system");
204 921141 : params.addParamNamesToGroup("skip_exception_check", "Advanced");
205 :
206 614094 : return params;
207 307047 : }
208 :
209 63876 : FEProblemSolve::FEProblemSolve(Executioner & ex)
210 : : MultiSystemSolveObject(ex),
211 63876 : _num_grid_steps(cast_int<unsigned int>(getParam<unsigned int>("num_grids") - 1)),
212 127752 : _using_multi_sys_fp_iterations(getParam<bool>("multi_system_fixed_point")),
213 63876 : _multi_sys_fp_convergence(nullptr) // has not been created yet
214 : {
215 127752 : if (_moose_line_searches.find(getParam<MooseEnum>("line_search").operator std::string()) !=
216 127752 : _moose_line_searches.end())
217 0 : _problem.addLineSearch(_pars);
218 :
219 64175 : auto set_solver_params = [this, &ex](const SolverSystem & sys)
220 : {
221 64175 : const auto prefix = sys.prefix();
222 64175 : Moose::PetscSupport::storePetscOptions(_problem, prefix, ex);
223 64175 : Moose::PetscSupport::setConvergedReasonFlags(_problem, prefix);
224 :
225 : // Set solver parameter prefix and system number
226 64175 : auto & solver_params = _problem.solverParams(sys.number());
227 64175 : solver_params._prefix = prefix;
228 64175 : solver_params._solver_sys_num = sys.number();
229 64175 : };
230 :
231 : // Extract and store PETSc related settings on FEProblemBase
232 128051 : for (const auto * const sys : _systems)
233 64175 : set_solver_params(*sys);
234 :
235 : // Set linear solve parameters in the equation system
236 : // Nonlinear solve parameters are added in the DefaultNonlinearConvergence
237 63876 : EquationSystems & es = _problem.es();
238 255504 : es.parameters.set<Real>("linear solver tolerance") = getParam<Real>("l_tol");
239 255504 : es.parameters.set<Real>("linear solver absolute tolerance") = getParam<Real>("l_abs_tol");
240 63876 : es.parameters.set<unsigned int>("linear solver maximum iterations") =
241 191628 : getParam<unsigned int>("l_max_its");
242 255504 : es.parameters.set<bool>("reuse preconditioner") = getParam<bool>("reuse_preconditioner");
243 63876 : es.parameters.set<unsigned int>("reuse preconditioner maximum linear iterations") =
244 191628 : getParam<unsigned int>("reuse_preconditioner_max_linear_its");
245 :
246 : // Transfer to the Problem misc nonlinear solve optimization parameters
247 63876 : _problem.setSNESMFReuseBase(getParam<bool>("snesmf_reuse_base"),
248 191628 : _pars.isParamSetByUser("snesmf_reuse_base"));
249 127752 : _problem.skipExceptionCheck(getParam<bool>("skip_exception_check"));
250 :
251 191628 : if (isParamValid("nonlinear_convergence"))
252 : {
253 344 : if (_problem.onlyAllowDefaultNonlinearConvergence())
254 0 : mooseError("The selected problem does not allow 'nonlinear_convergence' to be set.");
255 1032 : _problem.setNonlinearConvergenceNames(
256 : getParam<std::vector<ConvergenceName>>("nonlinear_convergence"));
257 : }
258 : else
259 63532 : _problem.setNeedToAddDefaultNonlinearConvergence();
260 191628 : if (isParamValid("linear_convergence"))
261 : {
262 181 : if (_problem.numLinearSystems() == 0)
263 0 : paramError(
264 : "linear_convergence",
265 : "Setting 'linear_convergence' is currently only possible for solving linear systems");
266 543 : _problem.setLinearConvergenceNames(
267 : getParam<std::vector<ConvergenceName>>("linear_convergence"));
268 : }
269 :
270 : // Check whether the user has explicitly requested automatic scaling and is using a solve type
271 : // without a matrix. If so, then we warn them
272 193081 : if ((_pars.isParamSetByUser("automatic_scaling") && getParam<bool>("automatic_scaling")) &&
273 449 : std::all_of(_systems.begin(),
274 : _systems.end(),
275 449 : [this](const auto & solver_sys)
276 449 : { return _problem.solverParams(solver_sys->number())._type == Moose::ST_JFNK; }))
277 : {
278 0 : paramWarning("automatic_scaling",
279 : "Automatic scaling isn't implemented for the case where you do not have a "
280 : "preconditioning matrix. No scaling will be applied");
281 0 : _problem.automaticScaling(false);
282 : }
283 : else
284 : // Check to see whether automatic_scaling has been specified anywhere, including at the
285 : // application level. No matter what: if we don't have a matrix, we don't do scaling
286 63876 : _problem.automaticScaling(
287 191628 : isParamValid("automatic_scaling")
288 65382 : ? getParam<bool>("automatic_scaling")
289 63374 : : (getMooseApp().defaultAutomaticScaling() &&
290 0 : std::any_of(_systems.begin(),
291 : _systems.end(),
292 0 : [this](const auto & solver_sys) {
293 0 : return _problem.solverParams(solver_sys->number())._type !=
294 0 : Moose::ST_JFNK;
295 : })));
296 :
297 189592 : if (!_using_multi_sys_fp_iterations && isParamValid("multi_system_fixed_point_convergence"))
298 8 : paramError("multi_system_fixed_point_convergence",
299 : "Cannot set a convergence object for multi-system fixed point iterations if "
300 : "'multi_system_fixed_point' is set to false");
301 65908 : if (_using_multi_sys_fp_iterations && !isParamValid("multi_system_fixed_point_convergence"))
302 8 : paramError("multi_system_fixed_point_convergence",
303 : "Must set a convergence object for multi-system fixed point iterations if using "
304 : "multi-system fixed point iterations");
305 :
306 : // Set the same parameters to every nonlinear system by default
307 63868 : int i_nl_sys = -1;
308 128007 : for (const auto i_sys : index_range(_systems))
309 : {
310 64151 : auto nl_ptr = dynamic_cast<NonlinearSystemBase *>(_systems[i_sys]);
311 : // Linear systems have very different parameters at the moment
312 64151 : if (!nl_ptr)
313 1340 : continue;
314 62811 : auto & nl = *nl_ptr;
315 62811 : i_nl_sys++;
316 :
317 125622 : nl.setPreSMOResidual(getParam<bool>("use_pre_SMO_residual"));
318 :
319 : const auto res_and_jac =
320 125622 : getParamFromNonlinearSystemVectorParam<bool>("residual_and_jacobian_together", i_nl_sys);
321 62803 : if (res_and_jac)
322 340 : nl.residualAndJacobianTogether();
323 :
324 : // Automatic scaling parameters
325 62803 : nl.computeScalingOnce(
326 125606 : getParamFromNonlinearSystemVectorParam<bool>("compute_scaling_once", i_nl_sys));
327 125606 : nl.autoScalingParam(
328 : getParamFromNonlinearSystemVectorParam<Real>("resid_vs_jac_scaling_param", i_nl_sys));
329 62803 : nl.offDiagonalsInAutoScaling(
330 125606 : getParamFromNonlinearSystemVectorParam<bool>("off_diagonals_in_auto_scaling", i_nl_sys));
331 188409 : if (isParamValid("scaling_group_variables"))
332 17 : nl.scalingGroupVariables(
333 68 : getParamFromNonlinearSystemVectorParam<std::vector<std::vector<std::string>>>(
334 : "scaling_group_variables", i_nl_sys));
335 188409 : if (isParamValid("ignore_variables_for_autoscaling"))
336 : {
337 : // Before setting ignore_variables_for_autoscaling, check that they are not present in
338 : // scaling_group_variables
339 42 : if (isParamValid("scaling_group_variables"))
340 : {
341 : const auto & ignore_variables_for_autoscaling =
342 : getParamFromNonlinearSystemVectorParam<std::vector<std::string>>(
343 8 : "ignore_variables_for_autoscaling", i_nl_sys);
344 : const auto & scaling_group_variables =
345 : getParamFromNonlinearSystemVectorParam<std::vector<std::vector<std::string>>>(
346 8 : "scaling_group_variables", i_nl_sys);
347 4 : for (const auto & group : scaling_group_variables)
348 8 : for (const auto & var_name : group)
349 8 : if (std::find(ignore_variables_for_autoscaling.begin(),
350 : ignore_variables_for_autoscaling.end(),
351 16 : var_name) != ignore_variables_for_autoscaling.end())
352 8 : paramError("ignore_variables_for_autoscaling",
353 : "Variables cannot be in a scaling grouping and also be ignored");
354 0 : }
355 10 : nl.ignoreVariablesForAutoscaling(
356 40 : getParamFromNonlinearSystemVectorParam<std::vector<std::string>>(
357 : "ignore_variables_for_autoscaling", i_nl_sys));
358 : }
359 : }
360 :
361 : // Multi-grid options
362 63856 : _problem.numGridSteps(_num_grid_steps);
363 63856 : }
364 :
365 : template <typename T>
366 : T
367 251255 : FEProblemSolve::getParamFromNonlinearSystemVectorParam(const std::string & param_name,
368 : unsigned int index) const
369 : {
370 251255 : const auto & param_vec = getParam<std::vector<T>>(param_name);
371 251255 : if (index > _num_nl_systems)
372 0 : paramError(param_name,
373 : "Vector parameter is requested at index (" + std::to_string(index) +
374 : ") which is larger than number of nonlinear systems (" +
375 0 : std::to_string(_num_nl_systems) + ").");
376 251255 : if (param_vec.size() == 0)
377 4 : paramError(
378 : param_name,
379 : "This parameter was passed to a routine which cannot handle empty vector parameters");
380 251251 : if (param_vec.size() != 1 && param_vec.size() != _num_nl_systems)
381 4 : paramError(param_name,
382 : "Vector parameter size (" + std::to_string(param_vec.size()) +
383 : ") is different than the number of nonlinear systems (" +
384 4 : std::to_string(_num_nl_systems) + ").");
385 :
386 : // User passed only one parameter, assume it applies to all nonlinear systems
387 251247 : if (param_vec.size() == 1)
388 251247 : return param_vec[0];
389 : else
390 0 : return param_vec[index];
391 : }
392 :
393 : void
394 60313 : FEProblemSolve::initialSetup()
395 : {
396 60313 : MultiSystemSolveObject::initialSetup();
397 60313 : convergenceSetup();
398 : // Keep track of the solution warnings from the setup
399 60305 : if (!_app.isRecovering())
400 : {
401 56324 : _app.solutionInvalidity().syncIteration();
402 56324 : _app.solutionInvalidity().solutionInvalidAccumulation();
403 56324 : _app.solutionInvalidity().solutionInvalidAccumulationTimeStep(0);
404 : }
405 60305 : }
406 :
407 : void
408 60313 : FEProblemSolve::convergenceSetup()
409 : {
410 : // nonlinear
411 60313 : const auto conv_names = _problem.getNonlinearConvergenceNames();
412 119432 : for (const auto & conv_name : conv_names)
413 : {
414 59127 : auto & conv = _problem.getConvergence(conv_name);
415 59127 : conv.checkIterationType(ConvergenceIterationTypes::NONLINEAR);
416 : }
417 :
418 : // linear
419 180915 : if (isParamValid("linear_convergence"))
420 : {
421 362 : const auto conv_names = getParam<std::vector<ConvergenceName>>("linear_convergence");
422 362 : for (const auto & conv_name : conv_names)
423 : {
424 181 : auto & conv = _problem.getConvergence(conv_name);
425 181 : conv.checkIterationType(ConvergenceIterationTypes::LINEAR);
426 : }
427 181 : }
428 :
429 : // multisystem fixed point
430 180915 : if (isParamValid("multi_system_fixed_point_convergence"))
431 : {
432 1006 : _multi_sys_fp_convergence =
433 2012 : &_problem.getConvergence(getParam<ConvergenceName>("multi_system_fixed_point_convergence"));
434 1006 : _multi_sys_fp_convergence->checkIterationType(
435 : ConvergenceIterationTypes::MULTISYSTEM_FIXED_POINT);
436 : }
437 60305 : }
438 :
439 : bool
440 337870 : FEProblemSolve::solve()
441 : {
442 : // Outer loop for multi-grid convergence
443 337870 : bool converged = false;
444 337870 : unsigned int num_fp_multisys_iters = 0;
445 671786 : for (MooseIndex(_num_grid_steps) grid_step = 0; grid_step <= _num_grid_steps; ++grid_step)
446 : {
447 : // Multi-system fixed point loop
448 : // Use a convergence object if provided, if not, use a reasonable default of every nested system
449 : // being converged
450 337927 : num_fp_multisys_iters = 0;
451 337927 : converged = false;
452 676279 : while (!converged)
453 : {
454 : // Loop over each system
455 685102 : for (const auto sys : _systems)
456 : {
457 346750 : const bool is_nonlinear = (dynamic_cast<NonlinearSystemBase *>(sys) != nullptr);
458 :
459 : // Call solve on the problem for that system
460 346750 : if (is_nonlinear)
461 341102 : _problem.solve(sys->number());
462 : else
463 : {
464 : const auto linear_sys_number =
465 5648 : cast_int<unsigned int>(sys->number() - _problem.numNonlinearSystems());
466 5648 : _problem.solveLinearSystem(linear_sys_number, &_problem.getPetscOptions());
467 :
468 : // This is for postprocessing purposes in case none of the objects
469 : // request the gradients.
470 : // TODO: Somehow collect information if the postprocessors
471 : // need gradients and if nothing needs this, just skip it
472 5648 : _problem.getLinearSystem(linear_sys_number).computeGradients();
473 : }
474 :
475 : // Check convergence
476 : const auto solve_name =
477 684566 : _systems.size() == 1 ? " Solve" : "System " + sys->name() + ": Solve";
478 346670 : if (_problem.shouldSolve())
479 : {
480 315186 : if (_problem.converged(sys->number()))
481 311255 : _console << COLOR_GREEN << solve_name << " Converged!" << COLOR_DEFAULT << std::endl;
482 : else
483 : {
484 3927 : _console << COLOR_RED << solve_name << " Did NOT Converge!" << COLOR_DEFAULT
485 3927 : << std::endl;
486 3927 : return false;
487 : }
488 : }
489 : else
490 31484 : _console << COLOR_GREEN << solve_name << " Skipped!" << COLOR_DEFAULT << std::endl;
491 346666 : }
492 :
493 : // Assess convergence of the multi-system fixed point iteration
494 338352 : if (!_using_multi_sys_fp_iterations)
495 332906 : converged = true;
496 : else
497 : {
498 5446 : converged = _multi_sys_fp_convergence->checkConvergence(num_fp_multisys_iters) ==
499 : Convergence::MooseConvergenceStatus::CONVERGED;
500 5446 : if (_multi_sys_fp_convergence->checkConvergence(num_fp_multisys_iters) ==
501 : Convergence::MooseConvergenceStatus::DIVERGED)
502 0 : break;
503 : }
504 338352 : num_fp_multisys_iters++;
505 : }
506 :
507 333916 : if (grid_step != _num_grid_steps)
508 57 : _problem.uniformRefine();
509 : }
510 :
511 333859 : if (_multi_sys_fp_convergence)
512 1010 : return (_multi_sys_fp_convergence->checkConvergence(num_fp_multisys_iters) ==
513 1010 : Convergence::MooseConvergenceStatus::CONVERGED);
514 : else
515 332849 : return converged;
516 : }
|