LCOV - code coverage report
Current view: top level - src/userobjects - TensorMechanicsPlasticDruckerPragerHyperbolic.C (source / functions) Hit Total Coverage
Test: idaholab/moose tensor_mechanics: d6b47a Lines: 96 115 83.5 %
Date: 2024-02-27 11:53:14 Functions: 6 10 60.0 %
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 "TensorMechanicsPlasticDruckerPragerHyperbolic.h"
      11             : #include "RankFourTensor.h"
      12             : #include "libmesh/utility.h"
      13             : 
      14             : registerMooseObject("TensorMechanicsApp", TensorMechanicsPlasticDruckerPragerHyperbolic);
      15             : 
      16             : InputParameters
      17         138 : TensorMechanicsPlasticDruckerPragerHyperbolic::validParams()
      18             : {
      19         138 :   InputParameters params = TensorMechanicsPlasticDruckerPrager::validParams();
      20         276 :   params.addParam<bool>("use_custom_returnMap",
      21         276 :                         true,
      22             :                         "Whether to use the custom returnMap "
      23             :                         "algorithm.  Set to true if you are using "
      24             :                         "isotropic elasticity.");
      25         276 :   params.addParam<bool>("use_custom_cto",
      26         276 :                         true,
      27             :                         "Whether to use the custom consistent tangent "
      28             :                         "operator computations.  Set to true if you are "
      29             :                         "using isotropic elasticity.");
      30         138 :   params.addClassDescription("J2 plasticity, associative, with hardening");
      31         414 :   params.addRangeCheckedParam<Real>("smoother",
      32         276 :                                     0.0,
      33             :                                     "smoother>=0",
      34             :                                     "The cone vertex at J2=0 is smoothed.  The maximum mean "
      35             :                                     "stress possible, which is Cohesion*Cot(friction_angle) for "
      36             :                                     "smoother=0, becomes (Cohesion - "
      37             :                                     "smoother/3)*Cot(friction_angle).  This is a non-hardening "
      38             :                                     "parameter");
      39         414 :   params.addRangeCheckedParam<unsigned>(
      40             :       "max_iterations",
      41         276 :       40,
      42             :       "max_iterations>0",
      43             :       "Maximum iterations to use in the custom return map function");
      44         138 :   params.addClassDescription(
      45             :       "Non-associative Drucker Prager plasticity with hyperbolic smoothing of the cone tip.");
      46         138 :   return params;
      47           0 : }
      48             : 
      49          69 : TensorMechanicsPlasticDruckerPragerHyperbolic::TensorMechanicsPlasticDruckerPragerHyperbolic(
      50          69 :     const InputParameters & parameters)
      51             :   : TensorMechanicsPlasticDruckerPrager(parameters),
      52          69 :     _smoother2(Utility::pow<2>(getParam<Real>("smoother"))),
      53         138 :     _use_custom_returnMap(getParam<bool>("use_custom_returnMap")),
      54         138 :     _use_custom_cto(getParam<bool>("use_custom_cto")),
      55         207 :     _max_iters(getParam<unsigned>("max_iterations"))
      56             : {
      57          69 : }
      58             : 
      59             : Real
      60       49472 : TensorMechanicsPlasticDruckerPragerHyperbolic::yieldFunction(const RankTwoTensor & stress,
      61             :                                                              Real intnl) const
      62             : {
      63             :   Real aaa;
      64             :   Real bbb;
      65       49472 :   bothAB(intnl, aaa, bbb);
      66       49472 :   return std::sqrt(stress.secondInvariant() + _smoother2) + stress.trace() * bbb - aaa;
      67             : }
      68             : 
      69             : RankTwoTensor
      70           0 : TensorMechanicsPlasticDruckerPragerHyperbolic::df_dsig(const RankTwoTensor & stress, Real bbb) const
      71             : {
      72           0 :   return 0.5 * stress.dsecondInvariant() / std::sqrt(stress.secondInvariant() + _smoother2) +
      73           0 :          stress.dtrace() * bbb;
      74             : }
      75             : 
      76             : RankFourTensor
      77           0 : TensorMechanicsPlasticDruckerPragerHyperbolic::dflowPotential_dstress(const RankTwoTensor & stress,
      78             :                                                                       Real /*intnl*/) const
      79             : {
      80           0 :   RankFourTensor dr_dstress;
      81           0 :   dr_dstress = 0.5 * stress.d2secondInvariant() / std::sqrt(stress.secondInvariant() + _smoother2);
      82           0 :   dr_dstress += -0.5 * 0.5 * stress.dsecondInvariant().outerProduct(stress.dsecondInvariant()) /
      83           0 :                 std::pow(stress.secondInvariant() + _smoother2, 1.5);
      84           0 :   return dr_dstress;
      85             : }
      86             : 
      87             : std::string
      88           0 : TensorMechanicsPlasticDruckerPragerHyperbolic::modelName() const
      89             : {
      90           0 :   return "DruckerPragerHyperbolic";
      91             : }
      92             : 
      93             : bool
      94       49472 : TensorMechanicsPlasticDruckerPragerHyperbolic::returnMap(const RankTwoTensor & trial_stress,
      95             :                                                          Real intnl_old,
      96             :                                                          const RankFourTensor & E_ijkl,
      97             :                                                          Real ep_plastic_tolerance,
      98             :                                                          RankTwoTensor & returned_stress,
      99             :                                                          Real & returned_intnl,
     100             :                                                          std::vector<Real> & dpm,
     101             :                                                          RankTwoTensor & delta_dp,
     102             :                                                          std::vector<Real> & yf,
     103             :                                                          bool & trial_stress_inadmissible) const
     104             : {
     105       49472 :   if (!(_use_custom_returnMap))
     106           0 :     return TensorMechanicsPlasticModel::returnMap(trial_stress,
     107             :                                                   intnl_old,
     108             :                                                   E_ijkl,
     109             :                                                   ep_plastic_tolerance,
     110             :                                                   returned_stress,
     111             :                                                   returned_intnl,
     112             :                                                   dpm,
     113             :                                                   delta_dp,
     114             :                                                   yf,
     115             :                                                   trial_stress_inadmissible);
     116             : 
     117       49472 :   yf.resize(1);
     118             : 
     119       49472 :   yf[0] = yieldFunction(trial_stress, intnl_old);
     120             : 
     121       49472 :   if (yf[0] < _f_tol)
     122             :   {
     123             :     // the trial_stress is admissible
     124       19072 :     trial_stress_inadmissible = false;
     125       19072 :     return true;
     126             :   }
     127             : 
     128       30400 :   trial_stress_inadmissible = true;
     129       30400 :   const Real mu = E_ijkl(0, 1, 0, 1);
     130       30400 :   const Real lambda = E_ijkl(0, 0, 0, 0) - 2.0 * mu;
     131       30400 :   const Real bulky = 3.0 * lambda + 2.0 * mu;
     132       30400 :   const Real Tr_trial = trial_stress.trace();
     133       30400 :   const Real J2trial = trial_stress.secondInvariant();
     134             : 
     135             :   // Perform a Newton-Raphson to find dpm when
     136             :   // residual = (1 + dpm*mu/ll)sqrt(ll^2 - s^2) - sqrt(J2trial) = 0, with s=smoother
     137             :   // with ll = sqrt(J2 + s^2) = aaa - bbb*Tr(stress) = aaa - bbb(Tr_trial - p*3*bulky*bbb_flow)
     138             :   Real aaa;
     139             :   Real daaa;
     140             :   Real bbb;
     141             :   Real dbbb;
     142             :   Real bbb_flow;
     143             :   Real dbbb_flow;
     144             :   Real ll;
     145             :   Real dll;
     146             :   Real residual;
     147             :   Real jac;
     148       30400 :   dpm[0] = 0;
     149             :   unsigned int iter = 0;
     150             :   do
     151             :   {
     152      208664 :     bothAB(intnl_old + dpm[0], aaa, bbb);
     153      208664 :     dbothAB(intnl_old + dpm[0], daaa, dbbb);
     154      208664 :     onlyB(intnl_old + dpm[0], dilation, bbb_flow);
     155      208664 :     donlyB(intnl_old + dpm[0], dilation, dbbb_flow);
     156      208664 :     ll = aaa - bbb * (Tr_trial - dpm[0] * bulky * 3 * bbb_flow);
     157      208664 :     dll = daaa - dbbb * (Tr_trial - dpm[0] * bulky * 3 * bbb_flow) +
     158      208664 :           bbb * bulky * 3 * (bbb_flow + dpm[0] * dbbb_flow);
     159      208664 :     residual = bbb * (Tr_trial - dpm[0] * bulky * 3 * bbb_flow) - aaa +
     160      208664 :                std::sqrt(J2trial / Utility::pow<2>(1 + dpm[0] * mu / ll) + _smoother2);
     161      208664 :     jac = dbbb * (Tr_trial - dpm[0] * bulky * 3 * bbb_flow) -
     162      208664 :           bbb * bulky * 3 * (bbb_flow + dpm[0] * dbbb_flow) - daaa +
     163      208664 :           0.5 * J2trial * (-2.0) * (mu / ll - dpm[0] * mu * dll / ll / ll) /
     164      208664 :               Utility::pow<3>(1 + dpm[0] * mu / ll) /
     165      208664 :               std::sqrt(J2trial / Utility::pow<2>(1.0 + dpm[0] * mu / ll) + _smoother2);
     166      208664 :     dpm[0] += -residual / jac;
     167      208664 :     if (iter > _max_iters) // not converging
     168             :       return false;
     169      208664 :     iter++;
     170      208664 :   } while (residual * residual > _f_tol * _f_tol);
     171             : 
     172             :   // set the returned values
     173       30400 :   yf[0] = 0;
     174       30400 :   returned_intnl = intnl_old + dpm[0];
     175             : 
     176       30400 :   bothAB(returned_intnl, aaa, bbb);
     177       30400 :   onlyB(returned_intnl, dilation, bbb_flow);
     178       30400 :   ll = aaa - bbb * (Tr_trial - dpm[0] * bulky * 3.0 * bbb_flow);
     179             :   returned_stress =
     180       30400 :       trial_stress.deviatoric() / (1.0 + dpm[0] * mu / ll); // this is the deviatoric part only
     181             : 
     182       30400 :   RankTwoTensor rij = 0.5 * returned_stress.deviatoric() /
     183             :                       ll; // this is the derivatoric part the flow potential only
     184             : 
     185             :   // form the returned stress and the full flow potential
     186       30400 :   const Real returned_trace_over_3 = (aaa - ll) / bbb / 3.0;
     187      121600 :   for (unsigned i = 0; i < 3; ++i)
     188             :   {
     189       91200 :     returned_stress(i, i) += returned_trace_over_3;
     190       91200 :     rij(i, i) += bbb_flow;
     191             :   }
     192             : 
     193       30400 :   delta_dp = rij * dpm[0];
     194             : 
     195             :   return true;
     196             : }
     197             : 
     198             : RankFourTensor
     199       30400 : TensorMechanicsPlasticDruckerPragerHyperbolic::consistentTangentOperator(
     200             :     const RankTwoTensor & trial_stress,
     201             :     Real intnl_old,
     202             :     const RankTwoTensor & stress,
     203             :     Real intnl,
     204             :     const RankFourTensor & E_ijkl,
     205             :     const std::vector<Real> & cumulative_pm) const
     206             : {
     207       30400 :   if (!_use_custom_cto)
     208           0 :     return TensorMechanicsPlasticModel::consistentTangentOperator(
     209             :         trial_stress, intnl_old, stress, intnl, E_ijkl, cumulative_pm);
     210             : 
     211       30400 :   const Real mu = E_ijkl(0, 1, 0, 1);
     212       30400 :   const Real la = E_ijkl(0, 0, 0, 0) - 2.0 * mu;
     213       30400 :   const Real bulky = 3.0 * la + 2.0 * mu;
     214             :   Real bbb;
     215       30400 :   onlyB(intnl, friction, bbb);
     216             :   Real bbb_flow;
     217       30400 :   onlyB(intnl, dilation, bbb_flow);
     218             :   Real dbbb_flow;
     219       30400 :   donlyB(intnl, dilation, dbbb_flow);
     220       30400 :   const Real bbb_flow_mod = bbb_flow + cumulative_pm[0] * dbbb_flow;
     221       30400 :   const Real J2 = stress.secondInvariant();
     222       30400 :   const RankTwoTensor sij = stress.deviatoric();
     223       30400 :   const Real sq = std::sqrt(J2 + _smoother2);
     224             : 
     225             :   const Real one_over_h =
     226       30400 :       1.0 / (-dyieldFunction_dintnl(stress, intnl) + mu * J2 / Utility::pow<2>(sq) +
     227       30400 :              3.0 * bbb * bbb_flow_mod * bulky); // correct up to hard
     228             : 
     229             :   const RankTwoTensor df_dsig_timesE =
     230       30400 :       mu * sij / sq + bulky * bbb * RankTwoTensor(RankTwoTensor::initIdentity); // correct
     231             :   const RankTwoTensor rmod_timesE =
     232       30400 :       mu * sij / sq +
     233       30400 :       bulky * bbb_flow_mod * RankTwoTensor(RankTwoTensor::initIdentity); // correct up to hard
     234             : 
     235             :   const RankFourTensor coeff_ep =
     236       30400 :       E_ijkl - one_over_h * rmod_timesE.outerProduct(df_dsig_timesE); // correct
     237             : 
     238       30400 :   const RankFourTensor dr_dsig_timesE = -0.5 * mu * sij.outerProduct(sij) / Utility::pow<3>(sq) +
     239       60800 :                                         mu * stress.d2secondInvariant() / sq; // correct
     240             :   const RankTwoTensor df_dsig_E_dr_dsig =
     241       30400 :       0.5 * mu * _smoother2 * sij / Utility::pow<4>(sq); // correct
     242             : 
     243             :   const RankFourTensor coeff_si =
     244       30400 :       RankFourTensor(RankFourTensor::initIdentitySymmetricFour) +
     245       30400 :       cumulative_pm[0] *
     246       60800 :           (dr_dsig_timesE - one_over_h * rmod_timesE.outerProduct(df_dsig_E_dr_dsig));
     247             : 
     248       30400 :   RankFourTensor s_inv;
     249             :   try
     250             :   {
     251       30400 :     s_inv = coeff_si.invSymm();
     252             :   }
     253           0 :   catch (MooseException & e)
     254             :   {
     255           0 :     return coeff_ep; // when coeff_si is singular return the "linear" tangent operator
     256           0 :   }
     257             : 
     258       30400 :   return s_inv * coeff_ep;
     259             : }
     260             : 
     261             : bool
     262           0 : TensorMechanicsPlasticDruckerPragerHyperbolic::useCustomReturnMap() const
     263             : {
     264           0 :   return _use_custom_returnMap;
     265             : }
     266             : 
     267             : bool
     268       30400 : TensorMechanicsPlasticDruckerPragerHyperbolic::useCustomCTO() const
     269             : {
     270       30400 :   return _use_custom_cto;
     271             : }

Generated by: LCOV version 1.14