LCOV - code coverage report
Current view: top level - src/userobjects - SolidMechanicsPlasticDruckerPrager.C (source / functions) Hit Total Coverage
Test: idaholab/moose solid_mechanics: f45d79 Lines: 116 185 62.7 %
Date: 2025-07-25 05:00:39 Functions: 9 16 56.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 "SolidMechanicsPlasticDruckerPrager.h"
      11             : #include "RankFourTensor.h"
      12             : #include "libmesh/utility.h"
      13             : 
      14             : registerMooseObject("SolidMechanicsApp", SolidMechanicsPlasticDruckerPrager);
      15             : registerMooseObjectRenamed("SolidMechanicsApp",
      16             :                            TensorMechanicsPlasticDruckerPrager,
      17             :                            "01/01/2025 00:00",
      18             :                            SolidMechanicsPlasticDruckerPrager);
      19             : 
      20             : InputParameters
      21         468 : SolidMechanicsPlasticDruckerPrager::validParams()
      22             : {
      23         468 :   InputParameters params = SolidMechanicsPlasticModel::validParams();
      24             :   MooseEnum mc_interpolation_scheme("outer_tip=0 inner_tip=1 lode_zero=2 inner_edge=3 native=4",
      25         936 :                                     "lode_zero");
      26         936 :   params.addParam<MooseEnum>(
      27             :       "mc_interpolation_scheme",
      28             :       mc_interpolation_scheme,
      29             :       "Scheme by which the Drucker-Prager cohesion, friction angle and dilation angle are set from "
      30             :       "the Mohr-Coulomb parameters mc_cohesion, mc_friction_angle and mc_dilation_angle.  Consider "
      31             :       "the DP and MC yield surfaces on the deviatoric (octahedral) plane.  Outer_tip: the DP "
      32             :       "circle touches the outer tips of the MC hex.  Inner_tip: the DP circle touches the inner "
      33             :       "tips of the MC hex.  Lode_zero: the DP circle intersects the MC hex at lode angle=0.  "
      34             :       "Inner_edge: the DP circle is the largest circle that wholly fits inside the MC hex.  "
      35             :       "Native: The DP cohesion, friction angle and dilation angle are set equal to the mc_ "
      36             :       "parameters entered.");
      37         936 :   params.addRequiredParam<UserObjectName>(
      38             :       "mc_cohesion",
      39             :       "A SolidMechanicsHardening UserObject that defines hardening of the "
      40             :       "Mohr-Coulomb cohesion.  Physically this should not be negative.");
      41         936 :   params.addRequiredParam<UserObjectName>(
      42             :       "mc_friction_angle",
      43             :       "A SolidMechanicsHardening UserObject that defines hardening of the "
      44             :       "Mohr-Coulomb friction angle (in radians).  Physically this should be "
      45             :       "between 0 and Pi/2.");
      46         936 :   params.addRequiredParam<UserObjectName>(
      47             :       "mc_dilation_angle",
      48             :       "A SolidMechanicsHardening UserObject that defines hardening of the "
      49             :       "Mohr-Coulomb dilation angle (in radians).  Usually the dilation angle "
      50             :       "is not greater than the friction angle, and it is between 0 and Pi/2.");
      51         468 :   params.addClassDescription(
      52             :       "Non-associative Drucker Prager plasticity with no smoothing of the cone tip.");
      53         468 :   return params;
      54         468 : }
      55             : 
      56         234 : SolidMechanicsPlasticDruckerPrager::SolidMechanicsPlasticDruckerPrager(
      57         234 :     const InputParameters & parameters)
      58             :   : SolidMechanicsPlasticModel(parameters),
      59         234 :     _mc_cohesion(getUserObject<SolidMechanicsHardeningModel>("mc_cohesion")),
      60         234 :     _mc_phi(getUserObject<SolidMechanicsHardeningModel>("mc_friction_angle")),
      61         234 :     _mc_psi(getUserObject<SolidMechanicsHardeningModel>("mc_dilation_angle")),
      62         468 :     _mc_interpolation_scheme(getParam<MooseEnum>("mc_interpolation_scheme")),
      63         234 :     _zero_cohesion_hardening(_mc_cohesion.modelName().compare("Constant") == 0),
      64         234 :     _zero_phi_hardening(_mc_phi.modelName().compare("Constant") == 0),
      65         468 :     _zero_psi_hardening(_mc_psi.modelName().compare("Constant") == 0)
      66             : {
      67         702 :   if (_mc_phi.value(0.0) < 0.0 || _mc_psi.value(0.0) < 0.0 ||
      68         702 :       _mc_phi.value(0.0) > libMesh::pi / 2.0 || _mc_psi.value(0.0) > libMesh::pi / 2.0)
      69           0 :     mooseError("SolidMechanicsPlasticDruckerPrager: MC friction and dilation angles must lie in "
      70             :                "[0, Pi/2]");
      71         234 :   if (_mc_phi.value(0) < _mc_psi.value(0.0))
      72           0 :     mooseError("SolidMechanicsPlasticDruckerPrager: MC friction angle must not be less than MC "
      73             :                "dilation angle");
      74         234 :   if (_mc_cohesion.value(0.0) < 0)
      75           0 :     mooseError("SolidMechanicsPlasticDruckerPrager: MC cohesion should not be negative");
      76             : 
      77         234 :   initializeAandB(0.0, _aaa, _bbb);
      78         234 :   initializeB(0.0, dilation, _bbb_flow);
      79         234 : }
      80             : 
      81             : Real
      82           0 : SolidMechanicsPlasticDruckerPrager::yieldFunction(const RankTwoTensor & stress, Real intnl) const
      83             : {
      84             :   Real aaa;
      85             :   Real bbb;
      86           0 :   bothAB(intnl, aaa, bbb);
      87           0 :   return std::sqrt(stress.secondInvariant()) + stress.trace() * bbb - aaa;
      88             : }
      89             : 
      90             : RankTwoTensor
      91           0 : SolidMechanicsPlasticDruckerPrager::df_dsig(const RankTwoTensor & stress, Real bbb) const
      92             : {
      93           0 :   return 0.5 * stress.dsecondInvariant() / std::sqrt(stress.secondInvariant()) +
      94           0 :          stress.dtrace() * bbb;
      95             : }
      96             : 
      97             : RankTwoTensor
      98           0 : SolidMechanicsPlasticDruckerPrager::dyieldFunction_dstress(const RankTwoTensor & stress,
      99             :                                                            Real intnl) const
     100             : {
     101             :   Real bbb;
     102           0 :   onlyB(intnl, friction, bbb);
     103           0 :   return df_dsig(stress, bbb);
     104             : }
     105             : 
     106             : Real
     107       60576 : SolidMechanicsPlasticDruckerPrager::dyieldFunction_dintnl(const RankTwoTensor & stress,
     108             :                                                           Real intnl) const
     109             : {
     110             :   Real daaa;
     111             :   Real dbbb;
     112       60576 :   dbothAB(intnl, daaa, dbbb);
     113       60576 :   return stress.trace() * dbbb - daaa;
     114             : }
     115             : 
     116             : RankTwoTensor
     117           0 : SolidMechanicsPlasticDruckerPrager::flowPotential(const RankTwoTensor & stress, Real intnl) const
     118             : {
     119             :   Real bbb_flow;
     120           0 :   onlyB(intnl, dilation, bbb_flow);
     121           0 :   return df_dsig(stress, bbb_flow);
     122             : }
     123             : 
     124             : RankFourTensor
     125           0 : SolidMechanicsPlasticDruckerPrager::dflowPotential_dstress(const RankTwoTensor & stress,
     126             :                                                            Real /*intnl*/) const
     127             : {
     128           0 :   RankFourTensor dr_dstress;
     129           0 :   dr_dstress = 0.5 * stress.d2secondInvariant() / std::sqrt(stress.secondInvariant());
     130           0 :   dr_dstress += -0.5 * 0.5 * stress.dsecondInvariant().outerProduct(stress.dsecondInvariant()) /
     131           0 :                 std::pow(stress.secondInvariant(), 1.5);
     132           0 :   return dr_dstress;
     133             : }
     134             : 
     135             : RankTwoTensor
     136           0 : SolidMechanicsPlasticDruckerPrager::dflowPotential_dintnl(const RankTwoTensor & stress,
     137             :                                                           Real intnl) const
     138             : {
     139             :   Real dbbb;
     140           0 :   donlyB(intnl, dilation, dbbb);
     141           0 :   return stress.dtrace() * dbbb;
     142             : }
     143             : 
     144             : std::string
     145           0 : SolidMechanicsPlasticDruckerPrager::modelName() const
     146             : {
     147           0 :   return "DruckerPrager";
     148             : }
     149             : 
     150             : void
     151     1023744 : SolidMechanicsPlasticDruckerPrager::bothAB(Real intnl, Real & aaa, Real & bbb) const
     152             : {
     153     1023744 :   if (_zero_cohesion_hardening && _zero_phi_hardening)
     154             :   {
     155      986368 :     aaa = _aaa;
     156      986368 :     bbb = _bbb;
     157      986368 :     return;
     158             :   }
     159       37376 :   initializeAandB(intnl, aaa, bbb);
     160             : }
     161             : 
     162             : void
     163     1483744 : SolidMechanicsPlasticDruckerPrager::onlyB(Real intnl, int fd, Real & bbb) const
     164             : {
     165     1483744 :   if (_zero_phi_hardening && (fd == friction))
     166             :   {
     167       59680 :     bbb = _bbb;
     168       59680 :     return;
     169             :   }
     170     1424064 :   if (_zero_psi_hardening && (fd == dilation))
     171             :   {
     172     1353536 :     bbb = _bbb_flow;
     173     1353536 :     return;
     174             :   }
     175       70528 :   initializeB(intnl, fd, bbb);
     176             : }
     177             : 
     178             : void
     179      948624 : SolidMechanicsPlasticDruckerPrager::donlyB(Real intnl, int fd, Real & dbbb) const
     180             : {
     181      948624 :   if (_zero_phi_hardening && (fd == friction))
     182             :   {
     183           0 :     dbbb = 0;
     184           0 :     return;
     185             :   }
     186      948624 :   if (_zero_psi_hardening && (fd == dilation))
     187             :   {
     188      905872 :     dbbb = 0;
     189      905872 :     return;
     190             :   }
     191       42752 :   const Real s = (fd == friction) ? std::sin(_mc_phi.value(intnl)) : std::sin(_mc_psi.value(intnl));
     192       85504 :   const Real ds = (fd == friction) ? std::cos(_mc_phi.value(intnl)) * _mc_phi.derivative(intnl)
     193       42752 :                                    : std::cos(_mc_psi.value(intnl)) * _mc_psi.derivative(intnl);
     194       42752 :   switch (_mc_interpolation_scheme)
     195             :   {
     196           0 :     case 0: // outer_tip
     197           0 :       dbbb = 2.0 / std::sqrt(3.0) * (ds / (3.0 - s) + s * ds / Utility::pow<2>(3.0 - s));
     198           0 :       break;
     199           0 :     case 1: // inner_tip
     200           0 :       dbbb = 2.0 / std::sqrt(3.0) * (ds / (3.0 + s) - s * ds / Utility::pow<2>(3.0 + s));
     201           0 :       break;
     202       42752 :     case 2: // lode_zero
     203       42752 :       dbbb = ds / 3.0;
     204       42752 :       break;
     205             :     case 3: // inner_edge
     206           0 :       dbbb = ds / std::sqrt(9.0 + 3.0 * Utility::pow<2>(s)) -
     207           0 :              3 * s * s * ds / std::pow(9.0 + 3.0 * Utility::pow<2>(s), 1.5);
     208           0 :       break;
     209           0 :     case 4: // native
     210             :       const Real c =
     211           0 :           (fd == friction) ? std::cos(_mc_phi.value(intnl)) : std::cos(_mc_psi.value(intnl));
     212             :       const Real dc = (fd == friction)
     213           0 :                           ? -std::sin(_mc_phi.value(intnl)) * _mc_phi.derivative(intnl)
     214           0 :                           : -std::sin(_mc_psi.value(intnl)) * _mc_psi.derivative(intnl);
     215           0 :       dbbb = ds / c - s * dc / Utility::pow<2>(c);
     216           0 :       break;
     217             :   }
     218             : }
     219             : 
     220             : void
     221      748448 : SolidMechanicsPlasticDruckerPrager::dbothAB(Real intnl, Real & daaa, Real & dbbb) const
     222             : {
     223      748448 :   if (_zero_cohesion_hardening && _zero_phi_hardening)
     224             :   {
     225      721888 :     daaa = 0;
     226      721888 :     dbbb = 0;
     227             :     return;
     228             :   }
     229             : 
     230       26560 :   const Real C = _mc_cohesion.value(intnl);
     231       26560 :   const Real dC = _mc_cohesion.derivative(intnl);
     232       26560 :   const Real cosphi = std::cos(_mc_phi.value(intnl));
     233       26560 :   const Real dcosphi = -std::sin(_mc_phi.value(intnl)) * _mc_phi.derivative(intnl);
     234       26560 :   const Real sinphi = std::sin(_mc_phi.value(intnl));
     235       26560 :   const Real dsinphi = std::cos(_mc_phi.value(intnl)) * _mc_phi.derivative(intnl);
     236       26560 :   switch (_mc_interpolation_scheme)
     237             :   {
     238           0 :     case 0: // outer_tip
     239           0 :       daaa = 2.0 * std::sqrt(3.0) *
     240           0 :              (dC * cosphi / (3.0 - sinphi) + C * dcosphi / (3.0 - sinphi) +
     241           0 :               C * cosphi * dsinphi / Utility::pow<2>(3.0 - sinphi));
     242           0 :       dbbb = 2.0 / std::sqrt(3.0) *
     243           0 :              (dsinphi / (3.0 - sinphi) + sinphi * dsinphi / Utility::pow<2>(3.0 - sinphi));
     244           0 :       break;
     245           0 :     case 1: // inner_tip
     246           0 :       daaa = 2.0 * std::sqrt(3.0) *
     247           0 :              (dC * cosphi / (3.0 + sinphi) + C * dcosphi / (3.0 + sinphi) -
     248           0 :               C * cosphi * dsinphi / Utility::pow<2>(3.0 + sinphi));
     249           0 :       dbbb = 2.0 / std::sqrt(3.0) *
     250           0 :              (dsinphi / (3.0 + sinphi) - sinphi * dsinphi / Utility::pow<2>(3.0 + sinphi));
     251           0 :       break;
     252       26560 :     case 2: // lode_zero
     253       26560 :       daaa = dC * cosphi + C * dcosphi;
     254       26560 :       dbbb = dsinphi / 3.0;
     255       26560 :       break;
     256           0 :     case 3: // inner_edge
     257           0 :       daaa = 3.0 * dC * cosphi / std::sqrt(9.0 + 3.0 * Utility::pow<2>(sinphi)) +
     258           0 :              3.0 * C * dcosphi / std::sqrt(9.0 + 3.0 * Utility::pow<2>(sinphi)) -
     259           0 :              3.0 * C * cosphi * 3.0 * sinphi * dsinphi /
     260           0 :                  std::pow(9.0 + 3.0 * Utility::pow<2>(sinphi), 1.5);
     261           0 :       dbbb = dsinphi / std::sqrt(9.0 + 3.0 * Utility::pow<2>(sinphi)) -
     262           0 :              3.0 * sinphi * sinphi * dsinphi / std::pow(9.0 + 3.0 * Utility::pow<2>(sinphi), 1.5);
     263           0 :       break;
     264           0 :     case 4: // native
     265           0 :       daaa = dC;
     266           0 :       dbbb = dsinphi / cosphi - sinphi * dcosphi / Utility::pow<2>(cosphi);
     267           0 :       break;
     268             :   }
     269             : }
     270             : 
     271             : void
     272       37610 : SolidMechanicsPlasticDruckerPrager::initializeAandB(Real intnl, Real & aaa, Real & bbb) const
     273             : {
     274       37610 :   const Real C = _mc_cohesion.value(intnl);
     275       37610 :   const Real cosphi = std::cos(_mc_phi.value(intnl));
     276       37610 :   const Real sinphi = std::sin(_mc_phi.value(intnl));
     277       37610 :   switch (_mc_interpolation_scheme)
     278             :   {
     279          24 :     case 0: // outer_tip
     280          24 :       aaa = 2.0 * std::sqrt(3.0) * C * cosphi / (3.0 - sinphi);
     281          24 :       bbb = 2.0 * sinphi / std::sqrt(3.0) / (3.0 - sinphi);
     282          24 :       break;
     283          24 :     case 1: // inner_tip
     284          24 :       aaa = 2.0 * std::sqrt(3.0) * C * cosphi / (3.0 + sinphi);
     285          24 :       bbb = 2.0 * sinphi / std::sqrt(3.0) / (3.0 + sinphi);
     286          24 :       break;
     287       37514 :     case 2: // lode_zero
     288       37514 :       aaa = C * cosphi;
     289       37514 :       bbb = sinphi / 3.0;
     290       37514 :       break;
     291          24 :     case 3: // inner_edge
     292          24 :       aaa = 3.0 * C * cosphi / std::sqrt(9.0 + 3.0 * Utility::pow<2>(sinphi));
     293          24 :       bbb = sinphi / std::sqrt(9.0 + 3.0 * Utility::pow<2>(sinphi));
     294          24 :       break;
     295          24 :     case 4: // native
     296          24 :       aaa = C;
     297          24 :       bbb = sinphi / cosphi;
     298          24 :       break;
     299             :   }
     300       37610 : }
     301             : 
     302             : void
     303       70762 : SolidMechanicsPlasticDruckerPrager::initializeB(Real intnl, int fd, Real & bbb) const
     304             : {
     305       70762 :   const Real s = (fd == friction) ? std::sin(_mc_phi.value(intnl)) : std::sin(_mc_psi.value(intnl));
     306       70762 :   switch (_mc_interpolation_scheme)
     307             :   {
     308          24 :     case 0: // outer_tip
     309          24 :       bbb = 2.0 * s / std::sqrt(3.0) / (3.0 - s);
     310          24 :       break;
     311          24 :     case 1: // inner_tip
     312          24 :       bbb = 2.0 * s / std::sqrt(3.0) / (3.0 + s);
     313          24 :       break;
     314       70666 :     case 2: // lode_zero
     315       70666 :       bbb = s / 3.0;
     316       70666 :       break;
     317          24 :     case 3: // inner_edge
     318          24 :       bbb = s / std::sqrt(9.0 + 3.0 * Utility::pow<2>(s));
     319          24 :       break;
     320          24 :     case 4: // native
     321             :       const Real c =
     322          24 :           (fd == friction) ? std::cos(_mc_phi.value(intnl)) : std::cos(_mc_psi.value(intnl));
     323          24 :       bbb = s / c;
     324          24 :       break;
     325             :   }
     326       70762 : }

Generated by: LCOV version 1.14