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