LCOV - code coverage report
Current view: top level - src/materials - CappedDruckerPragerStressUpdate.C (source / functions) Hit Total Coverage
Test: idaholab/moose solid_mechanics: f45d79 Lines: 195 221 88.2 %
Date: 2025-07-25 05:00:39 Functions: 17 18 94.4 %
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 "CappedDruckerPragerStressUpdate.h"
      11             : 
      12             : #include "libmesh/utility.h"
      13             : 
      14             : registerMooseObject("SolidMechanicsApp", CappedDruckerPragerStressUpdate);
      15             : 
      16             : InputParameters
      17         600 : CappedDruckerPragerStressUpdate::validParams()
      18             : {
      19         600 :   InputParameters params = TwoParameterPlasticityStressUpdate::validParams();
      20         600 :   params.addClassDescription("Capped Drucker-Prager plasticity stress calculator");
      21        1200 :   params.addRequiredParam<UserObjectName>(
      22             :       "DP_model",
      23             :       "A SolidMechanicsPlasticDruckerPrager UserObject that defines the "
      24             :       "Drucker-Prager parameters (cohesion, friction angle and dilation angle)");
      25        1200 :   params.addRequiredParam<UserObjectName>(
      26             :       "tensile_strength",
      27             :       "A SolidMechanicsHardening UserObject that defines hardening of the "
      28             :       "tensile strength.  In physical situations this is positive (and always "
      29             :       "must be greater than negative compressive-strength.");
      30        1200 :   params.addRequiredParam<UserObjectName>(
      31             :       "compressive_strength",
      32             :       "A SolidMechanicsHardening UserObject that defines hardening of the "
      33             :       "compressive strength.  In physical situations this is positive.");
      34        1200 :   params.addRequiredRangeCheckedParam<Real>(
      35             :       "tip_smoother",
      36             :       "tip_smoother>=0",
      37             :       "The cone vertex at J2 = 0 will be smoothed by the given "
      38             :       "amount.  Typical value is 0.1*cohesion");
      39        1200 :   params.addParam<bool>("perfect_guess",
      40        1200 :                         true,
      41             :                         "Provide a guess to the Newton-Raphson procedure "
      42             :                         "that is the result from perfect plasticity.  With "
      43             :                         "severe hardening/softening this may be "
      44             :                         "suboptimal.");
      45        1200 :   params.addParam<bool>("small_dilation",
      46        1200 :                         true,
      47             :                         "If true, and if the trial stress exceeds the "
      48             :                         "tensile strength, then the user guarantees that "
      49             :                         "the returned stress will be independent of the "
      50             :                         "compressive strength.");
      51         600 :   return params;
      52           0 : }
      53             : 
      54         450 : CappedDruckerPragerStressUpdate::CappedDruckerPragerStressUpdate(const InputParameters & parameters)
      55             :   : TwoParameterPlasticityStressUpdate(parameters, 3, 2),
      56         450 :     _dp(getUserObject<SolidMechanicsPlasticDruckerPrager>("DP_model")),
      57         450 :     _tstrength(getUserObject<SolidMechanicsHardeningModel>("tensile_strength")),
      58         450 :     _cstrength(getUserObject<SolidMechanicsHardeningModel>("compressive_strength")),
      59         900 :     _small_smoother2(Utility::pow<2>(getParam<Real>("tip_smoother"))),
      60         900 :     _perfect_guess(getParam<bool>("perfect_guess")),
      61         450 :     _stress_return_type(StressReturnType::nothing_special),
      62         900 :     _small_dilation(getParam<bool>("small_dilation")),
      63         450 :     _in_q_trial(0.0)
      64             : {
      65             :   // With arbitary UserObjects, it is impossible to check everything,
      66             :   // but this will catch the common errors
      67         450 :   if (_tstrength.value(0) + _cstrength.value(0) <= _smoothing_tol)
      68           0 :     mooseError("CappedDruckerPragerStressUpdate: Tensile strength plus compressive strength must "
      69             :                "be greater than smoothing_tol");
      70         450 : }
      71             : 
      72             : void
      73       71680 : CappedDruckerPragerStressUpdate::initializeReturnProcess()
      74             : {
      75       71680 :   _stress_return_type = StressReturnType::nothing_special;
      76       71680 : }
      77             : 
      78             : void
      79       71328 : CappedDruckerPragerStressUpdate::finalizeReturnProcess(const RankTwoTensor & /*rotation_increment*/)
      80             : {
      81       71328 :   _stress_return_type = StressReturnType::nothing_special;
      82       71328 : }
      83             : 
      84             : void
      85       71328 : CappedDruckerPragerStressUpdate::preReturnMap(Real /*p_trial*/,
      86             :                                               Real q_trial,
      87             :                                               const RankTwoTensor & /*stress_trial*/,
      88             :                                               const std::vector<Real> & /*intnl_old*/,
      89             :                                               const std::vector<Real> & yf,
      90             :                                               const RankFourTensor & /*Eijkl*/)
      91             : {
      92             :   // If it's obvious, then simplify the return-type
      93       71328 :   if (yf[2] >= 0)
      94        3504 :     _stress_return_type = StressReturnType::no_tension;
      95       67824 :   else if (_small_dilation && yf[1] >= 0)
      96       12960 :     _stress_return_type = StressReturnType::no_compression;
      97             : 
      98       71328 :   _in_q_trial = q_trial;
      99       71328 : }
     100             : 
     101             : void
     102      123232 : CappedDruckerPragerStressUpdate::computePQ(const RankTwoTensor & stress, Real & p, Real & q) const
     103             : {
     104      123232 :   p = stress.trace();
     105      123232 :   q = std::sqrt(stress.secondInvariant());
     106      123232 : }
     107             : 
     108             : void
     109       64128 : CappedDruckerPragerStressUpdate::setEppEqq(const RankFourTensor & Eijkl,
     110             :                                            Real & Epp,
     111             :                                            Real & Eqq) const
     112             : {
     113       64128 :   Epp = Eijkl.sum3x3();
     114       64128 :   Eqq = Eijkl(0, 1, 0, 1);
     115       64128 : }
     116             : 
     117             : void
     118      200176 : CappedDruckerPragerStressUpdate::setIntnlDerivatives(Real /*p_trial*/,
     119             :                                                      Real q_trial,
     120             :                                                      Real /*p*/,
     121             :                                                      Real q,
     122             :                                                      const std::vector<Real> & intnl,
     123             :                                                      std::vector<std::vector<Real>> & dintnl) const
     124             : {
     125             :   Real tanpsi;
     126      200176 :   _dp.onlyB(intnl[0], _dp.dilation, tanpsi);
     127             :   Real dtanpsi;
     128      200176 :   _dp.donlyB(intnl[0], _dp.dilation, dtanpsi);
     129      200176 :   dintnl[0][0] = 0.0;
     130      200176 :   dintnl[0][1] = -1.0 / _Eqq;
     131      200176 :   dintnl[1][0] = -1.0 / _Epp;
     132      200176 :   dintnl[1][1] = tanpsi / _Eqq - (q_trial - q) * dtanpsi * dintnl[0][1] / _Eqq;
     133      200176 : }
     134             : 
     135             : void
     136      143008 : CappedDruckerPragerStressUpdate::yieldFunctionValues(Real p,
     137             :                                                      Real q,
     138             :                                                      const std::vector<Real> & intnl,
     139             :                                                      std::vector<Real> & yf) const
     140             : {
     141             :   Real aaa;
     142             :   Real bbb;
     143      143008 :   _dp.bothAB(intnl[0], aaa, bbb);
     144      143008 :   yf[0] = std::sqrt(Utility::pow<2>(q) + _small_smoother2) + p * bbb - aaa;
     145             : 
     146      143008 :   if (_stress_return_type == StressReturnType::no_tension)
     147           0 :     yf[1] = std::numeric_limits<Real>::lowest();
     148             :   else
     149      143008 :     yf[1] = p - _tstrength.value(intnl[1]);
     150             : 
     151      143008 :   if (_stress_return_type == StressReturnType::no_compression)
     152           0 :     yf[2] = std::numeric_limits<Real>::lowest();
     153             :   else
     154      143008 :     yf[2] = -p - _cstrength.value(intnl[1]);
     155      143008 : }
     156             : 
     157             : void
     158      271312 : CappedDruckerPragerStressUpdate::computeAllQ(Real p,
     159             :                                              Real q,
     160             :                                              const std::vector<Real> & intnl,
     161             :                                              std::vector<yieldAndFlow> & all_q) const
     162             : {
     163             :   Real aaa;
     164             :   Real bbb;
     165      271312 :   _dp.bothAB(intnl[0], aaa, bbb);
     166             :   Real daaa;
     167             :   Real dbbb;
     168      271312 :   _dp.dbothAB(intnl[0], daaa, dbbb);
     169             :   Real tanpsi;
     170      271312 :   _dp.onlyB(intnl[0], _dp.dilation, tanpsi);
     171             :   Real dtanpsi;
     172      271312 :   _dp.donlyB(intnl[0], _dp.dilation, dtanpsi);
     173             : 
     174             :   // yield function values
     175      271312 :   all_q[0].f = std::sqrt(Utility::pow<2>(q) + _small_smoother2) + p * bbb - aaa;
     176      271312 :   if (_stress_return_type == StressReturnType::no_tension)
     177       20864 :     all_q[1].f = std::numeric_limits<Real>::lowest();
     178             :   else
     179      250448 :     all_q[1].f = p - _tstrength.value(intnl[1]);
     180      271312 :   if (_stress_return_type == StressReturnType::no_compression)
     181       39424 :     all_q[2].f = std::numeric_limits<Real>::lowest();
     182             :   else
     183      231888 :     all_q[2].f = -p - _cstrength.value(intnl[1]);
     184             : 
     185             :   // d(yield Function)/d(p, q)
     186             :   // derivatives wrt p
     187      271312 :   all_q[0].df[0] = bbb;
     188      271312 :   all_q[1].df[0] = 1.0;
     189      271312 :   all_q[2].df[0] = -1.0;
     190             : 
     191             :   // derivatives wrt q
     192      271312 :   if (_small_smoother2 == 0.0)
     193           0 :     all_q[0].df[1] = 1.0;
     194             :   else
     195      271312 :     all_q[0].df[1] = q / std::sqrt(Utility::pow<2>(q) + _small_smoother2);
     196      271312 :   all_q[1].df[1] = 0.0;
     197      271312 :   all_q[2].df[1] = 0.0;
     198             : 
     199             :   // d(yield Function)/d(intnl)
     200             :   // derivatives wrt intnl[0] (shear plastic strain)
     201      271312 :   all_q[0].df_di[0] = p * dbbb - daaa;
     202      271312 :   all_q[1].df_di[0] = 0.0;
     203      271312 :   all_q[2].df_di[0] = 0.0;
     204             :   // derivatives wrt intnl[q] (tensile plastic strain)
     205      271312 :   all_q[0].df_di[1] = 0.0;
     206      271312 :   all_q[1].df_di[1] = -_tstrength.derivative(intnl[1]);
     207      271312 :   all_q[2].df_di[1] = -_cstrength.derivative(intnl[1]);
     208             : 
     209             :   // d(flowPotential)/d(p, q)
     210             :   // derivatives wrt p
     211      271312 :   all_q[0].dg[0] = tanpsi;
     212      271312 :   all_q[1].dg[0] = 1.0;
     213      271312 :   all_q[2].dg[0] = -1.0;
     214             :   // derivatives wrt q
     215      271312 :   if (_small_smoother2 == 0.0)
     216           0 :     all_q[0].dg[1] = 1.0;
     217             :   else
     218      271312 :     all_q[0].dg[1] = q / std::sqrt(Utility::pow<2>(q) + _small_smoother2);
     219      271312 :   all_q[1].dg[1] = 0.0;
     220      271312 :   all_q[2].dg[1] = 0.0;
     221             : 
     222             :   // d2(flowPotential)/d(p, q)/d(intnl)
     223             :   // d(dg/dp)/dintnl[0]
     224      271312 :   all_q[0].d2g_di[0][0] = dtanpsi;
     225      271312 :   all_q[1].d2g_di[0][0] = 0.0;
     226      271312 :   all_q[2].d2g_di[0][0] = 0.0;
     227             :   // d(dg/dp)/dintnl[1]
     228      271312 :   all_q[0].d2g_di[0][1] = 0.0;
     229      271312 :   all_q[1].d2g_di[0][1] = 0.0;
     230      271312 :   all_q[2].d2g_di[0][1] = 0.0;
     231             :   // d(dg/dq)/dintnl[0]
     232      271312 :   all_q[0].d2g_di[1][0] = 0.0;
     233      271312 :   all_q[1].d2g_di[1][0] = 0.0;
     234      271312 :   all_q[2].d2g_di[1][0] = 0.0;
     235             :   // d(dg/dq)/dintnl[1]
     236      271312 :   all_q[0].d2g_di[1][1] = 0.0;
     237      271312 :   all_q[1].d2g_di[1][1] = 0.0;
     238      271312 :   all_q[2].d2g_di[1][1] = 0.0;
     239             : 
     240             :   // d2(flowPotential)/d(p, q)/d(p, q)
     241             :   // d(dg/dp)/dp
     242      271312 :   all_q[0].d2g[0][0] = 0.0;
     243      271312 :   all_q[1].d2g[0][0] = 0.0;
     244      271312 :   all_q[2].d2g[0][0] = 0.0;
     245             :   // d(dg/dp)/dq
     246      271312 :   all_q[0].d2g[0][1] = 0.0;
     247      271312 :   all_q[1].d2g[0][1] = 0.0;
     248      271312 :   all_q[2].d2g[0][1] = 0.0;
     249             :   // d(dg/dq)/dp
     250      271312 :   all_q[0].d2g[1][0] = 0.0;
     251      271312 :   all_q[1].d2g[1][0] = 0.0;
     252      271312 :   all_q[2].d2g[1][0] = 0.0;
     253             :   // d(dg/dq)/dq
     254      271312 :   if (_small_smoother2 == 0.0)
     255           0 :     all_q[0].d2g[1][1] = 0.0;
     256             :   else
     257      271312 :     all_q[0].d2g[1][1] = _small_smoother2 / std::pow(Utility::pow<2>(q) + _small_smoother2, 1.5);
     258      271312 :   all_q[1].d2g[1][1] = 0.0;
     259      271312 :   all_q[2].d2g[1][1] = 0.0;
     260      271312 : }
     261             : 
     262             : void
     263       71328 : CappedDruckerPragerStressUpdate::initializeVars(Real p_trial,
     264             :                                                 Real q_trial,
     265             :                                                 const std::vector<Real> & intnl_old,
     266             :                                                 Real & p,
     267             :                                                 Real & q,
     268             :                                                 Real & gaE,
     269             :                                                 std::vector<Real> & intnl) const
     270             : {
     271       71328 :   if (!_perfect_guess)
     272             :   {
     273           0 :     p = p_trial;
     274           0 :     q = q_trial;
     275           0 :     gaE = 0.0;
     276             :   }
     277             :   else
     278             :   {
     279             :     Real coh;
     280             :     Real tanphi;
     281       71328 :     _dp.bothAB(intnl[0], coh, tanphi);
     282             :     Real tanpsi;
     283       71328 :     _dp.onlyB(intnl_old[0], _dp.dilation, tanpsi);
     284       71328 :     const Real tens = _tstrength.value(intnl_old[1]);
     285       71328 :     const Real comp = _cstrength.value(intnl_old[1]);
     286       71328 :     const Real q_at_T = coh - tens * tanphi;
     287       71328 :     const Real q_at_C = coh + comp * tanphi;
     288             : 
     289       71328 :     if ((p_trial >= tens) && (q_trial <= q_at_T))
     290             :     {
     291             :       // pure tensile failure
     292        6432 :       p = tens;
     293        6432 :       q = q_trial;
     294        6432 :       gaE = p_trial - p;
     295             :     }
     296       64896 :     else if ((p_trial <= -comp) && (q_trial <= q_at_C))
     297             :     {
     298             :       // pure compressive failure
     299          96 :       p = -comp;
     300          96 :       q = q_trial;
     301          96 :       gaE = p - p_trial;
     302             :     }
     303             :     else
     304             :     {
     305             :       // shear failure or a mixture
     306             :       // Calculate ga assuming a pure shear failure
     307       64800 :       const Real ga = (q_trial + p_trial * tanphi - coh) / (_Eqq + _Epp * tanphi * tanpsi);
     308       64800 :       if (ga <= 0 && p_trial <= tens && p_trial >= -comp)
     309             :       {
     310             :         // very close to one of the rounded corners:  there is no advantage to guessing the
     311             :         // solution, so:
     312           0 :         p = p_trial;
     313           0 :         q = q_trial;
     314           0 :         gaE = 0.0;
     315             :       }
     316             :       else
     317             :       {
     318       64800 :         q = q_trial - _Eqq * ga;
     319       64800 :         if (q <= 0.0 && q_at_T <= 0.0)
     320             :         {
     321             :           // user has set tensile strength so large that it is irrelevant: return to the tip of the
     322             :           // shear cone
     323           0 :           q = 0.0;
     324           0 :           p = coh / tanphi;
     325           0 :           gaE = (p_trial - p) / tanpsi; // just a guess, based on the angle to the corner
     326             :         }
     327       64800 :         else if (q <= q_at_T)
     328             :         {
     329             :           // pure shear is incorrect: mixture of tension and shear is correct
     330        5600 :           q = q_at_T;
     331        5600 :           p = tens;
     332        5600 :           gaE = (p_trial - p) / tanpsi; // just a guess, based on the angle to the corner
     333             :         }
     334       59200 :         else if (q >= q_at_C)
     335             :         {
     336             :           // pure shear is incorrect: mixture of compression and shear is correct
     337        3872 :           q = q_at_C;
     338        3872 :           p = -comp;
     339        3872 :           if (p - p_trial < _Epp * tanpsi * (q_trial - q) / _Eqq)
     340             :             // trial point is sitting almost directly above corner
     341         640 :             gaE = (q_trial - q) * _Epp / _Eqq;
     342             :           else
     343             :             // trial point is sitting to the left of the corner
     344        3232 :             gaE = (p - p_trial) / tanpsi;
     345             :         }
     346             :         else
     347             :         {
     348             :           // pure shear was correct
     349       55328 :           p = p_trial - _Epp * ga * tanpsi;
     350       55328 :           gaE = ga * _Epp;
     351             :         }
     352             :       }
     353             :     }
     354             :   }
     355       71328 :   setIntnlValues(p_trial, q_trial, p, q, intnl_old, intnl);
     356       71328 : }
     357             : 
     358             : void
     359      342640 : CappedDruckerPragerStressUpdate::setIntnlValues(Real p_trial,
     360             :                                                 Real q_trial,
     361             :                                                 Real p,
     362             :                                                 Real q,
     363             :                                                 const std::vector<Real> & intnl_old,
     364             :                                                 std::vector<Real> & intnl) const
     365             : {
     366      342640 :   intnl[0] = intnl_old[0] + (q_trial - q) / _Eqq;
     367             :   Real tanpsi;
     368      342640 :   _dp.onlyB(intnl[0], _dp.dilation, tanpsi);
     369      342640 :   intnl[1] = intnl_old[1] + (p_trial - p) / _Epp - (q_trial - q) * tanpsi / _Eqq;
     370      342640 : }
     371             : 
     372             : void
     373       64128 : CappedDruckerPragerStressUpdate::setStressAfterReturn(const RankTwoTensor & stress_trial,
     374             :                                                       Real p_ok,
     375             :                                                       Real q_ok,
     376             :                                                       Real /*gaE*/,
     377             :                                                       const std::vector<Real> & /*intnl*/,
     378             :                                                       const yieldAndFlow & /*smoothed_q*/,
     379             :                                                       const RankFourTensor & /*Eijkl*/,
     380             :                                                       RankTwoTensor & stress) const
     381             : {
     382             :   // stress = s_ij + de_ij tr(stress) / 3 = q / q_trial * s_ij^trial + de_ij p / 3 = q / q_trial *
     383             :   // (stress_ij^trial - de_ij tr(stress^trial) / 3) + de_ij p / 3
     384       64128 :   const Real p_trial = stress_trial.trace();
     385       64128 :   stress = RankTwoTensor(RankTwoTensor::initIdentity) / 3.0 *
     386       64128 :            (p_ok - (_in_q_trial == 0.0 ? 0.0 : p_trial * q_ok / _in_q_trial));
     387       64128 :   if (_in_q_trial > 0)
     388       64128 :     stress += q_ok / _in_q_trial * stress_trial;
     389       64128 : }
     390             : 
     391             : RankTwoTensor
     392       71328 : CappedDruckerPragerStressUpdate::dpdstress(const RankTwoTensor & stress) const
     393             : {
     394       71328 :   return stress.dtrace();
     395             : }
     396             : 
     397             : RankFourTensor
     398           0 : CappedDruckerPragerStressUpdate::d2pdstress2(const RankTwoTensor & /*stress*/) const
     399             : {
     400           0 :   return RankFourTensor();
     401             : }
     402             : 
     403             : RankTwoTensor
     404       71328 : CappedDruckerPragerStressUpdate::dqdstress(const RankTwoTensor & stress) const
     405             : {
     406       71328 :   const Real j2 = stress.secondInvariant();
     407       71328 :   if (j2 == 0.0)
     408           0 :     return RankTwoTensor();
     409       71328 :   return 0.5 * stress.dsecondInvariant() / std::sqrt(j2);
     410             : }
     411             : 
     412             : RankFourTensor
     413         192 : CappedDruckerPragerStressUpdate::d2qdstress2(const RankTwoTensor & stress) const
     414             : {
     415         192 :   const Real j2 = stress.secondInvariant();
     416         192 :   if (j2 == 0.0)
     417           0 :     return RankFourTensor();
     418             : 
     419         192 :   const RankTwoTensor dj2 = stress.dsecondInvariant();
     420         192 :   return -0.25 * dj2.outerProduct(dj2) / std::pow(j2, 1.5) +
     421         384 :          0.5 * stress.d2secondInvariant() / std::sqrt(j2);
     422             : }
     423             : 
     424             : void
     425         128 : CappedDruckerPragerStressUpdate::consistentTangentOperator(const RankTwoTensor & /*stress_trial*/,
     426             :                                                            Real /*p_trial*/,
     427             :                                                            Real /*q_trial*/,
     428             :                                                            const RankTwoTensor & stress,
     429             :                                                            Real /*p*/,
     430             :                                                            Real q,
     431             :                                                            Real gaE,
     432             :                                                            const yieldAndFlow & smoothed_q,
     433             :                                                            const RankFourTensor & Eijkl,
     434             :                                                            bool compute_full_tangent_operator,
     435             :                                                            RankFourTensor & cto) const
     436             : {
     437         128 :   cto = Eijkl;
     438         128 :   if (!compute_full_tangent_operator)
     439           0 :     return;
     440             : 
     441             :   const RankTwoTensor s_over_q =
     442         128 :       (q == 0.0 ? RankTwoTensor()
     443         512 :                 : (stress - stress.trace() * RankTwoTensor(RankTwoTensor::initIdentity) / 3.0) / q);
     444             : 
     445         512 :   for (unsigned i = 0; i < _tensor_dimensionality; ++i)
     446        1536 :     for (unsigned j = 0; j < _tensor_dimensionality; ++j)
     447        4608 :       for (unsigned k = 0; k < _tensor_dimensionality; ++k)
     448       13824 :         for (unsigned l = 0; l < _tensor_dimensionality; ++l)
     449             :         {
     450       10368 :           cto(i, j, k, l) -=
     451       20736 :               (i == j) * (1.0 / 3.0) *
     452       17280 :               (_Epp * (1.0 - _dp_dpt) / 3.0 * (k == l) + s_over_q(k, l) * _Eqq * (-_dp_dqt));
     453       10368 :           cto(i, j, k, l) -= s_over_q(i, j) * (_Epp * (-_dq_dpt) / 3.0 * (k == l) +
     454       10368 :                                                s_over_q(k, l) * _Eqq * (1.0 - _dq_dqt));
     455             :         }
     456             : 
     457         128 :   if (smoothed_q.dg[1] != 0.0)
     458             :   {
     459         192 :     const RankFourTensor Tijab = Eijkl * (gaE / _Epp) * smoothed_q.dg[1] * d2qdstress2(stress);
     460          96 :     RankFourTensor inv = RankFourTensor(RankFourTensor::initIdentityFour) + Tijab;
     461             :     try
     462             :     {
     463          96 :       inv = inv.transposeMajor().invSymm();
     464             :     }
     465           0 :     catch (const MooseException & e)
     466             :     {
     467             :       // Cannot form the inverse, so probably at some degenerate place in stress space.
     468             :       // Just return with the "best estimate" of the cto.
     469           0 :       mooseWarning("CappedDruckerPragerStressUpdate: Cannot invert 1+T in consistent tangent "
     470             :                    "operator computation at quadpoint ",
     471           0 :                    _qp,
     472             :                    " of element ",
     473           0 :                    _current_elem->id());
     474             :       return;
     475           0 :     }
     476          96 :     cto = (cto.transposeMajor() * inv).transposeMajor();
     477             :   }
     478             : }

Generated by: LCOV version 1.14