LCOV - code coverage report
Current view: top level - src/userobjects - SolidMechanicsPlasticMohrCoulomb.C (source / functions) Hit Total Coverage
Test: idaholab/moose solid_mechanics: f45d79 Lines: 264 268 98.5 %
Date: 2025-07-25 05:00:39 Functions: 20 21 95.2 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : 
      10             : #include "SolidMechanicsPlasticMohrCoulomb.h"
      11             : #include "RankFourTensor.h"
      12             : #include "libmesh/utility.h"
      13             : 
      14             : registerMooseObject("SolidMechanicsApp", SolidMechanicsPlasticMohrCoulomb);
      15             : registerMooseObjectRenamed("SolidMechanicsApp",
      16             :                            TensorMechanicsPlasticMohrCoulomb,
      17             :                            "01/01/2025 00:00",
      18             :                            SolidMechanicsPlasticMohrCoulomb);
      19             : 
      20             : InputParameters
      21         240 : SolidMechanicsPlasticMohrCoulomb::validParams()
      22             : {
      23         240 :   InputParameters params = SolidMechanicsPlasticModel::validParams();
      24         480 :   params.addRequiredParam<UserObjectName>(
      25             :       "cohesion",
      26             :       "A SolidMechanicsHardening UserObject that defines hardening of the cohesion.  "
      27             :       "Physically the cohesion should not be negative.");
      28         480 :   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         480 :   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         720 :   params.addRangeCheckedParam<Real>(
      39             :       "mc_edge_smoother",
      40         480 :       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         480 :   MooseEnum tip_scheme("hyperbolic cap", "hyperbolic");
      44         480 :   params.addParam<MooseEnum>(
      45             :       "tip_scheme", tip_scheme, "Scheme by which the pyramid's tip will be smoothed.");
      46         480 :   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         480 :   params.addParam<Real>(
      52             :       "cap_start",
      53         480 :       0.0,
      54             :       "For the 'cap' tip_scheme, smoothing is performed in the stress_mean > cap_start region");
      55         720 :   params.addRangeCheckedParam<Real>("cap_rate",
      56         480 :                                     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         480 :   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         240 :   params.addClassDescription("Non-associative Mohr-Coulomb plasticity with hardening/softening");
      69             : 
      70         240 :   return params;
      71         240 : }
      72             : 
      73         124 : SolidMechanicsPlasticMohrCoulomb::SolidMechanicsPlasticMohrCoulomb(
      74         124 :     const InputParameters & parameters)
      75             :   : SolidMechanicsPlasticModel(parameters),
      76         124 :     _cohesion(getUserObject<SolidMechanicsHardeningModel>("cohesion")),
      77         124 :     _phi(getUserObject<SolidMechanicsHardeningModel>("friction_angle")),
      78         124 :     _psi(getUserObject<SolidMechanicsHardeningModel>("dilation_angle")),
      79         248 :     _tip_scheme(getParam<MooseEnum>("tip_scheme")),
      80         248 :     _small_smoother2(Utility::pow<2>(getParam<Real>("mc_tip_smoother"))),
      81         248 :     _cap_start(getParam<Real>("cap_start")),
      82         248 :     _cap_rate(getParam<Real>("cap_rate")),
      83         248 :     _tt(getParam<Real>("mc_edge_smoother") * libMesh::pi / 180.0),
      84         124 :     _costt(std::cos(_tt)),
      85         124 :     _sintt(std::sin(_tt)),
      86         124 :     _cos3tt(std::cos(3 * _tt)),
      87         124 :     _sin3tt(std::sin(3 * _tt)),
      88         124 :     _cos6tt(std::cos(6 * _tt)),
      89         124 :     _sin6tt(std::sin(6 * _tt)),
      90         128 :     _lode_cutoff(parameters.isParamValid("mc_lode_cutoff") ? getParam<Real>("mc_lode_cutoff")
      91         124 :                                                            : 1.0E-5 * Utility::pow<2>(_f_tol))
      92             : 
      93             : {
      94         124 :   if (_lode_cutoff < 0)
      95           2 :     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         122 :   if (phi(0) < 0 || psi(0) < 0 || phi(0) > libMesh::pi / 2.0 || psi(0) > libMesh::pi / 2.0)
     100           0 :     mooseError("Mohr-Coulomb friction and dilation angles must lie in [0, Pi/2]");
     101         122 :   if (phi(0) < psi(0))
     102           2 :     mooseError("Mohr-Coulomb friction angle must not be less than Mohr-Coulomb dilation angle");
     103         120 :   if (cohesion(0) < 0)
     104           0 :     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         120 :   Real sin_angle = std::sin(std::max(phi(0), psi(0)));
     110         120 :   sin_angle = std::max(sin_angle, std::sin(std::max(phi(1E6), psi(1E6))));
     111         120 :   Real rhs = std::sqrt(3) * (35 * std::sin(_tt) + 14 * std::sin(5 * _tt) - 5 * std::sin(7 * _tt)) /
     112         120 :              16 / Utility::pow<5>(std::cos(_tt)) / (11 - 10 * std::cos(2 * _tt));
     113         120 :   if (rhs <= sin_angle)
     114           4 :     mooseError("Mohr-Coulomb edge smoothing angle is too small and a non-convex yield surface will "
     115             :                "result.  Please choose a larger value");
     116         116 : }
     117             : 
     118             : Real
     119      991968 : SolidMechanicsPlasticMohrCoulomb::yieldFunction(const RankTwoTensor & stress, Real intnl) const
     120             : {
     121      991968 :   Real mean_stress = stress.trace() / 3.0;
     122      991968 :   Real sinphi = std::sin(phi(intnl));
     123      991968 :   Real cosphi = std::cos(phi(intnl));
     124      991968 :   Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0);
     125      991968 :   if (std::abs(sin3Lode) <= _sin3tt)
     126             :   {
     127             :     // the non-edge-smoothed version
     128             :     std::vector<Real> eigvals;
     129      258416 :     stress.symmetricEigenvalues(eigvals);
     130      516832 :     return mean_stress * sinphi +
     131      258416 :            std::sqrt(smooth(stress) +
     132      258416 :                      0.25 * Utility::pow<2>(eigvals[2] - eigvals[0] +
     133      258416 :                                             (eigvals[2] + eigvals[0] - 2 * mean_stress) * sinphi)) -
     134      258416 :            cohesion(intnl) * cosphi;
     135             :   }
     136             :   else
     137             :   {
     138             :     // the edge-smoothed version
     139             :     Real aaa, bbb, ccc;
     140      733552 :     abbo(sin3Lode, sinphi, aaa, bbb, ccc);
     141      733552 :     Real kk = aaa + bbb * sin3Lode + ccc * Utility::pow<2>(sin3Lode);
     142      733552 :     Real sibar2 = stress.secondInvariant();
     143      733552 :     return mean_stress * sinphi + std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk)) -
     144      733552 :            cohesion(intnl) * cosphi;
     145             :   }
     146             : }
     147             : 
     148             : RankTwoTensor
     149     1652528 : SolidMechanicsPlasticMohrCoulomb::df_dsig(const RankTwoTensor & stress, const Real sin_angle) const
     150             : {
     151     1652528 :   Real mean_stress = stress.trace() / 3.0;
     152     1652528 :   RankTwoTensor dmean_stress = stress.dtrace() / 3.0;
     153     1652528 :   Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0);
     154     1652528 :   if (std::abs(sin3Lode) <= _sin3tt)
     155             :   {
     156             :     // the non-edge-smoothed version
     157             :     std::vector<Real> eigvals;
     158             :     std::vector<RankTwoTensor> deigvals;
     159      385648 :     stress.dsymmetricEigenvalues(eigvals, deigvals);
     160      385648 :     Real tmp = eigvals[2] - eigvals[0] + (eigvals[2] + eigvals[0] - 2.0 * mean_stress) * sin_angle;
     161             :     RankTwoTensor dtmp =
     162      385648 :         deigvals[2] - deigvals[0] + (deigvals[2] + deigvals[0] - 2.0 * dmean_stress) * sin_angle;
     163      385648 :     Real denom = std::sqrt(smooth(stress) + 0.25 * Utility::pow<2>(tmp));
     164      385648 :     return dmean_stress * sin_angle +
     165      385648 :            (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     1266880 :     abbo(sin3Lode, sin_angle, aaa, bbb, ccc);
     172     1266880 :     Real kk = aaa + bbb * sin3Lode + ccc * Utility::pow<2>(sin3Lode);
     173     1266880 :     RankTwoTensor dkk = (bbb + 2 * ccc * sin3Lode) * stress.dsin3Lode(_lode_cutoff);
     174     1266880 :     Real sibar2 = stress.secondInvariant();
     175     1266880 :     RankTwoTensor dsibar2 = stress.dsecondInvariant();
     176     1266880 :     Real denom = std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk));
     177     1266880 :     return dmean_stress * sin_angle + (0.5 * dsmooth(stress) * dmean_stress +
     178     1266880 :                                        0.5 * dsibar2 * Utility::pow<2>(kk) + sibar2 * kk * dkk) /
     179     1266880 :                                           denom;
     180             :   }
     181             : }
     182             : 
     183             : RankTwoTensor
     184      393216 : SolidMechanicsPlasticMohrCoulomb::dyieldFunction_dstress(const RankTwoTensor & stress,
     185             :                                                          Real intnl) const
     186             : {
     187      393216 :   Real sinphi = std::sin(phi(intnl));
     188      393216 :   return df_dsig(stress, sinphi);
     189             : }
     190             : 
     191             : Real
     192      393216 : SolidMechanicsPlasticMohrCoulomb::dyieldFunction_dintnl(const RankTwoTensor & stress,
     193             :                                                         Real intnl) const
     194             : {
     195      393216 :   Real sin_angle = std::sin(phi(intnl));
     196      393216 :   Real cos_angle = std::cos(phi(intnl));
     197      393216 :   Real dsin_angle = cos_angle * dphi(intnl);
     198      393216 :   Real dcos_angle = -sin_angle * dphi(intnl);
     199             : 
     200      393216 :   Real mean_stress = stress.trace() / 3.0;
     201      393216 :   Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0);
     202      393216 :   if (std::abs(sin3Lode) <= _sin3tt)
     203             :   {
     204             :     // the non-edge-smoothed version
     205             :     std::vector<Real> eigvals;
     206       90320 :     stress.symmetricEigenvalues(eigvals);
     207       90320 :     Real tmp = eigvals[2] - eigvals[0] + (eigvals[2] + eigvals[0] - 2 * mean_stress) * sin_angle;
     208       90320 :     Real dtmp = (eigvals[2] + eigvals[0] - 2 * mean_stress) * dsin_angle;
     209       90320 :     Real denom = std::sqrt(smooth(stress) + 0.25 * Utility::pow<2>(tmp));
     210       90320 :     return mean_stress * dsin_angle + 0.25 * tmp * dtmp / denom - dcohesion(intnl) * cos_angle -
     211       90320 :            cohesion(intnl) * dcos_angle;
     212             :   }
     213             :   else
     214             :   {
     215             :     // the edge-smoothed version
     216             :     Real aaa, bbb, ccc;
     217      302896 :     abbo(sin3Lode, sin_angle, aaa, bbb, ccc);
     218             :     Real daaa, dbbb, dccc;
     219      302896 :     dabbo(sin3Lode, sin_angle, daaa, dbbb, dccc);
     220      302896 :     Real kk = aaa + bbb * sin3Lode + ccc * Utility::pow<2>(sin3Lode);
     221      302896 :     Real dkk = (daaa + dbbb * sin3Lode + dccc * Utility::pow<2>(sin3Lode)) * dsin_angle;
     222      302896 :     Real sibar2 = stress.secondInvariant();
     223      302896 :     Real denom = std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk));
     224      302896 :     return mean_stress * dsin_angle + sibar2 * kk * dkk / denom - dcohesion(intnl) * cos_angle -
     225      302896 :            cohesion(intnl) * dcos_angle;
     226             :   }
     227             : }
     228             : 
     229             : RankTwoTensor
     230     1259312 : SolidMechanicsPlasticMohrCoulomb::flowPotential(const RankTwoTensor & stress, Real intnl) const
     231             : {
     232     1259312 :   Real sinpsi = std::sin(psi(intnl));
     233     1259312 :   return df_dsig(stress, sinpsi);
     234             : }
     235             : 
     236             : RankFourTensor
     237      393216 : SolidMechanicsPlasticMohrCoulomb::dflowPotential_dstress(const RankTwoTensor & stress,
     238             :                                                          Real intnl) const
     239             : {
     240      393216 :   RankFourTensor dr_dstress;
     241      393216 :   Real sin_angle = std::sin(psi(intnl));
     242      393216 :   Real mean_stress = stress.trace() / 3.0;
     243      393216 :   RankTwoTensor dmean_stress = stress.dtrace() / 3.0;
     244      393216 :   Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0);
     245      393216 :   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       90320 :     stress.dsymmetricEigenvalues(eigvals, deigvals);
     252       90320 :     stress.d2symmetricEigenvalues(d2eigvals);
     253             : 
     254       90320 :     Real tmp = eigvals[2] - eigvals[0] + (eigvals[2] + eigvals[0] - 2.0 * mean_stress) * sin_angle;
     255             :     RankTwoTensor dtmp =
     256       90320 :         deigvals[2] - deigvals[0] + (deigvals[2] + deigvals[0] - 2.0 * dmean_stress) * sin_angle;
     257       90320 :     Real denom = std::sqrt(smooth(stress) + 0.25 * Utility::pow<2>(tmp));
     258             :     Real denom3 = Utility::pow<3>(denom);
     259       90320 :     Real d2smooth_over_denom = d2smooth(stress) / denom;
     260       90320 :     RankTwoTensor numer = dsmooth(stress) * dmean_stress + 0.5 * tmp * dtmp;
     261             : 
     262       90320 :     dr_dstress = 0.25 * tmp *
     263      180640 :                  (d2eigvals[2] - d2eigvals[0] + (d2eigvals[2] + d2eigvals[0]) * sin_angle) / denom;
     264             : 
     265      361280 :     for (unsigned i = 0; i < 3; ++i)
     266     1083840 :       for (unsigned j = 0; j < 3; ++j)
     267     3251520 :         for (unsigned k = 0; k < 3; ++k)
     268     9754560 :           for (unsigned l = 0; l < 3; ++l)
     269             :           {
     270     7315920 :             dr_dstress(i, j, k, l) +=
     271     7315920 :                 0.5 * d2smooth_over_denom * dmean_stress(i, j) * dmean_stress(k, l);
     272     7315920 :             dr_dstress(i, j, k, l) += 0.25 * dtmp(i, j) * dtmp(k, l) / denom;
     273     7315920 :             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      302896 :     abbo(sin3Lode, sin_angle, aaa, bbb, ccc);
     281      302896 :     RankTwoTensor dsin3Lode = stress.dsin3Lode(_lode_cutoff);
     282      302896 :     Real kk = aaa + bbb * sin3Lode + ccc * Utility::pow<2>(sin3Lode);
     283      302896 :     RankTwoTensor dkk = (bbb + 2 * ccc * sin3Lode) * dsin3Lode;
     284      302896 :     RankFourTensor d2kk = (bbb + 2 * ccc * sin3Lode) * stress.d2sin3Lode(_lode_cutoff);
     285     1211584 :     for (unsigned i = 0; i < 3; ++i)
     286     3634752 :       for (unsigned j = 0; j < 3; ++j)
     287    10904256 :         for (unsigned k = 0; k < 3; ++k)
     288    32712768 :           for (unsigned l = 0; l < 3; ++l)
     289    24534576 :             d2kk(i, j, k, l) += 2 * ccc * dsin3Lode(i, j) * dsin3Lode(k, l);
     290             : 
     291      302896 :     Real sibar2 = stress.secondInvariant();
     292      302896 :     RankTwoTensor dsibar2 = stress.dsecondInvariant();
     293      302896 :     RankFourTensor d2sibar2 = stress.d2secondInvariant();
     294             : 
     295      302896 :     Real denom = std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk));
     296             :     Real denom3 = Utility::pow<3>(denom);
     297      302896 :     Real d2smooth_over_denom = d2smooth(stress) / denom;
     298             :     RankTwoTensor numer_full =
     299      302896 :         0.5 * dsmooth(stress) * dmean_stress + 0.5 * dsibar2 * kk * kk + sibar2 * kk * dkk;
     300             : 
     301      302896 :     dr_dstress = (0.5 * d2sibar2 * Utility::pow<2>(kk) + sibar2 * kk * d2kk) / denom;
     302     1211584 :     for (unsigned i = 0; i < 3; ++i)
     303     3634752 :       for (unsigned j = 0; j < 3; ++j)
     304    10904256 :         for (unsigned k = 0; k < 3; ++k)
     305    32712768 :           for (unsigned l = 0; l < 3; ++l)
     306             :           {
     307    24534576 :             dr_dstress(i, j, k, l) +=
     308    24534576 :                 0.5 * d2smooth_over_denom * dmean_stress(i, j) * dmean_stress(k, l);
     309    24534576 :             dr_dstress(i, j, k, l) +=
     310    24534576 :                 (dsibar2(i, j) * dkk(k, l) * kk + dkk(i, j) * dsibar2(k, l) * kk +
     311    24534576 :                  sibar2 * dkk(i, j) * dkk(k, l)) /
     312             :                 denom;
     313    24534576 :             dr_dstress(i, j, k, l) -= numer_full(i, j) * numer_full(k, l) / denom3;
     314             :           }
     315             :   }
     316      393216 :   return dr_dstress;
     317             : }
     318             : 
     319             : RankTwoTensor
     320      393216 : SolidMechanicsPlasticMohrCoulomb::dflowPotential_dintnl(const RankTwoTensor & stress,
     321             :                                                         Real intnl) const
     322             : {
     323      393216 :   Real sin_angle = std::sin(psi(intnl));
     324      393216 :   Real dsin_angle = std::cos(psi(intnl)) * dpsi(intnl);
     325             : 
     326      393216 :   Real mean_stress = stress.trace() / 3.0;
     327      393216 :   RankTwoTensor dmean_stress = stress.dtrace() / 3.0;
     328      393216 :   Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0);
     329             : 
     330      393216 :   if (std::abs(sin3Lode) <= _sin3tt)
     331             :   {
     332             :     // the non-edge-smoothed version
     333             :     std::vector<Real> eigvals;
     334             :     std::vector<RankTwoTensor> deigvals;
     335       90320 :     stress.dsymmetricEigenvalues(eigvals, deigvals);
     336       90320 :     Real tmp = eigvals[2] - eigvals[0] + (eigvals[2] + eigvals[0] - 2.0 * mean_stress) * sin_angle;
     337       90320 :     Real dtmp_dintnl = (eigvals[2] + eigvals[0] - 2 * mean_stress) * dsin_angle;
     338             :     RankTwoTensor dtmp_dstress =
     339       90320 :         deigvals[2] - deigvals[0] + (deigvals[2] + deigvals[0] - 2.0 * dmean_stress) * sin_angle;
     340             :     RankTwoTensor d2tmp_dstress_dintnl =
     341       90320 :         (deigvals[2] + deigvals[0] - 2.0 * dmean_stress) * dsin_angle;
     342       90320 :     Real denom = std::sqrt(smooth(stress) + 0.25 * Utility::pow<2>(tmp));
     343       90320 :     return dmean_stress * dsin_angle + 0.25 * dtmp_dintnl * dtmp_dstress / denom +
     344       90320 :            0.25 * tmp * d2tmp_dstress_dintnl / denom -
     345       90320 :            0.5 * (dsmooth(stress) * dmean_stress + 0.5 * tmp * dtmp_dstress) * 0.25 * tmp *
     346       90320 :                dtmp_dintnl / Utility::pow<3>(denom);
     347             :   }
     348             :   else
     349             :   {
     350             :     // the edge-smoothed version
     351             :     Real aaa, bbb, ccc;
     352      302896 :     abbo(sin3Lode, sin_angle, aaa, bbb, ccc);
     353      302896 :     Real kk = aaa + bbb * sin3Lode + ccc * Utility::pow<2>(sin3Lode);
     354             : 
     355             :     Real daaa, dbbb, dccc;
     356      302896 :     dabbo(sin3Lode, sin_angle, daaa, dbbb, dccc);
     357      302896 :     Real dkk_dintnl = (daaa + dbbb * sin3Lode + dccc * Utility::pow<2>(sin3Lode)) * dsin_angle;
     358      302896 :     RankTwoTensor dkk_dstress = (bbb + 2 * ccc * sin3Lode) * stress.dsin3Lode(_lode_cutoff);
     359             :     RankTwoTensor d2kk_dstress_dintnl =
     360      302896 :         (dbbb + 2 * dccc * sin3Lode) * stress.dsin3Lode(_lode_cutoff) * dsin_angle;
     361             : 
     362      302896 :     Real sibar2 = stress.secondInvariant();
     363      302896 :     RankTwoTensor dsibar2 = stress.dsecondInvariant();
     364      302896 :     Real denom = std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk));
     365             : 
     366      302896 :     return dmean_stress * dsin_angle +
     367      302896 :            (dsibar2 * kk * dkk_dintnl + sibar2 * dkk_dintnl * dkk_dstress +
     368      302896 :             sibar2 * kk * d2kk_dstress_dintnl) /
     369             :                denom -
     370      302896 :            (0.5 * dsmooth(stress) * dmean_stress + 0.5 * dsibar2 * Utility::pow<2>(kk) +
     371      605792 :             sibar2 * kk * dkk_dstress) *
     372      302896 :                sibar2 * kk * dkk_dintnl / Utility::pow<3>(denom);
     373             :   }
     374             : }
     375             : 
     376             : Real
     377     1385304 : SolidMechanicsPlasticMohrCoulomb::cohesion(const Real internal_param) const
     378             : {
     379     1385304 :   return _cohesion.value(internal_param);
     380             : }
     381             : 
     382             : Real
     383      393216 : SolidMechanicsPlasticMohrCoulomb::dcohesion(const Real internal_param) const
     384             : {
     385      393216 :   return _cohesion.derivative(internal_param);
     386             : }
     387             : 
     388             : Real
     389     3164190 : SolidMechanicsPlasticMohrCoulomb::phi(const Real internal_param) const
     390             : {
     391     3164190 :   return _phi.value(internal_param);
     392             : }
     393             : 
     394             : Real
     395      786432 : SolidMechanicsPlasticMohrCoulomb::dphi(const Real internal_param) const
     396             : {
     397      786432 :   return _phi.derivative(internal_param);
     398             : }
     399             : 
     400             : Real
     401     2439566 : SolidMechanicsPlasticMohrCoulomb::psi(const Real internal_param) const
     402             : {
     403     2439566 :   return _psi.value(internal_param);
     404             : }
     405             : 
     406             : Real
     407      393216 : SolidMechanicsPlasticMohrCoulomb::dpsi(const Real internal_param) const
     408             : {
     409      393216 :   return _psi.derivative(internal_param);
     410             : }
     411             : 
     412             : void
     413     2909120 : SolidMechanicsPlasticMohrCoulomb::abbo(
     414             :     const Real sin3lode, const Real sin_angle, Real & aaa, Real & bbb, Real & ccc) const
     415             : {
     416     2909120 :   Real tmp1 = (sin3lode >= 0 ? _costt - sin_angle * _sintt / std::sqrt(3.0)
     417     1152352 :                              : _costt + sin_angle * _sintt / std::sqrt(3.0));
     418     2909120 :   Real tmp2 = (sin3lode >= 0 ? _sintt + sin_angle * _costt / std::sqrt(3.0)
     419     1152352 :                              : -_sintt + sin_angle * _costt / std::sqrt(3.0));
     420             : 
     421     2909120 :   ccc = -_cos3tt * tmp1;
     422     2909120 :   ccc += (sin3lode >= 0 ? -3 * _sin3tt * tmp2 : 3 * _sin3tt * tmp2);
     423     2909120 :   ccc /= 18 * Utility::pow<3>(_cos3tt);
     424             : 
     425     2909120 :   bbb = (sin3lode >= 0 ? _sin6tt * tmp1 : -_sin6tt * tmp1);
     426     2909120 :   bbb -= 6 * _cos6tt * tmp2;
     427     2909120 :   bbb /= 18 * Utility::pow<3>(_cos3tt);
     428             : 
     429     2909120 :   aaa = (sin3lode >= 0 ? -sin_angle * _sintt / std::sqrt(3.0) - bbb * _sin3tt
     430     1152352 :                        : sin_angle * _sintt / std::sqrt(3.0) + bbb * _sin3tt);
     431     2909120 :   aaa += -ccc * Utility::pow<2>(_sin3tt) + _costt;
     432     2909120 : }
     433             : 
     434             : void
     435      605792 : SolidMechanicsPlasticMohrCoulomb::dabbo(
     436             :     const Real sin3lode, const Real /*sin_angle*/, Real & daaa, Real & dbbb, Real & dccc) const
     437             : {
     438      605792 :   Real dtmp1 = (sin3lode >= 0 ? -_sintt / std::sqrt(3.0) : _sintt / std::sqrt(3.0));
     439      605792 :   Real dtmp2 = _costt / std::sqrt(3.0);
     440             : 
     441      605792 :   dccc = -_cos3tt * dtmp1;
     442      605792 :   dccc += (sin3lode >= 0 ? -3 * _sin3tt * dtmp2 : 3 * _sin3tt * dtmp2);
     443      605792 :   dccc /= 18 * Utility::pow<3>(_cos3tt);
     444             : 
     445      605792 :   dbbb = (sin3lode >= 0 ? _sin6tt * dtmp1 : -_sin6tt * dtmp1);
     446      605792 :   dbbb -= 6 * _cos6tt * dtmp2;
     447      605792 :   dbbb /= 18 * Utility::pow<3>(_cos3tt);
     448             : 
     449      605792 :   daaa = (sin3lode >= 0 ? -_sintt / std::sqrt(3.0) - dbbb * _sin3tt
     450      236160 :                         : _sintt / std::sqrt(3.0) + dbbb * _sin3tt);
     451      605792 :   daaa += -dccc * Utility::pow<2>(_sin3tt);
     452      605792 : }
     453             : 
     454             : Real
     455     3824144 : SolidMechanicsPlasticMohrCoulomb::smooth(const RankTwoTensor & stress) const
     456             : {
     457     3824144 :   Real smoother2 = _small_smoother2;
     458     3824144 :   if (_tip_scheme == "cap")
     459             :   {
     460      486912 :     Real x = stress.trace() / 3.0 - _cap_start;
     461             :     Real p = 0;
     462      486912 :     if (x > 0)
     463      436704 :       p = x * (1 - std::exp(-_cap_rate * x));
     464      486912 :     smoother2 += Utility::pow<2>(p);
     465             :   }
     466     3824144 :   return smoother2;
     467             : }
     468             : 
     469             : Real
     470     2438960 : SolidMechanicsPlasticMohrCoulomb::dsmooth(const RankTwoTensor & stress) const
     471             : {
     472             :   Real dsmoother2 = 0;
     473     2438960 :   if (_tip_scheme == "cap")
     474             :   {
     475      312192 :     Real x = stress.trace() / 3.0 - _cap_start;
     476             :     Real p = 0;
     477             :     Real dp_dx = 0;
     478      312192 :     if (x > 0)
     479             :     {
     480      279456 :       p = x * (1 - std::exp(-_cap_rate * x));
     481      279456 :       dp_dx = (1 - std::exp(-_cap_rate * x)) + x * _cap_rate * std::exp(-_cap_rate * x);
     482             :     }
     483      312192 :     dsmoother2 += 2 * p * dp_dx;
     484             :   }
     485     2438960 :   return dsmoother2;
     486             : }
     487             : 
     488             : Real
     489      393216 : SolidMechanicsPlasticMohrCoulomb::d2smooth(const RankTwoTensor & stress) const
     490             : {
     491             :   Real d2smoother2 = 0;
     492      393216 :   if (_tip_scheme == "cap")
     493             :   {
     494       49920 :     Real x = stress.trace() / 3.0 - _cap_start;
     495             :     Real p = 0;
     496             :     Real dp_dx = 0;
     497             :     Real d2p_dx2 = 0;
     498       49920 :     if (x > 0)
     499             :     {
     500       44064 :       p = x * (1 - std::exp(-_cap_rate * x));
     501       44064 :       dp_dx = (1 - std::exp(-_cap_rate * x)) + x * _cap_rate * std::exp(-_cap_rate * x);
     502       44064 :       d2p_dx2 = 2 * _cap_rate * std::exp(-_cap_rate * x) -
     503       44064 :                 x * Utility::pow<2>(_cap_rate) * std::exp(-_cap_rate * x);
     504             :     }
     505       49920 :     d2smoother2 += 2 * Utility::pow<2>(dp_dx) + 2 * p * d2p_dx2;
     506             :   }
     507      393216 :   return d2smoother2;
     508             : }
     509             : 
     510             : std::string
     511           0 : SolidMechanicsPlasticMohrCoulomb::modelName() const
     512             : {
     513           0 :   return "MohrCoulomb";
     514             : }

Generated by: LCOV version 1.14