Line data Source code
1 : #include "CombinedNonlinearHardeningPlasticity.h" 2 : #include "Function.h" 3 : #include "ElasticityTensorTools.h" 4 : #include "RadialReturnBackstressStressUpdateBase.h" 5 : #include "ElasticityTensorTools.h" 6 : 7 : registerMooseObject("SolidMechanicsApp", ADCombinedNonlinearHardeningPlasticity); 8 : registerMooseObject("SolidMechanicsApp", CombinedNonlinearHardeningPlasticity); 9 : 10 : template <bool is_ad> 11 : InputParameters 12 192 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::validParams() 13 : { 14 : InputParameters params = RadialReturnBackstressStressUpdateBaseTempl<is_ad>::validParams(); 15 192 : params.addClassDescription("Combined isotropic and kinematic plasticity model with nonlinear " 16 : "hardening rules, including a Voce model for isotropic hardening and " 17 : "an Armstrong-Fredrick model for kinematic hardening."); 18 384 : params.addParam<Real>("q", 0.0, "Saturation value for isotropic hardening (Q in Voce model)"); 19 384 : params.addParam<Real>("b", 0.0, "Rate constant for isotropic hardening (b in Voce model)"); 20 384 : params.addParam<FunctionName>("yield_stress_function", 21 : "Yield stress as a function of temperature"); 22 384 : params.addParam<Real>("yield_stress", "The point at which plastic strain begins accumulating"); 23 384 : params.addParam<FunctionName>("isotropic_hardening_function", 24 : "True stress as a function of plastic strain"); 25 384 : params.addParam<Real>("isotropic_hardening_constant", "Isotropic hardening slope"); 26 384 : params.addCoupledVar("temperature", 0.0, "Coupled Temperature"); 27 192 : params.set<std::string>("effective_inelastic_strain_name") = "effective_plastic_strain"; 28 384 : params.addParam<Real>("kinematic_hardening_modulus", 0.0, "Kinematic hardening modulus"); 29 384 : params.addParam<Real>( 30 384 : "gamma", 0.0, "The nonlinear hardening parameter (gamma) for back stress evolution"); 31 : 32 192 : return params; 33 0 : } 34 : 35 : template <bool is_ad> 36 144 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::CombinedNonlinearHardeningPlasticityTempl( 37 : const InputParameters & parameters) 38 : : RadialReturnBackstressStressUpdateBaseTempl<is_ad>(parameters), 39 432 : _yield_stress_function(this->isParamValid("yield_stress_function") 40 144 : ? &this->getFunction("yield_stress_function") 41 : : nullptr), 42 576 : _yield_stress(this->isParamValid("yield_stress") ? this->template getParam<Real>("yield_stress") 43 : : 0), 44 144 : _isotropic_hardening_constant( 45 144 : this->isParamValid("isotropic_hardening_constant") 46 432 : ? this->template getParam<Real>("isotropic_hardening_constant") 47 : : 0), 48 144 : _isotropic_hardening_function(this->isParamValid("isotropic_hardening_function") 49 144 : ? &this->getFunction("isotropic_hardening_function") 50 : : nullptr), 51 144 : _yield_condition(-1.0), // set to a non-physical value to catch uninitalized yield condition 52 144 : _isotropic_hardening_slope(0.0), 53 144 : _plastic_strain( 54 144 : this->template declareGenericProperty<RankTwoTensor, is_ad>(_base_name + "plastic_strain")), 55 144 : _plastic_strain_old( 56 144 : this->template getMaterialPropertyOld<RankTwoTensor>(_base_name + "plastic_strain")), 57 288 : _kinematic_hardening_modulus(this->template getParam<Real>("kinematic_hardening_modulus")), 58 288 : _gamma(this->template getParam<Real>("gamma")), 59 288 : _q(this->template getParam<Real>("q")), 60 288 : _b(this->template getParam<Real>("b")), 61 288 : _isotropic_hardening_variable(this->template declareGenericProperty<Real, is_ad>( 62 : _base_name + "isotropic_hardening_variable")), 63 144 : _isotropic_hardening_variable_old( 64 144 : this->template getMaterialPropertyOld<Real>(_base_name + "isotropic_hardening_variable")), 65 144 : _kinematic_hardening_variable( 66 144 : this->template declareGenericProperty<Real, is_ad>("kinematic_hardening_variable")), 67 144 : _kinematic_hardening_variable_old( 68 144 : this->template getMaterialPropertyOld<Real>("kinematic_hardening_variable")), 69 432 : _temperature(this->template coupledGenericValue<is_ad>("temperature")) 70 : { 71 288 : if (parameters.isParamSetByUser("yield_stress") && _yield_stress <= 0.0) 72 0 : mooseError("Yield stress must be greater than zero"); 73 : // Both of these parameters are given default values by derived classes, which makes them valid 74 576 : if (_yield_stress_function == nullptr && !this->isParamValid("yield_stress")) 75 0 : mooseError("Either yield_stress or yield_stress_function must be given"); 76 288 : if (!parameters.isParamValid("isotropic_hardening_constant") && 77 144 : !this->isParamValid("isotropic_hardening_function")) 78 0 : mooseError( 79 : "Either isotropic_hardening_constant or isotropic_hardening_function must be defined"); 80 288 : if (parameters.isParamSetByUser("isotropic_hardening_constant") && 81 432 : this->isParamValid("isotropic_hardening_function")) 82 0 : mooseError( 83 : "Only the isotropic_hardening_constant or only the isotropic_hardening_function can be " 84 : "defined but not both"); 85 144 : } 86 : 87 : template <bool is_ad> 88 : void 89 576 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::initQpStatefulProperties() 90 : { 91 576 : _isotropic_hardening_variable[_qp] = 0.0; 92 576 : _kinematic_hardening_variable[_qp] = 0.0; 93 576 : _plastic_strain[_qp].zero(); 94 576 : RadialReturnBackstressStressUpdateBaseTempl<is_ad>::initQpStatefulProperties(); 95 576 : } 96 : 97 : template <bool is_ad> 98 : void 99 0 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::propagateQpStatefulProperties() 100 : { 101 0 : _isotropic_hardening_variable[_qp] = _isotropic_hardening_variable_old[_qp]; 102 0 : _kinematic_hardening_variable[_qp] = _kinematic_hardening_variable_old[_qp]; 103 0 : _plastic_strain[_qp] = _plastic_strain_old[_qp]; 104 : 105 0 : RadialReturnBackstressStressUpdateBaseTempl<is_ad>::propagateQpStatefulPropertiesRadialReturn(); 106 0 : } 107 : 108 : template <bool is_ad> 109 : void 110 1323840 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeStressInitialize( 111 : const GenericReal<is_ad> & effective_trial_stress, 112 : const GenericRankFourTensor<is_ad> & elasticity_tensor) 113 : { 114 0 : RadialReturnBackstressStressUpdateBaseTempl<is_ad>::computeStressInitialize( 115 : effective_trial_stress, elasticity_tensor); 116 : 117 1323840 : computeYieldStress(elasticity_tensor); 118 1323840 : _yield_condition = 119 1323840 : effective_trial_stress - _isotropic_hardening_variable_old[_qp] - _yield_stress; 120 1323840 : _plastic_strain[_qp] = _plastic_strain_old[_qp]; 121 1323840 : } 122 : 123 : template <bool is_ad> 124 : GenericReal<is_ad> 125 3712528 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeResidual( 126 : const GenericReal<is_ad> & effective_trial_stress, const GenericReal<is_ad> & scalar) 127 : { 128 : mooseAssert(_yield_condition != -1.0, 129 : "the yield stress was not updated by computeStressInitialize"); 130 3712528 : if (_yield_condition > 0.0) 131 : { 132 3587824 : _isotropic_hardening_slope = computeIsotropicHardeningDerivative(scalar); 133 3587824 : _isotropic_hardening_variable[_qp] = computeIsotropicHardeningValue(scalar); 134 3587824 : _kinematic_hardening_variable[_qp] = computeKinematicHardeningValue(scalar); 135 3587824 : GenericReal<is_ad> residual = (effective_trial_stress - _kinematic_hardening_variable[_qp] - 136 3587824 : _isotropic_hardening_variable[_qp] - _yield_stress) / 137 3587824 : _three_shear_modulus - 138 : scalar; 139 3587824 : return residual; 140 : } 141 0 : return 0.0; 142 : } 143 : 144 : template <bool is_ad> 145 : GenericReal<is_ad> 146 3712528 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeDerivative( 147 : const GenericReal<is_ad> & /*effective_trial_stress*/, const GenericReal<is_ad> & /*scalar*/) 148 : { 149 3712528 : if (_yield_condition > 0.0) 150 3587824 : return -1.0 - _isotropic_hardening_slope / _three_shear_modulus; 151 0 : return 1.0; 152 : } 153 : 154 : template <bool is_ad> 155 : void 156 2517896 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::iterationFinalize( 157 : const GenericReal<is_ad> & scalar) 158 : { 159 2517896 : if (_yield_condition > 0.0) 160 : { 161 2393192 : _isotropic_hardening_variable[_qp] = computeIsotropicHardeningValue(scalar); 162 2393192 : _kinematic_hardening_variable[_qp] = computeKinematicHardeningValue(scalar); 163 : } 164 2517896 : } 165 : 166 : template <bool is_ad> 167 : void 168 1323840 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeStressFinalize( 169 : const GenericRankTwoTensor<is_ad> & plastic_strain_increment) 170 : { 171 1323840 : _plastic_strain[_qp] += plastic_strain_increment; 172 1323840 : this->_backstress[_qp] = 173 1323840 : this->_backstress_old[_qp] + 174 1323840 : (2.0 / 3.0) * _kinematic_hardening_modulus * plastic_strain_increment - 175 1323840 : _gamma * this->_backstress[_qp] * this->_effective_inelastic_strain_increment; 176 1323840 : } 177 : 178 : template <bool is_ad> 179 : GenericReal<is_ad> 180 5981016 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeIsotropicHardeningValue( 181 : const GenericReal<is_ad> & scalar) 182 : { 183 11962032 : const Real _q = this->template getParam<Real>("q"); 184 11962032 : const Real _b = this->template getParam<Real>("b"); 185 5981016 : if (_isotropic_hardening_function) 186 : { 187 0 : const Real strain_old = this->_effective_inelastic_strain_old[_qp]; 188 0 : return _isotropic_hardening_function->value(strain_old + scalar) - _yield_stress; 189 : } 190 : 191 5981016 : _isotropic_hardening_variable[_qp] = _q * (1.0 - std::exp(-_b * scalar)); 192 : 193 5981016 : return (_isotropic_hardening_variable_old[_qp] + _isotropic_hardening_slope * scalar + 194 5981016 : _b * (_q - _isotropic_hardening_variable_old[_qp]) * 195 5981016 : this->_effective_inelastic_strain_increment); 196 : } 197 : 198 : template <bool is_ad> 199 : GenericReal<is_ad> 200 3587824 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeIsotropicHardeningDerivative( 201 : const GenericReal<is_ad> & /*scalar*/) 202 : { 203 3587824 : if (_isotropic_hardening_function) 204 : { 205 0 : const Real strain_old = this->_effective_inelastic_strain_old[_qp]; 206 0 : return _isotropic_hardening_function->timeDerivative(strain_old); 207 : } 208 3587824 : return _isotropic_hardening_constant; 209 : } 210 : 211 : template <bool is_ad> 212 : GenericReal<is_ad> 213 5981016 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeKinematicHardeningValue( 214 : const GenericReal<is_ad> & scalar) 215 : { 216 5981016 : _kinematic_hardening_variable[_qp] = _kinematic_hardening_modulus * scalar; 217 5981016 : return _kinematic_hardening_variable[_qp]; 218 : } 219 : 220 : template <bool is_ad> 221 : void 222 1323840 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeYieldStress( 223 : const GenericRankFourTensor<is_ad> & /*elasticity_tensor*/) 224 : { 225 1323840 : if (_yield_stress_function) 226 : { 227 0 : static const Moose::GenericType<Point, is_ad> p; 228 0 : _yield_stress = _yield_stress_function->value(_temperature[_qp], p); 229 0 : if (_yield_stress <= 0.0) 230 0 : mooseError("In ", 231 0 : this->_name, 232 : ": The calculated yield stress (", 233 0 : _yield_stress, 234 : ") is less than zero"); 235 : } 236 1323840 : } 237 : 238 : template class CombinedNonlinearHardeningPlasticityTempl<false>; 239 : template class CombinedNonlinearHardeningPlasticityTempl<true>;