LCOV - code coverage report
Current view: top level - src/userobjects - TensorMechanicsPlasticMohrCoulomb.C (source / functions) Hit Total Coverage
Test: idaholab/moose tensor_mechanics: d6b47a Lines: 264 268 98.5 %
Date: 2024-02-27 11:53:14 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://www.mooseframework.org
       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 "TensorMechanicsPlasticMohrCoulomb.h"
      11             : #include "RankFourTensor.h"
      12             : #include "libmesh/utility.h"
      13             : 
      14             : registerMooseObject("TensorMechanicsApp", TensorMechanicsPlasticMohrCoulomb);
      15             : 
      16             : InputParameters
      17         120 : TensorMechanicsPlasticMohrCoulomb::validParams()
      18             : {
      19         120 :   InputParameters params = TensorMechanicsPlasticModel::validParams();
      20         240 :   params.addRequiredParam<UserObjectName>(
      21             :       "cohesion",
      22             :       "A TensorMechanicsHardening UserObject that defines hardening of the cohesion.  "
      23             :       "Physically the cohesion should not be negative.");
      24         240 :   params.addRequiredParam<UserObjectName>(
      25             :       "friction_angle",
      26             :       "A TensorMechanicsHardening UserObject that defines hardening of the "
      27             :       "friction angle (in radians).  Physically the friction angle should be "
      28             :       "between 0 and 90deg.");
      29         240 :   params.addRequiredParam<UserObjectName>(
      30             :       "dilation_angle",
      31             :       "A TensorMechanicsHardening UserObject that defines hardening of the "
      32             :       "dilation angle (in radians).  Usually the dilation angle is not greater "
      33             :       "than the friction angle, and it is between 0 and 90deg.");
      34         360 :   params.addRangeCheckedParam<Real>(
      35             :       "mc_edge_smoother",
      36         240 :       25.0,
      37             :       "mc_edge_smoother>=0 & mc_edge_smoother<=30",
      38             :       "Smoothing parameter: the edges of the cone are smoothed by the given amount.");
      39         240 :   MooseEnum tip_scheme("hyperbolic cap", "hyperbolic");
      40         240 :   params.addParam<MooseEnum>(
      41             :       "tip_scheme", tip_scheme, "Scheme by which the pyramid's tip will be smoothed.");
      42         240 :   params.addRequiredRangeCheckedParam<Real>("mc_tip_smoother",
      43             :                                             "mc_tip_smoother>=0",
      44             :                                             "Smoothing parameter: the cone vertex at mean = "
      45             :                                             "cohesion*cot(friction_angle), will be smoothed by "
      46             :                                             "the given amount.  Typical value is 0.1*cohesion");
      47         240 :   params.addParam<Real>(
      48             :       "cap_start",
      49         240 :       0.0,
      50             :       "For the 'cap' tip_scheme, smoothing is performed in the stress_mean > cap_start region");
      51         360 :   params.addRangeCheckedParam<Real>("cap_rate",
      52         240 :                                     0.0,
      53             :                                     "cap_rate>=0",
      54             :                                     "For the 'cap' tip_scheme, this controls how quickly the cap "
      55             :                                     "degenerates to a hemisphere: small values mean a slow "
      56             :                                     "degeneration to a hemisphere (and zero means the 'cap' will "
      57             :                                     "be totally inactive).  Typical value is 1/tensile_strength");
      58         240 :   params.addParam<Real>("mc_lode_cutoff",
      59             :                         "If the second invariant of stress is less than this "
      60             :                         "amount, the Lode angle is assumed to be zero.  This is "
      61             :                         "to gaurd against precision-loss problems, and this "
      62             :                         "parameter should be set small.  Default = "
      63             :                         "0.00001*((yield_Function_tolerance)^2)");
      64         120 :   params.addClassDescription("Non-associative Mohr-Coulomb plasticity with hardening/softening");
      65             : 
      66         120 :   return params;
      67         120 : }
      68             : 
      69          62 : TensorMechanicsPlasticMohrCoulomb::TensorMechanicsPlasticMohrCoulomb(
      70          62 :     const InputParameters & parameters)
      71             :   : TensorMechanicsPlasticModel(parameters),
      72          62 :     _cohesion(getUserObject<TensorMechanicsHardeningModel>("cohesion")),
      73          62 :     _phi(getUserObject<TensorMechanicsHardeningModel>("friction_angle")),
      74          62 :     _psi(getUserObject<TensorMechanicsHardeningModel>("dilation_angle")),
      75         124 :     _tip_scheme(getParam<MooseEnum>("tip_scheme")),
      76         124 :     _small_smoother2(Utility::pow<2>(getParam<Real>("mc_tip_smoother"))),
      77         124 :     _cap_start(getParam<Real>("cap_start")),
      78         124 :     _cap_rate(getParam<Real>("cap_rate")),
      79         124 :     _tt(getParam<Real>("mc_edge_smoother") * libMesh::pi / 180.0),
      80          62 :     _costt(std::cos(_tt)),
      81          62 :     _sintt(std::sin(_tt)),
      82          62 :     _cos3tt(std::cos(3 * _tt)),
      83          62 :     _sin3tt(std::sin(3 * _tt)),
      84          62 :     _cos6tt(std::cos(6 * _tt)),
      85          62 :     _sin6tt(std::sin(6 * _tt)),
      86          64 :     _lode_cutoff(parameters.isParamValid("mc_lode_cutoff") ? getParam<Real>("mc_lode_cutoff")
      87          62 :                                                            : 1.0E-5 * Utility::pow<2>(_f_tol))
      88             : 
      89             : {
      90          62 :   if (_lode_cutoff < 0)
      91           1 :     mooseError("mc_lode_cutoff must not be negative");
      92             : 
      93             :   // With arbitary UserObjects, it is impossible to check everything, and
      94             :   // I think this is the best I can do
      95          61 :   if (phi(0) < 0 || psi(0) < 0 || phi(0) > libMesh::pi / 2.0 || psi(0) > libMesh::pi / 2.0)
      96           0 :     mooseError("Mohr-Coulomb friction and dilation angles must lie in [0, Pi/2]");
      97          61 :   if (phi(0) < psi(0))
      98           1 :     mooseError("Mohr-Coulomb friction angle must not be less than Mohr-Coulomb dilation angle");
      99          60 :   if (cohesion(0) < 0)
     100           0 :     mooseError("Mohr-Coulomb cohesion must not be negative");
     101             : 
     102             :   // check Abbo et al's convexity constraint (Eqn c.18 in their paper)
     103             :   // With an arbitrary UserObject, it is impossible to check for all angles
     104             :   // I think the following is the best we can do
     105          60 :   Real sin_angle = std::sin(std::max(phi(0), psi(0)));
     106          60 :   sin_angle = std::max(sin_angle, std::sin(std::max(phi(1E6), psi(1E6))));
     107          60 :   Real rhs = std::sqrt(3) * (35 * std::sin(_tt) + 14 * std::sin(5 * _tt) - 5 * std::sin(7 * _tt)) /
     108          60 :              16 / Utility::pow<5>(std::cos(_tt)) / (11 - 10 * std::cos(2 * _tt));
     109          60 :   if (rhs <= sin_angle)
     110           2 :     mooseError("Mohr-Coulomb edge smoothing angle is too small and a non-convex yield surface will "
     111             :                "result.  Please choose a larger value");
     112          58 : }
     113             : 
     114             : Real
     115      553952 : TensorMechanicsPlasticMohrCoulomb::yieldFunction(const RankTwoTensor & stress, Real intnl) const
     116             : {
     117      553952 :   Real mean_stress = stress.trace() / 3.0;
     118      553952 :   Real sinphi = std::sin(phi(intnl));
     119      553952 :   Real cosphi = std::cos(phi(intnl));
     120      553952 :   Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0);
     121      553952 :   if (std::abs(sin3Lode) <= _sin3tt)
     122             :   {
     123             :     // the non-edge-smoothed version
     124             :     std::vector<Real> eigvals;
     125      150520 :     stress.symmetricEigenvalues(eigvals);
     126      301040 :     return mean_stress * sinphi +
     127      150520 :            std::sqrt(smooth(stress) +
     128      150520 :                      0.25 * Utility::pow<2>(eigvals[2] - eigvals[0] +
     129      150520 :                                             (eigvals[2] + eigvals[0] - 2 * mean_stress) * sinphi)) -
     130      150520 :            cohesion(intnl) * cosphi;
     131             :   }
     132             :   else
     133             :   {
     134             :     // the edge-smoothed version
     135             :     Real aaa, bbb, ccc;
     136      403432 :     abbo(sin3Lode, sinphi, aaa, bbb, ccc);
     137      403432 :     Real kk = aaa + bbb * sin3Lode + ccc * Utility::pow<2>(sin3Lode);
     138      403432 :     Real sibar2 = stress.secondInvariant();
     139      403432 :     return mean_stress * sinphi + std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk)) -
     140      403432 :            cohesion(intnl) * cosphi;
     141             :   }
     142             : }
     143             : 
     144             : RankTwoTensor
     145      887592 : TensorMechanicsPlasticMohrCoulomb::df_dsig(const RankTwoTensor & stress, const Real sin_angle) const
     146             : {
     147      887592 :   Real mean_stress = stress.trace() / 3.0;
     148      887592 :   RankTwoTensor dmean_stress = stress.dtrace() / 3.0;
     149      887592 :   Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0);
     150      887592 :   if (std::abs(sin3Lode) <= _sin3tt)
     151             :   {
     152             :     // the non-edge-smoothed version
     153             :     std::vector<Real> eigvals;
     154             :     std::vector<RankTwoTensor> deigvals;
     155      217048 :     stress.dsymmetricEigenvalues(eigvals, deigvals);
     156      217048 :     Real tmp = eigvals[2] - eigvals[0] + (eigvals[2] + eigvals[0] - 2.0 * mean_stress) * sin_angle;
     157             :     RankTwoTensor dtmp =
     158      217048 :         deigvals[2] - deigvals[0] + (deigvals[2] + deigvals[0] - 2.0 * dmean_stress) * sin_angle;
     159      217048 :     Real denom = std::sqrt(smooth(stress) + 0.25 * Utility::pow<2>(tmp));
     160      217048 :     return dmean_stress * sin_angle +
     161      217048 :            (0.5 * dsmooth(stress) * dmean_stress + 0.25 * tmp * dtmp) / denom;
     162             :   }
     163             :   else
     164             :   {
     165             :     // the edge-smoothed version
     166             :     Real aaa, bbb, ccc;
     167      670544 :     abbo(sin3Lode, sin_angle, aaa, bbb, ccc);
     168      670544 :     Real kk = aaa + bbb * sin3Lode + ccc * Utility::pow<2>(sin3Lode);
     169      670544 :     RankTwoTensor dkk = (bbb + 2 * ccc * sin3Lode) * stress.dsin3Lode(_lode_cutoff);
     170      670544 :     Real sibar2 = stress.secondInvariant();
     171      670544 :     RankTwoTensor dsibar2 = stress.dsecondInvariant();
     172      670544 :     Real denom = std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk));
     173      670544 :     return dmean_stress * sin_angle + (0.5 * dsmooth(stress) * dmean_stress +
     174      670544 :                                        0.5 * dsibar2 * Utility::pow<2>(kk) + sibar2 * kk * dkk) /
     175      670544 :                                           denom;
     176             :   }
     177             : }
     178             : 
     179             : RankTwoTensor
     180      206064 : TensorMechanicsPlasticMohrCoulomb::dyieldFunction_dstress(const RankTwoTensor & stress,
     181             :                                                           Real intnl) const
     182             : {
     183      206064 :   Real sinphi = std::sin(phi(intnl));
     184      206064 :   return df_dsig(stress, sinphi);
     185             : }
     186             : 
     187             : Real
     188      206064 : TensorMechanicsPlasticMohrCoulomb::dyieldFunction_dintnl(const RankTwoTensor & stress,
     189             :                                                          Real intnl) const
     190             : {
     191      206064 :   Real sin_angle = std::sin(phi(intnl));
     192      206064 :   Real cos_angle = std::cos(phi(intnl));
     193      206064 :   Real dsin_angle = cos_angle * dphi(intnl);
     194      206064 :   Real dcos_angle = -sin_angle * dphi(intnl);
     195             : 
     196      206064 :   Real mean_stress = stress.trace() / 3.0;
     197      206064 :   Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0);
     198      206064 :   if (std::abs(sin3Lode) <= _sin3tt)
     199             :   {
     200             :     // the non-edge-smoothed version
     201             :     std::vector<Real> eigvals;
     202       48728 :     stress.symmetricEigenvalues(eigvals);
     203       48728 :     Real tmp = eigvals[2] - eigvals[0] + (eigvals[2] + eigvals[0] - 2 * mean_stress) * sin_angle;
     204       48728 :     Real dtmp = (eigvals[2] + eigvals[0] - 2 * mean_stress) * dsin_angle;
     205       48728 :     Real denom = std::sqrt(smooth(stress) + 0.25 * Utility::pow<2>(tmp));
     206       48728 :     return mean_stress * dsin_angle + 0.25 * tmp * dtmp / denom - dcohesion(intnl) * cos_angle -
     207       48728 :            cohesion(intnl) * dcos_angle;
     208             :   }
     209             :   else
     210             :   {
     211             :     // the edge-smoothed version
     212             :     Real aaa, bbb, ccc;
     213      157336 :     abbo(sin3Lode, sin_angle, aaa, bbb, ccc);
     214             :     Real daaa, dbbb, dccc;
     215      157336 :     dabbo(sin3Lode, sin_angle, daaa, dbbb, dccc);
     216      157336 :     Real kk = aaa + bbb * sin3Lode + ccc * Utility::pow<2>(sin3Lode);
     217      157336 :     Real dkk = (daaa + dbbb * sin3Lode + dccc * Utility::pow<2>(sin3Lode)) * dsin_angle;
     218      157336 :     Real sibar2 = stress.secondInvariant();
     219      157336 :     Real denom = std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk));
     220      157336 :     return mean_stress * dsin_angle + sibar2 * kk * dkk / denom - dcohesion(intnl) * cos_angle -
     221      157336 :            cohesion(intnl) * dcos_angle;
     222             :   }
     223             : }
     224             : 
     225             : RankTwoTensor
     226      681528 : TensorMechanicsPlasticMohrCoulomb::flowPotential(const RankTwoTensor & stress, Real intnl) const
     227             : {
     228      681528 :   Real sinpsi = std::sin(psi(intnl));
     229      681528 :   return df_dsig(stress, sinpsi);
     230             : }
     231             : 
     232             : RankFourTensor
     233      206064 : TensorMechanicsPlasticMohrCoulomb::dflowPotential_dstress(const RankTwoTensor & stress,
     234             :                                                           Real intnl) const
     235             : {
     236      206064 :   RankFourTensor dr_dstress;
     237      206064 :   Real sin_angle = std::sin(psi(intnl));
     238      206064 :   Real mean_stress = stress.trace() / 3.0;
     239      206064 :   RankTwoTensor dmean_stress = stress.dtrace() / 3.0;
     240      206064 :   Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0);
     241      206064 :   if (std::abs(sin3Lode) <= _sin3tt)
     242             :   {
     243             :     // the non-edge-smoothed version
     244             :     std::vector<Real> eigvals;
     245             :     std::vector<RankTwoTensor> deigvals;
     246             :     std::vector<RankFourTensor> d2eigvals;
     247       48728 :     stress.dsymmetricEigenvalues(eigvals, deigvals);
     248       48728 :     stress.d2symmetricEigenvalues(d2eigvals);
     249             : 
     250       48728 :     Real tmp = eigvals[2] - eigvals[0] + (eigvals[2] + eigvals[0] - 2.0 * mean_stress) * sin_angle;
     251             :     RankTwoTensor dtmp =
     252       48728 :         deigvals[2] - deigvals[0] + (deigvals[2] + deigvals[0] - 2.0 * dmean_stress) * sin_angle;
     253       48728 :     Real denom = std::sqrt(smooth(stress) + 0.25 * Utility::pow<2>(tmp));
     254             :     Real denom3 = Utility::pow<3>(denom);
     255       48728 :     Real d2smooth_over_denom = d2smooth(stress) / denom;
     256       48728 :     RankTwoTensor numer = dsmooth(stress) * dmean_stress + 0.5 * tmp * dtmp;
     257             : 
     258       48728 :     dr_dstress = 0.25 * tmp *
     259      146184 :                  (d2eigvals[2] - d2eigvals[0] + (d2eigvals[2] + d2eigvals[0]) * sin_angle) / denom;
     260             : 
     261      194912 :     for (unsigned i = 0; i < 3; ++i)
     262      584736 :       for (unsigned j = 0; j < 3; ++j)
     263     1754208 :         for (unsigned k = 0; k < 3; ++k)
     264     5262624 :           for (unsigned l = 0; l < 3; ++l)
     265             :           {
     266     3946968 :             dr_dstress(i, j, k, l) +=
     267     3946968 :                 0.5 * d2smooth_over_denom * dmean_stress(i, j) * dmean_stress(k, l);
     268     3946968 :             dr_dstress(i, j, k, l) += 0.25 * dtmp(i, j) * dtmp(k, l) / denom;
     269     3946968 :             dr_dstress(i, j, k, l) -= 0.25 * numer(i, j) * numer(k, l) / denom3;
     270             :           }
     271             :   }
     272             :   else
     273             :   {
     274             :     // the edge-smoothed version
     275             :     Real aaa, bbb, ccc;
     276      157336 :     abbo(sin3Lode, sin_angle, aaa, bbb, ccc);
     277      157336 :     RankTwoTensor dsin3Lode = stress.dsin3Lode(_lode_cutoff);
     278      157336 :     Real kk = aaa + bbb * sin3Lode + ccc * Utility::pow<2>(sin3Lode);
     279      157336 :     RankTwoTensor dkk = (bbb + 2 * ccc * sin3Lode) * dsin3Lode;
     280      157336 :     RankFourTensor d2kk = (bbb + 2 * ccc * sin3Lode) * stress.d2sin3Lode(_lode_cutoff);
     281      629344 :     for (unsigned i = 0; i < 3; ++i)
     282     1888032 :       for (unsigned j = 0; j < 3; ++j)
     283     5664096 :         for (unsigned k = 0; k < 3; ++k)
     284    16992288 :           for (unsigned l = 0; l < 3; ++l)
     285    12744216 :             d2kk(i, j, k, l) += 2 * ccc * dsin3Lode(i, j) * dsin3Lode(k, l);
     286             : 
     287      157336 :     Real sibar2 = stress.secondInvariant();
     288      157336 :     RankTwoTensor dsibar2 = stress.dsecondInvariant();
     289      157336 :     RankFourTensor d2sibar2 = stress.d2secondInvariant();
     290             : 
     291      157336 :     Real denom = std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk));
     292             :     Real denom3 = Utility::pow<3>(denom);
     293      157336 :     Real d2smooth_over_denom = d2smooth(stress) / denom;
     294             :     RankTwoTensor numer_full =
     295      157336 :         0.5 * dsmooth(stress) * dmean_stress + 0.5 * dsibar2 * kk * kk + sibar2 * kk * dkk;
     296             : 
     297      314672 :     dr_dstress = (0.5 * d2sibar2 * Utility::pow<2>(kk) + sibar2 * kk * d2kk) / denom;
     298      629344 :     for (unsigned i = 0; i < 3; ++i)
     299     1888032 :       for (unsigned j = 0; j < 3; ++j)
     300     5664096 :         for (unsigned k = 0; k < 3; ++k)
     301    16992288 :           for (unsigned l = 0; l < 3; ++l)
     302             :           {
     303    12744216 :             dr_dstress(i, j, k, l) +=
     304    12744216 :                 0.5 * d2smooth_over_denom * dmean_stress(i, j) * dmean_stress(k, l);
     305    12744216 :             dr_dstress(i, j, k, l) +=
     306    12744216 :                 (dsibar2(i, j) * dkk(k, l) * kk + dkk(i, j) * dsibar2(k, l) * kk +
     307    12744216 :                  sibar2 * dkk(i, j) * dkk(k, l)) /
     308             :                 denom;
     309    12744216 :             dr_dstress(i, j, k, l) -= numer_full(i, j) * numer_full(k, l) / denom3;
     310             :           }
     311             :   }
     312      206064 :   return dr_dstress;
     313             : }
     314             : 
     315             : RankTwoTensor
     316      206064 : TensorMechanicsPlasticMohrCoulomb::dflowPotential_dintnl(const RankTwoTensor & stress,
     317             :                                                          Real intnl) const
     318             : {
     319      206064 :   Real sin_angle = std::sin(psi(intnl));
     320      206064 :   Real dsin_angle = std::cos(psi(intnl)) * dpsi(intnl);
     321             : 
     322      206064 :   Real mean_stress = stress.trace() / 3.0;
     323      206064 :   RankTwoTensor dmean_stress = stress.dtrace() / 3.0;
     324      206064 :   Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0);
     325             : 
     326      206064 :   if (std::abs(sin3Lode) <= _sin3tt)
     327             :   {
     328             :     // the non-edge-smoothed version
     329             :     std::vector<Real> eigvals;
     330             :     std::vector<RankTwoTensor> deigvals;
     331       48728 :     stress.dsymmetricEigenvalues(eigvals, deigvals);
     332       48728 :     Real tmp = eigvals[2] - eigvals[0] + (eigvals[2] + eigvals[0] - 2.0 * mean_stress) * sin_angle;
     333       48728 :     Real dtmp_dintnl = (eigvals[2] + eigvals[0] - 2 * mean_stress) * dsin_angle;
     334             :     RankTwoTensor dtmp_dstress =
     335       48728 :         deigvals[2] - deigvals[0] + (deigvals[2] + deigvals[0] - 2.0 * dmean_stress) * sin_angle;
     336             :     RankTwoTensor d2tmp_dstress_dintnl =
     337       48728 :         (deigvals[2] + deigvals[0] - 2.0 * dmean_stress) * dsin_angle;
     338       48728 :     Real denom = std::sqrt(smooth(stress) + 0.25 * Utility::pow<2>(tmp));
     339       48728 :     return dmean_stress * dsin_angle + 0.25 * dtmp_dintnl * dtmp_dstress / denom +
     340       48728 :            0.25 * tmp * d2tmp_dstress_dintnl / denom -
     341       48728 :            0.5 * (dsmooth(stress) * dmean_stress + 0.5 * tmp * dtmp_dstress) * 0.25 * tmp *
     342       48728 :                dtmp_dintnl / Utility::pow<3>(denom);
     343             :   }
     344             :   else
     345             :   {
     346             :     // the edge-smoothed version
     347             :     Real aaa, bbb, ccc;
     348      157336 :     abbo(sin3Lode, sin_angle, aaa, bbb, ccc);
     349      157336 :     Real kk = aaa + bbb * sin3Lode + ccc * Utility::pow<2>(sin3Lode);
     350             : 
     351             :     Real daaa, dbbb, dccc;
     352      157336 :     dabbo(sin3Lode, sin_angle, daaa, dbbb, dccc);
     353      157336 :     Real dkk_dintnl = (daaa + dbbb * sin3Lode + dccc * Utility::pow<2>(sin3Lode)) * dsin_angle;
     354      157336 :     RankTwoTensor dkk_dstress = (bbb + 2 * ccc * sin3Lode) * stress.dsin3Lode(_lode_cutoff);
     355             :     RankTwoTensor d2kk_dstress_dintnl =
     356      157336 :         (dbbb + 2 * dccc * sin3Lode) * stress.dsin3Lode(_lode_cutoff) * dsin_angle;
     357             : 
     358      157336 :     Real sibar2 = stress.secondInvariant();
     359      157336 :     RankTwoTensor dsibar2 = stress.dsecondInvariant();
     360      157336 :     Real denom = std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk));
     361             : 
     362      157336 :     return dmean_stress * dsin_angle +
     363      157336 :            (dsibar2 * kk * dkk_dintnl + sibar2 * dkk_dintnl * dkk_dstress +
     364      157336 :             sibar2 * kk * d2kk_dstress_dintnl) /
     365             :                denom -
     366      157336 :            (0.5 * dsmooth(stress) * dmean_stress + 0.5 * dsibar2 * Utility::pow<2>(kk) +
     367      314672 :             sibar2 * kk * dkk_dstress) *
     368      157336 :                sibar2 * kk * dkk_dintnl / Utility::pow<3>(denom);
     369             :   }
     370             : }
     371             : 
     372             : Real
     373      760076 : TensorMechanicsPlasticMohrCoulomb::cohesion(const Real internal_param) const
     374             : {
     375      760076 :   return _cohesion.value(internal_param);
     376             : }
     377             : 
     378             : Real
     379      206064 : TensorMechanicsPlasticMohrCoulomb::dcohesion(const Real internal_param) const
     380             : {
     381      206064 :   return _cohesion.derivative(internal_param);
     382             : }
     383             : 
     384             : Real
     385     1726399 : TensorMechanicsPlasticMohrCoulomb::phi(const Real internal_param) const
     386             : {
     387     1726399 :   return _phi.value(internal_param);
     388             : }
     389             : 
     390             : Real
     391      412128 : TensorMechanicsPlasticMohrCoulomb::dphi(const Real internal_param) const
     392             : {
     393      412128 :   return _phi.derivative(internal_param);
     394             : }
     395             : 
     396             : Real
     397     1300023 : TensorMechanicsPlasticMohrCoulomb::psi(const Real internal_param) const
     398             : {
     399     1300023 :   return _psi.value(internal_param);
     400             : }
     401             : 
     402             : Real
     403      206064 : TensorMechanicsPlasticMohrCoulomb::dpsi(const Real internal_param) const
     404             : {
     405      206064 :   return _psi.derivative(internal_param);
     406             : }
     407             : 
     408             : void
     409     1545984 : TensorMechanicsPlasticMohrCoulomb::abbo(
     410             :     const Real sin3lode, const Real sin_angle, Real & aaa, Real & bbb, Real & ccc) const
     411             : {
     412     1545984 :   Real tmp1 = (sin3lode >= 0 ? _costt - sin_angle * _sintt / std::sqrt(3.0)
     413      606032 :                              : _costt + sin_angle * _sintt / std::sqrt(3.0));
     414     1545984 :   Real tmp2 = (sin3lode >= 0 ? _sintt + sin_angle * _costt / std::sqrt(3.0)
     415      606032 :                              : -_sintt + sin_angle * _costt / std::sqrt(3.0));
     416             : 
     417     1545984 :   ccc = -_cos3tt * tmp1;
     418     1545984 :   ccc += (sin3lode >= 0 ? -3 * _sin3tt * tmp2 : 3 * _sin3tt * tmp2);
     419     1545984 :   ccc /= 18 * Utility::pow<3>(_cos3tt);
     420             : 
     421     1545984 :   bbb = (sin3lode >= 0 ? _sin6tt * tmp1 : -_sin6tt * tmp1);
     422     1545984 :   bbb -= 6 * _cos6tt * tmp2;
     423     1545984 :   bbb /= 18 * Utility::pow<3>(_cos3tt);
     424             : 
     425     1545984 :   aaa = (sin3lode >= 0 ? -sin_angle * _sintt / std::sqrt(3.0) - bbb * _sin3tt
     426      606032 :                        : sin_angle * _sintt / std::sqrt(3.0) + bbb * _sin3tt);
     427     1545984 :   aaa += -ccc * Utility::pow<2>(_sin3tt) + _costt;
     428     1545984 : }
     429             : 
     430             : void
     431      314672 : TensorMechanicsPlasticMohrCoulomb::dabbo(
     432             :     const Real sin3lode, const Real /*sin_angle*/, Real & daaa, Real & dbbb, Real & dccc) const
     433             : {
     434      314672 :   Real dtmp1 = (sin3lode >= 0 ? -_sintt / std::sqrt(3.0) : _sintt / std::sqrt(3.0));
     435      314672 :   Real dtmp2 = _costt / std::sqrt(3.0);
     436             : 
     437      314672 :   dccc = -_cos3tt * dtmp1;
     438      314672 :   dccc += (sin3lode >= 0 ? -3 * _sin3tt * dtmp2 : 3 * _sin3tt * dtmp2);
     439      314672 :   dccc /= 18 * Utility::pow<3>(_cos3tt);
     440             : 
     441      314672 :   dbbb = (sin3lode >= 0 ? _sin6tt * dtmp1 : -_sin6tt * dtmp1);
     442      314672 :   dbbb -= 6 * _cos6tt * dtmp2;
     443      314672 :   dbbb /= 18 * Utility::pow<3>(_cos3tt);
     444             : 
     445      314672 :   daaa = (sin3lode >= 0 ? -_sintt / std::sqrt(3.0) - dbbb * _sin3tt
     446      122176 :                         : _sintt / std::sqrt(3.0) + dbbb * _sin3tt);
     447      314672 :   daaa += -dccc * Utility::pow<2>(_sin3tt);
     448      314672 : }
     449             : 
     450             : Real
     451     2059736 : TensorMechanicsPlasticMohrCoulomb::smooth(const RankTwoTensor & stress) const
     452             : {
     453     2059736 :   Real smoother2 = _small_smoother2;
     454     2059736 :   if (_tip_scheme == "cap")
     455             :   {
     456      245376 :     Real x = stress.trace() / 3.0 - _cap_start;
     457             :     Real p = 0;
     458      245376 :     if (x > 0)
     459      219824 :       p = x * (1 - std::exp(-_cap_rate * x));
     460      245376 :     smoother2 += Utility::pow<2>(p);
     461             :   }
     462     2059736 :   return smoother2;
     463             : }
     464             : 
     465             : Real
     466     1299720 : TensorMechanicsPlasticMohrCoulomb::dsmooth(const RankTwoTensor & stress) const
     467             : {
     468             :   Real dsmoother2 = 0;
     469     1299720 :   if (_tip_scheme == "cap")
     470             :   {
     471      156096 :     Real x = stress.trace() / 3.0 - _cap_start;
     472             :     Real p = 0;
     473             :     Real dp_dx = 0;
     474      156096 :     if (x > 0)
     475             :     {
     476      139728 :       p = x * (1 - std::exp(-_cap_rate * x));
     477      139728 :       dp_dx = (1 - std::exp(-_cap_rate * x)) + x * _cap_rate * std::exp(-_cap_rate * x);
     478             :     }
     479      156096 :     dsmoother2 += 2 * p * dp_dx;
     480             :   }
     481     1299720 :   return dsmoother2;
     482             : }
     483             : 
     484             : Real
     485      206064 : TensorMechanicsPlasticMohrCoulomb::d2smooth(const RankTwoTensor & stress) const
     486             : {
     487             :   Real d2smoother2 = 0;
     488      206064 :   if (_tip_scheme == "cap")
     489             :   {
     490       24960 :     Real x = stress.trace() / 3.0 - _cap_start;
     491             :     Real p = 0;
     492             :     Real dp_dx = 0;
     493             :     Real d2p_dx2 = 0;
     494       24960 :     if (x > 0)
     495             :     {
     496       22032 :       p = x * (1 - std::exp(-_cap_rate * x));
     497       22032 :       dp_dx = (1 - std::exp(-_cap_rate * x)) + x * _cap_rate * std::exp(-_cap_rate * x);
     498       22032 :       d2p_dx2 = 2 * _cap_rate * std::exp(-_cap_rate * x) -
     499       22032 :                 x * Utility::pow<2>(_cap_rate) * std::exp(-_cap_rate * x);
     500             :     }
     501       24960 :     d2smoother2 += 2 * Utility::pow<2>(dp_dx) + 2 * p * d2p_dx2;
     502             :   }
     503      206064 :   return d2smoother2;
     504             : }
     505             : 
     506             : std::string
     507           0 : TensorMechanicsPlasticMohrCoulomb::modelName() const
     508             : {
     509           0 :   return "MohrCoulomb";
     510             : }

Generated by: LCOV version 1.14