https://mooseframework.inl.gov
SolidMechanicsPlasticDruckerPragerHyperbolic.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 #include "libmesh/utility.h"
13 
15 registerMooseObjectRenamed("SolidMechanicsApp",
16  TensorMechanicsPlasticDruckerPragerHyperbolic,
17  "01/01/2025 00:00",
19 
22 {
24  params.addParam<bool>("use_custom_returnMap",
25  true,
26  "Whether to use the custom returnMap "
27  "algorithm. Set to true if you are using "
28  "isotropic elasticity.");
29  params.addParam<bool>("use_custom_cto",
30  true,
31  "Whether to use the custom consistent tangent "
32  "operator computations. Set to true if you are "
33  "using isotropic elasticity.");
34  params.addClassDescription("J2 plasticity, associative, with hardening");
35  params.addRangeCheckedParam<Real>("smoother",
36  0.0,
37  "smoother>=0",
38  "The cone vertex at J2=0 is smoothed. The maximum mean "
39  "stress possible, which is Cohesion*Cot(friction_angle) for "
40  "smoother=0, becomes (Cohesion - "
41  "smoother/3)*Cot(friction_angle). This is a non-hardening "
42  "parameter");
43  params.addRangeCheckedParam<unsigned>(
44  "max_iterations",
45  40,
46  "max_iterations>0",
47  "Maximum iterations to use in the custom return map function");
48  params.addClassDescription(
49  "Non-associative Drucker Prager plasticity with hyperbolic smoothing of the cone tip.");
50  return params;
51 }
52 
54  const InputParameters & parameters)
56  _smoother2(Utility::pow<2>(getParam<Real>("smoother"))),
57  _use_custom_returnMap(getParam<bool>("use_custom_returnMap")),
58  _use_custom_cto(getParam<bool>("use_custom_cto")),
59  _max_iters(getParam<unsigned>("max_iterations"))
60 {
61 }
62 
63 Real
65  Real intnl) const
66 {
67  Real aaa;
68  Real bbb;
69  bothAB(intnl, aaa, bbb);
70  return std::sqrt(stress.secondInvariant() + _smoother2) + stress.trace() * bbb - aaa;
71 }
72 
75 {
76  return 0.5 * stress.dsecondInvariant() / std::sqrt(stress.secondInvariant() + _smoother2) +
77  stress.dtrace() * bbb;
78 }
79 
82  Real /*intnl*/) const
83 {
84  RankFourTensor dr_dstress;
85  dr_dstress = 0.5 * stress.d2secondInvariant() / std::sqrt(stress.secondInvariant() + _smoother2);
86  dr_dstress += -0.5 * 0.5 * stress.dsecondInvariant().outerProduct(stress.dsecondInvariant()) /
87  std::pow(stress.secondInvariant() + _smoother2, 1.5);
88  return dr_dstress;
89 }
90 
91 std::string
93 {
94  return "DruckerPragerHyperbolic";
95 }
96 
97 bool
99  Real intnl_old,
100  const RankFourTensor & E_ijkl,
101  Real ep_plastic_tolerance,
102  RankTwoTensor & returned_stress,
103  Real & returned_intnl,
104  std::vector<Real> & dpm,
105  RankTwoTensor & delta_dp,
106  std::vector<Real> & yf,
107  bool & trial_stress_inadmissible) const
108 {
109  if (!(_use_custom_returnMap))
110  return SolidMechanicsPlasticModel::returnMap(trial_stress,
111  intnl_old,
112  E_ijkl,
113  ep_plastic_tolerance,
114  returned_stress,
115  returned_intnl,
116  dpm,
117  delta_dp,
118  yf,
119  trial_stress_inadmissible);
120 
121  yf.resize(1);
122 
123  yf[0] = yieldFunction(trial_stress, intnl_old);
124 
125  if (yf[0] < _f_tol)
126  {
127  // the trial_stress is admissible
128  trial_stress_inadmissible = false;
129  return true;
130  }
131 
132  trial_stress_inadmissible = true;
133  const Real mu = E_ijkl(0, 1, 0, 1);
134  const Real lambda = E_ijkl(0, 0, 0, 0) - 2.0 * mu;
135  const Real bulky = 3.0 * lambda + 2.0 * mu;
136  const Real Tr_trial = trial_stress.trace();
137  const Real J2trial = trial_stress.secondInvariant();
138 
139  // Perform a Newton-Raphson to find dpm when
140  // residual = (1 + dpm*mu/ll)sqrt(ll^2 - s^2) - sqrt(J2trial) = 0, with s=smoother
141  // with ll = sqrt(J2 + s^2) = aaa - bbb*Tr(stress) = aaa - bbb(Tr_trial - p*3*bulky*bbb_flow)
142  Real aaa;
143  Real daaa;
144  Real bbb;
145  Real dbbb;
146  Real bbb_flow;
147  Real dbbb_flow;
148  Real ll;
149  Real dll;
150  Real residual;
151  Real jac;
152  dpm[0] = 0;
153  unsigned int iter = 0;
154  do
155  {
156  bothAB(intnl_old + dpm[0], aaa, bbb);
157  dbothAB(intnl_old + dpm[0], daaa, dbbb);
158  onlyB(intnl_old + dpm[0], dilation, bbb_flow);
159  donlyB(intnl_old + dpm[0], dilation, dbbb_flow);
160  ll = aaa - bbb * (Tr_trial - dpm[0] * bulky * 3 * bbb_flow);
161  dll = daaa - dbbb * (Tr_trial - dpm[0] * bulky * 3 * bbb_flow) +
162  bbb * bulky * 3 * (bbb_flow + dpm[0] * dbbb_flow);
163  residual = bbb * (Tr_trial - dpm[0] * bulky * 3 * bbb_flow) - aaa +
164  std::sqrt(J2trial / Utility::pow<2>(1 + dpm[0] * mu / ll) + _smoother2);
165  jac = dbbb * (Tr_trial - dpm[0] * bulky * 3 * bbb_flow) -
166  bbb * bulky * 3 * (bbb_flow + dpm[0] * dbbb_flow) - daaa +
167  0.5 * J2trial * (-2.0) * (mu / ll - dpm[0] * mu * dll / ll / ll) /
168  Utility::pow<3>(1 + dpm[0] * mu / ll) /
169  std::sqrt(J2trial / Utility::pow<2>(1.0 + dpm[0] * mu / ll) + _smoother2);
170  dpm[0] += -residual / jac;
171  if (iter > _max_iters) // not converging
172  return false;
173  iter++;
174  } while (residual * residual > _f_tol * _f_tol);
175 
176  // set the returned values
177  yf[0] = 0;
178  returned_intnl = intnl_old + dpm[0];
179 
180  bothAB(returned_intnl, aaa, bbb);
181  onlyB(returned_intnl, dilation, bbb_flow);
182  ll = aaa - bbb * (Tr_trial - dpm[0] * bulky * 3.0 * bbb_flow);
183  returned_stress =
184  trial_stress.deviatoric() / (1.0 + dpm[0] * mu / ll); // this is the deviatoric part only
185 
186  RankTwoTensor rij = 0.5 * returned_stress.deviatoric() /
187  ll; // this is the derivatoric part the flow potential only
188 
189  // form the returned stress and the full flow potential
190  const Real returned_trace_over_3 = (aaa - ll) / bbb / 3.0;
191  for (unsigned i = 0; i < 3; ++i)
192  {
193  returned_stress(i, i) += returned_trace_over_3;
194  rij(i, i) += bbb_flow;
195  }
196 
197  delta_dp = rij * dpm[0];
198 
199  return true;
200 }
201 
204  const RankTwoTensor & trial_stress,
205  Real intnl_old,
206  const RankTwoTensor & stress,
207  Real intnl,
208  const RankFourTensor & E_ijkl,
209  const std::vector<Real> & cumulative_pm) const
210 {
211  if (!_use_custom_cto)
213  trial_stress, intnl_old, stress, intnl, E_ijkl, cumulative_pm);
214 
215  const Real mu = E_ijkl(0, 1, 0, 1);
216  const Real la = E_ijkl(0, 0, 0, 0) - 2.0 * mu;
217  const Real bulky = 3.0 * la + 2.0 * mu;
218  Real bbb;
219  onlyB(intnl, friction, bbb);
220  Real bbb_flow;
221  onlyB(intnl, dilation, bbb_flow);
222  Real dbbb_flow;
223  donlyB(intnl, dilation, dbbb_flow);
224  const Real bbb_flow_mod = bbb_flow + cumulative_pm[0] * dbbb_flow;
225  const Real J2 = stress.secondInvariant();
226  const RankTwoTensor sij = stress.deviatoric();
227  const Real sq = std::sqrt(J2 + _smoother2);
228 
229  const Real one_over_h =
230  1.0 / (-dyieldFunction_dintnl(stress, intnl) + mu * J2 / Utility::pow<2>(sq) +
231  3.0 * bbb * bbb_flow_mod * bulky); // correct up to hard
232 
233  const RankTwoTensor df_dsig_timesE =
234  mu * sij / sq + bulky * bbb * RankTwoTensor(RankTwoTensor::initIdentity); // correct
235  const RankTwoTensor rmod_timesE =
236  mu * sij / sq +
237  bulky * bbb_flow_mod * RankTwoTensor(RankTwoTensor::initIdentity); // correct up to hard
238 
239  const RankFourTensor coeff_ep =
240  E_ijkl - one_over_h * rmod_timesE.outerProduct(df_dsig_timesE); // correct
241 
242  const RankFourTensor dr_dsig_timesE = -0.5 * mu * sij.outerProduct(sij) / Utility::pow<3>(sq) +
243  mu * stress.d2secondInvariant() / sq; // correct
244  const RankTwoTensor df_dsig_E_dr_dsig =
245  0.5 * mu * _smoother2 * sij / Utility::pow<4>(sq); // correct
246 
247  const RankFourTensor coeff_si =
249  cumulative_pm[0] *
250  (dr_dsig_timesE - one_over_h * rmod_timesE.outerProduct(df_dsig_E_dr_dsig));
251 
252  RankFourTensor s_inv;
253  try
254  {
255  s_inv = coeff_si.invSymm();
256  }
257  catch (MooseException & e)
258  {
259  return coeff_ep; // when coeff_si is singular return the "linear" tangent operator
260  }
261 
262  return s_inv * coeff_ep;
263 }
264 
265 bool
267 {
268  return _use_custom_returnMap;
269 }
270 
271 bool
273 {
274  return _use_custom_cto;
275 }
RankFourTensorTempl< Real > outerProduct(const RankTwoTensorTempl< Real > &b) const
virtual RankTwoTensor df_dsig(const RankTwoTensor &stress, Real bbb) const override
Function that&#39;s used in dyieldFunction_dstress and flowPotential.
Rate-independent non-associative Drucker Prager with hardening/softening.
const bool _use_custom_cto
Whether to use the custom consistent tangent operator calculation.
RankTwoTensorTempl< Real > dsecondInvariant() const
RankFourTensorTempl< Real > d2secondInvariant() const
registerMooseObject("SolidMechanicsApp", SolidMechanicsPlasticDruckerPragerHyperbolic)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
virtual bool useCustomReturnMap() const override
Returns false. You will want to override this in your derived class if you write a custom returnMap f...
void donlyB(Real intnl, int fd, Real &dbbb) const
Calculate d(bbb)/d(intnl) or d(bbb_flow)/d(intnl)
void bothAB(Real intnl, Real &aaa, Real &bbb) const
Calculates aaa and bbb as a function of the internal parameter intnl.
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.
RankTwoTensorTempl< Real > dtrace() const
Real yieldFunction(const RankTwoTensor &stress, Real intnl) const override
The following functions are what you should override when building single-plasticity models...
void onlyB(Real intnl, int fd, Real &bbb) const
Calculate bbb or bbb_flow.
Rate-independent non-associative Drucker Prager with hardening/softening.
RankTwoTensorTempl< Real > deviatoric() const
const unsigned _max_iters
max iters for custom return map loop
static const std::string mu
Definition: NS.h:123
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.
registerMooseObjectRenamed("SolidMechanicsApp", TensorMechanicsPlasticDruckerPragerHyperbolic, "01/01/2025 00:00", SolidMechanicsPlasticDruckerPragerHyperbolic)
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.
const Real _smoother2
smoothing parameter for the cone&#39;s tip
const Real _f_tol
Tolerance on yield function.
void dbothAB(Real intnl, Real &daaa, Real &dbbb) const
Calculates d(aaa)/d(intnl) and d(bbb)/d(intnl) as a function of the internal parameter intnl...
ExpressionBuilder::EBTerm pow(const ExpressionBuilder::EBTerm &left, T exponent)
RankFourTensor dflowPotential_dstress(const RankTwoTensor &stress, Real intnl) const override
The derivative of the flow potential with respect to stress.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void addClassDescription(const std::string &doc_string)
const bool _use_custom_returnMap
whether to use the custom returnMap function
virtual bool useCustomCTO() const override
Returns false. You will want to override this in your derived class if you write a custom consistent ...
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
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.
virtual Real dyieldFunction_dintnl(const RankTwoTensor &stress, Real intnl) const override
The derivative of yield function with respect to the internal parameter.
RankFourTensorTempl< T > invSymm() const
MooseUnits pow(const MooseUnits &, int)