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 : #pragma once 11 : 12 : #include "MooseTypes.h" 13 : #include "ChainedReal.h" 14 : #include "ChainedADReal.h" 15 : #include "InputParameters.h" 16 : 17 : class ConsoleStream; 18 : 19 : /** 20 : * Base class that provides capability for Newton return mapping 21 : * iterations on a single variable 22 : */ 23 : template <bool is_ad> 24 : class SingleVariableReturnMappingSolutionTempl 25 : { 26 : public: 27 : static InputParameters validParams(); 28 : 29 : SingleVariableReturnMappingSolutionTempl(const InputParameters & parameters); 30 4290 : virtual ~SingleVariableReturnMappingSolutionTempl() {} 31 : 32 : protected: 33 : /** 34 : * Perform the return mapping iterations 35 : * @param effective_trial_stress Effective trial stress 36 : * @param scalar Inelastic strain increment magnitude being solved for 37 : * @param console Console output 38 : */ 39 : void returnMappingSolve(const GenericReal<is_ad> & effective_trial_stress, 40 : GenericReal<is_ad> & scalar, 41 : const ConsoleStream & console); 42 : 43 : /** 44 : * Compute the minimum permissible value of the scalar. For some models, the magnitude 45 : * of this may be known. 46 : * @param effective_trial_stress Effective trial stress 47 : */ 48 : virtual GenericReal<is_ad> 49 : minimumPermissibleValue(const GenericReal<is_ad> & effective_trial_stress) const; 50 : 51 : /** 52 : * Compute the maximum permissible value of the scalar. For some models, the magnitude 53 : * of this may be known. 54 : * @param effective_trial_stress Effective trial stress 55 : */ 56 : virtual GenericReal<is_ad> 57 : maximumPermissibleValue(const GenericReal<is_ad> & effective_trial_stress) const; 58 : 59 : /** 60 : * Compute an initial guess for the value of the scalar. For some cases, an 61 : * intellegent starting point can provide enhanced robustness in the Newton 62 : * iterations. This is also an opportunity for classes that derive from this 63 : * to perform initialization tasks. 64 : * @param effective_trial_stress Effective trial stress 65 : */ 66 56554214 : virtual GenericReal<is_ad> initialGuess(const GenericReal<is_ad> & /*effective_trial_stress*/) 67 : { 68 56554214 : return 0.0; 69 : } 70 : 71 : /** 72 : * Compute the residual for a predicted value of the scalar. This residual should be 73 : * in strain increment units for all models for consistency. 74 : * @param effective_trial_stress Effective trial stress 75 : * @param scalar Inelastic strain increment magnitude being solved for 76 : */ 77 : virtual GenericReal<is_ad> computeResidual(const GenericReal<is_ad> & /*effective_trial_stress*/, 78 : const GenericReal<is_ad> & /*scalar*/) = 0; 79 : 80 : /** 81 : * Compute the derivative of the residual as a function of the scalar variable. The 82 : * residual should be in strain increment units for all models for consistency. 83 : * @param effective_trial_stress Effective trial stress 84 : * @param scalar Inelastic strain increment magnitude being solved for 85 : */ 86 : virtual GenericReal<is_ad> 87 : computeDerivative(const GenericReal<is_ad> & /*effective_trial_stress*/, 88 : const GenericReal<is_ad> & /*scalar*/) = 0; 89 : 90 : /** 91 : * Compute the residual and the derivative for a predicted value of the scalar. This residual 92 : * should be in strain increment units for all models for consistency. 93 : * @param effective_trial_stress Effective trial stress 94 : * @param scalar Inelastic strain increment magnitude being solved for 95 : */ 96 : virtual GenericChainedReal<is_ad> 97 0 : computeResidualAndDerivative(const GenericReal<is_ad> & /*effective_trial_stress*/, 98 : const GenericChainedReal<is_ad> & /*scalar*/) 99 : { 100 0 : mooseError("computeResidualAndDerivative has to be implemented if " 101 : "automatic_differentiation_return_mapping = true."); 102 : return 0; 103 : }; 104 : 105 : /** 106 : * Compute a reference quantity to be used for checking relative convergence. This should 107 : * be in strain increment units for all models for consistency. 108 : * @param effective_trial_stress Effective trial stress 109 : * @param scalar Inelastic strain increment magnitude being solved for 110 : */ 111 : virtual Real computeReferenceResidual(const GenericReal<is_ad> & effective_trial_stress, 112 : const GenericReal<is_ad> & scalar) = 0; 113 : 114 : /** 115 : * This method is called before taking a step in the return mapping algorithm. A typical use case 116 : * is to accumulate the exact algorithmic tangent during return mapping. 117 : */ 118 236931628 : virtual void preStep(const GenericReal<is_ad> & /*scalar_old*/, 119 : const GenericReal<is_ad> & /*residual*/, 120 : const GenericReal<is_ad> & /*jacobian*/) 121 : { 122 236931628 : } 123 : 124 : /** 125 : * Finalize internal state variables for a model for a given iteration. 126 : * @param scalar Inelastic strain increment magnitude being solved for 127 : */ 128 232340406 : virtual void iterationFinalize(const GenericReal<is_ad> & /*scalar*/) {} 129 : 130 : /** 131 : * Output summary information for the convergence history of the model 132 : * @param iter_output Output stream 133 : * @param total_it Total iteration count 134 : */ 135 : virtual void outputIterationSummary(std::stringstream * iter_output, const unsigned int total_it); 136 : 137 : /// Whether to check to see whether iterative solution is within admissible range, and set within that range if outside 138 : bool _check_range; 139 : 140 : /// Whether to use line searches to improve convergence 141 : bool _line_search; 142 : 143 : /// Whether to save upper and lower bounds of root for scalar, and set solution to the midpoint between 144 : /// those bounds if outside them 145 : bool _bracket_solution; 146 : 147 : /** 148 : * Output information for a single iteration step to build the convergence history of the model 149 : * @param iter_output Output stream 150 : * @param effective_trial_stress Effective trial stress 151 : * @param residual Current value of the residual 152 : * @param reference Current value of the reference quantity 153 : */ 154 : virtual void outputIterationStep(std::stringstream * iter_output, 155 : const GenericReal<is_ad> & effective_trial_stress, 156 : const GenericReal<is_ad> & scalar, 157 : const Real reference_residual); 158 : 159 : /** 160 : * Check to see whether the residual is within the convergence limits. 161 : * @param residual Current value of the residual 162 : * @param reference Current value of the reference quantity 163 : * @return Whether the model converged 164 : */ 165 : bool converged(const GenericReal<is_ad> & residual, const Real reference); 166 : 167 : private: 168 : /// Helper function to compute and set the _residual and _derivative 169 : void computeResidualAndDerivativeHelper(const GenericReal<is_ad> & effective_trial_stress, 170 : const GenericReal<is_ad> & scalar); 171 : 172 : enum class InternalSolveOutput 173 : { 174 : NEVER, 175 : ON_ERROR, 176 : ALWAYS 177 : } _internal_solve_output_on; 178 : 179 : enum class SolveState 180 : { 181 : SUCCESS, 182 : NAN_INF, 183 : EXCEEDED_ITERATIONS 184 : }; 185 : 186 : /// Maximum number of return mapping iterations. This exists only to avoid an infinite loop, and is 187 : /// is intended to be a large number that is not settable by the user. 188 : const unsigned int _max_its; 189 : 190 : /// Whether to output iteration information all the time (regardless of whether iterations converge) 191 : const bool _internal_solve_full_iteration_history; 192 : 193 : /// Relative convergence tolerance 194 : Real _relative_tolerance; 195 : 196 : /// Absolute convergence tolerance 197 : Real _absolute_tolerance; 198 : 199 : /// Multiplier applied to relative and absolute tolerances for acceptable convergence 200 : Real _acceptable_multiplier; 201 : 202 : // Whether to use automatic differentiation to calculate the derivative. If set to false, you must 203 : // override both computeResidual and computeDerivative methods. If set to true, you must override 204 : // the computeResidualAndDerivative method. 205 : const bool _ad_derivative; 206 : 207 : /// Number of residuals to be stored in history 208 : const std::size_t _num_resids; 209 : 210 : /// History of residuals used to check whether progress is still being made on decreasing the residual 211 : std::vector<Real> _residual_history; 212 : 213 : /// iteration number 214 : unsigned int _iteration; 215 : 216 : ///@{ Residual values, kept as members to retain solver state for summary outputting 217 : GenericReal<is_ad> _initial_residual; 218 : GenericReal<is_ad> _residual; 219 : ///@} 220 : 221 : /// Derivative of the residual 222 : GenericReal<is_ad> _derivative; 223 : 224 : /// MOOSE input name of the object performing the solve 225 : const std::string _svrms_name; 226 : 227 : /** 228 : * Method called from within this class to perform the actual return mappping iterations. 229 : * @param effective_trial_stress Effective trial stress 230 : * @param scalar Inelastic strain increment magnitude being solved for 231 : * @param iter_output Output stream -- if null, no output is produced 232 : * @return Whether the solution was successful 233 : */ 234 : SolveState internalSolve(const GenericReal<is_ad> effective_trial_stress, 235 : GenericReal<is_ad> & scalar, 236 : std::stringstream * iter_output = nullptr); 237 : 238 : /** 239 : * Check to see whether the residual is within acceptable convergence limits. 240 : * This will only return true if it has been determined that progress is no 241 : * longer being made and that the residual is within the acceptable limits. 242 : * @param residual Current iteration count 243 : * @param residual Current value of the residual 244 : * @param reference Current value of the reference quantity 245 : * @return Whether the model converged 246 : */ 247 : bool convergedAcceptable(const unsigned int it, const Real reference); 248 : 249 : /** 250 : * Check to see whether solution is within admissible range, and set it within that range 251 : * if it is not. 252 : * @param scalar Current value of the inelastic strain increment 253 : * @param scalar_increment Incremental change in scalar from the previous iteration 254 : * @param scalar_old Previous value of scalar 255 : * @param min_permissible_scalar Minimum permissible value of scalar 256 : * @param max_permissible_scalar Maximum permissible value of scalar 257 : * @param iter_output Output stream 258 : */ 259 : void checkPermissibleRange(GenericReal<is_ad> & scalar, 260 : GenericReal<is_ad> & scalar_increment, 261 : const GenericReal<is_ad> & scalar_old, 262 : const GenericReal<is_ad> min_permissible_scalar, 263 : const GenericReal<is_ad> max_permissible_scalar, 264 : std::stringstream * iter_output); 265 : 266 : /** 267 : * Update the upper and lower bounds of the root for the effective inelastic strain. 268 : * @param scalar Current value of the inelastic strain increment 269 : * @param residual Current value of the residual 270 : * @param init_resid_sign Sign of the initial value of the residual 271 : * @param scalar_upper_bound Upper bound value of scalar 272 : * @param scalar_lower_bound Lower bound value of scalar 273 : * @param iter_output Output stream 274 : */ 275 : void updateBounds(const GenericReal<is_ad> & scalar, 276 : const GenericReal<is_ad> & residual, 277 : const Real init_resid_sign, 278 : GenericReal<is_ad> & scalar_upper_bound, 279 : GenericReal<is_ad> & scalar_lower_bound, 280 : std::stringstream * iter_output); 281 : }; 282 : 283 : typedef SingleVariableReturnMappingSolutionTempl<false> SingleVariableReturnMappingSolution; 284 : typedef SingleVariableReturnMappingSolutionTempl<true> ADSingleVariableReturnMappingSolution;