12 #include "libmesh/utility.h" 16 TensorMechanicsPlasticMohrCoulomb,
26 "A SolidMechanicsHardening UserObject that defines hardening of the cohesion. " 27 "Physically the cohesion should not be negative.");
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.");
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.");
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");
45 "tip_scheme", tip_scheme,
"Scheme by which the pyramid's tip will be smoothed.");
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");
54 "For the 'cap' tip_scheme, smoothing is performed in the stress_mean > cap_start region");
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");
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");
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),
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))
95 mooseError(
"mc_lode_cutoff must not be negative");
100 mooseError(
"Mohr-Coulomb friction and dilation angles must lie in [0, Pi/2]");
102 mooseError(
"Mohr-Coulomb friction angle must not be less than Mohr-Coulomb dilation angle");
104 mooseError(
"Mohr-Coulomb cohesion must not be negative");
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");
122 Real sinphi = std::sin(
phi(intnl));
123 Real cosphi = std::cos(
phi(intnl));
125 if (std::abs(sin3Lode) <=
_sin3tt)
128 std::vector<Real> 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)) -
140 abbo(sin3Lode, sinphi, aaa, bbb, ccc);
141 Real kk = aaa + bbb * sin3Lode + ccc * Utility::pow<2>(sin3Lode);
143 return mean_stress * sinphi + std::sqrt(
smooth(stress) + sibar2 * Utility::pow<2>(kk)) -
154 if (std::abs(sin3Lode) <=
_sin3tt)
157 std::vector<Real> eigvals;
158 std::vector<RankTwoTensor> deigvals;
160 Real tmp = eigvals[2] - eigvals[0] + (eigvals[2] + eigvals[0] - 2.0 * mean_stress) * sin_angle;
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;
171 abbo(sin3Lode, sin_angle, aaa, bbb, ccc);
172 Real kk = aaa + bbb * sin3Lode + ccc * Utility::pow<2>(sin3Lode);
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) /
187 Real sinphi = std::sin(
phi(intnl));
188 return df_dsig(stress, sinphi);
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);
202 if (std::abs(sin3Lode) <=
_sin3tt)
205 std::vector<Real> 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 -
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;
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 -
232 Real sinpsi = std::sin(
psi(intnl));
233 return df_dsig(stress, sinpsi);
241 Real sin_angle = std::sin(
psi(intnl));
245 if (std::abs(sin3Lode) <=
_sin3tt)
248 std::vector<Real> eigvals;
249 std::vector<RankTwoTensor> deigvals;
250 std::vector<RankFourTensor> d2eigvals;
254 Real tmp = eigvals[2] - eigvals[0] + (eigvals[2] + eigvals[0] - 2.0 * mean_stress) * sin_angle;
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);
262 dr_dstress = 0.25 * tmp *
263 (d2eigvals[2] - d2eigvals[0] + (d2eigvals[2] + d2eigvals[0]) * sin_angle) / denom;
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)
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;
280 abbo(sin3Lode, sin_angle, aaa, bbb, ccc);
282 Real kk = aaa + bbb * sin3Lode + ccc * Utility::pow<2>(sin3Lode);
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);
295 Real denom = std::sqrt(
smooth(stress) + sibar2 * Utility::pow<2>(kk));
296 Real denom3 = Utility::pow<3>(denom);
299 0.5 *
dsmooth(stress) * dmean_stress + 0.5 * dsibar2 * kk * kk + sibar2 * kk * dkk;
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)
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)) /
313 dr_dstress(i,
j,
k, l) -= numer_full(i,
j) * numer_full(
k, l) / denom3;
323 Real sin_angle = std::sin(
psi(intnl));
324 Real dsin_angle = std::cos(
psi(intnl)) *
dpsi(intnl);
330 if (std::abs(sin3Lode) <=
_sin3tt)
333 std::vector<Real> eigvals;
334 std::vector<RankTwoTensor> 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;
339 deigvals[2] - deigvals[0] + (deigvals[2] + deigvals[0] - 2.0 * dmean_stress) * sin_angle;
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);
352 abbo(sin3Lode, sin_angle, aaa, bbb, ccc);
353 Real kk = aaa + bbb * sin3Lode + ccc * Utility::pow<2>(sin3Lode);
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;
364 Real denom = std::sqrt(
smooth(stress) + sibar2 * Utility::pow<2>(kk));
366 return dmean_stress * dsin_angle +
367 (dsibar2 * kk * dkk_dintnl + sibar2 * dkk_dintnl * dkk_dstress +
368 sibar2 * kk * d2kk_dstress_dintnl) /
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);
414 const Real sin3lode,
const Real sin_angle, Real & aaa, Real & bbb, Real & ccc)
const 422 ccc += (sin3lode >= 0 ? -3 *
_sin3tt * tmp2 : 3 *
_sin3tt * tmp2);
423 ccc /= 18 * Utility::pow<3>(
_cos3tt);
427 bbb /= 18 * Utility::pow<3>(
_cos3tt);
429 aaa = (sin3lode >= 0 ? -sin_angle *
_sintt / std::sqrt(3.0) - bbb *
_sin3tt 436 const Real sin3lode,
const Real , Real & daaa, Real & dbbb, Real & dccc)
const 438 Real dtmp1 = (sin3lode >= 0 ? -
_sintt / std::sqrt(3.0) :
_sintt / std::sqrt(3.0));
442 dccc += (sin3lode >= 0 ? -3 *
_sin3tt * dtmp2 : 3 *
_sin3tt * dtmp2);
443 dccc /= 18 * Utility::pow<3>(
_cos3tt);
447 dbbb /= 18 * Utility::pow<3>(
_cos3tt);
449 daaa = (sin3lode >= 0 ? -
_sintt / std::sqrt(3.0) - dbbb *
_sin3tt 451 daaa += -dccc * Utility::pow<2>(
_sin3tt);
464 smoother2 += Utility::pow<2>(p);
483 dsmoother2 += 2 * p * dp_dx;
491 Real d2smoother2 = 0;
505 d2smoother2 += 2 * Utility::pow<2>(dp_dx) + 2 * p * d2p_dx2;
513 return "MohrCoulomb";
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
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
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 'cap' 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
Real secondInvariant() const
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's A, B and C parameters wrt sin_angle.
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 ¶meters)
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);
static InputParameters validParams()
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's A, B and C parameters.
virtual Real derivative(Real intnl) const
Hardening Model base class.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Real _cap_start
smoothing parameter dictating when the 'cap' 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 ...
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
registerMooseObjectRenamed("SolidMechanicsApp", TensorMechanicsPlasticMohrCoulomb, "01/01/2025 00:00", SolidMechanicsPlasticMohrCoulomb)
Plastic Model base class The virtual functions written below must be over-ridden in derived classes t...
static const std::string k
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 'a' parameter - see doco for _tip_scheme