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