https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ComputeCreepPlasticityStress.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
13
14#include "MooseException.h"
15#include "libmesh/int_range.h"
16
18
21{
23 params.addClassDescription("Compute state (stress and internal parameters such as inelastic "
24 "strains and internal parameters) using an Newton process for one "
25 "creep and one plasticity model");
26 params.addRequiredParam<MaterialName>("creep_model",
27 "Creep model that derives from PowerLawCreepStressUpdate.");
28 params.addRequiredParam<MaterialName>(
29 "plasticity_model", "Plasticity model that derives from IsotropicPlasticityStressUpdate.");
30
31 return params;
32}
33
38
39std::vector<MaterialName>
41{
42 std::vector<MaterialName> names = {getParam<MaterialName>("creep_model"),
43 getParam<MaterialName>("plasticity_model")};
44 return names;
45}
46
47void
49{
51
52 if (_models.size() != 2)
53 mooseError("Error in ComputeCreepPlasticityStress: two models are required.");
54
56 if (!_creep_model)
57 mooseError("Model " + getParam<MaterialName>("creep_model") +
58 " is not a compatible creep model in ComputeCreepPlasticityStress.");
59
62 mooseError("Model " + getParam<MaterialName>("plasticity_model") +
63 " is not a compatible plasticity model in ComputeCreepPlasticityStress.");
64}
65
66void
68 RankTwoTensor & combined_inelastic_strain_increment)
69{
71 {
72 _console << std::endl
73 << "iteration output for ComputeCreepPlasticityStress solve:"
74 << " time=" << _t << " int_pt=" << _qp << std::endl;
75 }
76
77 for (const auto i_rmm : index_range(_models))
78 _inelastic_strain_increment[i_rmm].zero();
79
80 elastic_strain_increment = _strain_increment[_qp];
81 computeStress(elastic_strain_increment, _stress[_qp]);
82
83 const RankTwoTensor trial_stress = _stress[_qp];
84 const RankTwoTensor deviatoric_trial_stress = trial_stress.deviatoric();
85 const Real effective_trial_stress =
86 std::sqrt(1.5 * deviatoric_trial_stress.doubleContraction(deviatoric_trial_stress));
87
88 //
89 // First, compute creep response assuming no plasticity
90 //
91 _creep_model->setQp(_qp);
93 0, elastic_strain_increment, _inelastic_strain_increment[0], _consistent_tangent_operator[0]);
95
96 //
97 // Now check the plasticity model.
98 // If no yielding, we are done.
99 //
102 1, elastic_strain_increment, _inelastic_strain_increment[1], _consistent_tangent_operator[1]);
104 const Real yield_condition = _plasticity_model->yieldCondition();
105
106 if (yield_condition > 0.0) // yielding even with maximum creep strain
107 {
108 const Real max_effective_creep_strain_increment = _effective_creep_strain_increment;
109
110 //
111 // Compute plastic response given no creep
112 //
113 elastic_strain_increment = _strain_increment[_qp];
114 _stress[_qp] = trial_stress;
116 elastic_strain_increment,
119 const Real max_effective_plastic_strain_increment =
121
122 //
123 // Reset plasticity model
124 //
125 _plasticity_model->computeStressInitialize(effective_trial_stress, _elasticity_tensor[_qp]);
126
127 //
128 // The residual for the creep law is (creep rate)*dt - (creep strain increment)
129 // We want the creep rate calculation to depend on both creep and plasticity.
130 // Since we send in the total scalar inelastic strain (creep and plasticity), we need to correct
131 // the second term by adding the plastic strain.
132 //
133 Real creep_residual = _creep_model->computeResidual(effective_trial_stress,
136 creep_residual += _effective_plastic_strain_increment;
137
138 //
139 // We want the plasticity resdiual to be (effective_trial_stress - r - yield_stress)/3G - (total
140 // inelastic increment)
141 // The standard residual for plasticity is (effective_trial_stress - r - yield_stress)/3G -
142 // (plasticity strain increment)
143 // Since we send in the plastic inelastic strain (for calculation of r), we must subtract the
144 // creep strain to correct the final term in our desired residual
145 //
146 Real plasticity_residual = _plasticity_model->computeResidual(
147 effective_trial_stress, _effective_plastic_strain_increment);
148 plasticity_residual -= _effective_creep_strain_increment;
149
150 unsigned int counter = 0;
151 Real residual = 0;
152 const Real threeG =
154 const Real reference_residual = effective_trial_stress / threeG;
155
156 do
157 {
158 //
159 // Solve Ax=b where x is the vector of creep and plastic inelastic strains
160 //
161 // x1 => creep
162 // x2 => plasticity
163 //
164 //
165 // A11 (creep,creep)
166 //
167 Real A11 = _creep_model->computeDerivative(effective_trial_stress,
170 //
171 // A12 (creep,plasticity)
172 //
173 Real A12 = A11 + 1.0;
174 //
175 // A21 (plasticity,creep)
176 //
177 Real A21 = -1.0;
178 //
179 // A22 (plasticity,plasticity)
180 //
181 Real A22 = _plasticity_model->computeDerivative(effective_trial_stress,
183
184 Real rhs1 = creep_residual;
185 Real rhs2 = plasticity_residual;
186
187 //
188 // Solve
189 //
190 // A11*a + A21 = 0
191 // A11*a = -A21
192 // a = -A21/A11
193 const Real a = -A21 / A11;
194 A21 = 0;
195 A22 += a * A12;
196 rhs2 += a * rhs1;
197
198 Real x2 = rhs2 / A22;
199 Real x1 = (rhs1 - A12 * x2) / A11;
200
201 while (_effective_creep_strain_increment - x1 < 0)
202 x1 *= 0.5;
204 x2 *= 0.5;
205
206 while (_effective_creep_strain_increment - x1 > max_effective_creep_strain_increment)
207 x1 *= 0.5;
208 while (_effective_plastic_strain_increment - x2 > max_effective_plastic_strain_increment)
209 x2 *= 0.5;
210
211 // This check is to avoid a fpe in the creep law.
212 // Maybe it is better to check for this condition in the creep law
213 if (effective_trial_stress < threeG * (_effective_creep_strain_increment - x1 +
215 {
216 const Real sum =
218 const Real factor = 0.9 * effective_trial_stress / (threeG * sum);
219 const Real cNew = (_effective_creep_strain_increment - x1) * factor;
220 const Real pNew = (_effective_plastic_strain_increment - x2) * factor;
223 }
224
227
228 //
229 // The residual for the creep law is (creep rate)*dt - (creep strain increment)
230 //
231 creep_residual = _creep_model->computeResidual(effective_trial_stress,
234 creep_residual += _effective_plastic_strain_increment;
235 //
236 // The residual for plasticity is (effective_trial_stress - r - yield_stress)/3G - scalar
237 //
238 plasticity_residual = _plasticity_model->computeResidual(effective_trial_stress,
240 plasticity_residual -= _effective_creep_strain_increment;
241
242 residual =
243 std::sqrt(creep_residual * creep_residual + plasticity_residual * plasticity_residual);
244
246 {
247 _console << "stress iteration number = " << counter << "\n relative residual = "
248 << (0 == reference_residual ? 0 : residual / reference_residual)
249 << "\n stress convergence relative tolerance = " << _relative_tolerance
250 << "\n absolute residual = " << residual
251 << "\n creep residual = " << creep_residual
252 << "\n plasticity residual = " << plasticity_residual
253 << "\n creep iteration increment = " << x1
254 << "\n plasticity iteration increment = " << x2
255 << "\n creep scalar strain = " << _effective_creep_strain_increment
256 << "\n plasticity scalar strain = " << _effective_plastic_strain_increment
257 << "\n max creep scalar strain = " << max_effective_creep_strain_increment
258 << "\n max plasticity scalar strain = " << max_effective_plastic_strain_increment
259 << "\n stress convergence absolute tolerance = " << _absolute_tolerance
260 << std::endl;
261 }
262 ++counter;
263 } while (counter < _max_iterations && residual > _absolute_tolerance &&
264 (residual / reference_residual) > _relative_tolerance);
265
266 if (counter == _max_iterations && residual > _absolute_tolerance &&
267 (residual / reference_residual) > _relative_tolerance)
268 {
269 std::stringstream msg;
270 msg << "\n relative residual = "
271 << (0 == reference_residual ? 0 : residual / reference_residual)
272 << "\n stress convergence relative tolerance = " << _relative_tolerance
273 << "\n absolute residual = " << residual << "\n creep residual = " << creep_residual
274 << "\n plasticity residual = " << plasticity_residual
275 << "\n creep scalar strain = " << _effective_creep_strain_increment
276 << "\n plasticity scalar strain = " << _effective_plastic_strain_increment
277 << "\n max creep scalar strain = " << max_effective_creep_strain_increment
278 << "\n max plasticity scalar strain = " << max_effective_plastic_strain_increment
279 << "\n stress convergence absolute tolerance = " << _absolute_tolerance << std::endl;
280
281 throw MooseException("Max stress iteration hit during ComputeCreepPlasticityStress solve! " +
282 _name + msg.str());
283 }
284 }
285 computeInelasticStrainIncrements(effective_trial_stress, deviatoric_trial_stress);
286
288
289 combined_inelastic_strain_increment.zero();
290 for (const auto i_rmm : make_range(_num_models))
291 combined_inelastic_strain_increment += _inelastic_strain_increment[i_rmm];
292
293 if (yield_condition > 0.0)
294 {
295 elastic_strain_increment = _strain_increment[_qp] - combined_inelastic_strain_increment;
296 _stress[_qp] = _elasticity_tensor[_qp] * (elastic_strain_increment + _elastic_strain_old[_qp]);
297
299 }
300 else
301 {
302 // The tangent for creep was called in the initial creep solve.
303
304 // Set the tangent for plasticity to zero
306 }
307
308 if (_fe_problem.currentlyComputingJacobian())
310
311 _material_timestep_limit[_qp] = 0.0;
312 for (const auto i_rmm : make_range(_num_models))
313 _material_timestep_limit[_qp] += 1.0 / _models[i_rmm]->computeTimeStepLimit();
314
315 if (MooseUtils::absoluteFuzzyEqual(_material_timestep_limit[_qp], 0.0))
316 _material_timestep_limit[_qp] = std::numeric_limits<Real>::max();
317 else
319}
320
321void
323 RankTwoTensor & stress)
324{
325 // form the stress, with the check for changed elasticity constants
327 stress = _elasticity_tensor[_qp] * (_elastic_strain_old[_qp] + elastic_strain_increment);
328 else
329 {
330 if (_damage_model)
331 stress = _undamaged_stress_old + _elasticity_tensor[_qp] * elastic_strain_increment;
332 else
333 stress = _stress_old[_qp] + _elasticity_tensor[_qp] * elastic_strain_increment;
334 }
335}
336
337void
339{
340 auto elastic_strain_inc = _strain_increment[_qp] - _inelastic_strain_increment[1];
341
342 RankTwoTensor stress;
343 computeStress(elastic_strain_inc, stress);
344 RankTwoTensor deviatoric_stress = stress.deviatoric();
345 Real effective_stress = std::sqrt(1.5 * deviatoric_stress.doubleContraction(deviatoric_stress));
346
348 effective_stress, _stress[_qp], _consistent_tangent_operator[0]);
349
350 elastic_strain_inc = _strain_increment[_qp] - _inelastic_strain_increment[0];
351
352 computeStress(elastic_strain_inc, stress);
353 deviatoric_stress = stress.deviatoric();
354 effective_stress = std::sqrt(1.5 * deviatoric_stress.doubleContraction(deviatoric_stress));
355
357 effective_stress, _stress[_qp], _consistent_tangent_operator[1]);
358}
359
360void
362 Real effective_trial_stress, const RankTwoTensor & deviatoric_trial_stress)
363{
364 if (!MooseUtils::absoluteFuzzyEqual(effective_trial_stress, 0.0))
365 {
368 deviatoric_trial_stress *
369 (1.5 * _effective_creep_strain_increment / effective_trial_stress);
370 else
372
375 deviatoric_trial_stress *
376 (1.5 * _effective_plastic_strain_increment / effective_trial_stress);
377 else
379 }
380 else
381 {
384 }
385}
386
387void
registerMooseObject("SolidMechanicsApp", ComputeCreepPlasticityStress)
void mooseError(Args &&... args)
ComputeCreepPlasticityStress computes the stress, the consistent tangent operator (or an approximatio...
std::array< RankTwoTensor, 2 > _inelastic_strain_increment
ComputeCreepPlasticityStress(const InputParameters &parameters)
IsotropicPlasticityStressUpdate * _plasticity_model
virtual void updateQpState(RankTwoTensor &elastic_strain_increment, RankTwoTensor &combined_inelastic_strain_increment) override
Given the _strain_increment[_qp], iterate over all of the user-specified recompute materials in order...
PowerLawCreepStressUpdate * _creep_model
void computeInelasticStrainIncrements(Real effective_trial_stress, const RankTwoTensor &deviatoric_trial_stress)
void computeStress(const RankTwoTensor &elastic_strain_increment, RankTwoTensor &stress)
virtual std::vector< MaterialName > getInelasticModelNames() override
const MaterialProperty< RankFourTensor > & _elasticity_tensor
Elasticity tensor material property.
const MaterialProperty< RankTwoTensor > & _stress_old
Old state of the stress tensor material property.
MaterialProperty< RankTwoTensor > & _stress
Stress material property.
ComputeMultipleInelasticStressBase computes the stress, the consistent tangent operator (or an approx...
const MaterialProperty< RankTwoTensor > & _strain_increment
const bool _perform_finite_strain_rotations
after updateQpState, rotate the stress, elastic_strain, inelastic_strain and Jacobian_mult using _rot...
std::vector< StressUpdateBase * > _models
The user supplied list of inelastic models to use in the simulation.
virtual void computeAdmissibleState(unsigned model_number, RankTwoTensor &elastic_strain_increment, RankTwoTensor &inelastic_strain_increment, RankFourTensor &consistent_tangent_operator)
Given a trial stress (_stress[_qp]) and a strain increment (elastic_strain_increment) let the model_n...
DamageBaseTempl< false > * _damage_model
Pointer to the damage model.
const MaterialProperty< RankTwoTensor > & _elastic_strain_old
Strain tensors.
const unsigned int _max_iterations
Input parameters associated with the recompute iteration to return the stress state to the yield surf...
std::vector< RankFourTensor > _consistent_tangent_operator
the consistent tangent operators computed by each plastic model
bool _is_elasticity_tensor_guaranteed_isotropic
is the elasticity tensor guaranteed to be isotropic?
virtual void computeQpJacobianMult()
Using _elasticity_tensor[_qp] and the consistent tangent operators, _consistent_tangent_operator[....
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
This class uses the Discrete material in a radial return isotropic plasticity model.
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 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.
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 > 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.
This class uses the stress update material in a radial return isotropic creep model.
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 void computeStressFinalize(const GenericRankTwoTensor< is_ad > &plastic_strain_increment) override
Perform any necessary steps to finalize state after return mapping iterations.
virtual void resetIncrementalMaterialProperties() override
Reset material properties.
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.
const GenericReal< is_ad > & effectiveInelasticStrainIncrement() const
Current value of scalar inelastic strain.
void computeTangentOperator(Real effective_trial_stress, const RankTwoTensor &stress_new, RankFourTensor &tangent_operator)
Calculate the tangent_operator.
void updateEffectiveInelasticStrainIncrement(const GenericReal< is_ad > &eisi)
void updateEffectiveInelasticStrain(const GenericReal< is_ad > &increment)
T doubleContraction(const RankTwoTensorTempl< T > &a) const
RankTwoTensorTempl< T > deviatoric() const
void setQp(unsigned int qp)
Sets the value of the global variable _qp for inheriting classes.
T getIsotropicShearModulus(const RankFourTensorTempl< T > &elasticity_tensor)
Get the shear modulus for an isotropic elasticity tensor param elasticity_tensor the tensor (must be ...