11 #include "RankFourTensor.h"
14 #include "MooseRandom.h"
15 #include "libmesh/utility.h"
25 params.addClassDescription(
"Non-associative Mohr-Coulomb plasticity with hardening/softening");
26 params.addRequiredParam<UserObjectName>(
27 "cohesion",
"A TensorMechanicsHardening UserObject that defines hardening of the cohesion");
28 params.addRequiredParam<UserObjectName>(
"friction_angle",
29 "A TensorMechanicsHardening UserObject "
30 "that defines hardening of the "
31 "friction angle (in radians)");
32 params.addRequiredParam<UserObjectName>(
"dilation_angle",
33 "A TensorMechanicsHardening UserObject "
34 "that defines hardening of the "
35 "dilation angle (in radians)");
36 params.addParam<
unsigned int>(
"max_iterations",
38 "Maximum number of Newton-Raphson iterations "
39 "allowed in the custom return-map algorithm. "
40 " For highly nonlinear hardening this may "
41 "need to be higher than 10.");
42 params.addParam<Real>(
"shift",
43 "Yield surface is shifted by this amount to avoid problems with "
44 "defining derivatives when eigenvalues are equal. If this is "
45 "larger than f_tol, a warning will be issued. This may be set "
46 "very small when using the custom returnMap. Default = f_tol.");
47 params.addParam<
bool>(
"use_custom_returnMap",
49 "Use a custom return-map algorithm for this "
50 "plasticity model, which may speed up "
51 "computations considerably. Set to true "
52 "only for isotropic elasticity with no "
53 "hardening of the dilation angle. In this "
54 "case you may set 'shift' very small.");
60 const InputParameters & parameters)
65 _max_iters(getParam<unsigned int>(
"max_iterations")),
66 _shift(parameters.isParamValid(
"shift") ? getParam<Real>(
"shift") : _f_tol),
67 _use_custom_returnMap(getParam<bool>(
"use_custom_returnMap"))
70 mooseError(
"Value of 'shift' in TensorMechanicsPlasticMohrCoulombMulti must not be negative\n");
72 _console <<
"WARNING: value of 'shift' in TensorMechanicsPlasticMohrCoulombMulti is probably "
75 mooseError(
"TensorMechanicsPlasticMohrCoulombMulti is only defined for LIBMESH_DIM=3");
88 std::vector<Real> & f)
const
90 std::vector<Real> eigvals;
91 stress.symmetricEigenvalues(eigvals);
95 const Real sinphi = std::sin(
phi(intnl));
96 const Real cosphi = std::cos(
phi(intnl));
97 const Real cohcos =
cohesion(intnl) * cosphi;
104 Real e0, Real e1, Real e2, Real sinphi, Real cohcos, std::vector<Real> & f)
const
112 f[0] = 0.5 * (e0 - e1) + 0.5 * (e0 + e1) * sinphi - cohcos;
113 f[1] = 0.5 * (e1 - e0) + 0.5 * (e0 + e1) * sinphi - cohcos;
114 f[2] = 0.5 * (e0 - e2) + 0.5 * (e0 + e2) * sinphi - cohcos;
115 f[3] = 0.5 * (e2 - e0) + 0.5 * (e0 + e2) * sinphi - cohcos;
116 f[4] = 0.5 * (e1 - e2) + 0.5 * (e1 + e2) * sinphi - cohcos;
117 f[5] = 0.5 * (e2 - e1) + 0.5 * (e1 + e2) * sinphi - cohcos;
122 std::vector<Real> & eigvals,
123 std::vector<RankTwoTensor> & deigvals)
const
125 Real small_perturbation;
127 while (eigvals[0] > eigvals[1] - 0.1 *
_shift || eigvals[1] > eigvals[2] - 0.1 *
_shift)
129 for (
unsigned i = 0; i < 3; ++i)
130 for (
unsigned j = 0; j <= i; ++j)
132 small_perturbation = 0.1 *
_shift * 2 * (MooseRandom::rand() - 0.5);
133 shifted_stress(i, j) += small_perturbation;
134 shifted_stress(j, i) += small_perturbation;
136 shifted_stress.dsymmetricEigenvalues(eigvals, deigvals);
143 std::vector<RankTwoTensor> & df)
const
145 std::vector<Real> eigvals;
146 std::vector<RankTwoTensor> deigvals;
147 stress.dsymmetricEigenvalues(eigvals, deigvals);
149 if (eigvals[0] > eigvals[1] - 0.1 *
_shift || eigvals[1] > eigvals[2] - 0.1 *
_shift)
153 df[0] = 0.5 * (deigvals[0] - deigvals[1]) + 0.5 * (deigvals[0] + deigvals[1]) * sin_angle;
154 df[1] = 0.5 * (deigvals[1] - deigvals[0]) + 0.5 * (deigvals[0] + deigvals[1]) * sin_angle;
155 df[2] = 0.5 * (deigvals[0] - deigvals[2]) + 0.5 * (deigvals[0] + deigvals[2]) * sin_angle;
156 df[3] = 0.5 * (deigvals[2] - deigvals[0]) + 0.5 * (deigvals[0] + deigvals[2]) * sin_angle;
157 df[4] = 0.5 * (deigvals[1] - deigvals[2]) + 0.5 * (deigvals[1] + deigvals[2]) * sin_angle;
158 df[5] = 0.5 * (deigvals[2] - deigvals[1]) + 0.5 * (deigvals[1] + deigvals[2]) * sin_angle;
163 const RankTwoTensor & stress, Real intnl, std::vector<RankTwoTensor> & df_dstress)
const
165 const Real sinphi = std::sin(
phi(intnl));
166 df_dsig(stress, sinphi, df_dstress);
172 std::vector<Real> & df_dintnl)
const
174 std::vector<Real> eigvals;
175 stress.symmetricEigenvalues(eigvals);
179 const Real sin_angle = std::sin(
phi(intnl));
180 const Real cos_angle = std::cos(
phi(intnl));
181 const Real dsin_angle = cos_angle *
dphi(intnl);
182 const Real dcos_angle = -sin_angle *
dphi(intnl);
183 const Real dcohcos =
dcohesion(intnl) * cos_angle +
cohesion(intnl) * dcos_angle;
186 df_dintnl[0] = df_dintnl[1] = 0.5 * (eigvals[0] + eigvals[1]) * dsin_angle - dcohcos;
187 df_dintnl[2] = df_dintnl[3] = 0.5 * (eigvals[0] + eigvals[2]) * dsin_angle - dcohcos;
188 df_dintnl[4] = df_dintnl[5] = 0.5 * (eigvals[1] + eigvals[2]) * dsin_angle - dcohcos;
194 std::vector<RankTwoTensor> & r)
const
196 const Real sinpsi = std::sin(
psi(intnl));
202 const RankTwoTensor & stress, Real intnl, std::vector<RankFourTensor> & dr_dstress)
const
204 std::vector<RankFourTensor> d2eigvals;
205 stress.d2symmetricEigenvalues(d2eigvals);
207 const Real sinpsi = std::sin(
psi(intnl));
209 dr_dstress.resize(6);
211 0.5 * (d2eigvals[0] - d2eigvals[1]) + 0.5 * (d2eigvals[0] + d2eigvals[1]) * sinpsi;
213 0.5 * (d2eigvals[1] - d2eigvals[0]) + 0.5 * (d2eigvals[0] + d2eigvals[1]) * sinpsi;
215 0.5 * (d2eigvals[0] - d2eigvals[2]) + 0.5 * (d2eigvals[0] + d2eigvals[2]) * sinpsi;
217 0.5 * (d2eigvals[2] - d2eigvals[0]) + 0.5 * (d2eigvals[0] + d2eigvals[2]) * sinpsi;
219 0.5 * (d2eigvals[1] - d2eigvals[2]) + 0.5 * (d2eigvals[1] + d2eigvals[2]) * sinpsi;
221 0.5 * (d2eigvals[2] - d2eigvals[1]) + 0.5 * (d2eigvals[1] + d2eigvals[2]) * sinpsi;
226 const RankTwoTensor & stress, Real intnl, std::vector<RankTwoTensor> & dr_dintnl)
const
228 const Real cos_angle = std::cos(
psi(intnl));
229 const Real dsin_angle = cos_angle *
dpsi(intnl);
231 std::vector<Real> eigvals;
232 std::vector<RankTwoTensor> deigvals;
233 stress.dsymmetricEigenvalues(eigvals, deigvals);
235 if (eigvals[0] > eigvals[1] - 0.1 *
_shift || eigvals[1] > eigvals[2] - 0.1 *
_shift)
239 dr_dintnl[0] = dr_dintnl[1] = 0.5 * (deigvals[0] + deigvals[1]) * dsin_angle;
240 dr_dintnl[2] = dr_dintnl[3] = 0.5 * (deigvals[0] + deigvals[2]) * dsin_angle;
241 dr_dintnl[4] = dr_dintnl[5] = 0.5 * (deigvals[1] + deigvals[2]) * dsin_angle;
249 std::vector<bool> & act,
252 act.assign(6,
false);
257 returned_stress = stress;
262 std::vector<Real> dpm(6);
264 std::vector<Real> yf(6);
265 bool trial_stress_inadmissible;
275 trial_stress_inadmissible);
277 for (
unsigned i = 0; i < 6; ++i)
278 act[i] = (dpm[i] > 0);
320 return "MohrCoulombMulti";
327 Real ep_plastic_tolerance,
329 Real & returned_intnl,
330 std::vector<Real> & dpm,
332 std::vector<Real> & yf,
333 bool & trial_stress_inadmissible)
const
339 ep_plastic_tolerance,
345 trial_stress_inadmissible);
350 ep_plastic_tolerance,
356 trial_stress_inadmissible);
363 Real ep_plastic_tolerance,
365 Real & returned_intnl,
366 std::vector<Real> & dpm,
368 std::vector<Real> & yf,
369 bool & trial_stress_inadmissible)
const
371 mooseAssert(dpm.size() == 6,
372 "TensorMechanicsPlasticMohrCoulombMulti size of dpm should be 6 but it is "
375 std::vector<Real> eigvals;
377 trial_stress.symmetricEigenvaluesEigenvectors(eigvals, eigvecs);
381 Real sinphi = std::sin(
phi(intnl_old));
382 Real cosphi = std::cos(
phi(intnl_old));
384 Real cohcos = coh * cosphi;
392 trial_stress_inadmissible =
false;
396 trial_stress_inadmissible =
true;
402 std::vector<RealVectorValue> norm(6);
403 const Real sinpsi = std::sin(
psi(intnl_old));
404 const Real oneminus = 0.5 * (1 - sinpsi);
405 const Real oneplus = 0.5 * (1 + sinpsi);
406 norm[0](0) = oneplus;
407 norm[0](1) = -oneminus;
409 norm[1](0) = -oneminus;
410 norm[1](1) = oneplus;
412 norm[2](0) = oneplus;
414 norm[2](2) = -oneminus;
415 norm[3](0) = -oneminus;
417 norm[3](2) = oneplus;
419 norm[4](1) = oneplus;
420 norm[4](2) = -oneminus;
422 norm[5](1) = -oneminus;
423 norm[5](2) = oneplus;
431 std::vector<RealVectorValue> n(6);
432 for (
unsigned ys = 0; ys < 6; ++ys)
433 for (
unsigned i = 0; i < 3; ++i)
434 for (
unsigned j = 0; j < 3; ++j)
435 n[ys](i) += E_ijkl(i, i, j, j) * norm[ys](j);
436 const Real mag_E = E_ijkl(0, 0, 0, 0);
452 const unsigned int number_of_return_paths = 5;
453 std::vector<int> trial_order(number_of_return_paths);
488 bool nr_converged =
false;
489 bool kt_success =
false;
490 std::vector<RealVectorValue> ntip(3);
491 std::vector<Real> dpmtip(3);
493 for (trial = 0; trial < number_of_return_paths; ++trial)
495 switch (trial_order[trial])
498 for (
unsigned int i = 0; i < 3; ++i)
500 ntip[0](i) = n[0](i);
501 ntip[1](i) = n[1](i);
502 ntip[2](i) = n[3](i);
513 ep_plastic_tolerance,
515 if (nr_converged && kt_success)
520 dpm[2] = dpm[4] = dpm[5] = 0;
525 for (
unsigned int i = 0; i < 3; ++i)
527 ntip[0](i) = n[1](i);
528 ntip[1](i) = n[3](i);
529 ntip[2](i) = n[5](i);
540 ep_plastic_tolerance,
542 if (nr_converged && kt_success)
547 dpm[0] = dpm[2] = dpm[4] = 0;
562 ep_plastic_tolerance,
577 ep_plastic_tolerance,
591 ep_plastic_tolerance,
596 if (nr_converged && kt_success)
600 if (trial == number_of_return_paths)
602 sinphi = std::sin(
phi(intnl_old));
603 cosphi = std::cos(
phi(intnl_old));
605 cohcos = coh * cosphi;
607 Moose::err <<
"Trial stress = \n";
608 trial_stress.print(Moose::err);
609 Moose::err <<
"which has eigenvalues = " << eigvals[0] <<
" " << eigvals[1] <<
" " << eigvals[2]
611 Moose::err <<
"and yield functions = " << yf[0] <<
" " << yf[1] <<
" " << yf[2] <<
" " << yf[3]
612 <<
" " << yf[4] <<
" " << yf[5] <<
"\n";
613 Moose::err <<
"Internal parameter = " << intnl_old <<
"\n";
614 mooseError(
"TensorMechanicsPlasticMohrCoulombMulti: FAILURE! You probably need to implement a "
615 "line search if your hardening is too severe, or you need to tune your tolerances "
616 "(eg, yield_function_tolerance should be a little smaller than (young "
617 "modulus)*ep_plastic_tolerance).\n");
623 returned_intnl = intnl_old;
624 for (
unsigned i = 0; i < 6; ++i)
625 returned_intnl += dpm[i];
626 for (
unsigned i = 0; i < 6; ++i)
627 for (
unsigned j = 0; j < 3; ++j)
628 delta_dp(j, j) += dpm[i] * norm[i](j);
629 returned_stress = eigvecs * returned_stress * (eigvecs.transpose());
630 delta_dp = eigvecs * delta_dp * (eigvecs.transpose());
636 const std::vector<RealVectorValue> & n,
637 std::vector<Real> & dpm,
644 Real ep_plastic_tolerance,
645 std::vector<Real> & yf)
const
681 mooseAssert(n.size() == 3,
682 "TensorMechanicsPlasticMohrCoulombMulti: Custom tip-return algorithm must be "
683 "supplied with n of size 3, whereas yours is "
685 mooseAssert(dpm.size() == 3,
686 "TensorMechanicsPlasticMohrCoulombMulti: Custom tip-return algorithm must be "
687 "supplied with dpm of size 3, whereas yours is "
689 mooseAssert(yf.size() == 6,
690 "TensorMechanicsPlasticMohrCoulombMulti: Custom tip-return algorithm must be "
691 "supplied with yf of size 6, whereas yours is "
694 Real x = initial_guess;
695 const Real trip = triple_product(n[0], n[1], n[2]);
696 sinphi = std::sin(
phi(intnl_old + x));
697 Real cosphi = std::cos(
phi(intnl_old + x));
699 cohcos = coh * cosphi;
700 Real cohcot = cohcos / sinphi;
714 (n[0](0) * (n[1](1) - n[1](2) - n[2](1)) + (n[1](2) - n[1](1)) * n[2](0) +
715 (n[1](0) - n[1](2)) * n[2](1) + n[0](2) * (n[1](0) - n[1](1) - n[2](0) + n[2](1)) +
716 n[0](1) * (n[1](2) - n[1](0) + n[2](0) - n[2](2)) +
717 (n[0](0) - n[1](0) + n[1](1)) * n[2](2)) /
720 Real eig_term = eigvals[0] *
721 (-n[0](2) * n[1](1) + n[0](1) * n[1](2) + n[0](2) * n[2](1) -
722 n[1](2) * n[2](1) - n[0](1) * n[2](2) + n[1](1) * n[2](2)) /
724 eig_term += eigvals[1] *
725 (n[0](2) * n[1](0) - n[0](0) * n[1](2) - n[0](2) * n[2](0) + n[1](2) * n[2](0) +
726 n[0](0) * n[2](2) - n[1](0) * n[2](2)) /
728 eig_term += eigvals[2] *
729 (n[0](0) * n[1](1) - n[1](1) * n[2](0) + n[0](1) * n[2](0) - n[0](1) * n[1](0) -
730 n[0](0) * n[2](1) + n[1](0) * n[2](1)) /
736 eig_term /= cohcot_coeff;
737 Real residual = x / cohcot_coeff - eig_term + cohcot;
741 unsigned int iter = 0;
744 deriv_phi =
dphi(intnl_old + x);
746 jacobian = 1.0 / cohcot_coeff + deriv_coh * cosphi / sinphi -
747 coh * deriv_phi / Utility::pow<2>(sinphi);
748 x += -residual / jacobian;
752 nr_converged =
false;
756 sinphi = std::sin(
phi(intnl_old + x));
757 cosphi = std::cos(
phi(intnl_old + x));
759 cohcos = coh * cosphi;
760 cohcot = cohcos / sinphi;
761 residual = x / cohcot_coeff - eig_term + cohcot;
770 if (x < -3 * ep_plastic_tolerance)
781 v(0) = eigvals[0] - cohcot;
782 v(1) = eigvals[1] - cohcot;
783 v(2) = eigvals[2] - cohcot;
784 dpm[0] = triple_product(v, n[1], n[2]) / trip;
785 dpm[1] = triple_product(v, n[2], n[0]) / trip;
786 dpm[2] = triple_product(v, n[0], n[1]) / trip;
788 if (dpm[0] < -ep_plastic_tolerance || dpm[1] < -ep_plastic_tolerance ||
789 dpm[2] < -ep_plastic_tolerance)
796 returned_stress(0, 0) = returned_stress(1, 1) = returned_stress(2, 2) = cohcot;
798 yf[0] = yf[1] = yf[2] = yf[3] = yf[4] = yf[5] = 0;
804 const std::vector<RealVectorValue> & n,
805 std::vector<Real> & dpm,
812 Real ep_plastic_tolerance,
813 std::vector<Real> & yf)
const
830 mooseAssert(n.size() == 6,
831 "TensorMechanicsPlasticMohrCoulombMulti: Custom plane-return algorithm must be "
832 "supplied with n of size 6, whereas yours is "
834 mooseAssert(dpm.size() == 6,
835 "TensorMechanicsPlasticMohrCoulombMulti: Custom plane-return algorithm must be "
836 "supplied with dpm of size 6, whereas yours is "
838 mooseAssert(yf.size() == 6,
839 "TensorMechanicsPlasticMohrCoulombMulti: Custom tip-return algorithm must be "
840 "supplied with yf of size 6, whereas yours is "
843 dpm[3] = initial_guess;
844 sinphi = std::sin(
phi(intnl_old + dpm[3]));
845 Real cosphi = std::cos(
phi(intnl_old + dpm[3]));
846 Real coh =
cohesion(intnl_old + dpm[3]);
847 cohcos = coh * cosphi;
849 Real alpha = n[3](0) - n[3](2) - (n[3](2) + n[3](0)) * sinphi;
852 const Real beta = eigvals[2] + eigvals[0];
856 alpha * dpm[3] + eigvals[2] - eigvals[0] + beta * sinphi - 2.0 * cohcos;
859 const Real f_tol2 = Utility::pow<2>(
_f_tol);
860 unsigned int iter = 0;
863 deriv_phi =
dphi(intnl_old + dpm[3]);
864 dalpha = -(n[3](2) + n[3](0)) * cosphi * deriv_phi;
865 deriv_coh =
dcohesion(intnl_old + dpm[3]);
866 jacobian = alpha + dalpha * dpm[3] + beta * cosphi * deriv_phi - 2.0 * deriv_coh * cosphi +
867 2.0 * coh * sinphi * deriv_phi;
869 dpm[3] -= residual / jacobian;
872 nr_converged =
false;
876 sinphi = std::sin(
phi(intnl_old + dpm[3]));
877 cosphi = std::cos(
phi(intnl_old + dpm[3]));
879 cohcos = coh * cosphi;
880 alpha = n[3](0) - n[3](2) - (n[3](2) + n[3](0)) * sinphi;
881 residual = alpha * dpm[3] + eigvals[2] - eigvals[0] + beta * sinphi - 2.0 * cohcos;
883 }
while (residual * residual > f_tol2);
888 if (dpm[3] < -ep_plastic_tolerance)
892 for (
unsigned i = 0; i < 3; ++i)
893 returned_stress(i, i) = eigvals[i] - dpm[3] * n[3](i);
895 returned_stress(0, 0), returned_stress(1, 1), returned_stress(2, 2), sinphi, cohcos, yf);
903 dpm[0] = dpm[1] = dpm[2] = dpm[4] = dpm[5] = 0;
909 const std::vector<RealVectorValue> & n,
910 std::vector<Real> & dpm,
918 Real ep_plastic_tolerance,
919 std::vector<Real> & yf)
const
936 Real x = initial_guess;
937 sinphi = std::sin(
phi(intnl_old + x));
938 Real cosphi = std::cos(
phi(intnl_old + x));
940 cohcos = coh * cosphi;
942 const Real numer_const =
943 -n[3](2) * eigvals[0] - n[5](1) * eigvals[0] + n[5](2) * eigvals[0] + n[3](2) * eigvals[1] +
944 n[5](0) * eigvals[1] - n[5](2) * eigvals[1] - n[5](0) * eigvals[2] + n[5](1) * eigvals[2] +
945 n[3](0) * (-eigvals[1] + eigvals[2]) - n[3](1) * (-eigvals[0] + eigvals[2]);
946 const Real numer_coeff1 = 2 * (-n[3](0) + n[3](1) + n[5](0) - n[5](1));
947 const Real numer_coeff2 =
948 n[5](2) * (eigvals[0] - eigvals[1]) + n[3](2) * (-eigvals[0] + eigvals[1]) +
949 n[5](1) * (eigvals[0] + eigvals[2]) + (n[3](0) - n[5](0)) * (eigvals[1] + eigvals[2]) -
950 n[3](1) * (eigvals[0] + eigvals[2]);
951 Real numer = numer_const + numer_coeff1 * cohcos + numer_coeff2 * sinphi;
952 const Real denom_const = -n[3](2) * (n[5](0) - n[5](1)) - n[3](1) * (-n[5](0) + n[5](2)) +
953 n[3](0) * (-n[5](1) + n[5](2));
954 const Real denom_coeff = -n[3](2) * (n[5](0) - n[5](1)) - n[3](1) * (n[5](0) + n[5](2)) +
955 n[3](0) * (n[5](1) + n[5](2));
956 Real denom = denom_const + denom_coeff * sinphi;
957 Real residual = -x + numer / denom;
962 const Real
tol = Utility::pow<2>(
_f_tol / (mag_E * 10.0));
963 unsigned int iter = 0;
968 deriv_phi =
dphi(intnl_old + dpm[3]);
969 deriv_coh =
dcohesion(intnl_old + dpm[3]);
971 (numer_coeff1 * deriv_coh * cosphi - numer_coeff1 * coh * sinphi * deriv_phi +
972 numer_coeff2 * cosphi * deriv_phi) /
974 numer * denom_coeff * cosphi * deriv_phi / denom / denom;
975 x -= residual / jacobian;
978 nr_converged =
false;
982 sinphi = std::sin(
phi(intnl_old + x));
983 cosphi = std::cos(
phi(intnl_old + x));
985 cohcos = coh * cosphi;
986 numer = numer_const + numer_coeff1 * cohcos + numer_coeff2 * sinphi;
987 denom = denom_const + denom_coeff * sinphi;
988 residual = -x + numer / denom;
990 }
while (residual * residual >
tol);
993 const Real dpm3minusdpm5 =
994 (2.0 * (eigvals[0] - eigvals[1]) + x * (n[3](1) - n[3](0) + n[5](1) - n[5](0))) /
995 (n[3](0) - n[3](1) + n[5](1) - n[5](0));
996 dpm[3] = (x + dpm3minusdpm5) / 2.0;
997 dpm[5] = (x - dpm3minusdpm5) / 2.0;
999 for (
unsigned i = 0; i < 3; ++i)
1000 returned_stress(i, i) = eigvals[i] - dpm[3] * n[3](i) - dpm[5] * n[5](i);
1002 returned_stress(0, 0), returned_stress(1, 1), returned_stress(2, 2), sinphi, cohcos, yf);
1007 nr_converged =
true;
1009 if (dpm[3] < -ep_plastic_tolerance || dpm[5] < -ep_plastic_tolerance)
1020 dpm[0] = dpm[1] = dpm[2] = dpm[4] = 0;
1026 const std::vector<RealVectorValue> & n,
1027 std::vector<Real> & dpm,
1034 bool & nr_converged,
1035 Real ep_plastic_tolerance,
1036 std::vector<Real> & yf)
const
1053 Real x = initial_guess;
1054 sinphi = std::sin(
phi(intnl_old + x));
1055 Real cosphi = std::cos(
phi(intnl_old + x));
1056 Real coh =
cohesion(intnl_old + x);
1057 cohcos = coh * cosphi;
1059 const Real numer_const = -n[1](2) * eigvals[0] - n[3](1) * eigvals[0] + n[3](2) * eigvals[0] -
1060 n[1](0) * eigvals[1] + n[1](2) * eigvals[1] + n[3](0) * eigvals[1] -
1061 n[3](2) * eigvals[1] + n[1](0) * eigvals[2] - n[3](0) * eigvals[2] +
1062 n[3](1) * eigvals[2] - n[1](1) * (-eigvals[0] + eigvals[2]);
1063 const Real numer_coeff1 = 2 * (n[1](1) - n[1](2) - n[3](1) + n[3](2));
1064 const Real numer_coeff2 =
1065 n[3](2) * (-eigvals[0] - eigvals[1]) + n[1](2) * (eigvals[0] + eigvals[1]) +
1066 n[3](1) * (eigvals[0] + eigvals[2]) + (n[1](0) - n[3](0)) * (eigvals[1] - eigvals[2]) -
1067 n[1](1) * (eigvals[0] + eigvals[2]);
1068 Real numer = numer_const + numer_coeff1 * cohcos + numer_coeff2 * sinphi;
1069 const Real denom_const = -n[1](0) * (n[3](1) - n[3](2)) + n[1](2) * (-n[3](0) + n[3](1)) +
1070 n[1](1) * (-n[3](2) + n[3](0));
1071 const Real denom_coeff =
1072 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));
1073 Real denom = denom_const + denom_coeff * sinphi;
1074 Real residual = -x + numer / denom;
1079 const Real
tol = Utility::pow<2>(
_f_tol / (mag_E * 10.0));
1080 unsigned int iter = 0;
1085 deriv_phi =
dphi(intnl_old + dpm[3]);
1086 deriv_coh =
dcohesion(intnl_old + dpm[3]);
1088 (numer_coeff1 * deriv_coh * cosphi - numer_coeff1 * coh * sinphi * deriv_phi +
1089 numer_coeff2 * cosphi * deriv_phi) /
1091 numer * denom_coeff * cosphi * deriv_phi / denom / denom;
1092 x -= residual / jacobian;
1095 nr_converged =
false;
1099 sinphi = std::sin(
phi(intnl_old + x));
1100 cosphi = std::cos(
phi(intnl_old + x));
1102 cohcos = coh * cosphi;
1103 numer = numer_const + numer_coeff1 * cohcos + numer_coeff2 * sinphi;
1104 denom = denom_const + denom_coeff * sinphi;
1105 residual = -x + numer / denom;
1107 }
while (residual * residual >
tol);
1110 Real dpm1minusdpm3 =
1111 (2 * (eigvals[1] - eigvals[2]) + x * (n[1](2) - n[1](1) + n[3](2) - n[3](1))) /
1112 (n[1](1) - n[1](2) + n[3](2) - n[3](1));
1113 dpm[1] = (x + dpm1minusdpm3) / 2.0;
1114 dpm[3] = (x - dpm1minusdpm3) / 2.0;
1116 for (
unsigned i = 0; i < 3; ++i)
1117 returned_stress(i, i) = eigvals[i] - dpm[1] * n[1](i) - dpm[3] * n[3](i);
1119 returned_stress(0, 0), returned_stress(1, 1), returned_stress(2, 2), sinphi, cohcos, yf);
1124 nr_converged =
true;
1126 if (dpm[1] < -ep_plastic_tolerance || dpm[3] < -ep_plastic_tolerance)
1137 dpm[0] = dpm[2] = dpm[4] = dpm[5] = 0;
1143 const std::vector<Real> & dpm,
1144 Real ep_plastic_tolerance)
const
1148 "TensorMechanicsPlasticMohrCoulomb::KuhnTuckerOK requires yf to be size 6, but your is "
1152 "TensorMechanicsPlasticMohrCoulomb::KuhnTuckerOK requires dpm to be size 6, but your is "
1154 for (
unsigned i = 0; i < 6; ++i)