12 #include "InputParameters.h"
13 #include "Conversion.h"
14 #include "MooseEnum.h"
16 #include "MathUtils.h"
18 #include "libmesh/auto_ptr.h"
30 InputParameters params = emptyInputParameters();
33 params.addParam<Real>(
34 "relative_tolerance", 1e-8,
"Relative convergence tolerance for Newton iteration");
35 params.addParam<Real>(
36 "absolute_tolerance", 1e-11,
"Absolute convergence tolerance for Newton iteration");
37 params.addParam<Real>(
"acceptable_multiplier",
39 "Factor applied to relative and absolute "
40 "tolerance for acceptable convergence if "
41 "iterations are no longer making progress");
44 MooseEnum internal_solve_output_on_enum(
"never on_error always",
"on_error");
45 params.addParam<MooseEnum>(
"internal_solve_output_on",
46 internal_solve_output_on_enum,
47 "When to output internal Newton solve information");
48 params.addParam<
bool>(
"internal_solve_full_iteration_history",
50 "Set true to output full internal Newton iteration history at times "
51 "determined by `internal_solve_output_on`. If false, only a summary is "
53 params.addParamNamesToGroup(
"internal_solve_output_on internal_solve_full_iteration_history",
60 const InputParameters & parameters)
61 : _check_range(false),
63 _bracket_solution(true),
64 _internal_solve_output_on(
67 _internal_solve_full_iteration_history(
68 parameters.get<bool>(
"internal_solve_full_iteration_history")),
69 _relative_tolerance(parameters.get<Real>(
"relative_tolerance")),
70 _absolute_tolerance(parameters.get<Real>(
"absolute_tolerance")),
71 _acceptable_multiplier(parameters.get<Real>(
"acceptable_multiplier")),
73 _residual_history(_num_resids, std::numeric_limits<Real>::max()),
75 _initial_residual(0.0),
77 _svrms_name(parameters.get<std::string>(
"_object_name"))
85 return std::numeric_limits<Real>::lowest();
92 return std::numeric_limits<Real>::max();
98 const ConsoleStream & console)
101 std::unique_ptr<std::stringstream> iter_output =
103 ? libmesh_make_unique<std::stringstream>()
117 throw MooseException(
"");
121 iter_output = libmesh_make_unique<std::stringstream>();
127 *iter_output <<
"Encountered inf or nan in material return mapping iterations.\n";
131 *iter_output <<
"Exceeded maximum iterations in material return mapping iterations.\n";
135 mooseError(
"Unhandled solver state");
141 internalSolve(effective_trial_stress, scalar, iter_output.get());
145 throw MooseException(iter_output->str());
152 console << iter_output->str();
159 std::stringstream * iter_output)
162 Real scalar_old = scalar;
163 Real scalar_increment = 0.0;
166 Real scalar_upper_bound = max_permissible_scalar;
167 Real scalar_lower_bound = min_permissible_scalar;
173 Real init_resid_sign = MathUtils::sign(
_residual);
191 scalar = scalar_old + scalar_increment;
197 min_permissible_scalar,
198 max_permissible_scalar,
207 scalar,
_residual, init_resid_sign, scalar_upper_bound, scalar_lower_bound, iter_output);
217 bool modified_increment =
false;
224 Real alpha = residual_old / (residual_old -
_residual);
225 alpha = MathUtils::clamp(alpha, 1.0e-2, 1.0);
229 modified_increment =
true;
230 scalar_increment *= alpha;
232 *iter_output <<
" Line search alpha = " << alpha
233 <<
" increment = " << scalar_increment << std::endl;
242 if (scalar_old + scalar_increment >= scalar_upper_bound ||
243 scalar_old + scalar_increment <= scalar_lower_bound)
245 if (scalar_upper_bound != max_permissible_scalar &&
246 scalar_lower_bound != min_permissible_scalar)
248 const Real frac = 0.5;
250 (1.0 - frac) * scalar_lower_bound + frac * scalar_upper_bound - scalar_old;
251 modified_increment =
true;
253 *iter_output <<
" Trial scalar_increment exceeded bounds. Setting between "
254 "lower/upper bounds. frac: "
255 << frac << std::endl;
262 if (modified_increment)
264 scalar = scalar_old + scalar_increment;
307 const Real reference)
317 const Real convergence_history_factor = 10.0;
318 if (std::abs(residual * convergence_history_factor) <
329 const unsigned int it,
330 const Real effective_trial_stress,
333 const Real reference_residual)
337 *iter_output <<
" iteration=" << it <<
" trial_stress=" << effective_trial_stress
338 <<
" scalar=" << scalar <<
" residual=" << residual
339 <<
" ref_res=" << reference_residual
340 <<
" rel_res=" << std::abs(residual) / reference_residual
348 const unsigned int total_it)
351 *iter_output <<
"In " << total_it <<
" iterations the residual went from " <<
_initial_residual
357 Real & scalar_increment,
358 const Real scalar_old,
359 const Real min_permissible_scalar,
360 const Real max_permissible_scalar,
361 std::stringstream * iter_output)
363 if (scalar > max_permissible_scalar)
365 scalar_increment = (max_permissible_scalar - scalar_old) / 2.0;
366 scalar = scalar_old + scalar_increment;
368 *iter_output <<
"Scalar greater than maximum (" << max_permissible_scalar
369 <<
") adjusted scalar=" << scalar <<
" scalar_increment=" << scalar_increment
372 else if (scalar < min_permissible_scalar)
374 scalar_increment = (min_permissible_scalar - scalar_old) / 2.0;
375 scalar = scalar_old + scalar_increment;
377 *iter_output <<
"Scalar less than minimum (" << min_permissible_scalar
378 <<
") adjusted scalar=" << scalar <<
" scalar_increment=" << scalar_increment
386 const Real init_resid_sign,
387 Real & scalar_upper_bound,
388 Real & scalar_lower_bound,
389 std::stringstream * iter_output)
392 if (residual * init_resid_sign < 0.0 && scalar < scalar_upper_bound)
394 scalar_upper_bound = scalar;
395 if (scalar_upper_bound < scalar_lower_bound)
397 scalar_upper_bound = scalar_lower_bound;
398 scalar_lower_bound = 0.0;
400 *iter_output <<
" Corrected for scalar_upper_bound < scalar_lower_bound" << std::endl;
405 else if (residual * init_resid_sign > 0.0 && scalar > scalar_lower_bound &&
406 scalar < scalar_upper_bound)
407 scalar_lower_bound = scalar;