https://mooseframework.inl.gov
CombinedNonlinearHardeningPlasticity.C
Go to the documentation of this file.
2 #include "Function.h"
6 
9 
10 template <bool is_ad>
13 {
15  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  params.addParam<Real>("q", 0.0, "Saturation value for isotropic hardening (Q in Voce model)");
19  params.addParam<Real>("b", 0.0, "Rate constant for isotropic hardening (b in Voce model)");
20  params.addParam<FunctionName>("yield_stress_function",
21  "Yield stress as a function of temperature");
22  params.addParam<Real>("yield_stress", "The point at which plastic strain begins accumulating");
23  params.addParam<FunctionName>("isotropic_hardening_function",
24  "True stress as a function of plastic strain");
25  params.addParam<Real>("isotropic_hardening_constant", "Isotropic hardening slope");
26  params.addCoupledVar("temperature", 0.0, "Coupled Temperature");
27  params.set<std::string>("effective_inelastic_strain_name") = "effective_plastic_strain";
28  params.addParam<Real>("kinematic_hardening_modulus", 0.0, "Kinematic hardening modulus");
29  params.addParam<Real>(
30  "gamma", 0.0, "The nonlinear hardening parameter (gamma) for back stress evolution");
31 
32  return params;
33 }
34 
35 template <bool is_ad>
37  const InputParameters & parameters)
39  _yield_stress_function(this->isParamValid("yield_stress_function")
40  ? &this->getFunction("yield_stress_function")
41  : nullptr),
42  _yield_stress(this->isParamValid("yield_stress") ? this->template getParam<Real>("yield_stress")
43  : 0),
44  _isotropic_hardening_constant(
45  this->isParamValid("isotropic_hardening_constant")
46  ? this->template getParam<Real>("isotropic_hardening_constant")
47  : 0),
48  _isotropic_hardening_function(this->isParamValid("isotropic_hardening_function")
49  ? &this->getFunction("isotropic_hardening_function")
50  : nullptr),
51  _yield_condition(-1.0), // set to a non-physical value to catch uninitalized yield condition
52  _isotropic_hardening_slope(0.0),
53  _plastic_strain(
54  this->template declareGenericProperty<RankTwoTensor, is_ad>(_base_name + "plastic_strain")),
55  _plastic_strain_old(
56  this->template getMaterialPropertyOld<RankTwoTensor>(_base_name + "plastic_strain")),
57  _kinematic_hardening_modulus(this->template getParam<Real>("kinematic_hardening_modulus")),
58  _gamma(this->template getParam<Real>("gamma")),
59  _q(this->template getParam<Real>("q")),
60  _b(this->template getParam<Real>("b")),
61  _isotropic_hardening_variable(this->template declareGenericProperty<Real, is_ad>(
62  _base_name + "isotropic_hardening_variable")),
63  _isotropic_hardening_variable_old(
64  this->template getMaterialPropertyOld<Real>(_base_name + "isotropic_hardening_variable")),
65  _kinematic_hardening_variable(
66  this->template declareGenericProperty<Real, is_ad>("kinematic_hardening_variable")),
67  _kinematic_hardening_variable_old(
68  this->template getMaterialPropertyOld<Real>("kinematic_hardening_variable")),
69  _temperature(this->template coupledGenericValue<is_ad>("temperature"))
70 {
71  if (parameters.isParamSetByUser("yield_stress") && _yield_stress <= 0.0)
72  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  if (_yield_stress_function == nullptr && !this->isParamValid("yield_stress"))
75  mooseError("Either yield_stress or yield_stress_function must be given");
76  if (!parameters.isParamValid("isotropic_hardening_constant") &&
77  !this->isParamValid("isotropic_hardening_function"))
78  mooseError(
79  "Either isotropic_hardening_constant or isotropic_hardening_function must be defined");
80  if (parameters.isParamSetByUser("isotropic_hardening_constant") &&
81  this->isParamValid("isotropic_hardening_function"))
82  mooseError(
83  "Only the isotropic_hardening_constant or only the isotropic_hardening_function can be "
84  "defined but not both");
85 }
86 
87 template <bool is_ad>
88 void
90 {
91  _isotropic_hardening_variable[_qp] = 0.0;
92  _kinematic_hardening_variable[_qp] = 0.0;
93  _plastic_strain[_qp].zero();
95 }
96 
97 template <bool is_ad>
98 void
100 {
101  _isotropic_hardening_variable[_qp] = _isotropic_hardening_variable_old[_qp];
102  _kinematic_hardening_variable[_qp] = _kinematic_hardening_variable_old[_qp];
103  _plastic_strain[_qp] = _plastic_strain_old[_qp];
104 
106 }
107 
108 template <bool is_ad>
109 void
111  const GenericReal<is_ad> & effective_trial_stress,
112  const GenericRankFourTensor<is_ad> & elasticity_tensor)
113 {
115  effective_trial_stress, elasticity_tensor);
116 
117  computeYieldStress(elasticity_tensor);
118  _yield_condition =
119  effective_trial_stress - _isotropic_hardening_variable_old[_qp] - _yield_stress;
120  _plastic_strain[_qp] = _plastic_strain_old[_qp];
121 }
122 
123 template <bool is_ad>
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  if (_yield_condition > 0.0)
131  {
132  _isotropic_hardening_slope = computeIsotropicHardeningDerivative(scalar);
133  _isotropic_hardening_variable[_qp] = computeIsotropicHardeningValue(scalar);
134  _kinematic_hardening_variable[_qp] = computeKinematicHardeningValue(scalar);
135  GenericReal<is_ad> residual = (effective_trial_stress - _kinematic_hardening_variable[_qp] -
136  _isotropic_hardening_variable[_qp] - _yield_stress) /
137  _three_shear_modulus -
138  scalar;
139  return residual;
140  }
141  return 0.0;
142 }
143 
144 template <bool is_ad>
147  const GenericReal<is_ad> & /*effective_trial_stress*/, const GenericReal<is_ad> & /*scalar*/)
148 {
149  if (_yield_condition > 0.0)
150  return -1.0 - _isotropic_hardening_slope / _three_shear_modulus;
151  return 1.0;
152 }
153 
154 template <bool is_ad>
155 void
157  const GenericReal<is_ad> & scalar)
158 {
159  if (_yield_condition > 0.0)
160  {
161  _isotropic_hardening_variable[_qp] = computeIsotropicHardeningValue(scalar);
162  _kinematic_hardening_variable[_qp] = computeKinematicHardeningValue(scalar);
163  }
164 }
165 
166 template <bool is_ad>
167 void
169  const GenericRankTwoTensor<is_ad> & plastic_strain_increment)
170 {
171  _plastic_strain[_qp] += plastic_strain_increment;
172  this->_backstress[_qp] =
173  this->_backstress_old[_qp] +
174  (2.0 / 3.0) * _kinematic_hardening_modulus * plastic_strain_increment -
175  _gamma * this->_backstress[_qp] * this->_effective_inelastic_strain_increment;
176 }
177 
178 template <bool is_ad>
181  const GenericReal<is_ad> & scalar)
182 {
183  const Real _q = this->template getParam<Real>("q");
184  const Real _b = this->template getParam<Real>("b");
185  if (_isotropic_hardening_function)
186  {
187  const Real strain_old = this->_effective_inelastic_strain_old[_qp];
188  return _isotropic_hardening_function->value(strain_old + scalar) - _yield_stress;
189  }
190 
191  _isotropic_hardening_variable[_qp] = _q * (1.0 - std::exp(-_b * scalar));
192 
193  return (_isotropic_hardening_variable_old[_qp] + _isotropic_hardening_slope * scalar +
194  _b * (_q - _isotropic_hardening_variable_old[_qp]) *
195  this->_effective_inelastic_strain_increment);
196 }
197 
198 template <bool is_ad>
201  const GenericReal<is_ad> & /*scalar*/)
202 {
203  if (_isotropic_hardening_function)
204  {
205  const Real strain_old = this->_effective_inelastic_strain_old[_qp];
206  return _isotropic_hardening_function->timeDerivative(strain_old);
207  }
208  return _isotropic_hardening_constant;
209 }
210 
211 template <bool is_ad>
214  const GenericReal<is_ad> & scalar)
215 {
216  _kinematic_hardening_variable[_qp] = _kinematic_hardening_modulus * scalar;
217  return _kinematic_hardening_variable[_qp];
218 }
219 
220 template <bool is_ad>
221 void
223  const GenericRankFourTensor<is_ad> & /*elasticity_tensor*/)
224 {
225  if (_yield_stress_function)
226  {
227  static const Moose::GenericType<Point, is_ad> p;
228  _yield_stress = _yield_stress_function->value(_temperature[_qp], p);
229  if (_yield_stress <= 0.0)
230  mooseError("In ",
231  this->_name,
232  ": The calculated yield stress (",
233  _yield_stress,
234  ") is less than zero");
235  }
236 }
237 
virtual GenericReal< is_ad > computeResidual(const GenericReal< is_ad > &effective_trial_stress, const GenericReal< is_ad > &scalar) override
Compute the residual for a predicted value of the scalar.
Moose::GenericType< Real, is_ad > GenericReal
virtual GenericReal< is_ad > computeIsotropicHardeningValue(const GenericReal< is_ad > &scalar)
registerMooseObject("SolidMechanicsApp", ADCombinedNonlinearHardeningPlasticity)
CombinedNonlinearHardeningPlasticityTempl(const InputParameters &parameters)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void mooseError(Args &&... args)
virtual void computeStressInitialize(const GenericReal< is_ad > &effective_trial_stress, const GenericRankFourTensor< is_ad > &elasticity_tensor)
Perform any necessary initialization before return mapping iterations.
virtual GenericReal< is_ad > computeKinematicHardeningValue(const GenericReal< is_ad > &scalar)
T & set(const std::string &name, bool quiet_mode=false)
virtual void computeStressFinalize(const GenericRankTwoTensor< is_ad > &plastic_strain_increment) override
Perform any necessary steps to finalize state after return mapping iterations.
virtual void computeStressInitialize(const GenericReal< is_ad > &effective_trial_stress, const GenericRankFourTensor< is_ad > &elasticity_tensor) override
Perform any necessary initialization before return mapping iterations.
Moose::GenericType< RankFourTensor, is_ad > GenericRankFourTensor
typename std::conditional< is_ad, typename ADType< T >::type, T >::type GenericType
bool isParamValid(const std::string &name) const
Real elasticity_tensor(unsigned int i, unsigned int j, unsigned int k, unsigned int l)
virtual void propagateQpStatefulProperties() override
If updateState is not called during a timestep, this will be.
virtual GenericReal< is_ad > computeDerivative(const GenericReal< is_ad > &effective_trial_stress, const GenericReal< is_ad > &scalar) override
Compute the derivative of the residual as a function of the scalar variable.
void addCoupledVar(const std::string &name, const std::string &doc_string)
bool isParamSetByUser(const std::string &name) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void propagateQpStatefulPropertiesRadialReturn()
Propagate the properties pertaining to this intermediate class.
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
const InputParameters & parameters() const
virtual void iterationFinalize(const GenericReal< is_ad > &scalar) override
Finalize internal state variables for a model for a given iteration.
virtual void computeYieldStress(const GenericRankFourTensor< is_ad > &elasticity_tensor)
virtual GenericReal< is_ad > computeIsotropicHardeningDerivative(const GenericReal< is_ad > &scalar)
Moose::GenericType< RankTwoTensor, is_ad > GenericRankTwoTensor
bool isParamValid(const std::string &name) const