15 #include "libmesh/utility.h" 19 TensorMechanicsPlasticMohrCoulombMulti,
27 params.
addClassDescription(
"Non-associative Mohr-Coulomb plasticity with hardening/softening");
29 "cohesion",
"A SolidMechanicsHardening UserObject that defines hardening of the cohesion");
31 "A SolidMechanicsHardening UserObject " 32 "that defines hardening of the " 33 "friction angle (in radians)");
35 "A SolidMechanicsHardening UserObject " 36 "that defines hardening of the " 37 "dilation angle (in radians)");
38 params.
addParam<
unsigned int>(
"max_iterations",
40 "Maximum number of Newton-Raphson iterations " 41 "allowed in the custom return-map algorithm. " 42 " For highly nonlinear hardening this may " 43 "need to be higher than 10.");
45 "Yield surface is shifted by this amount to avoid problems with " 46 "defining derivatives when eigenvalues are equal. If this is " 47 "larger than f_tol, a warning will be issued. This may be set " 48 "very small when using the custom returnMap. Default = f_tol.");
49 params.
addParam<
bool>(
"use_custom_returnMap",
51 "Use a custom return-map algorithm for this " 52 "plasticity model, which may speed up " 53 "computations considerably. Set to true " 54 "only for isotropic elasticity with no " 55 "hardening of the dilation angle. In this " 56 "case you may set 'shift' very small.");
67 _max_iters(getParam<unsigned
int>(
"max_iterations")),
68 _shift(parameters.isParamValid(
"shift") ? getParam<
Real>(
"shift") : _f_tol),
69 _use_custom_returnMap(getParam<bool>(
"use_custom_returnMap"))
72 mooseError(
"Value of 'shift' in SolidMechanicsPlasticMohrCoulombMulti must not be negative\n");
74 _console <<
"WARNING: value of 'shift' in SolidMechanicsPlasticMohrCoulombMulti is probably " 78 mooseError(
"SolidMechanicsPlasticMohrCoulombMulti is only defined for LIBMESH_DIM=3");
91 std::vector<Real> &
f)
const 93 std::vector<Real> eigvals;
98 const Real sinphi = std::sin(
phi(intnl));
99 const Real cosphi = std::cos(
phi(intnl));
107 Real e0, Real e1, Real e2, Real sinphi, Real cohcos, std::vector<Real> &
f)
const 115 f[0] = 0.5 * (e0 - e1) + 0.5 * (e0 + e1) * sinphi - cohcos;
116 f[1] = 0.5 * (e1 - e0) + 0.5 * (e0 + e1) * sinphi - cohcos;
117 f[2] = 0.5 * (e0 - e2) + 0.5 * (e0 + e2) * sinphi - cohcos;
118 f[3] = 0.5 * (e2 - e0) + 0.5 * (e0 + e2) * sinphi - cohcos;
119 f[4] = 0.5 * (e1 - e2) + 0.5 * (e1 + e2) * sinphi - cohcos;
120 f[5] = 0.5 * (e2 - e1) + 0.5 * (e1 + e2) * sinphi - cohcos;
125 std::vector<Real> & eigvals,
126 std::vector<RankTwoTensor> & deigvals)
const 128 Real small_perturbation;
130 while (eigvals[0] > eigvals[1] - 0.1 *
_shift || eigvals[1] > eigvals[2] - 0.1 *
_shift)
132 for (
unsigned i = 0; i < 3; ++i)
133 for (
unsigned j = 0;
j <= i; ++
j)
136 shifted_stress(i,
j) += small_perturbation;
137 shifted_stress(
j, i) += small_perturbation;
146 std::vector<RankTwoTensor> & df)
const 148 std::vector<Real> eigvals;
149 std::vector<RankTwoTensor> deigvals;
152 if (eigvals[0] > eigvals[1] - 0.1 *
_shift || eigvals[1] > eigvals[2] - 0.1 *
_shift)
156 df[0] = 0.5 * (deigvals[0] - deigvals[1]) + 0.5 * (deigvals[0] + deigvals[1]) * sin_angle;
157 df[1] = 0.5 * (deigvals[1] - deigvals[0]) + 0.5 * (deigvals[0] + deigvals[1]) * sin_angle;
158 df[2] = 0.5 * (deigvals[0] - deigvals[2]) + 0.5 * (deigvals[0] + deigvals[2]) * sin_angle;
159 df[3] = 0.5 * (deigvals[2] - deigvals[0]) + 0.5 * (deigvals[0] + deigvals[2]) * sin_angle;
160 df[4] = 0.5 * (deigvals[1] - deigvals[2]) + 0.5 * (deigvals[1] + deigvals[2]) * sin_angle;
161 df[5] = 0.5 * (deigvals[2] - deigvals[1]) + 0.5 * (deigvals[1] + deigvals[2]) * sin_angle;
166 const RankTwoTensor & stress, Real intnl, std::vector<RankTwoTensor> & df_dstress)
const 168 const Real sinphi = std::sin(
phi(intnl));
169 df_dsig(stress, sinphi, df_dstress);
175 std::vector<Real> & df_dintnl)
const 177 std::vector<Real> eigvals;
182 const Real sin_angle = std::sin(
phi(intnl));
183 const Real cos_angle = std::cos(
phi(intnl));
184 const Real dsin_angle = cos_angle *
dphi(intnl);
185 const Real dcos_angle = -sin_angle *
dphi(intnl);
189 df_dintnl[0] = df_dintnl[1] = 0.5 * (eigvals[0] + eigvals[1]) * dsin_angle - dcohcos;
190 df_dintnl[2] = df_dintnl[3] = 0.5 * (eigvals[0] + eigvals[2]) * dsin_angle - dcohcos;
191 df_dintnl[4] = df_dintnl[5] = 0.5 * (eigvals[1] + eigvals[2]) * dsin_angle - dcohcos;
197 std::vector<RankTwoTensor> & r)
const 199 const Real sinpsi = std::sin(
psi(intnl));
205 const RankTwoTensor & stress, Real intnl, std::vector<RankFourTensor> & dr_dstress)
const 207 std::vector<RankFourTensor> d2eigvals;
210 const Real sinpsi = std::sin(
psi(intnl));
212 dr_dstress.resize(6);
214 0.5 * (d2eigvals[0] - d2eigvals[1]) + 0.5 * (d2eigvals[0] + d2eigvals[1]) * sinpsi;
216 0.5 * (d2eigvals[1] - d2eigvals[0]) + 0.5 * (d2eigvals[0] + d2eigvals[1]) * sinpsi;
218 0.5 * (d2eigvals[0] - d2eigvals[2]) + 0.5 * (d2eigvals[0] + d2eigvals[2]) * sinpsi;
220 0.5 * (d2eigvals[2] - d2eigvals[0]) + 0.5 * (d2eigvals[0] + d2eigvals[2]) * sinpsi;
222 0.5 * (d2eigvals[1] - d2eigvals[2]) + 0.5 * (d2eigvals[1] + d2eigvals[2]) * sinpsi;
224 0.5 * (d2eigvals[2] - d2eigvals[1]) + 0.5 * (d2eigvals[1] + d2eigvals[2]) * sinpsi;
229 const RankTwoTensor & stress, Real intnl, std::vector<RankTwoTensor> & dr_dintnl)
const 231 const Real cos_angle = std::cos(
psi(intnl));
232 const Real dsin_angle = cos_angle *
dpsi(intnl);
234 std::vector<Real> eigvals;
235 std::vector<RankTwoTensor> deigvals;
238 if (eigvals[0] > eigvals[1] - 0.1 *
_shift || eigvals[1] > eigvals[2] - 0.1 *
_shift)
242 dr_dintnl[0] = dr_dintnl[1] = 0.5 * (deigvals[0] + deigvals[1]) * dsin_angle;
243 dr_dintnl[2] = dr_dintnl[3] = 0.5 * (deigvals[0] + deigvals[2]) * dsin_angle;
244 dr_dintnl[4] = dr_dintnl[5] = 0.5 * (deigvals[1] + deigvals[2]) * dsin_angle;
252 std::vector<bool> & act,
255 act.assign(6,
false);
260 returned_stress = stress;
265 std::vector<Real> dpm(6);
267 std::vector<Real> yf(6);
268 bool trial_stress_inadmissible;
278 trial_stress_inadmissible);
280 for (
unsigned i = 0; i < 6; ++i)
281 act[i] = (dpm[i] > 0);
323 return "MohrCoulombMulti";
330 Real ep_plastic_tolerance,
332 Real & returned_intnl,
333 std::vector<Real> & dpm,
335 std::vector<Real> & yf,
336 bool & trial_stress_inadmissible)
const 342 ep_plastic_tolerance,
348 trial_stress_inadmissible);
353 ep_plastic_tolerance,
359 trial_stress_inadmissible);
366 Real ep_plastic_tolerance,
368 Real & returned_intnl,
369 std::vector<Real> & dpm,
371 std::vector<Real> & yf,
372 bool & trial_stress_inadmissible)
const 374 mooseAssert(dpm.size() == 6,
375 "SolidMechanicsPlasticMohrCoulombMulti size of dpm should be 6 but it is " 378 std::vector<Real> eigvals;
384 Real sinphi = std::sin(
phi(intnl_old));
385 Real cosphi = std::cos(
phi(intnl_old));
387 Real cohcos = coh * cosphi;
395 trial_stress_inadmissible =
false;
399 trial_stress_inadmissible =
true;
405 std::vector<RealVectorValue>
norm(6);
406 const Real sinpsi = std::sin(
psi(intnl_old));
407 const Real oneminus = 0.5 * (1 - sinpsi);
408 const Real oneplus = 0.5 * (1 + sinpsi);
409 norm[0](0) = oneplus;
410 norm[0](1) = -oneminus;
412 norm[1](0) = -oneminus;
413 norm[1](1) = oneplus;
415 norm[2](0) = oneplus;
417 norm[2](2) = -oneminus;
418 norm[3](0) = -oneminus;
420 norm[3](2) = oneplus;
422 norm[4](1) = oneplus;
423 norm[4](2) = -oneminus;
425 norm[5](1) = -oneminus;
426 norm[5](2) = oneplus;
434 std::vector<RealVectorValue> n(6);
435 for (
unsigned ys = 0; ys < 6; ++ys)
436 for (
unsigned i = 0; i < 3; ++i)
437 for (
unsigned j = 0;
j < 3; ++
j)
438 n[ys](i) += E_ijkl(i, i,
j,
j) *
norm[ys](
j);
439 const Real mag_E = E_ijkl(0, 0, 0, 0);
455 const unsigned int number_of_return_paths = 5;
456 std::vector<int> trial_order(number_of_return_paths);
491 bool nr_converged =
false;
492 bool kt_success =
false;
493 std::vector<RealVectorValue> ntip(3);
494 std::vector<Real> dpmtip(3);
496 for (trial = 0; trial < number_of_return_paths; ++trial)
498 switch (trial_order[trial])
501 for (
unsigned int i = 0; i < 3; ++i)
503 ntip[0](i) = n[0](i);
504 ntip[1](i) = n[1](i);
505 ntip[2](i) = n[3](i);
516 ep_plastic_tolerance,
518 if (nr_converged && kt_success)
523 dpm[2] = dpm[4] = dpm[5] = 0;
528 for (
unsigned int i = 0; i < 3; ++i)
530 ntip[0](i) = n[1](i);
531 ntip[1](i) = n[3](i);
532 ntip[2](i) = n[5](i);
543 ep_plastic_tolerance,
545 if (nr_converged && kt_success)
550 dpm[0] = dpm[2] = dpm[4] = 0;
565 ep_plastic_tolerance,
580 ep_plastic_tolerance,
594 ep_plastic_tolerance,
599 if (nr_converged && kt_success)
603 if (trial == number_of_return_paths)
605 sinphi = std::sin(
phi(intnl_old));
606 cosphi = std::cos(
phi(intnl_old));
608 cohcos = coh * cosphi;
610 Moose::err <<
"Trial stress = \n";
611 trial_stress.
print(Moose::err);
612 Moose::err <<
"which has eigenvalues = " << eigvals[0] <<
" " << eigvals[1] <<
" " << eigvals[2]
614 Moose::err <<
"and yield functions = " << yf[0] <<
" " << yf[1] <<
" " << yf[2] <<
" " << yf[3]
615 <<
" " << yf[4] <<
" " << yf[5] <<
"\n";
616 Moose::err <<
"Internal parameter = " << intnl_old << std::endl;
617 mooseError(
"SolidMechanicsPlasticMohrCoulombMulti: FAILURE! You probably need to implement a " 618 "line search if your hardening is too severe, or you need to tune your tolerances " 619 "(eg, yield_function_tolerance should be a little smaller than (young " 620 "modulus)*ep_plastic_tolerance).\n");
626 returned_intnl = intnl_old;
627 for (
unsigned i = 0; i < 6; ++i)
628 returned_intnl += dpm[i];
629 for (
unsigned i = 0; i < 6; ++i)
630 for (
unsigned j = 0;
j < 3; ++
j)
631 delta_dp(
j,
j) += dpm[i] *
norm[i](
j);
632 returned_stress = eigvecs * returned_stress * (eigvecs.
transpose());
633 delta_dp = eigvecs * delta_dp * (eigvecs.
transpose());
639 const std::vector<RealVectorValue> & n,
640 std::vector<Real> & dpm,
647 Real ep_plastic_tolerance,
648 std::vector<Real> & yf)
const 684 mooseAssert(n.size() == 3,
685 "SolidMechanicsPlasticMohrCoulombMulti: Custom tip-return algorithm must be " 686 "supplied with n of size 3, whereas yours is " 688 mooseAssert(dpm.size() == 3,
689 "SolidMechanicsPlasticMohrCoulombMulti: Custom tip-return algorithm must be " 690 "supplied with dpm of size 3, whereas yours is " 692 mooseAssert(yf.size() == 6,
693 "SolidMechanicsPlasticMohrCoulombMulti: Custom tip-return algorithm must be " 694 "supplied with yf of size 6, whereas yours is " 697 Real x = initial_guess;
699 sinphi = std::sin(
phi(intnl_old +
x));
700 Real cosphi = std::cos(
phi(intnl_old +
x));
702 cohcos = coh * cosphi;
703 Real cohcot = cohcos / sinphi;
717 (n[0](0) * (n[1](1) - n[1](2) - n[2](1)) + (n[1](2) - n[1](1)) * n[2](0) +
718 (n[1](0) - n[1](2)) * n[2](1) + n[0](2) * (n[1](0) - n[1](1) - n[2](0) + n[2](1)) +
719 n[0](1) * (n[1](2) - n[1](0) + n[2](0) - n[2](2)) +
720 (n[0](0) - n[1](0) + n[1](1)) * n[2](2)) /
723 Real eig_term = eigvals[0] *
724 (-n[0](2) * n[1](1) + n[0](1) * n[1](2) + n[0](2) * n[2](1) -
725 n[1](2) * n[2](1) - n[0](1) * n[2](2) + n[1](1) * n[2](2)) /
727 eig_term += eigvals[1] *
728 (n[0](2) * n[1](0) - n[0](0) * n[1](2) - n[0](2) * n[2](0) + n[1](2) * n[2](0) +
729 n[0](0) * n[2](2) - n[1](0) * n[2](2)) /
731 eig_term += eigvals[2] *
732 (n[0](0) * n[1](1) - n[1](1) * n[2](0) + n[0](1) * n[2](0) - n[0](1) * n[1](0) -
733 n[0](0) * n[2](1) + n[1](0) * n[2](1)) /
739 eig_term /= cohcot_coeff;
740 Real residual =
x / cohcot_coeff - eig_term + cohcot;
744 unsigned int iter = 0;
747 deriv_phi =
dphi(intnl_old +
x);
749 jacobian = 1.0 / cohcot_coeff + deriv_coh * cosphi / sinphi -
750 coh * deriv_phi / Utility::pow<2>(sinphi);
751 x += -residual / jacobian;
755 nr_converged =
false;
759 sinphi = std::sin(
phi(intnl_old +
x));
760 cosphi = std::cos(
phi(intnl_old +
x));
762 cohcos = coh * cosphi;
763 cohcot = cohcos / sinphi;
764 residual =
x / cohcot_coeff - eig_term + cohcot;
773 if (
x < -3 * ep_plastic_tolerance)
784 v(0) = eigvals[0] - cohcot;
785 v(1) = eigvals[1] - cohcot;
786 v(2) = eigvals[2] - cohcot;
791 if (dpm[0] < -ep_plastic_tolerance || dpm[1] < -ep_plastic_tolerance ||
792 dpm[2] < -ep_plastic_tolerance)
799 returned_stress(0, 0) = returned_stress(1, 1) = returned_stress(2, 2) = cohcot;
801 yf[0] = yf[1] = yf[2] = yf[3] = yf[4] = yf[5] = 0;
807 const std::vector<RealVectorValue> & n,
808 std::vector<Real> & dpm,
815 Real ep_plastic_tolerance,
816 std::vector<Real> & yf)
const 833 mooseAssert(n.size() == 6,
834 "SolidMechanicsPlasticMohrCoulombMulti: Custom plane-return algorithm must be " 835 "supplied with n of size 6, whereas yours is " 837 mooseAssert(dpm.size() == 6,
838 "SolidMechanicsPlasticMohrCoulombMulti: Custom plane-return algorithm must be " 839 "supplied with dpm of size 6, whereas yours is " 841 mooseAssert(yf.size() == 6,
842 "SolidMechanicsPlasticMohrCoulombMulti: Custom tip-return algorithm must be " 843 "supplied with yf of size 6, whereas yours is " 846 dpm[3] = initial_guess;
847 sinphi = std::sin(
phi(intnl_old + dpm[3]));
848 Real cosphi = std::cos(
phi(intnl_old + dpm[3]));
850 cohcos = coh * cosphi;
852 Real alpha = n[3](0) - n[3](2) - (n[3](2) + n[3](0)) * sinphi;
855 const Real beta = eigvals[2] + eigvals[0];
859 alpha * dpm[3] + eigvals[2] - eigvals[0] + beta * sinphi - 2.0 * cohcos;
863 unsigned int iter = 0;
866 deriv_phi =
dphi(intnl_old + dpm[3]);
867 dalpha = -(n[3](2) + n[3](0)) * cosphi * deriv_phi;
868 deriv_coh =
dcohesion(intnl_old + dpm[3]);
869 jacobian =
alpha + dalpha * dpm[3] + beta * cosphi * deriv_phi - 2.0 * deriv_coh * cosphi +
870 2.0 * coh * sinphi * deriv_phi;
872 dpm[3] -= residual / jacobian;
875 nr_converged =
false;
879 sinphi = std::sin(
phi(intnl_old + dpm[3]));
880 cosphi = std::cos(
phi(intnl_old + dpm[3]));
882 cohcos = coh * cosphi;
883 alpha = n[3](0) - n[3](2) - (n[3](2) + n[3](0)) * sinphi;
884 residual =
alpha * dpm[3] + eigvals[2] - eigvals[0] + beta * sinphi - 2.0 * cohcos;
886 }
while (residual * residual > f_tol2);
891 if (dpm[3] < -ep_plastic_tolerance)
895 for (
unsigned i = 0; i < 3; ++i)
896 returned_stress(i, i) = eigvals[i] - dpm[3] * n[3](i);
898 returned_stress(0, 0), returned_stress(1, 1), returned_stress(2, 2), sinphi, cohcos, yf);
906 dpm[0] = dpm[1] = dpm[2] = dpm[4] = dpm[5] = 0;
912 const std::vector<RealVectorValue> & n,
913 std::vector<Real> & dpm,
921 Real ep_plastic_tolerance,
922 std::vector<Real> & yf)
const 939 Real x = initial_guess;
940 sinphi = std::sin(
phi(intnl_old +
x));
941 Real cosphi = std::cos(
phi(intnl_old +
x));
943 cohcos = coh * cosphi;
945 const Real numer_const =
946 -n[3](2) * eigvals[0] - n[5](1) * eigvals[0] + n[5](2) * eigvals[0] + n[3](2) * eigvals[1] +
947 n[5](0) * eigvals[1] - n[5](2) * eigvals[1] - n[5](0) * eigvals[2] + n[5](1) * eigvals[2] +
948 n[3](0) * (-eigvals[1] + eigvals[2]) - n[3](1) * (-eigvals[0] + eigvals[2]);
949 const Real numer_coeff1 = 2 * (-n[3](0) + n[3](1) + n[5](0) - n[5](1));
950 const Real numer_coeff2 =
951 n[5](2) * (eigvals[0] - eigvals[1]) + n[3](2) * (-eigvals[0] + eigvals[1]) +
952 n[5](1) * (eigvals[0] + eigvals[2]) + (n[3](0) - n[5](0)) * (eigvals[1] + eigvals[2]) -
953 n[3](1) * (eigvals[0] + eigvals[2]);
954 Real numer = numer_const + numer_coeff1 * cohcos + numer_coeff2 * sinphi;
955 const Real denom_const = -n[3](2) * (n[5](0) - n[5](1)) - n[3](1) * (-n[5](0) + n[5](2)) +
956 n[3](0) * (-n[5](1) + n[5](2));
957 const Real denom_coeff = -n[3](2) * (n[5](0) - n[5](1)) - n[3](1) * (n[5](0) + n[5](2)) +
958 n[3](0) * (n[5](1) + n[5](2));
959 Real denom = denom_const + denom_coeff * sinphi;
960 Real residual = -
x + numer / denom;
966 unsigned int iter = 0;
971 deriv_phi =
dphi(intnl_old + dpm[3]);
972 deriv_coh =
dcohesion(intnl_old + dpm[3]);
974 (numer_coeff1 * deriv_coh * cosphi - numer_coeff1 * coh * sinphi * deriv_phi +
975 numer_coeff2 * cosphi * deriv_phi) /
977 numer * denom_coeff * cosphi * deriv_phi / denom / denom;
978 x -= residual / jacobian;
981 nr_converged =
false;
985 sinphi = std::sin(
phi(intnl_old +
x));
986 cosphi = std::cos(
phi(intnl_old +
x));
988 cohcos = coh * cosphi;
989 numer = numer_const + numer_coeff1 * cohcos + numer_coeff2 * sinphi;
990 denom = denom_const + denom_coeff * sinphi;
991 residual = -
x + numer / denom;
993 }
while (residual * residual >
tol);
996 const Real dpm3minusdpm5 =
997 (2.0 * (eigvals[0] - eigvals[1]) +
x * (n[3](1) - n[3](0) + n[5](1) - n[5](0))) /
998 (n[3](0) - n[3](1) + n[5](1) - n[5](0));
999 dpm[3] = (
x + dpm3minusdpm5) / 2.0;
1000 dpm[5] = (
x - dpm3minusdpm5) / 2.0;
1002 for (
unsigned i = 0; i < 3; ++i)
1003 returned_stress(i, i) = eigvals[i] - dpm[3] * n[3](i) - dpm[5] * n[5](i);
1005 returned_stress(0, 0), returned_stress(1, 1), returned_stress(2, 2), sinphi, cohcos, yf);
1010 nr_converged =
true;
1012 if (dpm[3] < -ep_plastic_tolerance || dpm[5] < -ep_plastic_tolerance)
1023 dpm[0] = dpm[1] = dpm[2] = dpm[4] = 0;
1029 const std::vector<RealVectorValue> & n,
1030 std::vector<Real> & dpm,
1037 bool & nr_converged,
1038 Real ep_plastic_tolerance,
1039 std::vector<Real> & yf)
const 1056 Real x = initial_guess;
1057 sinphi = std::sin(
phi(intnl_old +
x));
1058 Real cosphi = std::cos(
phi(intnl_old +
x));
1060 cohcos = coh * cosphi;
1062 const Real numer_const = -n[1](2) * eigvals[0] - n[3](1) * eigvals[0] + n[3](2) * eigvals[0] -
1063 n[1](0) * eigvals[1] + n[1](2) * eigvals[1] + n[3](0) * eigvals[1] -
1064 n[3](2) * eigvals[1] + n[1](0) * eigvals[2] - n[3](0) * eigvals[2] +
1065 n[3](1) * eigvals[2] - n[1](1) * (-eigvals[0] + eigvals[2]);
1066 const Real numer_coeff1 = 2 * (n[1](1) - n[1](2) - n[3](1) + n[3](2));
1067 const Real numer_coeff2 =
1068 n[3](2) * (-eigvals[0] - eigvals[1]) + n[1](2) * (eigvals[0] + eigvals[1]) +
1069 n[3](1) * (eigvals[0] + eigvals[2]) + (n[1](0) - n[3](0)) * (eigvals[1] - eigvals[2]) -
1070 n[1](1) * (eigvals[0] + eigvals[2]);
1071 Real numer = numer_const + numer_coeff1 * cohcos + numer_coeff2 * sinphi;
1072 const Real denom_const = -n[1](0) * (n[3](1) - n[3](2)) + n[1](2) * (-n[3](0) + n[3](1)) +
1073 n[1](1) * (-n[3](2) + n[3](0));
1074 const Real denom_coeff =
1075 n[1](0) * (n[3](1) - n[3](2)) + n[1](2) * (n[3](0) + n[3](1)) - n[1](1) * (n[3](0) + n[3](2));
1076 Real denom = denom_const + denom_coeff * sinphi;
1077 Real residual = -
x + numer / denom;
1083 unsigned int iter = 0;
1088 deriv_phi =
dphi(intnl_old + dpm[3]);
1089 deriv_coh =
dcohesion(intnl_old + dpm[3]);
1091 (numer_coeff1 * deriv_coh * cosphi - numer_coeff1 * coh * sinphi * deriv_phi +
1092 numer_coeff2 * cosphi * deriv_phi) /
1094 numer * denom_coeff * cosphi * deriv_phi / denom / denom;
1095 x -= residual / jacobian;
1098 nr_converged =
false;
1102 sinphi = std::sin(
phi(intnl_old +
x));
1103 cosphi = std::cos(
phi(intnl_old +
x));
1105 cohcos = coh * cosphi;
1106 numer = numer_const + numer_coeff1 * cohcos + numer_coeff2 * sinphi;
1107 denom = denom_const + denom_coeff * sinphi;
1108 residual = -
x + numer / denom;
1110 }
while (residual * residual >
tol);
1113 Real dpm1minusdpm3 =
1114 (2 * (eigvals[1] - eigvals[2]) +
x * (n[1](2) - n[1](1) + n[3](2) - n[3](1))) /
1115 (n[1](1) - n[1](2) + n[3](2) - n[3](1));
1116 dpm[1] = (
x + dpm1minusdpm3) / 2.0;
1117 dpm[3] = (
x - dpm1minusdpm3) / 2.0;
1119 for (
unsigned i = 0; i < 3; ++i)
1120 returned_stress(i, i) = eigvals[i] - dpm[1] * n[1](i) - dpm[3] * n[3](i);
1122 returned_stress(0, 0), returned_stress(1, 1), returned_stress(2, 2), sinphi, cohcos, yf);
1127 nr_converged =
true;
1129 if (dpm[1] < -ep_plastic_tolerance || dpm[3] < -ep_plastic_tolerance)
1140 dpm[0] = dpm[2] = dpm[4] = dpm[5] = 0;
1146 const std::vector<Real> & dpm,
1147 Real ep_plastic_tolerance)
const 1151 "SolidMechanicsPlasticMohrCoulomb::KuhnTuckerOK requires yf to be size 6, but your is " 1155 "SolidMechanicsPlasticMohrCoulomb::KuhnTuckerOK requires dpm to be size 6, but your is " 1157 for (
unsigned i = 0; i < 6; ++i)
bool KuhnTuckerOK(const std::vector< Real > &yf, const std::vector< Real > &dpm, Real ep_plastic_tolerance) const
Returns true if the Kuhn-Tucker conditions are satisfied.
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.
void perturbStress(const RankTwoTensor &stress, std::vector< Real > &eigvals, std::vector< RankTwoTensor > &deigvals) const
perturbs the stress tensor in the case of almost-equal eigenvalues.
void yieldFunctionEigvals(Real e0, Real e1, Real e2, Real sinphi, Real cohcos, std::vector< Real > &f) const
Calculates the yield functions given the eigenvalues of stress.
void symmetricEigenvalues(std::vector< Real > &eigvals) const
void df_dsig(const RankTwoTensor &stress, Real sin_angle, std::vector< RankTwoTensor > &df) const
this is exactly dyieldFunction_dstress, or flowPotential, depending on whether sin_angle = sin(phi)...
void dsymmetricEigenvalues(std::vector< Real > &eigvals, std::vector< RankTwoTensorTempl< Real >> &deigvals) const
void print(std::ostream &stm=Moose::out) const
virtual void dyieldFunction_dstressV(const RankTwoTensor &stress, Real intnl, std::vector< RankTwoTensor > &df_dstress) const override
The derivative of yield functions with respect to stress.
void seed(std::size_t i, unsigned int seed)
static InputParameters validParams()
virtual void dflowPotential_dstressV(const RankTwoTensor &stress, Real intnl, std::vector< RankFourTensor > &dr_dstress) const override
The derivative of the flow potential with respect to stress.
virtual Real dphi(const Real internal_param) const
d(phi)/d(internal_param) as a function of residual value, rate, and internal_param ...
virtual std::string modelName() const =0
bool KuhnTuckerSingleSurface(Real yf, Real dpm, Real dpm_tol) const
Returns true if the Kuhn-Tucker conditions for the single surface are satisfied.
virtual Real value(Real intnl) const
registerMooseObjectRenamed("SolidMechanicsApp", TensorMechanicsPlasticMohrCoulombMulti, "01/01/2025 00:00", SolidMechanicsPlasticMohrCoulombMulti)
virtual void flowPotentialV(const RankTwoTensor &stress, Real intnl, std::vector< RankTwoTensor > &r) const override
The flow potentials.
SolidMechanicsPlasticMohrCoulombMulti(const InputParameters ¶meters)
virtual Real dpsi(const Real internal_param) const
d(psi)/d(internal_param) as a function of residual value, rate, and internal_param ...
const SolidMechanicsHardeningModel & _cohesion
Hardening model for cohesion.
const bool _use_custom_returnMap
Whether to use the custom return-map algorithm.
T triple_product(const TypeVector< T > &a, const TypeVector< T > &b, const TypeVector< T > &c)
const SolidMechanicsHardeningModel & _psi
Hardening model for psi.
virtual Real psi(const Real internal_param) const
psi as a function of residual value, rate, and internal_param
static InputParameters validParams()
bool returnEdge000101(const std::vector< Real > &eigvals, const std::vector< RealVectorValue > &n, std::vector< Real > &dpm, RankTwoTensor &returned_stress, Real intnl_old, Real &sinphi, Real &cohcos, Real initial_guess, Real mag_E, bool &nr_converged, Real ep_plastic_tolerance, std::vector< Real > &yf) const
Tries to return-map to the MC edge using the n[4] and n[6] directions The return value is true if the...
const std::vector< double > x
Real f(Real x)
Test function for Brents method.
registerMooseObject("SolidMechanicsApp", SolidMechanicsPlasticMohrCoulombMulti)
virtual void yieldFunctionV(const RankTwoTensor &stress, Real intnl, std::vector< Real > &f) const override
Calculates the yield functions.
void d2symmetricEigenvalues(std::vector< RankFourTensorTempl< Real >> &deriv) const
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 void dyieldFunction_dintnlV(const RankTwoTensor &stress, Real intnl, std::vector< Real > &df_dintnl) const override
The derivative of yield functions with respect to the internal parameter.
virtual void dflowPotential_dintnlV(const RankTwoTensor &stress, Real intnl, std::vector< RankTwoTensor > &dr_dintnl) const override
The derivative of the flow potential with respect to the internal parameter.
const Real _shift
yield function is shifted by this amount to avoid problems with stress-derivatives at equal eigenvalu...
virtual std::string modelName() const override
const Real _f_tol
Tolerance on yield function.
virtual Real cohesion(const Real internal_param) const
cohesion as a function of residual value, rate, and internal_param
virtual Real derivative(Real intnl) const
const SolidMechanicsHardeningModel & _phi
Hardening model for phi.
RankTwoTensorTempl< Real > transpose() const
Hardening Model base class.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const std::string v
void symmetricEigenvaluesEigenvectors(std::vector< Real > &eigvals, RankTwoTensorTempl< Real > &eigvecs) const
static const std::string alpha
const unsigned int _max_iters
Maximum Newton-Raphison iterations in the custom returnMap algorithm.
FiniteStrainMohrCoulombMulti implements rate-independent non-associative mohr-coulomb with hardening/...
bool doReturnMap(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
See doco for returnMap function.
void mooseError(Args &&... args) const
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
bool returnTip(const std::vector< Real > &eigvals, const std::vector< RealVectorValue > &n, std::vector< Real > &dpm, RankTwoTensor &returned_stress, Real intnl_old, Real &sinphi, Real &cohcos, Real initial_guess, bool &nr_converged, Real ep_plastic_tolerance, std::vector< Real > &yf) const
Tries to return-map to the MC tip using the THREE directions given in n, and THREE dpm values are ret...
virtual unsigned int numberSurfaces() const override
The number of yield surfaces for this plasticity model.
const ConsoleStream _console
virtual void activeConstraints(const std::vector< Real > &f, const RankTwoTensor &stress, Real intnl, const RankFourTensor &Eijkl, std::vector< bool > &act, RankTwoTensor &returned_stress) const override
The active yield surfaces, given a vector of yield functions.
virtual Real phi(const Real internal_param) const
phi as a function of residual value, rate, and internal_param
virtual Real dcohesion(const Real internal_param) const
d(cohesion)/d(internal_param) as a function of residual value, rate, and internal_param ...
bool returnPlane(const std::vector< Real > &eigvals, const std::vector< RealVectorValue > &n, std::vector< Real > &dpm, RankTwoTensor &returned_stress, Real intnl_old, Real &sinphi, Real &cohcos, Real initial_guess, bool &nr_converged, Real ep_plastic_tolerance, std::vector< Real > &yf) const
Tries to return-map to the MC plane using the n[3] direction The return value is true if the internal...
Plastic Model base class The virtual functions written below must be over-ridden in derived classes t...
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 ErrorVector unsigned int
bool returnEdge010100(const std::vector< Real > &eigvals, const std::vector< RealVectorValue > &n, std::vector< Real > &dpm, RankTwoTensor &returned_stress, Real intnl_old, Real &sinphi, Real &cohcos, Real initial_guess, Real mag_E, bool &nr_converged, Real ep_plastic_tolerance, std::vector< Real > &yf) const
Tries to return-map to the MC edge using the n[1] and n[3] directions The return value is true if the...