LCOV - code coverage report
Current view: top level - src/userobjects - TensorMechanicsPlasticJ2.C (source / functions) Hit Total Coverage
Test: idaholab/moose tensor_mechanics: d6b47a Lines: 82 90 91.1 %
Date: 2024-02-27 11:53:14 Functions: 13 15 86.7 %
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 "TensorMechanicsPlasticJ2.h"
      11             : #include "RankFourTensor.h"
      12             : 
      13             : registerMooseObject("TensorMechanicsApp", TensorMechanicsPlasticJ2);
      14             : 
      15             : InputParameters
      16         126 : TensorMechanicsPlasticJ2::validParams()
      17             : {
      18         126 :   InputParameters params = TensorMechanicsPlasticModel::validParams();
      19         252 :   params.addRequiredParam<UserObjectName>(
      20             :       "yield_strength",
      21             :       "A TensorMechanicsHardening UserObject that defines hardening of the yield strength");
      22         378 :   params.addRangeCheckedParam<unsigned>(
      23         252 :       "max_iterations", 10, "max_iterations>0", "Maximum iterations for custom J2 return map");
      24         252 :   params.addParam<bool>("use_custom_returnMap",
      25         252 :                         true,
      26             :                         "Whether to use the custom returnMap "
      27             :                         "algorithm.  Set to true if you are using "
      28             :                         "isotropic elasticity.");
      29         252 :   params.addParam<bool>("use_custom_cto",
      30         252 :                         true,
      31             :                         "Whether to use the custom consistent tangent "
      32             :                         "operator computations.  Set to true if you are "
      33             :                         "using isotropic elasticity.");
      34         126 :   params.addClassDescription("J2 plasticity, associative, with hardening");
      35             : 
      36         126 :   return params;
      37           0 : }
      38             : 
      39          63 : TensorMechanicsPlasticJ2::TensorMechanicsPlasticJ2(const InputParameters & parameters)
      40             :   : TensorMechanicsPlasticModel(parameters),
      41          63 :     _strength(getUserObject<TensorMechanicsHardeningModel>("yield_strength")),
      42         126 :     _max_iters(getParam<unsigned>("max_iterations")),
      43         126 :     _use_custom_returnMap(getParam<bool>("use_custom_returnMap")),
      44         189 :     _use_custom_cto(getParam<bool>("use_custom_cto"))
      45             : {
      46          63 : }
      47             : 
      48             : Real
      49     3213376 : TensorMechanicsPlasticJ2::yieldFunction(const RankTwoTensor & stress, Real intnl) const
      50             : {
      51     3213376 :   return std::sqrt(3.0 * stress.secondInvariant()) - yieldStrength(intnl);
      52             : }
      53             : 
      54             : RankTwoTensor
      55        6144 : TensorMechanicsPlasticJ2::dyieldFunction_dstress(const RankTwoTensor & stress, Real /*intnl*/) const
      56             : {
      57        6144 :   Real sII = stress.secondInvariant();
      58        6144 :   if (sII == 0.0)
      59           0 :     return RankTwoTensor();
      60             :   else
      61        6144 :     return 0.5 * std::sqrt(3.0 / sII) * stress.dsecondInvariant();
      62             : }
      63             : 
      64             : Real
      65        8352 : TensorMechanicsPlasticJ2::dyieldFunction_dintnl(const RankTwoTensor & /*stress*/, Real intnl) const
      66             : {
      67        8352 :   return -dyieldStrength(intnl);
      68             : }
      69             : 
      70             : RankTwoTensor
      71        4608 : TensorMechanicsPlasticJ2::flowPotential(const RankTwoTensor & stress, Real intnl) const
      72             : {
      73        4608 :   return dyieldFunction_dstress(stress, intnl);
      74             : }
      75             : 
      76             : RankFourTensor
      77     3201726 : TensorMechanicsPlasticJ2::dflowPotential_dstress(const RankTwoTensor & stress, Real /*intnl*/) const
      78             : {
      79     3201726 :   Real sII = stress.secondInvariant();
      80     3201726 :   if (sII == 0)
      81           0 :     return RankFourTensor();
      82             : 
      83     3201726 :   RankFourTensor dfp = 0.5 * std::sqrt(3.0 / sII) * stress.d2secondInvariant();
      84     3201726 :   Real pre = -0.25 * std::sqrt(3.0) * std::pow(sII, -1.5);
      85     3201726 :   RankTwoTensor dII = stress.dsecondInvariant();
      86    12806904 :   for (unsigned i = 0; i < 3; ++i)
      87    38420712 :     for (unsigned j = 0; j < 3; ++j)
      88   115262136 :       for (unsigned k = 0; k < 3; ++k)
      89   345786408 :         for (unsigned l = 0; l < 3; ++l)
      90   259339806 :           dfp(i, j, k, l) += pre * dII(i, j) * dII(k, l);
      91     3201726 :   return dfp;
      92             : }
      93             : 
      94             : RankTwoTensor
      95        8352 : TensorMechanicsPlasticJ2::dflowPotential_dintnl(const RankTwoTensor & /*stress*/,
      96             :                                                 Real /*intnl*/) const
      97             : {
      98        8352 :   return RankTwoTensor();
      99             : }
     100             : 
     101             : Real
     102    16065744 : TensorMechanicsPlasticJ2::yieldStrength(Real intnl) const
     103             : {
     104    16065744 :   return _strength.value(intnl);
     105             : }
     106             : 
     107             : Real
     108     9640338 : TensorMechanicsPlasticJ2::dyieldStrength(Real intnl) const
     109             : {
     110     9640338 :   return _strength.derivative(intnl);
     111             : }
     112             : 
     113             : std::string
     114           0 : TensorMechanicsPlasticJ2::modelName() const
     115             : {
     116           0 :   return "J2";
     117             : }
     118             : 
     119             : bool
     120     3215672 : TensorMechanicsPlasticJ2::returnMap(const RankTwoTensor & trial_stress,
     121             :                                     Real intnl_old,
     122             :                                     const RankFourTensor & E_ijkl,
     123             :                                     Real ep_plastic_tolerance,
     124             :                                     RankTwoTensor & returned_stress,
     125             :                                     Real & returned_intnl,
     126             :                                     std::vector<Real> & dpm,
     127             :                                     RankTwoTensor & delta_dp,
     128             :                                     std::vector<Real> & yf,
     129             :                                     bool & trial_stress_inadmissible) const
     130             : {
     131     3215672 :   if (!(_use_custom_returnMap))
     132        8480 :     return TensorMechanicsPlasticModel::returnMap(trial_stress,
     133             :                                                   intnl_old,
     134             :                                                   E_ijkl,
     135             :                                                   ep_plastic_tolerance,
     136             :                                                   returned_stress,
     137             :                                                   returned_intnl,
     138             :                                                   dpm,
     139             :                                                   delta_dp,
     140             :                                                   yf,
     141             :                                                   trial_stress_inadmissible);
     142             : 
     143     3207192 :   yf.resize(1);
     144             : 
     145     3207192 :   Real yf_orig = yieldFunction(trial_stress, intnl_old);
     146             : 
     147     3207192 :   yf[0] = yf_orig;
     148             : 
     149     3207192 :   if (yf_orig < _f_tol)
     150             :   {
     151             :     // the trial_stress is admissible
     152        7002 :     trial_stress_inadmissible = false;
     153        7002 :     return true;
     154             :   }
     155             : 
     156     3200190 :   trial_stress_inadmissible = true;
     157     3200190 :   Real mu = E_ijkl(0, 1, 0, 1);
     158             : 
     159             :   // Perform a Newton-Raphson to find dpm when
     160             :   // residual = 3*mu*dpm - trial_equivalent_stress + yieldStrength(intnl_old + dpm) = 0
     161     3200190 :   Real trial_equivalent_stress = yf_orig + yieldStrength(intnl_old);
     162             :   Real residual;
     163             :   Real jac;
     164     3200190 :   dpm[0] = 0;
     165             :   unsigned int iter = 0;
     166             :   do
     167             :   {
     168     6431796 :     residual = 3.0 * mu * dpm[0] - trial_equivalent_stress + yieldStrength(intnl_old + dpm[0]);
     169     6431796 :     jac = 3.0 * mu + dyieldStrength(intnl_old + dpm[0]);
     170     6431796 :     dpm[0] += -residual / jac;
     171     6431796 :     if (iter > _max_iters) // not converging
     172             :       return false;
     173     6431796 :     iter++;
     174     6431796 :   } while (residual * residual > _f_tol * _f_tol);
     175             : 
     176             :   // set the returned values
     177     3200190 :   yf[0] = 0;
     178     3200190 :   returned_intnl = intnl_old + dpm[0];
     179     3200190 :   RankTwoTensor nn = 1.5 * trial_stress.deviatoric() /
     180             :                      trial_equivalent_stress; // = dyieldFunction_dstress(trial_stress, intnl_old) =
     181             :                                               // the normal to the yield surface, at the trial
     182             :                                               // stress
     183     3200190 :   returned_stress = 2.0 / 3.0 * nn * yieldStrength(returned_intnl);
     184     3200190 :   returned_stress.addIa(1.0 / 3.0 * trial_stress.trace());
     185     3200190 :   delta_dp = nn * dpm[0];
     186             : 
     187             :   return true;
     188             : }
     189             : 
     190             : RankFourTensor
     191     3200190 : TensorMechanicsPlasticJ2::consistentTangentOperator(const RankTwoTensor & trial_stress,
     192             :                                                     Real intnl_old,
     193             :                                                     const RankTwoTensor & stress,
     194             :                                                     Real intnl,
     195             :                                                     const RankFourTensor & E_ijkl,
     196             :                                                     const std::vector<Real> & cumulative_pm) const
     197             : {
     198     3200190 :   if (!_use_custom_cto)
     199           0 :     return TensorMechanicsPlasticModel::consistentTangentOperator(
     200             :         trial_stress, intnl_old, stress, intnl, E_ijkl, cumulative_pm);
     201             : 
     202     3200190 :   Real mu = E_ijkl(0, 1, 0, 1);
     203             : 
     204     3200190 :   Real h = 3 * mu + dyieldStrength(intnl);
     205     3200190 :   RankTwoTensor sij = stress.deviatoric();
     206     3200190 :   Real sII = stress.secondInvariant();
     207     3200190 :   Real equivalent_stress = std::sqrt(3.0 * sII);
     208     3200190 :   Real zeta = cumulative_pm[0] / (1.0 + 3.0 * mu * cumulative_pm[0] / equivalent_stress);
     209             : 
     210     6400380 :   return E_ijkl - 3.0 * mu * mu / sII / h * sij.outerProduct(sij) -
     211     6400380 :          4.0 * mu * mu * zeta * dflowPotential_dstress(stress, intnl);
     212             : }
     213             : 
     214             : bool
     215           0 : TensorMechanicsPlasticJ2::useCustomReturnMap() const
     216             : {
     217           0 :   return _use_custom_returnMap;
     218             : }
     219             : 
     220             : bool
     221     3200190 : TensorMechanicsPlasticJ2::useCustomCTO() const
     222             : {
     223     3200190 :   return _use_custom_cto;
     224             : }

Generated by: LCOV version 1.14