https://mooseframework.inl.gov
SolidMechanicsPlasticMohrCoulomb.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  TensorMechanicsPlasticMohrCoulomb,
17  "01/01/2025 00:00",
19 
22 {
24  params.addRequiredParam<UserObjectName>(
25  "cohesion",
26  "A SolidMechanicsHardening UserObject that defines hardening of the cohesion. "
27  "Physically the cohesion should not be negative.");
28  params.addRequiredParam<UserObjectName>(
29  "friction_angle",
30  "A SolidMechanicsHardening UserObject that defines hardening of the "
31  "friction angle (in radians). Physically the friction angle should be "
32  "between 0 and 90deg.");
33  params.addRequiredParam<UserObjectName>(
34  "dilation_angle",
35  "A SolidMechanicsHardening UserObject that defines hardening of the "
36  "dilation angle (in radians). Usually the dilation angle is not greater "
37  "than the friction angle, and it is between 0 and 90deg.");
38  params.addRangeCheckedParam<Real>(
39  "mc_edge_smoother",
40  25.0,
41  "mc_edge_smoother>=0 & mc_edge_smoother<=30",
42  "Smoothing parameter: the edges of the cone are smoothed by the given amount.");
43  MooseEnum tip_scheme("hyperbolic cap", "hyperbolic");
44  params.addParam<MooseEnum>(
45  "tip_scheme", tip_scheme, "Scheme by which the pyramid's tip will be smoothed.");
46  params.addRequiredRangeCheckedParam<Real>("mc_tip_smoother",
47  "mc_tip_smoother>=0",
48  "Smoothing parameter: the cone vertex at mean = "
49  "cohesion*cot(friction_angle), will be smoothed by "
50  "the given amount. Typical value is 0.1*cohesion");
51  params.addParam<Real>(
52  "cap_start",
53  0.0,
54  "For the 'cap' tip_scheme, smoothing is performed in the stress_mean > cap_start region");
55  params.addRangeCheckedParam<Real>("cap_rate",
56  0.0,
57  "cap_rate>=0",
58  "For the 'cap' tip_scheme, this controls how quickly the cap "
59  "degenerates to a hemisphere: small values mean a slow "
60  "degeneration to a hemisphere (and zero means the 'cap' will "
61  "be totally inactive). Typical value is 1/tensile_strength");
62  params.addParam<Real>("mc_lode_cutoff",
63  "If the second invariant of stress is less than this "
64  "amount, the Lode angle is assumed to be zero. This is "
65  "to gaurd against precision-loss problems, and this "
66  "parameter should be set small. Default = "
67  "0.00001*((yield_Function_tolerance)^2)");
68  params.addClassDescription("Non-associative Mohr-Coulomb plasticity with hardening/softening");
69 
70  return params;
71 }
72 
74  const InputParameters & parameters)
75  : SolidMechanicsPlasticModel(parameters),
76  _cohesion(getUserObject<SolidMechanicsHardeningModel>("cohesion")),
77  _phi(getUserObject<SolidMechanicsHardeningModel>("friction_angle")),
78  _psi(getUserObject<SolidMechanicsHardeningModel>("dilation_angle")),
79  _tip_scheme(getParam<MooseEnum>("tip_scheme")),
80  _small_smoother2(Utility::pow<2>(getParam<Real>("mc_tip_smoother"))),
81  _cap_start(getParam<Real>("cap_start")),
82  _cap_rate(getParam<Real>("cap_rate")),
83  _tt(getParam<Real>("mc_edge_smoother") * libMesh::pi / 180.0),
84  _costt(std::cos(_tt)),
85  _sintt(std::sin(_tt)),
86  _cos3tt(std::cos(3 * _tt)),
87  _sin3tt(std::sin(3 * _tt)),
88  _cos6tt(std::cos(6 * _tt)),
89  _sin6tt(std::sin(6 * _tt)),
90  _lode_cutoff(parameters.isParamValid("mc_lode_cutoff") ? getParam<Real>("mc_lode_cutoff")
91  : 1.0E-5 * Utility::pow<2>(_f_tol))
92 
93 {
94  if (_lode_cutoff < 0)
95  mooseError("mc_lode_cutoff must not be negative");
96 
97  // With arbitary UserObjects, it is impossible to check everything, and
98  // I think this is the best I can do
99  if (phi(0) < 0 || psi(0) < 0 || phi(0) > libMesh::pi / 2.0 || psi(0) > libMesh::pi / 2.0)
100  mooseError("Mohr-Coulomb friction and dilation angles must lie in [0, Pi/2]");
101  if (phi(0) < psi(0))
102  mooseError("Mohr-Coulomb friction angle must not be less than Mohr-Coulomb dilation angle");
103  if (cohesion(0) < 0)
104  mooseError("Mohr-Coulomb cohesion must not be negative");
105 
106  // check Abbo et al's convexity constraint (Eqn c.18 in their paper)
107  // With an arbitrary UserObject, it is impossible to check for all angles
108  // I think the following is the best we can do
109  Real sin_angle = std::sin(std::max(phi(0), psi(0)));
110  sin_angle = std::max(sin_angle, std::sin(std::max(phi(1E6), psi(1E6))));
111  Real rhs = std::sqrt(3) * (35 * std::sin(_tt) + 14 * std::sin(5 * _tt) - 5 * std::sin(7 * _tt)) /
112  16 / Utility::pow<5>(std::cos(_tt)) / (11 - 10 * std::cos(2 * _tt));
113  if (rhs <= sin_angle)
114  mooseError("Mohr-Coulomb edge smoothing angle is too small and a non-convex yield surface will "
115  "result. Please choose a larger value");
116 }
117 
118 Real
120 {
121  Real mean_stress = stress.trace() / 3.0;
122  Real sinphi = std::sin(phi(intnl));
123  Real cosphi = std::cos(phi(intnl));
124  Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0);
125  if (std::abs(sin3Lode) <= _sin3tt)
126  {
127  // the non-edge-smoothed version
128  std::vector<Real> eigvals;
129  stress.symmetricEigenvalues(eigvals);
130  return mean_stress * sinphi +
131  std::sqrt(smooth(stress) +
132  0.25 * Utility::pow<2>(eigvals[2] - eigvals[0] +
133  (eigvals[2] + eigvals[0] - 2 * mean_stress) * sinphi)) -
134  cohesion(intnl) * cosphi;
135  }
136  else
137  {
138  // the edge-smoothed version
139  Real aaa, bbb, ccc;
140  abbo(sin3Lode, sinphi, aaa, bbb, ccc);
141  Real kk = aaa + bbb * sin3Lode + ccc * Utility::pow<2>(sin3Lode);
142  Real sibar2 = stress.secondInvariant();
143  return mean_stress * sinphi + std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk)) -
144  cohesion(intnl) * cosphi;
145  }
146 }
147 
149 SolidMechanicsPlasticMohrCoulomb::df_dsig(const RankTwoTensor & stress, const Real sin_angle) const
150 {
151  Real mean_stress = stress.trace() / 3.0;
152  RankTwoTensor dmean_stress = stress.dtrace() / 3.0;
153  Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0);
154  if (std::abs(sin3Lode) <= _sin3tt)
155  {
156  // the non-edge-smoothed version
157  std::vector<Real> eigvals;
158  std::vector<RankTwoTensor> deigvals;
159  stress.dsymmetricEigenvalues(eigvals, deigvals);
160  Real tmp = eigvals[2] - eigvals[0] + (eigvals[2] + eigvals[0] - 2.0 * mean_stress) * sin_angle;
161  RankTwoTensor dtmp =
162  deigvals[2] - deigvals[0] + (deigvals[2] + deigvals[0] - 2.0 * dmean_stress) * sin_angle;
163  Real denom = std::sqrt(smooth(stress) + 0.25 * Utility::pow<2>(tmp));
164  return dmean_stress * sin_angle +
165  (0.5 * dsmooth(stress) * dmean_stress + 0.25 * tmp * dtmp) / denom;
166  }
167  else
168  {
169  // the edge-smoothed version
170  Real aaa, bbb, ccc;
171  abbo(sin3Lode, sin_angle, aaa, bbb, ccc);
172  Real kk = aaa + bbb * sin3Lode + ccc * Utility::pow<2>(sin3Lode);
173  RankTwoTensor dkk = (bbb + 2 * ccc * sin3Lode) * stress.dsin3Lode(_lode_cutoff);
174  Real sibar2 = stress.secondInvariant();
175  RankTwoTensor dsibar2 = stress.dsecondInvariant();
176  Real denom = std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk));
177  return dmean_stress * sin_angle + (0.5 * dsmooth(stress) * dmean_stress +
178  0.5 * dsibar2 * Utility::pow<2>(kk) + sibar2 * kk * dkk) /
179  denom;
180  }
181 }
182 
185  Real intnl) const
186 {
187  Real sinphi = std::sin(phi(intnl));
188  return df_dsig(stress, sinphi);
189 }
190 
191 Real
193  Real intnl) const
194 {
195  Real sin_angle = std::sin(phi(intnl));
196  Real cos_angle = std::cos(phi(intnl));
197  Real dsin_angle = cos_angle * dphi(intnl);
198  Real dcos_angle = -sin_angle * dphi(intnl);
199 
200  Real mean_stress = stress.trace() / 3.0;
201  Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0);
202  if (std::abs(sin3Lode) <= _sin3tt)
203  {
204  // the non-edge-smoothed version
205  std::vector<Real> eigvals;
206  stress.symmetricEigenvalues(eigvals);
207  Real tmp = eigvals[2] - eigvals[0] + (eigvals[2] + eigvals[0] - 2 * mean_stress) * sin_angle;
208  Real dtmp = (eigvals[2] + eigvals[0] - 2 * mean_stress) * dsin_angle;
209  Real denom = std::sqrt(smooth(stress) + 0.25 * Utility::pow<2>(tmp));
210  return mean_stress * dsin_angle + 0.25 * tmp * dtmp / denom - dcohesion(intnl) * cos_angle -
211  cohesion(intnl) * dcos_angle;
212  }
213  else
214  {
215  // the edge-smoothed version
216  Real aaa, bbb, ccc;
217  abbo(sin3Lode, sin_angle, aaa, bbb, ccc);
218  Real daaa, dbbb, dccc;
219  dabbo(sin3Lode, sin_angle, daaa, dbbb, dccc);
220  Real kk = aaa + bbb * sin3Lode + ccc * Utility::pow<2>(sin3Lode);
221  Real dkk = (daaa + dbbb * sin3Lode + dccc * Utility::pow<2>(sin3Lode)) * dsin_angle;
222  Real sibar2 = stress.secondInvariant();
223  Real denom = std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk));
224  return mean_stress * dsin_angle + sibar2 * kk * dkk / denom - dcohesion(intnl) * cos_angle -
225  cohesion(intnl) * dcos_angle;
226  }
227 }
228 
231 {
232  Real sinpsi = std::sin(psi(intnl));
233  return df_dsig(stress, sinpsi);
234 }
235 
238  Real intnl) const
239 {
240  RankFourTensor dr_dstress;
241  Real sin_angle = std::sin(psi(intnl));
242  Real mean_stress = stress.trace() / 3.0;
243  RankTwoTensor dmean_stress = stress.dtrace() / 3.0;
244  Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0);
245  if (std::abs(sin3Lode) <= _sin3tt)
246  {
247  // the non-edge-smoothed version
248  std::vector<Real> eigvals;
249  std::vector<RankTwoTensor> deigvals;
250  std::vector<RankFourTensor> d2eigvals;
251  stress.dsymmetricEigenvalues(eigvals, deigvals);
252  stress.d2symmetricEigenvalues(d2eigvals);
253 
254  Real tmp = eigvals[2] - eigvals[0] + (eigvals[2] + eigvals[0] - 2.0 * mean_stress) * sin_angle;
255  RankTwoTensor dtmp =
256  deigvals[2] - deigvals[0] + (deigvals[2] + deigvals[0] - 2.0 * dmean_stress) * sin_angle;
257  Real denom = std::sqrt(smooth(stress) + 0.25 * Utility::pow<2>(tmp));
258  Real denom3 = Utility::pow<3>(denom);
259  Real d2smooth_over_denom = d2smooth(stress) / denom;
260  RankTwoTensor numer = dsmooth(stress) * dmean_stress + 0.5 * tmp * dtmp;
261 
262  dr_dstress = 0.25 * tmp *
263  (d2eigvals[2] - d2eigvals[0] + (d2eigvals[2] + d2eigvals[0]) * sin_angle) / denom;
264 
265  for (unsigned i = 0; i < 3; ++i)
266  for (unsigned j = 0; j < 3; ++j)
267  for (unsigned k = 0; k < 3; ++k)
268  for (unsigned l = 0; l < 3; ++l)
269  {
270  dr_dstress(i, j, k, l) +=
271  0.5 * d2smooth_over_denom * dmean_stress(i, j) * dmean_stress(k, l);
272  dr_dstress(i, j, k, l) += 0.25 * dtmp(i, j) * dtmp(k, l) / denom;
273  dr_dstress(i, j, k, l) -= 0.25 * numer(i, j) * numer(k, l) / denom3;
274  }
275  }
276  else
277  {
278  // the edge-smoothed version
279  Real aaa, bbb, ccc;
280  abbo(sin3Lode, sin_angle, aaa, bbb, ccc);
281  RankTwoTensor dsin3Lode = stress.dsin3Lode(_lode_cutoff);
282  Real kk = aaa + bbb * sin3Lode + ccc * Utility::pow<2>(sin3Lode);
283  RankTwoTensor dkk = (bbb + 2 * ccc * sin3Lode) * dsin3Lode;
284  RankFourTensor d2kk = (bbb + 2 * ccc * sin3Lode) * stress.d2sin3Lode(_lode_cutoff);
285  for (unsigned i = 0; i < 3; ++i)
286  for (unsigned j = 0; j < 3; ++j)
287  for (unsigned k = 0; k < 3; ++k)
288  for (unsigned l = 0; l < 3; ++l)
289  d2kk(i, j, k, l) += 2 * ccc * dsin3Lode(i, j) * dsin3Lode(k, l);
290 
291  Real sibar2 = stress.secondInvariant();
292  RankTwoTensor dsibar2 = stress.dsecondInvariant();
293  RankFourTensor d2sibar2 = stress.d2secondInvariant();
294 
295  Real denom = std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk));
296  Real denom3 = Utility::pow<3>(denom);
297  Real d2smooth_over_denom = d2smooth(stress) / denom;
298  RankTwoTensor numer_full =
299  0.5 * dsmooth(stress) * dmean_stress + 0.5 * dsibar2 * kk * kk + sibar2 * kk * dkk;
300 
301  dr_dstress = (0.5 * d2sibar2 * Utility::pow<2>(kk) + sibar2 * kk * d2kk) / denom;
302  for (unsigned i = 0; i < 3; ++i)
303  for (unsigned j = 0; j < 3; ++j)
304  for (unsigned k = 0; k < 3; ++k)
305  for (unsigned l = 0; l < 3; ++l)
306  {
307  dr_dstress(i, j, k, l) +=
308  0.5 * d2smooth_over_denom * dmean_stress(i, j) * dmean_stress(k, l);
309  dr_dstress(i, j, k, l) +=
310  (dsibar2(i, j) * dkk(k, l) * kk + dkk(i, j) * dsibar2(k, l) * kk +
311  sibar2 * dkk(i, j) * dkk(k, l)) /
312  denom;
313  dr_dstress(i, j, k, l) -= numer_full(i, j) * numer_full(k, l) / denom3;
314  }
315  }
316  return dr_dstress;
317 }
318 
321  Real intnl) const
322 {
323  Real sin_angle = std::sin(psi(intnl));
324  Real dsin_angle = std::cos(psi(intnl)) * dpsi(intnl);
325 
326  Real mean_stress = stress.trace() / 3.0;
327  RankTwoTensor dmean_stress = stress.dtrace() / 3.0;
328  Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0);
329 
330  if (std::abs(sin3Lode) <= _sin3tt)
331  {
332  // the non-edge-smoothed version
333  std::vector<Real> eigvals;
334  std::vector<RankTwoTensor> deigvals;
335  stress.dsymmetricEigenvalues(eigvals, deigvals);
336  Real tmp = eigvals[2] - eigvals[0] + (eigvals[2] + eigvals[0] - 2.0 * mean_stress) * sin_angle;
337  Real dtmp_dintnl = (eigvals[2] + eigvals[0] - 2 * mean_stress) * dsin_angle;
338  RankTwoTensor dtmp_dstress =
339  deigvals[2] - deigvals[0] + (deigvals[2] + deigvals[0] - 2.0 * dmean_stress) * sin_angle;
340  RankTwoTensor d2tmp_dstress_dintnl =
341  (deigvals[2] + deigvals[0] - 2.0 * dmean_stress) * dsin_angle;
342  Real denom = std::sqrt(smooth(stress) + 0.25 * Utility::pow<2>(tmp));
343  return dmean_stress * dsin_angle + 0.25 * dtmp_dintnl * dtmp_dstress / denom +
344  0.25 * tmp * d2tmp_dstress_dintnl / denom -
345  0.5 * (dsmooth(stress) * dmean_stress + 0.5 * tmp * dtmp_dstress) * 0.25 * tmp *
346  dtmp_dintnl / Utility::pow<3>(denom);
347  }
348  else
349  {
350  // the edge-smoothed version
351  Real aaa, bbb, ccc;
352  abbo(sin3Lode, sin_angle, aaa, bbb, ccc);
353  Real kk = aaa + bbb * sin3Lode + ccc * Utility::pow<2>(sin3Lode);
354 
355  Real daaa, dbbb, dccc;
356  dabbo(sin3Lode, sin_angle, daaa, dbbb, dccc);
357  Real dkk_dintnl = (daaa + dbbb * sin3Lode + dccc * Utility::pow<2>(sin3Lode)) * dsin_angle;
358  RankTwoTensor dkk_dstress = (bbb + 2 * ccc * sin3Lode) * stress.dsin3Lode(_lode_cutoff);
359  RankTwoTensor d2kk_dstress_dintnl =
360  (dbbb + 2 * dccc * sin3Lode) * stress.dsin3Lode(_lode_cutoff) * dsin_angle;
361 
362  Real sibar2 = stress.secondInvariant();
363  RankTwoTensor dsibar2 = stress.dsecondInvariant();
364  Real denom = std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk));
365 
366  return dmean_stress * dsin_angle +
367  (dsibar2 * kk * dkk_dintnl + sibar2 * dkk_dintnl * dkk_dstress +
368  sibar2 * kk * d2kk_dstress_dintnl) /
369  denom -
370  (0.5 * dsmooth(stress) * dmean_stress + 0.5 * dsibar2 * Utility::pow<2>(kk) +
371  sibar2 * kk * dkk_dstress) *
372  sibar2 * kk * dkk_dintnl / Utility::pow<3>(denom);
373  }
374 }
375 
376 Real
377 SolidMechanicsPlasticMohrCoulomb::cohesion(const Real internal_param) const
378 {
379  return _cohesion.value(internal_param);
380 }
381 
382 Real
383 SolidMechanicsPlasticMohrCoulomb::dcohesion(const Real internal_param) const
384 {
385  return _cohesion.derivative(internal_param);
386 }
387 
388 Real
389 SolidMechanicsPlasticMohrCoulomb::phi(const Real internal_param) const
390 {
391  return _phi.value(internal_param);
392 }
393 
394 Real
395 SolidMechanicsPlasticMohrCoulomb::dphi(const Real internal_param) const
396 {
397  return _phi.derivative(internal_param);
398 }
399 
400 Real
401 SolidMechanicsPlasticMohrCoulomb::psi(const Real internal_param) const
402 {
403  return _psi.value(internal_param);
404 }
405 
406 Real
407 SolidMechanicsPlasticMohrCoulomb::dpsi(const Real internal_param) const
408 {
409  return _psi.derivative(internal_param);
410 }
411 
412 void
414  const Real sin3lode, const Real sin_angle, Real & aaa, Real & bbb, Real & ccc) const
415 {
416  Real tmp1 = (sin3lode >= 0 ? _costt - sin_angle * _sintt / std::sqrt(3.0)
417  : _costt + sin_angle * _sintt / std::sqrt(3.0));
418  Real tmp2 = (sin3lode >= 0 ? _sintt + sin_angle * _costt / std::sqrt(3.0)
419  : -_sintt + sin_angle * _costt / std::sqrt(3.0));
420 
421  ccc = -_cos3tt * tmp1;
422  ccc += (sin3lode >= 0 ? -3 * _sin3tt * tmp2 : 3 * _sin3tt * tmp2);
423  ccc /= 18 * Utility::pow<3>(_cos3tt);
424 
425  bbb = (sin3lode >= 0 ? _sin6tt * tmp1 : -_sin6tt * tmp1);
426  bbb -= 6 * _cos6tt * tmp2;
427  bbb /= 18 * Utility::pow<3>(_cos3tt);
428 
429  aaa = (sin3lode >= 0 ? -sin_angle * _sintt / std::sqrt(3.0) - bbb * _sin3tt
430  : sin_angle * _sintt / std::sqrt(3.0) + bbb * _sin3tt);
431  aaa += -ccc * Utility::pow<2>(_sin3tt) + _costt;
432 }
433 
434 void
436  const Real sin3lode, const Real /*sin_angle*/, Real & daaa, Real & dbbb, Real & dccc) const
437 {
438  Real dtmp1 = (sin3lode >= 0 ? -_sintt / std::sqrt(3.0) : _sintt / std::sqrt(3.0));
439  Real dtmp2 = _costt / std::sqrt(3.0);
440 
441  dccc = -_cos3tt * dtmp1;
442  dccc += (sin3lode >= 0 ? -3 * _sin3tt * dtmp2 : 3 * _sin3tt * dtmp2);
443  dccc /= 18 * Utility::pow<3>(_cos3tt);
444 
445  dbbb = (sin3lode >= 0 ? _sin6tt * dtmp1 : -_sin6tt * dtmp1);
446  dbbb -= 6 * _cos6tt * dtmp2;
447  dbbb /= 18 * Utility::pow<3>(_cos3tt);
448 
449  daaa = (sin3lode >= 0 ? -_sintt / std::sqrt(3.0) - dbbb * _sin3tt
450  : _sintt / std::sqrt(3.0) + dbbb * _sin3tt);
451  daaa += -dccc * Utility::pow<2>(_sin3tt);
452 }
453 
454 Real
456 {
457  Real smoother2 = _small_smoother2;
458  if (_tip_scheme == "cap")
459  {
460  Real x = stress.trace() / 3.0 - _cap_start;
461  Real p = 0;
462  if (x > 0)
463  p = x * (1 - std::exp(-_cap_rate * x));
464  smoother2 += Utility::pow<2>(p);
465  }
466  return smoother2;
467 }
468 
469 Real
471 {
472  Real dsmoother2 = 0;
473  if (_tip_scheme == "cap")
474  {
475  Real x = stress.trace() / 3.0 - _cap_start;
476  Real p = 0;
477  Real dp_dx = 0;
478  if (x > 0)
479  {
480  p = x * (1 - std::exp(-_cap_rate * x));
481  dp_dx = (1 - std::exp(-_cap_rate * x)) + x * _cap_rate * std::exp(-_cap_rate * x);
482  }
483  dsmoother2 += 2 * p * dp_dx;
484  }
485  return dsmoother2;
486 }
487 
488 Real
490 {
491  Real d2smoother2 = 0;
492  if (_tip_scheme == "cap")
493  {
494  Real x = stress.trace() / 3.0 - _cap_start;
495  Real p = 0;
496  Real dp_dx = 0;
497  Real d2p_dx2 = 0;
498  if (x > 0)
499  {
500  p = x * (1 - std::exp(-_cap_rate * x));
501  dp_dx = (1 - std::exp(-_cap_rate * x)) + x * _cap_rate * std::exp(-_cap_rate * x);
502  d2p_dx2 = 2 * _cap_rate * std::exp(-_cap_rate * x) -
503  x * Utility::pow<2>(_cap_rate) * std::exp(-_cap_rate * x);
504  }
505  d2smoother2 += 2 * Utility::pow<2>(dp_dx) + 2 * p * d2p_dx2;
506  }
507  return d2smoother2;
508 }
509 
510 std::string
512 {
513  return "MohrCoulomb";
514 }
Real _lode_cutoff
if secondInvariant < _lode_cutoff then set Lode angle to zero. This is to guard against precision-los...
RankTwoTensorTempl< Real > dsecondInvariant() const
RankFourTensorTempl< Real > d2secondInvariant() const
void addRequiredRangeCheckedParam(const std::string &name, const std::string &parsed_function, const std::string &doc_string)
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sin(_arg) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tan
void symmetricEigenvalues(std::vector< Real > &eigvals) const
Real sin3Lode(const Real &r0, const Real &r0_value) const
virtual Real d2smooth(const RankTwoTensor &stress) const
returns the d^2a/dstress_mean^2 - see doco for _tip_scheme
virtual Real dcohesion(const Real internal_param) const
d(cohesion)/d(internal_param);
virtual Real cohesion(const Real internal_param) const
cohesion as a function of internal parameter
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
Real _sin3tt
sin(3*_tt) - useful for making comparisons with Lode angle
void dsymmetricEigenvalues(std::vector< Real > &eigvals, std::vector< RankTwoTensorTempl< Real >> &deigvals) const
RankTwoTensor dflowPotential_dintnl(const RankTwoTensor &stress, Real intnl) const override
The derivative of the flow potential with respect to the internal parameter.
Real _cap_rate
dictates how quickly the &#39;cap&#39; degenerates to a hemisphere - see doco for _tip_scheme ...
virtual Real dsmooth(const RankTwoTensor &stress) const
returns the da/dstress_mean - see doco for _tip_scheme
Real _tt
edge smoothing parameter, in radians
MooseEnum _tip_scheme
The yield function is modified to f = s_m*sinphi + sqrt(a + s_bar^2 K^2) - C*cosphi where "a" depends...
virtual std::string modelName() const override
RankTwoTensorTempl< Real > dtrace() const
virtual Real dphi(const Real internal_param) const
d(phi)/d(internal_param);
virtual Real phi(const Real internal_param) const
friction angle as a function of internal parameter
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
Mohr-Coulomb plasticity, nonassociative with hardening/softening.
virtual Real value(Real intnl) const
void dabbo(const Real sin3lode, const Real sin_angle, Real &daaa, Real &dbbb, Real &dccc) const
Computes derivatives of Abbo et al&#39;s A, B and C parameters wrt sin_angle.
void addRequiredParam(const std::string &name, const std::string &doc_string)
Real yieldFunction(const RankTwoTensor &stress, Real intnl) const override
The following functions are what you should override when building single-plasticity models...
RankTwoTensorTempl< Real > dsin3Lode(const Real &r0) const
static InputParameters validParams()
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template cos(_arg) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(cos
SolidMechanicsPlasticMohrCoulomb(const InputParameters &parameters)
const SolidMechanicsHardeningModel & _cohesion
Hardening model for cohesion.
const std::vector< double > x
Real dyieldFunction_dintnl(const RankTwoTensor &stress, Real intnl) const override
The derivative of yield function with respect to the internal parameter.
void d2symmetricEigenvalues(std::vector< RankFourTensorTempl< Real >> &deriv) const
virtual Real psi(const Real internal_param) const
dilation angle as a function of internal parameter
const SolidMechanicsHardeningModel & _psi
Hardening model for psi.
registerMooseObject("SolidMechanicsApp", SolidMechanicsPlasticMohrCoulomb)
RankFourTensorTempl< Real > d2sin3Lode(const Real &r0) const
RankFourTensor dflowPotential_dstress(const RankTwoTensor &stress, Real intnl) const override
The derivative of the flow potential with respect to stress.
const SolidMechanicsHardeningModel & _phi
Hardening model for phi.
RankTwoTensor dyieldFunction_dstress(const RankTwoTensor &stress, Real intnl) const override
The derivative of yield function with respect to stress.
RankTwoTensor flowPotential(const RankTwoTensor &stress, Real intnl) const override
The flow potential.
virtual Real dpsi(const Real internal_param) const
d(psi)/d(internal_param);
ExpressionBuilder::EBTerm pow(const ExpressionBuilder::EBTerm &left, T exponent)
void abbo(const Real sin3lode, const Real sin_angle, Real &aaa, Real &bbb, Real &ccc) const
Computes Abbo et al&#39;s A, B and C parameters.
virtual Real derivative(Real intnl) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Real _cap_start
smoothing parameter dictating when the &#39;cap&#39; will start - see doco for _tip_scheme ...
void mooseError(Args &&... args) const
RankTwoTensor df_dsig(const RankTwoTensor &stress, const Real sin_angle) const
d(yieldFunction)/d(stress), but with the ability to put friction or dilation angle into the result ...
void addClassDescription(const std::string &doc_string)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
registerMooseObjectRenamed("SolidMechanicsApp", TensorMechanicsPlasticMohrCoulomb, "01/01/2025 00:00", SolidMechanicsPlasticMohrCoulomb)
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...
static const std::string k
Definition: NS.h:130
Real _small_smoother2
Square of tip smoothing parameter to smooth the cone at mean_stress = T.
virtual Real smooth(const RankTwoTensor &stress) const
returns the &#39;a&#39; parameter - see doco for _tip_scheme
const Real pi