https://mooseframework.inl.gov
SolidMechanicsPlasticJ2.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 "RankFourTensor.h"
12 
13 registerMooseObject("SolidMechanicsApp", SolidMechanicsPlasticJ2);
14 registerMooseObjectRenamed("SolidMechanicsApp",
15  TensorMechanicsPlasticJ2,
16  "01/01/2025 00:00",
18 
21 {
23  params.addRequiredParam<UserObjectName>(
24  "yield_strength",
25  "A SolidMechanicsHardening UserObject that defines hardening of the yield strength");
26  params.addRangeCheckedParam<unsigned>(
27  "max_iterations", 10, "max_iterations>0", "Maximum iterations for custom J2 return map");
28  params.addParam<bool>("use_custom_returnMap",
29  true,
30  "Whether to use the custom returnMap "
31  "algorithm. Set to true if you are using "
32  "isotropic elasticity.");
33  params.addParam<bool>("use_custom_cto",
34  true,
35  "Whether to use the custom consistent tangent "
36  "operator computations. Set to true if you are "
37  "using isotropic elasticity.");
38  params.addClassDescription("J2 plasticity, associative, with hardening");
39 
40  return params;
41 }
42 
44  : SolidMechanicsPlasticModel(parameters),
45  _strength(getUserObject<SolidMechanicsHardeningModel>("yield_strength")),
46  _max_iters(getParam<unsigned>("max_iterations")),
47  _use_custom_returnMap(getParam<bool>("use_custom_returnMap")),
48  _use_custom_cto(getParam<bool>("use_custom_cto"))
49 {
50 }
51 
52 Real
53 SolidMechanicsPlasticJ2::yieldFunction(const RankTwoTensor & stress, Real intnl) const
54 {
55  return std::sqrt(3.0 * stress.secondInvariant()) - yieldStrength(intnl);
56 }
57 
60 {
61  Real sII = stress.secondInvariant();
62  if (sII == 0.0)
63  return RankTwoTensor();
64  else
65  return 0.5 * std::sqrt(3.0 / sII) * stress.dsecondInvariant();
66 }
67 
68 Real
70 {
71  return -dyieldStrength(intnl);
72 }
73 
75 SolidMechanicsPlasticJ2::flowPotential(const RankTwoTensor & stress, Real intnl) const
76 {
77  return dyieldFunction_dstress(stress, intnl);
78 }
79 
82 {
83  Real sII = stress.secondInvariant();
84  if (sII == 0)
85  return RankFourTensor();
86 
87  RankFourTensor dfp = 0.5 * std::sqrt(3.0 / sII) * stress.d2secondInvariant();
88  Real pre = -0.25 * std::sqrt(3.0) * std::pow(sII, -1.5);
89  RankTwoTensor dII = stress.dsecondInvariant();
90  for (unsigned i = 0; i < 3; ++i)
91  for (unsigned j = 0; j < 3; ++j)
92  for (unsigned k = 0; k < 3; ++k)
93  for (unsigned l = 0; l < 3; ++l)
94  dfp(i, j, k, l) += pre * dII(i, j) * dII(k, l);
95  return dfp;
96 }
97 
100  Real /*intnl*/) const
101 {
102  return RankTwoTensor();
103 }
104 
105 Real
107 {
108  return _strength.value(intnl);
109 }
110 
111 Real
113 {
114  return _strength.derivative(intnl);
115 }
116 
117 std::string
119 {
120  return "J2";
121 }
122 
123 bool
125  Real intnl_old,
126  const RankFourTensor & E_ijkl,
127  Real ep_plastic_tolerance,
128  RankTwoTensor & returned_stress,
129  Real & returned_intnl,
130  std::vector<Real> & dpm,
131  RankTwoTensor & delta_dp,
132  std::vector<Real> & yf,
133  bool & trial_stress_inadmissible) const
134 {
135  if (!(_use_custom_returnMap))
136  return SolidMechanicsPlasticModel::returnMap(trial_stress,
137  intnl_old,
138  E_ijkl,
139  ep_plastic_tolerance,
140  returned_stress,
141  returned_intnl,
142  dpm,
143  delta_dp,
144  yf,
145  trial_stress_inadmissible);
146 
147  yf.resize(1);
148 
149  Real yf_orig = yieldFunction(trial_stress, intnl_old);
150 
151  yf[0] = yf_orig;
152 
153  if (yf_orig < _f_tol)
154  {
155  // the trial_stress is admissible
156  trial_stress_inadmissible = false;
157  return true;
158  }
159 
160  trial_stress_inadmissible = true;
161  Real mu = E_ijkl(0, 1, 0, 1);
162 
163  // Perform a Newton-Raphson to find dpm when
164  // residual = 3*mu*dpm - trial_equivalent_stress + yieldStrength(intnl_old + dpm) = 0
165  Real trial_equivalent_stress = yf_orig + yieldStrength(intnl_old);
166  Real residual;
167  Real jac;
168  dpm[0] = 0;
169  unsigned int iter = 0;
170  do
171  {
172  residual = 3.0 * mu * dpm[0] - trial_equivalent_stress + yieldStrength(intnl_old + dpm[0]);
173  jac = 3.0 * mu + dyieldStrength(intnl_old + dpm[0]);
174  dpm[0] += -residual / jac;
175  if (iter > _max_iters) // not converging
176  return false;
177  iter++;
178  } while (residual * residual > _f_tol * _f_tol);
179 
180  // set the returned values
181  yf[0] = 0;
182  returned_intnl = intnl_old + dpm[0];
183  RankTwoTensor nn = 1.5 * trial_stress.deviatoric() /
184  trial_equivalent_stress; // = dyieldFunction_dstress(trial_stress, intnl_old) =
185  // the normal to the yield surface, at the trial
186  // stress
187  returned_stress = 2.0 / 3.0 * nn * yieldStrength(returned_intnl);
188  returned_stress.addIa(1.0 / 3.0 * trial_stress.trace());
189  delta_dp = nn * dpm[0];
190 
191  return true;
192 }
193 
196  Real intnl_old,
197  const RankTwoTensor & stress,
198  Real intnl,
199  const RankFourTensor & E_ijkl,
200  const std::vector<Real> & cumulative_pm) const
201 {
202  if (!_use_custom_cto)
204  trial_stress, intnl_old, stress, intnl, E_ijkl, cumulative_pm);
205 
206  Real mu = E_ijkl(0, 1, 0, 1);
207 
208  Real h = 3 * mu + dyieldStrength(intnl);
209  RankTwoTensor sij = stress.deviatoric();
210  Real sII = stress.secondInvariant();
211  Real equivalent_stress = std::sqrt(3.0 * sII);
212  Real zeta = cumulative_pm[0] / (1.0 + 3.0 * mu * cumulative_pm[0] / equivalent_stress);
213 
214  return E_ijkl - 3.0 * mu * mu / sII / h * sij.outerProduct(sij) -
215  4.0 * mu * mu * zeta * dflowPotential_dstress(stress, intnl);
216 }
217 
218 bool
220 {
221  return _use_custom_returnMap;
222 }
223 
224 bool
226 {
227  return _use_custom_cto;
228 }
RankFourTensorTempl< Real > outerProduct(const RankTwoTensorTempl< Real > &b) const
RankTwoTensorTempl< Real > dsecondInvariant() const
RankFourTensorTempl< Real > d2secondInvariant() const
virtual RankFourTensor consistentTangentOperator(const RankTwoTensor &trial_stress, Real intnl_old, const RankTwoTensor &stress, Real intnl, const RankFourTensor &E_ijkl, const std::vector< Real > &cumulative_pm) const override
Calculates a custom consistent tangent operator.
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
registerMooseObject("SolidMechanicsApp", SolidMechanicsPlasticJ2)
registerMooseObjectRenamed("SolidMechanicsApp", TensorMechanicsPlasticJ2, "01/01/2025 00:00", SolidMechanicsPlasticJ2)
const SolidMechanicsHardeningModel & _strength
yield strength, from user input
static InputParameters validParams()
virtual RankFourTensor consistentTangentOperator(const RankTwoTensor &trial_stress, Real intnl_old, const RankTwoTensor &stress, Real intnl, const RankFourTensor &E_ijkl, const std::vector< Real > &cumulative_pm) const
Calculates a custom consistent tangent operator.
const unsigned _max_iters
max iters for custom return map loop
virtual Real value(Real intnl) const
void addRequiredParam(const std::string &name, const std::string &doc_string)
virtual Real yieldFunction(const RankTwoTensor &stress, Real intnl) const override
The following functions are what you should override when building single-plasticity models...
virtual Real dyieldStrength(Real intnl) const
d(yieldStrength)/d(intnl)
RankTwoTensorTempl< Real > deviatoric() const
J2 plasticity, associative, with hardning.
virtual RankFourTensor dflowPotential_dstress(const RankTwoTensor &stress, Real intnl) const override
The derivative of the flow potential with respect to stress.
static InputParameters validParams()
static const std::string mu
Definition: NS.h:123
void addIa(const Real &a)
virtual bool returnMap(const RankTwoTensor &trial_stress, Real intnl_old, const RankFourTensor &E_ijkl, Real ep_plastic_tolerance, RankTwoTensor &returned_stress, Real &returned_intnl, std::vector< Real > &dpm, RankTwoTensor &delta_dp, std::vector< Real > &yf, bool &trial_stress_inadmissible) const
Performs a custom return-map.
virtual bool returnMap(const RankTwoTensor &trial_stress, Real intnl_old, const RankFourTensor &E_ijkl, Real ep_plastic_tolerance, RankTwoTensor &returned_stress, Real &returned_intnl, std::vector< Real > &dpm, RankTwoTensor &delta_dp, std::vector< Real > &yf, bool &trial_stress_inadmissible) const override
Performs a custom return-map.
Real dyieldFunction_dintnl(const RankTwoTensor &stress, Real intnl) const override
The derivative of yield function with respect to the internal parameter.
SolidMechanicsPlasticJ2(const InputParameters &parameters)
virtual Real yieldStrength(Real intnl) const
YieldStrength.
const Real _f_tol
Tolerance on yield function.
const bool _use_custom_cto
Whether to use the custom consistent tangent operator calculation.
virtual Real derivative(Real intnl) const
virtual std::string modelName() const override
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const bool _use_custom_returnMap
Whether to use the custom return-map algorithm.
virtual RankTwoTensor dyieldFunction_dstress(const RankTwoTensor &stress, Real intnl) const override
The derivative of yield function with respect to stress.
virtual bool useCustomCTO() const override
Returns false. You will want to override this in your derived class if you write a custom consistent ...
void addClassDescription(const std::string &doc_string)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
Plastic Model base class The virtual functions written below must be over-ridden in derived classes t...
MooseUnits pow(const MooseUnits &, int)
static const std::string k
Definition: NS.h:130
virtual RankTwoTensor flowPotential(const RankTwoTensor &stress, Real intnl) const override
The flow potential.
RankTwoTensor dflowPotential_dintnl(const RankTwoTensor &stress, Real intnl) const override
The derivative of the flow potential with respect to the internal parameter.
virtual bool useCustomReturnMap() const override
Returns false. You will want to override this in your derived class if you write a custom returnMap f...