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

Generated by: LCOV version 1.14