https://mooseframework.inl.gov
GeneralizedRadialReturnStressUpdate.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 "MooseMesh.h"
13 #include "MooseTypes.h"
14 #include "ElasticityTensorTools.h"
15 #include "libmesh/ignore_warnings.h"
16 #include "Eigen/Dense"
17 #include "Eigen/Eigenvalues"
18 #include "libmesh/restore_warnings.h"
19 
20 template <bool is_ad>
23 {
25  params.addClassDescription("Calculates the effective inelastic strain increment required to "
26  "return the isotropic stress state to a J2 yield surface. This class "
27  "is intended to be a parent class for classes with specific "
28  "constitutive models.");
30  params.addParam<Real>("max_inelastic_increment",
31  1e-4,
32  "The maximum inelastic strain increment allowed in a time step");
33  params.addParam<Real>("max_integration_error",
34  5e-4,
35  "The maximum inelastic strain increment integration error allowed");
36  params.addRequiredParam<std::string>(
37  "effective_inelastic_strain_name",
38  "Name of the material property that stores the effective inelastic strain");
39  params.addRequiredParam<std::string>(
40  "inelastic_strain_rate_name",
41  "Name of the material property that stores the inelastic strain rate");
42  params.addParam<bool>(
43  "use_transformation",
44  true,
45  "Whether to employ updated Hill's tensor due to rigid body or large "
46  "deformation kinematic rotations. If an initial rigid body rotation is provided by the user "
47  "in increments of 90 degrees (e.g. 90, 180, 270), this option can be set to false, in which "
48  "case the Hill's coefficients are extracted from the transformed Hill's tensor.");
49 
50  return params;
51 }
52 template <bool is_ad>
54  const InputParameters & parameters)
55  : StressUpdateBaseTempl<is_ad>(parameters),
56  GeneralizedReturnMappingSolutionTempl<is_ad>(parameters),
57  _effective_inelastic_strain(this->template declareGenericProperty<Real, is_ad>(
58  this->_base_name +
59  this->template getParam<std::string>("effective_inelastic_strain_name"))),
60  _effective_inelastic_strain_old(this->template getMaterialPropertyOld<Real>(
61  this->_base_name +
62  this->template getParam<std::string>("effective_inelastic_strain_name"))),
63  _inelastic_strain_rate(this->template declareProperty<Real>(
64  this->_base_name + this->template getParam<std::string>("inelastic_strain_rate_name"))),
65  _inelastic_strain_rate_old(this->template getMaterialPropertyOld<Real>(
66  this->_base_name + this->template getParam<std::string>("inelastic_strain_rate_name"))),
67  _max_inelastic_increment(this->template getParam<Real>("max_inelastic_increment")),
68  _max_integration_error(this->template getParam<Real>("max_integration_error")),
69  _max_integration_error_time_step(std::numeric_limits<Real>::max()),
70  _use_transformation(this->template getParam<bool>("use_transformation"))
71 {
72 }
73 
74 template <bool is_ad>
75 void
77 {
78  _effective_inelastic_strain[_qp] = 0.0;
79  _inelastic_strain_rate[_qp] = 0.0;
80 }
81 
82 template <bool is_ad>
83 void
85 {
86  _effective_inelastic_strain[_qp] = _effective_inelastic_strain_old[_qp];
87  _inelastic_strain_rate[_qp] = _inelastic_strain_rate_old[_qp];
88 }
89 
90 template <bool is_ad>
91 void
93  GenericRankTwoTensor<is_ad> & elastic_strain_increment,
94  GenericRankTwoTensor<is_ad> & inelastic_strain_increment,
95  const GenericRankTwoTensor<is_ad> & /*rotation_increment*/,
96  GenericRankTwoTensor<is_ad> & stress_new,
97  const RankTwoTensor & stress_old,
98  const GenericRankFourTensor<is_ad> & elasticity_tensor,
99  const RankTwoTensor & /*elastic_strain_old*/,
100  bool /*compute_full_tangent_operator = false*/,
101  RankFourTensor & /*tangent_operator = StressUpdateBaseTempl<is_ad>::_identityTensor*/)
102 {
103  // Prepare initial trial stress for generalized return mapping
104  GenericRankTwoTensor<is_ad> deviatoric_trial_stress = stress_new.deviatoric();
105 
106  GenericDenseVector<is_ad> stress_new_vector(6);
107  stress_new_vector(0) = stress_new(0, 0);
108  stress_new_vector(1) = stress_new(1, 1);
109  stress_new_vector(2) = stress_new(2, 2);
110  stress_new_vector(3) = stress_new(0, 1);
111  stress_new_vector(4) = stress_new(1, 2);
112  stress_new_vector(5) = stress_new(0, 2);
113 
114  GenericDenseVector<is_ad> stress_dev(6);
115  stress_dev(0) = deviatoric_trial_stress(0, 0);
116  stress_dev(1) = deviatoric_trial_stress(1, 1);
117  stress_dev(2) = deviatoric_trial_stress(2, 2);
118  stress_dev(3) = deviatoric_trial_stress(0, 1);
119  stress_dev(4) = deviatoric_trial_stress(1, 2);
120  stress_dev(5) = deviatoric_trial_stress(0, 2);
121 
122  computeStressInitialize(stress_dev, stress_new_vector, elasticity_tensor);
123 
124  // Use Newton iteration to determine a plastic multiplier variable
125  GenericReal<is_ad> delta_gamma = 0.0;
126 
127  // Use Newton iteration to determine the scalar effective inelastic strain increment
128  if (!MooseUtils::absoluteFuzzyEqual(MetaPhysicL::raw_value(stress_dev).l2_norm(), 0.0))
129  {
130  this->returnMappingSolve(stress_dev, stress_new_vector, delta_gamma, this->_console);
131 
132  computeStrainFinalize(inelastic_strain_increment, stress_new, stress_dev, delta_gamma);
133  }
134  else
135  inelastic_strain_increment.zero();
136 
137  elastic_strain_increment -= inelastic_strain_increment;
138 
139  computeStressFinalize(inelastic_strain_increment,
140  delta_gamma,
141  stress_new,
142  stress_dev,
143  stress_old,
145 }
146 
147 template <bool is_ad>
148 Real
150  const GenericDenseVector<is_ad> & /*effective_trial_stress*/,
151  const GenericDenseVector<is_ad> & /*stress_new*/,
152  const GenericReal<is_ad> & /*residual*/,
153  const GenericReal<is_ad> & /*scalar_effective_inelastic_strain*/)
154 {
155  mooseError("GeneralizedRadialReturnStressUpdate::computeReferenceResidual must be implemented "
156  "by child classes");
157 
158  return 0.0;
159 }
160 
161 template <bool is_ad>
164  const GenericDenseVector<is_ad> & /*effective_trial_stress*/) const
165 {
166  return std::numeric_limits<Real>::max();
167 }
168 
169 template <bool is_ad>
170 Real
172 {
173 
174  // Add a new criterion including numerical integration error
175  Real scalar_inelastic_strain_incr = MetaPhysicL::raw_value(_effective_inelastic_strain[_qp]) -
176  _effective_inelastic_strain_old[_qp];
177 
178  if (MooseUtils::absoluteFuzzyEqual(scalar_inelastic_strain_incr, 0.0))
179  return std::numeric_limits<Real>::max();
180 
181  return std::min(_dt * _max_inelastic_increment / scalar_inelastic_strain_incr,
182  computeIntegrationErrorTimeStep());
183 }
184 
185 template <bool is_ad>
186 void
188  std::stringstream * iter_output, const unsigned int total_it)
189 {
190  if (iter_output)
191  {
192  *iter_output << "At element " << _current_elem->id() << " _qp=" << _qp << " Coordinates "
193  << _q_point[_qp] << " block=" << _current_elem->subdomain_id() << '\n';
194  }
196 }
197 
198 template <bool is_ad>
199 bool
201 {
202  AnisotropyMatrixRealBlock A_bottom_left(A.block<3, 3>(0, 3));
203  AnisotropyMatrixRealBlock A_top_right(A.block<3, 3>(3, 0));
204 
205  for (unsigned int index_i = 0; index_i < 3; index_i++)
206  for (unsigned int index_j = 0; index_j < 3; index_j++)
207  if (A_bottom_left(index_i, index_j) != 0 || A_top_right(index_i, index_j) != 0)
208  return false;
209 
210  return true;
211 }
212 
Moose::GenericType< Real, is_ad > GenericReal
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
ADGeneralizedRadialReturnStressUpdate computes the generalized radial return stress increment for ani...
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void mooseError(Args &&... args)
void outputIterationSummary(std::stringstream *iter_output, const unsigned int total_it) override
Output summary information for the convergence history of the model.
Eigen::Matrix< Real, 6, 6 > AnisotropyMatrixReal
void propagateQpStatefulPropertiesRadialReturn()
Propagate the properties pertaining to this intermediate class.
Eigen::Matrix< Real, 3, 3 > AnisotropyMatrixRealBlock
auto raw_value(const Eigen::Map< T > &in)
static InputParameters validParams()
GeneralizedRadialReturnStressUpdateTempl(const InputParameters &parameters)
Moose::GenericType< DenseVector< Real >, is_ad > GenericDenseVector
Moose::GenericType< RankFourTensor, is_ad > GenericRankFourTensor
void addRequiredParam(const std::string &name, const std::string &doc_string)
auto max(const L &left, const R &right)
bool isBlockDiagonal(const AnisotropyMatrixReal &A)
Check if an anisotropic matrix is block diagonal.
Real elasticity_tensor(unsigned int i, unsigned int j, unsigned int k, unsigned int l)
virtual Real computeTimeStepLimit() override
Compute the limiting value of the time step for this material.
StressUpdateBase is a material that is not called by MOOSE because of the compute=false flag set in t...
virtual GenericReal< is_ad > maximumPermissibleValue(const GenericDenseVector< is_ad > &effective_trial_stress) const override
Compute the maximum permissible value of the scalar.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual Real computeReferenceResidual(const GenericDenseVector< is_ad > &effective_trial_stress, const GenericDenseVector< is_ad > &stress_new, const GenericReal< is_ad > &residual, const GenericReal< is_ad > &scalar_effective_inelastic_strain) override
Compute a reference quantity to be used for checking relative convergence.
Base class that provides capability for Newton generalized (anisotropic) return mapping iterations on...
void addClassDescription(const std::string &doc_string)
virtual void updateState(GenericRankTwoTensor< is_ad > &strain_increment, GenericRankTwoTensor< is_ad > &inelastic_strain_increment, const GenericRankTwoTensor< is_ad > &rotation_increment, GenericRankTwoTensor< is_ad > &stress_new, const RankTwoTensor &stress_old, const GenericRankFourTensor< is_ad > &elasticity_tensor, const RankTwoTensor &elastic_strain_old, bool, RankFourTensor &) override
A radial return (J2) mapping method is performed with return mapping iterations.
virtual void outputIterationSummary(std::stringstream *iter_output, const unsigned int total_it)
Output summary information for the convergence history of the model.
Moose::GenericType< RankTwoTensor, is_ad > GenericRankTwoTensor