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")),
72 _ad_derivative(parameters.get<bool>(
"automatic_differentiation_return_mapping")),
74 _residual_history(_num_resids,
std::numeric_limits<Real>::max()),
76 _initial_residual(0.0),
78 _svrms_name(parameters.getObjectName())
106 std::unique_ptr<std::stringstream> iter_output =
107 (_internal_solve_output_on == InternalSolveOutput::ALWAYS)
108 ? std::make_unique<std::stringstream>()
114 internalSolve(effective_trial_stress,
116 _internal_solve_full_iteration_history ? iter_output.get() :
nullptr);
117 if (solve_state != SolveState::SUCCESS &&
118 _internal_solve_output_on != InternalSolveOutput::ALWAYS)
121 if (_internal_solve_output_on == InternalSolveOutput::NEVER)
126 iter_output = std::make_unique<std::stringstream>();
131 case SolveState::NAN_INF:
132 *iter_output <<
"Encountered inf or nan in material return mapping iterations.\n";
135 case SolveState::EXCEEDED_ITERATIONS:
136 *iter_output <<
"Exceeded maximum iterations in material return mapping iterations.\n";
145 if (_internal_solve_full_iteration_history)
146 internalSolve(effective_trial_stress, scalar, iter_output.get());
149 outputIterationSummary(iter_output.get(), _iteration);
150 mooseException(iter_output->str());
153 if (_internal_solve_output_on == InternalSolveOutput::ALWAYS)
156 outputIterationSummary(iter_output.get(), _iteration);
157 console << iter_output->str() << std::flush;
166 std::stringstream * iter_output)
168 scalar = initialGuess(effective_trial_stress);
171 const GenericReal<is_ad> min_permissible_scalar = minimumPermissibleValue(effective_trial_stress);
172 const GenericReal<is_ad> max_permissible_scalar = maximumPermissibleValue(effective_trial_stress);
177 computeResidualAndDerivativeHelper(effective_trial_stress, scalar);
178 _initial_residual = _residual;
182 Real reference_residual = computeReferenceResidual(effective_trial_stress, scalar);
184 if (converged(_residual, reference_residual))
186 iterationFinalize(scalar);
187 outputIterationStep(iter_output, effective_trial_stress, scalar, reference_residual);
188 return SolveState::SUCCESS;
191 _residual_history.assign(_num_resids, std::numeric_limits<Real>::max());
194 while (_iteration < _max_its && !converged(_residual, reference_residual) &&
195 !convergedAcceptable(_iteration, reference_residual))
197 preStep(scalar_old, _residual, _derivative);
199 scalar_increment = -_residual / _derivative;
200 scalar = scalar_old + scalar_increment;
203 checkPermissibleRange(scalar,
206 min_permissible_scalar,
207 max_permissible_scalar,
210 computeResidualAndDerivativeHelper(effective_trial_stress, scalar);
211 reference_residual = computeReferenceResidual(effective_trial_stress, scalar);
212 iterationFinalize(scalar);
214 if (_bracket_solution)
216 scalar, _residual, init_resid_sign, scalar_upper_bound, scalar_lower_bound, iter_output);
218 if (converged(_residual, reference_residual))
220 outputIterationStep(iter_output, effective_trial_stress, scalar, reference_residual);
225 bool modified_increment =
false;
230 if (residual_old - _residual != 0.0)
237 modified_increment =
true;
238 scalar_increment *= alpha;
247 if (_bracket_solution)
251 if (scalar_old + scalar_increment >= scalar_upper_bound ||
252 scalar_old + scalar_increment <= scalar_lower_bound)
254 if (scalar_upper_bound != max_permissible_scalar &&
255 scalar_lower_bound != min_permissible_scalar)
257 const Real frac = 0.5;
259 (1.0 - frac) * scalar_lower_bound + frac * scalar_upper_bound - scalar_old;
260 modified_increment =
true;
262 *iter_output <<
" Trial scalar_increment exceeded bounds. Setting between "
263 "lower/upper bounds. frac: "
264 << frac << std::endl;
271 if (modified_increment)
273 scalar = scalar_old + scalar_increment;
274 computeResidualAndDerivativeHelper(effective_trial_stress, scalar);
275 reference_residual = computeReferenceResidual(effective_trial_stress, scalar);
276 iterationFinalize(scalar);
278 if (_bracket_solution)
288 outputIterationStep(iter_output, effective_trial_stress, scalar, reference_residual);
291 residual_old = _residual;
296 using std::isnan, std::isinf;
298 return SolveState::NAN_INF;
300 if (_iteration == _max_its)
301 return SolveState::EXCEEDED_ITERATIONS;
303 return SolveState::SUCCESS;
void updateBounds(const GenericReal< is_ad > &scalar, const GenericReal< is_ad > &residual, const Real init_resid_sign, GenericReal< is_ad > &scalar_upper_bound, GenericReal< is_ad > &scalar_lower_bound, std::stringstream *iter_output)
Update the upper and lower bounds of the root for the effective inelastic strain.
void checkPermissibleRange(GenericReal< is_ad > &scalar, GenericReal< is_ad > &scalar_increment, const GenericReal< is_ad > &scalar_old, const GenericReal< is_ad > min_permissible_scalar, const GenericReal< is_ad > max_permissible_scalar, std::stringstream *iter_output)
Check to see whether solution is within admissible range, and set it within that range if it is not.