https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
15registerMooseObjectRenamed("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
118Real
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
149SolidMechanicsPlasticMohrCoulomb::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
191Real
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
376Real
377SolidMechanicsPlasticMohrCoulomb::cohesion(const Real internal_param) const
378{
379 return _cohesion.value(internal_param);
380}
381
382Real
383SolidMechanicsPlasticMohrCoulomb::dcohesion(const Real internal_param) const
384{
385 return _cohesion.derivative(internal_param);
386}
387
388Real
389SolidMechanicsPlasticMohrCoulomb::phi(const Real internal_param) const
390{
391 return _phi.value(internal_param);
392}
393
394Real
395SolidMechanicsPlasticMohrCoulomb::dphi(const Real internal_param) const
396{
397 return _phi.derivative(internal_param);
398}
399
400Real
401SolidMechanicsPlasticMohrCoulomb::psi(const Real internal_param) const
402{
403 return _psi.value(internal_param);
404}
405
406Real
407SolidMechanicsPlasticMohrCoulomb::dpsi(const Real internal_param) const
408{
409 return _psi.derivative(internal_param);
410}
411
412void
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
434void
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
454Real
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
469Real
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
488Real
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
510std::string
512{
513 return "MohrCoulomb";
514}
const std::vector< double > x
ExpressionBuilder::EBTerm pow(const ExpressionBuilder::EBTerm &left, T exponent)
const Real p
registerMooseObject("SolidMechanicsApp", SolidMechanicsPlasticMohrCoulomb)
registerMooseObjectRenamed("SolidMechanicsApp", TensorMechanicsPlasticMohrCoulomb, "01/01/2025 00:00", SolidMechanicsPlasticMohrCoulomb)
void addRequiredRangeCheckedParam(const std::string &name, const std::string &parsed_function, const std::string &doc_string)
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
void mooseError(Args &&... args) const
RankTwoTensorTempl< T > dsin3Lode(const T &r0) const
void dsymmetricEigenvalues(std::vector< T > &eigvals, std::vector< RankTwoTensorTempl< T > > &deigvals) const
T secondInvariant() const
void d2symmetricEigenvalues(std::vector< RankFourTensorTempl< T > > &deriv) const
T sin3Lode(const T &r0, const T &r0_value) const
void symmetricEigenvalues(std::vector< T > &eigvals) const
RankTwoTensorTempl< T > dsecondInvariant() const
RankTwoTensorTempl< T > dtrace() const
RankFourTensorTempl< T > d2secondInvariant() const
RankFourTensorTempl< T > d2sin3Lode(const T &r0) const
virtual Real derivative(Real intnl) const
virtual Real value(Real intnl) const
Plastic Model base class The virtual functions written below must be over-ridden in derived classes t...
static InputParameters validParams()
Mohr-Coulomb plasticity, nonassociative with hardening/softening.
RankTwoTensor dyieldFunction_dstress(const RankTwoTensor &stress, Real intnl) const override
The derivative of yield function with respect to stress.
Real _cap_start
smoothing parameter dictating when the 'cap' will start - see doco for _tip_scheme
Real _tt
edge smoothing parameter, in radians
Real yieldFunction(const RankTwoTensor &stress, Real intnl) const override
The following functions are what you should override when building single-plasticity models.
virtual Real smooth(const RankTwoTensor &stress) const
returns the 'a' parameter - see doco for _tip_scheme
virtual Real dphi(const Real internal_param) const
d(phi)/d(internal_param);
virtual Real dcohesion(const Real internal_param) const
d(cohesion)/d(internal_param);
RankTwoTensor dflowPotential_dintnl(const RankTwoTensor &stress, Real intnl) const override
The derivative of the flow potential with respect to the internal parameter.
Real _small_smoother2
Square of tip smoothing parameter to smooth the cone at mean_stress = T.
const SolidMechanicsHardeningModel & _phi
Hardening model for phi.
virtual Real dsmooth(const RankTwoTensor &stress) const
returns the da/dstress_mean - see doco for _tip_scheme
Real _cap_rate
dictates how quickly the 'cap' degenerates to a hemisphere - see doco for _tip_scheme
virtual Real dpsi(const Real internal_param) const
d(psi)/d(internal_param);
Real _lode_cutoff
if secondInvariant < _lode_cutoff then set Lode angle to zero. This is to guard against precision-los...
void dabbo(const Real sin3lode, const Real sin_angle, Real &daaa, Real &dbbb, Real &dccc) const
Computes derivatives of Abbo et al's A, B and C parameters wrt sin_angle.
RankFourTensor dflowPotential_dstress(const RankTwoTensor &stress, Real intnl) const override
The derivative of the flow potential with respect to stress.
virtual Real psi(const Real internal_param) const
dilation angle as a function of internal parameter
const SolidMechanicsHardeningModel & _cohesion
Hardening model for cohesion.
RankTwoTensor flowPotential(const RankTwoTensor &stress, Real intnl) const override
The flow potential.
Real _sin3tt
sin(3*_tt) - useful for making comparisons with Lode angle
const SolidMechanicsHardeningModel & _psi
Hardening model for psi.
void abbo(const Real sin3lode, const Real sin_angle, Real &aaa, Real &bbb, Real &ccc) const
Computes Abbo et al's A, B and C parameters.
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
SolidMechanicsPlasticMohrCoulomb(const InputParameters &parameters)
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 Real cohesion(const Real internal_param) const
cohesion as a function of internal parameter
virtual Real phi(const Real internal_param) const
friction angle as a function of internal parameter
virtual Real d2smooth(const RankTwoTensor &stress) const
returns the d^2a/dstress_mean^2 - see doco for _tip_scheme
Real dyieldFunction_dintnl(const RankTwoTensor &stress, Real intnl) const override
The derivative of yield function with respect to the internal parameter.
virtual std::string modelName() const override
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
const Real pi