https://mooseframework.inl.gov
Loading...
Searching...
No Matches
CombinedNonlinearHardeningPlasticity.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
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
11#include "Function.h"
15
18
19template <bool is_ad>
22{
24 params.addClassDescription("Combined isotropic and kinematic plasticity model with nonlinear "
25 "hardening rules, including a Voce model for isotropic hardening and "
26 "an Armstrong-Fredrick model for kinematic hardening.");
27 params.addParam<Real>("q", 0.0, "Saturation value for isotropic hardening (Q in Voce model)");
28 params.addParam<Real>("b", 0.0, "Rate constant for isotropic hardening (b in Voce model)");
29 params.addParam<FunctionName>("yield_stress_function",
30 "Yield stress as a function of temperature");
31 params.addParam<Real>("yield_stress", "The point at which plastic strain begins accumulating");
32 params.addParam<FunctionName>("isotropic_hardening_function",
33 "True stress as a function of plastic strain");
34 params.addParam<Real>("isotropic_hardening_constant", "Isotropic hardening slope");
35 params.addCoupledVar("temperature", 0.0, "Coupled Temperature");
36 params.set<std::string>("effective_inelastic_strain_name") = "effective_plastic_strain";
37 params.addParam<Real>("kinematic_hardening_modulus", 0.0, "Kinematic hardening modulus");
38 params.addParam<Real>(
39 "gamma", 0.0, "The nonlinear hardening parameter (gamma) for back stress evolution");
40
41 return params;
42}
43
44template <bool is_ad>
46 const InputParameters & parameters)
48 _yield_stress_function(this->isParamValid("yield_stress_function")
49 ? &this->getFunction("yield_stress_function")
50 : nullptr),
51 _yield_stress(this->isParamValid("yield_stress") ? this->template getParam<Real>("yield_stress")
52 : 0),
53 _isotropic_hardening_constant(
54 this->isParamValid("isotropic_hardening_constant")
55 ? this->template getParam<Real>("isotropic_hardening_constant")
56 : 0),
57 _isotropic_hardening_function(this->isParamValid("isotropic_hardening_function")
58 ? &this->getFunction("isotropic_hardening_function")
59 : nullptr),
60 _yield_condition(-1.0), // set to a non-physical value to catch uninitalized yield condition
61 _isotropic_hardening_slope(0.0),
62 _plastic_strain(
63 this->template declareGenericProperty<RankTwoTensor, is_ad>(_base_name + "plastic_strain")),
64 _plastic_strain_old(
65 this->template getMaterialPropertyOld<RankTwoTensor>(_base_name + "plastic_strain")),
66 _kinematic_hardening_modulus(this->template getParam<Real>("kinematic_hardening_modulus")),
67 _gamma(this->template getParam<Real>("gamma")),
68 _q(this->template getParam<Real>("q")),
69 _b(this->template getParam<Real>("b")),
70 _isotropic_hardening_variable(this->template declareGenericProperty<Real, is_ad>(
71 _base_name + "isotropic_hardening_variable")),
72 _isotropic_hardening_variable_old(
73 this->template getMaterialPropertyOld<Real>(_base_name + "isotropic_hardening_variable")),
74 _kinematic_hardening_variable(
75 this->template declareGenericProperty<Real, is_ad>("kinematic_hardening_variable")),
76 _kinematic_hardening_variable_old(
77 this->template getMaterialPropertyOld<Real>("kinematic_hardening_variable")),
78 _temperature(this->template coupledGenericValue<is_ad>("temperature"))
79{
80 if (parameters.isParamSetByUser("yield_stress") && _yield_stress <= 0.0)
81 mooseError("Yield stress must be greater than zero");
82 // Both of these parameters are given default values by derived classes, which makes them valid
83 if (_yield_stress_function == nullptr && !this->isParamValid("yield_stress"))
84 mooseError("Either yield_stress or yield_stress_function must be given");
85 if (!parameters.isParamValid("isotropic_hardening_constant") &&
86 !this->isParamValid("isotropic_hardening_function"))
88 "Either isotropic_hardening_constant or isotropic_hardening_function must be defined");
89 if (parameters.isParamSetByUser("isotropic_hardening_constant") &&
90 this->isParamValid("isotropic_hardening_function"))
92 "Only the isotropic_hardening_constant or only the isotropic_hardening_function can be "
93 "defined but not both");
94}
95
96template <bool is_ad>
97void
99{
100 _isotropic_hardening_variable[_qp] = 0.0;
101 _kinematic_hardening_variable[_qp] = 0.0;
102 _plastic_strain[_qp].zero();
104}
105
106template <bool is_ad>
107void
109{
110 _isotropic_hardening_variable[_qp] = _isotropic_hardening_variable_old[_qp];
111 _kinematic_hardening_variable[_qp] = _kinematic_hardening_variable_old[_qp];
112 _plastic_strain[_qp] = _plastic_strain_old[_qp];
113
115}
116
117template <bool is_ad>
118void
120 const GenericReal<is_ad> & effective_trial_stress,
121 const GenericRankFourTensor<is_ad> & elasticity_tensor)
122{
124 effective_trial_stress, elasticity_tensor);
125
126 computeYieldStress(elasticity_tensor);
127 _yield_condition =
128 effective_trial_stress - _isotropic_hardening_variable_old[_qp] - _yield_stress;
129 _plastic_strain[_qp] = _plastic_strain_old[_qp];
130}
131
132template <bool is_ad>
135 const GenericReal<is_ad> & effective_trial_stress, const GenericReal<is_ad> & scalar)
136{
137 mooseAssert(_yield_condition != -1.0,
138 "the yield stress was not updated by computeStressInitialize");
139 if (_yield_condition > 0.0)
140 {
141 _isotropic_hardening_slope = computeIsotropicHardeningDerivative(scalar);
142 _isotropic_hardening_variable[_qp] = computeIsotropicHardeningValue(scalar);
143 _kinematic_hardening_variable[_qp] = computeKinematicHardeningValue(scalar);
144 GenericReal<is_ad> residual = (effective_trial_stress - _kinematic_hardening_variable[_qp] -
145 _isotropic_hardening_variable[_qp] - _yield_stress) /
146 _three_shear_modulus -
147 scalar;
148 return residual;
149 }
150 return 0.0;
151}
152
153template <bool is_ad>
156 const GenericReal<is_ad> & /*effective_trial_stress*/, const GenericReal<is_ad> & /*scalar*/)
157{
158 if (_yield_condition > 0.0)
159 return -1.0 - _isotropic_hardening_slope / _three_shear_modulus;
160 return 1.0;
161}
162
163template <bool is_ad>
164void
166 const GenericReal<is_ad> & scalar)
167{
168 if (_yield_condition > 0.0)
169 {
170 _isotropic_hardening_variable[_qp] = computeIsotropicHardeningValue(scalar);
171 _kinematic_hardening_variable[_qp] = computeKinematicHardeningValue(scalar);
172 }
173}
174
175template <bool is_ad>
176void
178 const GenericRankTwoTensor<is_ad> & plastic_strain_increment)
179{
180 _plastic_strain[_qp] += plastic_strain_increment;
181 this->_backstress[_qp] =
182 this->_backstress_old[_qp] +
183 (2.0 / 3.0) * _kinematic_hardening_modulus * plastic_strain_increment -
184 _gamma * this->_backstress[_qp] * this->_effective_inelastic_strain_increment;
185}
186
187template <bool is_ad>
190 const GenericReal<is_ad> & scalar)
191{
192 using std::exp;
193
194 const Real _q = this->template getParam<Real>("q");
195 const Real _b = this->template getParam<Real>("b");
196 if (_isotropic_hardening_function)
197 {
198 const Real strain_old = this->_effective_inelastic_strain_old[_qp];
199 return _isotropic_hardening_function->value(strain_old + scalar) - _yield_stress;
200 }
201
202 _isotropic_hardening_variable[_qp] = _q * (1.0 - exp(-_b * scalar));
203
204 return (_isotropic_hardening_variable_old[_qp] + _isotropic_hardening_slope * scalar +
205 _b * (_q - _isotropic_hardening_variable_old[_qp]) *
206 this->_effective_inelastic_strain_increment);
207}
208
209template <bool is_ad>
212 const GenericReal<is_ad> & /*scalar*/)
213{
214 if (_isotropic_hardening_function)
215 {
216 const Real strain_old = this->_effective_inelastic_strain_old[_qp];
217 return _isotropic_hardening_function->timeDerivative(strain_old);
218 }
219 return _isotropic_hardening_constant;
220}
221
222template <bool is_ad>
225 const GenericReal<is_ad> & scalar)
226{
227 _kinematic_hardening_variable[_qp] = _kinematic_hardening_modulus * scalar;
228 return _kinematic_hardening_variable[_qp];
229}
230
231template <bool is_ad>
232void
234 const GenericRankFourTensor<is_ad> & /*elasticity_tensor*/)
235{
236 if (_yield_stress_function)
237 {
239 _yield_stress = _yield_stress_function->value(_temperature[_qp], p);
240 if (_yield_stress <= 0.0)
241 mooseError("In ",
242 this->_name,
243 ": The calculated yield stress (",
244 _yield_stress,
245 ") is less than zero");
246 }
247}
248
registerMooseObject("SolidMechanicsApp", ADCombinedNonlinearHardeningPlasticity)
const Real p
void mooseError(Args &&... args)
Moose::GenericType< RankFourTensor, is_ad > GenericRankFourTensor
Moose::GenericType< Real, is_ad > GenericReal
Moose::GenericType< RankTwoTensor, is_ad > GenericRankTwoTensor
virtual void iterationFinalize(const GenericReal< is_ad > &scalar) override
Finalize internal state variables for a model for a given iteration.
virtual GenericReal< is_ad > computeKinematicHardeningValue(const GenericReal< is_ad > &scalar)
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.
virtual void propagateQpStatefulProperties() override
If updateState is not called during a timestep, this will be.
virtual GenericReal< is_ad > computeIsotropicHardeningDerivative(const GenericReal< is_ad > &scalar)
CombinedNonlinearHardeningPlasticityTempl(const InputParameters &parameters)
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.
virtual GenericReal< is_ad > computeIsotropicHardeningValue(const GenericReal< is_ad > &scalar)
virtual void computeYieldStress(const GenericRankFourTensor< is_ad > &elasticity_tensor)
virtual void computeStressFinalize(const GenericRankTwoTensor< is_ad > &plastic_strain_increment) override
Perform any necessary steps to finalize state after return mapping iterations.
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.
bool isParamSetByUser(const std::string &name) const
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
T & set(const std::string &name, bool quiet_mode=false)
void addCoupledVar(const std::string &name, const std::string &doc_string)
bool isParamValid(const std::string &name) const
const InputParameters & parameters() const
void mooseError(Args &&... args) const
bool isParamValid(const std::string &name) const
void propagateQpStatefulPropertiesRadialReturn()
Propagate the properties pertaining to this intermediate class.
virtual void computeStressInitialize(const GenericReal< is_ad > &effective_trial_stress, const GenericRankFourTensor< is_ad > &elasticity_tensor)
Perform any necessary initialization before return mapping iterations.
typename std::conditional< is_ad, typename ADType< T >::type, T >::type GenericType
Real elasticity_tensor(unsigned int i, unsigned int j, unsigned int k, unsigned int l)