https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ComputeMultipleInelasticStress.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
12#include "StressUpdateBase.h"
13#include "MooseException.h"
14#include "DamageBase.h"
15#include "libmesh/int_range.h"
16
18
21{
23 params.addRequiredParam<std::vector<MaterialName>>(
24 "inelastic_models",
25 "The material objects to use to calculate stress and inelastic strains. "
26 "Note: specify creep models first and plasticity models second.");
27 return params;
28}
29
34
35std::vector<MaterialName>
37{
38 return getParam<std::vector<MaterialName>>("inelastic_models");
39}
40
41void
43 RankTwoTensor & combined_inelastic_strain_increment)
44{
46 {
47 _console << std::endl
48 << "iteration output for ComputeMultipleInelasticStress solve:"
49 << " time=" << _t << " int_pt=" << _qp << std::endl;
50 }
51 Real l2norm_delta_stress;
52 Real first_l2norm_delta_stress = 1.0;
53 unsigned int counter = 0;
54
55 std::vector<RankTwoTensor> inelastic_strain_increment;
56 inelastic_strain_increment.resize(_num_models);
57
58 for (const auto i_rmm : index_range(_models))
59 inelastic_strain_increment[i_rmm].zero();
60
61 RankTwoTensor stress_max, stress_min;
62
63 do
64 {
65 for (const auto i_rmm : index_range(_models))
66 {
67 _models[i_rmm]->setQp(_qp);
68
69 // initially assume the strain is completely elastic
70 elastic_strain_increment = _strain_increment[_qp];
71 // and subtract off all inelastic strain increments calculated so far
72 // except the one that we're about to calculate
73 for (const auto j_rmm : make_range(_num_models))
74 if (i_rmm != j_rmm)
75 elastic_strain_increment -= inelastic_strain_increment[j_rmm];
76
77 // form the trial stress, with the check for changed elasticity constants
79 _stress[_qp] =
80 _elasticity_tensor[_qp] * (_elastic_strain_old[_qp] + elastic_strain_increment);
81 else
82 {
83 if (_damage_model)
84 _stress[_qp] = _undamaged_stress_old + _elasticity_tensor[_qp] * elastic_strain_increment;
85 else
86 _stress[_qp] = _stress_old[_qp] + _elasticity_tensor[_qp] * elastic_strain_increment;
87 }
88
89 // given a trial stress (_stress[_qp]) and a strain increment (elastic_strain_increment)
90 // let the i^th model produce an admissible stress (as _stress[_qp]), and decompose
91 // the strain increment into an elastic part (elastic_strain_increment) and an
92 // inelastic part (inelastic_strain_increment[i_rmm])
94 elastic_strain_increment,
95 inelastic_strain_increment[i_rmm],
97
98 if (i_rmm == 0)
99 {
100 stress_max = _stress[_qp];
101 stress_min = _stress[_qp];
102 }
103 else
104 {
105 for (const auto i : make_range(Moose::dim))
106 for (const auto j : make_range(Moose::dim))
107 if (_stress[_qp](i, j) > stress_max(i, j))
108 stress_max(i, j) = _stress[_qp](i, j);
109 else if (stress_min(i, j) > _stress[_qp](i, j))
110 stress_min(i, j) = _stress[_qp](i, j);
111 }
112 }
113
114 // now check convergence in the stress:
115 // once the change in stress is within tolerance after each recompute material
116 // consider the stress to be converged
117 l2norm_delta_stress = (stress_max - stress_min).L2norm();
118 if (counter == 0 && l2norm_delta_stress > 0.0)
119 first_l2norm_delta_stress = l2norm_delta_stress;
120
122 {
123 _console << "stress iteration number = " << counter << "\n"
124 << " relative l2 norm delta stress = "
125 << (0 == first_l2norm_delta_stress ? 0
126 : l2norm_delta_stress / first_l2norm_delta_stress)
127 << "\n"
128 << " stress convergence relative tolerance = " << _relative_tolerance << "\n"
129 << " absolute l2 norm delta stress = " << l2norm_delta_stress << "\n"
130 << " stress convergence absolute tolerance = " << _absolute_tolerance << std::endl;
131 }
132 ++counter;
133 } while (counter < _max_iterations && l2norm_delta_stress > _absolute_tolerance &&
134 (l2norm_delta_stress / first_l2norm_delta_stress) > _relative_tolerance &&
135 _num_models != 1);
136
137 if (counter == _max_iterations && l2norm_delta_stress > _absolute_tolerance &&
138 (l2norm_delta_stress / first_l2norm_delta_stress) > _relative_tolerance)
139 throw MooseException("Max stress iteration hit during ComputeMultipleInelasticStress solve!");
140
141 combined_inelastic_strain_increment.zero();
142 for (const auto i_rmm : make_range(_num_models))
143 combined_inelastic_strain_increment +=
144 _inelastic_weights[i_rmm] * inelastic_strain_increment[i_rmm];
145
146 if (_fe_problem.currentlyComputingJacobian())
148
149 _material_timestep_limit[_qp] = 0.0;
150 for (const auto i_rmm : make_range(_num_models))
151 _material_timestep_limit[_qp] += 1.0 / _models[i_rmm]->computeTimeStepLimit();
152
153 if (MooseUtils::absoluteFuzzyEqual(_material_timestep_limit[_qp], 0.0))
154 _material_timestep_limit[_qp] = std::numeric_limits<Real>::max();
155 else
157}
registerMooseObject("SolidMechanicsApp", ComputeMultipleInelasticStress)
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< Real > _inelastic_weights
_inelastic_strain = sum_i (_inelastic_weights_i * inelastic_strain_from_model_i)
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[....
ComputeMultipleInelasticStress computes the stress, the consistent tangent operator (or an approximat...
virtual std::vector< MaterialName > getInelasticModelNames() override
ComputeMultipleInelasticStress(const InputParameters &parameters)
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...
void addRequiredParam(const std::string &name, const std::string &doc_string)
static constexpr std::size_t dim