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 224 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::validParams() 13 : { 14 : InputParameters params = RadialReturnBackstressStressUpdateBaseTempl<is_ad>::validParams(); 15 224 : 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 448 : params.addParam<Real>("q", 0.0, "Saturation value for isotropic hardening (Q in Voce model)"); 19 448 : params.addParam<Real>("b", 0.0, "Rate constant for isotropic hardening (b in Voce model)"); 20 448 : params.addParam<FunctionName>("yield_stress_function", 21 : "Yield stress as a function of temperature"); 22 448 : params.addParam<Real>("yield_stress", "The point at which plastic strain begins accumulating"); 23 448 : params.addParam<FunctionName>("isotropic_hardening_function", 24 : "True stress as a function of plastic strain"); 25 448 : params.addParam<Real>("isotropic_hardening_constant", "Isotropic hardening slope"); 26 448 : params.addCoupledVar("temperature", 0.0, "Coupled Temperature"); 27 224 : params.set<std::string>("effective_inelastic_strain_name") = "effective_plastic_strain"; 28 448 : params.addParam<Real>("kinematic_hardening_modulus", 0.0, "Kinematic hardening modulus"); 29 448 : params.addParam<Real>( 30 448 : "gamma", 0.0, "The nonlinear hardening parameter (gamma) for back stress evolution"); 31 : 32 224 : return params; 33 0 : } 34 : 35 : template <bool is_ad> 36 168 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::CombinedNonlinearHardeningPlasticityTempl( 37 : const InputParameters & parameters) 38 : : RadialReturnBackstressStressUpdateBaseTempl<is_ad>(parameters), 39 504 : _yield_stress_function(this->isParamValid("yield_stress_function") 40 168 : ? &this->getFunction("yield_stress_function") 41 : : nullptr), 42 672 : _yield_stress(this->isParamValid("yield_stress") ? this->template getParam<Real>("yield_stress") 43 : : 0), 44 168 : _isotropic_hardening_constant( 45 168 : this->isParamValid("isotropic_hardening_constant") 46 504 : ? this->template getParam<Real>("isotropic_hardening_constant") 47 : : 0), 48 168 : _isotropic_hardening_function(this->isParamValid("isotropic_hardening_function") 49 168 : ? &this->getFunction("isotropic_hardening_function") 50 : : nullptr), 51 168 : _yield_condition(-1.0), // set to a non-physical value to catch uninitalized yield condition 52 168 : _isotropic_hardening_slope(0.0), 53 168 : _plastic_strain( 54 168 : this->template declareGenericProperty<RankTwoTensor, is_ad>(_base_name + "plastic_strain")), 55 168 : _plastic_strain_old( 56 168 : this->template getMaterialPropertyOld<RankTwoTensor>(_base_name + "plastic_strain")), 57 336 : _kinematic_hardening_modulus(this->template getParam<Real>("kinematic_hardening_modulus")), 58 336 : _gamma(this->template getParam<Real>("gamma")), 59 336 : _q(this->template getParam<Real>("q")), 60 336 : _b(this->template getParam<Real>("b")), 61 336 : _isotropic_hardening_variable(this->template declareGenericProperty<Real, is_ad>( 62 : _base_name + "isotropic_hardening_variable")), 63 168 : _isotropic_hardening_variable_old( 64 168 : this->template getMaterialPropertyOld<Real>(_base_name + "isotropic_hardening_variable")), 65 168 : _kinematic_hardening_variable( 66 168 : this->template declareGenericProperty<Real, is_ad>("kinematic_hardening_variable")), 67 168 : _kinematic_hardening_variable_old( 68 168 : this->template getMaterialPropertyOld<Real>("kinematic_hardening_variable")), 69 504 : _temperature(this->template coupledGenericValue<is_ad>("temperature")) 70 : { 71 336 : 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 672 : if (_yield_stress_function == nullptr && !this->isParamValid("yield_stress")) 75 0 : mooseError("Either yield_stress or yield_stress_function must be given"); 76 336 : if (!parameters.isParamValid("isotropic_hardening_constant") && 77 168 : !this->isParamValid("isotropic_hardening_function")) 78 0 : mooseError( 79 : "Either isotropic_hardening_constant or isotropic_hardening_function must be defined"); 80 336 : if (parameters.isParamSetByUser("isotropic_hardening_constant") && 81 504 : 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 168 : } 86 : 87 : template <bool is_ad> 88 : void 89 720 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::initQpStatefulProperties() 90 : { 91 720 : _isotropic_hardening_variable[_qp] = 0.0; 92 720 : _kinematic_hardening_variable[_qp] = 0.0; 93 720 : _plastic_strain[_qp].zero(); 94 720 : RadialReturnBackstressStressUpdateBaseTempl<is_ad>::initQpStatefulProperties(); 95 720 : } 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 1656376 : 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 1656376 : computeYieldStress(elasticity_tensor); 118 1656376 : _yield_condition = 119 1656376 : effective_trial_stress - _isotropic_hardening_variable_old[_qp] - _yield_stress; 120 1656376 : _plastic_strain[_qp] = _plastic_strain_old[_qp]; 121 1656376 : } 122 : 123 : template <bool is_ad> 124 : GenericReal<is_ad> 125 4645760 : 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 4645760 : if (_yield_condition > 0.0) 131 : { 132 4490059 : _isotropic_hardening_slope = computeIsotropicHardeningDerivative(scalar); 133 4490059 : _isotropic_hardening_variable[_qp] = computeIsotropicHardeningValue(scalar); 134 4490059 : _kinematic_hardening_variable[_qp] = computeKinematicHardeningValue(scalar); 135 4490059 : GenericReal<is_ad> residual = (effective_trial_stress - _kinematic_hardening_variable[_qp] - 136 4490059 : _isotropic_hardening_variable[_qp] - _yield_stress) / 137 4490059 : _three_shear_modulus - 138 : scalar; 139 4490059 : return residual; 140 : } 141 0 : return 0.0; 142 : } 143 : 144 : template <bool is_ad> 145 : GenericReal<is_ad> 146 4645760 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeDerivative( 147 : const GenericReal<is_ad> & /*effective_trial_stress*/, const GenericReal<is_ad> & /*scalar*/) 148 : { 149 4645760 : if (_yield_condition > 0.0) 150 4490059 : return -1.0 - _isotropic_hardening_slope / _three_shear_modulus; 151 0 : return 1.0; 152 : } 153 : 154 : template <bool is_ad> 155 : void 156 3150708 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::iterationFinalize( 157 : const GenericReal<is_ad> & scalar) 158 : { 159 3150708 : if (_yield_condition > 0.0) 160 : { 161 2995007 : _isotropic_hardening_variable[_qp] = computeIsotropicHardeningValue(scalar); 162 2995007 : _kinematic_hardening_variable[_qp] = computeKinematicHardeningValue(scalar); 163 : } 164 3150708 : } 165 : 166 : template <bool is_ad> 167 : void 168 1656376 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeStressFinalize( 169 : const GenericRankTwoTensor<is_ad> & plastic_strain_increment) 170 : { 171 1656376 : _plastic_strain[_qp] += plastic_strain_increment; 172 1656376 : this->_backstress[_qp] = 173 1656376 : this->_backstress_old[_qp] + 174 1656376 : (2.0 / 3.0) * _kinematic_hardening_modulus * plastic_strain_increment - 175 1656376 : _gamma * this->_backstress[_qp] * this->_effective_inelastic_strain_increment; 176 1656376 : } 177 : 178 : template <bool is_ad> 179 : GenericReal<is_ad> 180 7485066 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeIsotropicHardeningValue( 181 : const GenericReal<is_ad> & scalar) 182 : { 183 14970132 : const Real _q = this->template getParam<Real>("q"); 184 14970132 : const Real _b = this->template getParam<Real>("b"); 185 7485066 : 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 7485066 : _isotropic_hardening_variable[_qp] = _q * (1.0 - std::exp(-_b * scalar)); 192 : 193 7485066 : return (_isotropic_hardening_variable_old[_qp] + _isotropic_hardening_slope * scalar + 194 7485066 : _b * (_q - _isotropic_hardening_variable_old[_qp]) * 195 7485066 : this->_effective_inelastic_strain_increment); 196 : } 197 : 198 : template <bool is_ad> 199 : GenericReal<is_ad> 200 4490059 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeIsotropicHardeningDerivative( 201 : const GenericReal<is_ad> & /*scalar*/) 202 : { 203 4490059 : 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 4490059 : return _isotropic_hardening_constant; 209 : } 210 : 211 : template <bool is_ad> 212 : GenericReal<is_ad> 213 7485066 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeKinematicHardeningValue( 214 : const GenericReal<is_ad> & scalar) 215 : { 216 7485066 : _kinematic_hardening_variable[_qp] = _kinematic_hardening_modulus * scalar; 217 7485066 : return _kinematic_hardening_variable[_qp]; 218 : } 219 : 220 : template <bool is_ad> 221 : void 222 1656376 : CombinedNonlinearHardeningPlasticityTempl<is_ad>::computeYieldStress( 223 : const GenericRankFourTensor<is_ad> & /*elasticity_tensor*/) 224 : { 225 1656376 : 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 1656376 : } 237 : 238 : template class CombinedNonlinearHardeningPlasticityTempl<false>; 239 : template class CombinedNonlinearHardeningPlasticityTempl<true>;