LCOV - code coverage report
Current view: top level - src/materials/lagrangian - ComputeLagrangianObjectiveStress.C (source / functions) Hit Total Coverage
Test: idaholab/moose solid_mechanics: f45d79 Lines: 96 97 99.0 %
Date: 2025-07-25 05:00:39 Functions: 12 12 100.0 %
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 "ComputeLagrangianObjectiveStress.h"
      11             : 
      12             : #include "FactorizedRankTwoTensor.h"
      13             : 
      14             : InputParameters
      15        4792 : ComputeLagrangianObjectiveStress::validParams()
      16             : {
      17        4792 :   InputParameters params = ComputeLagrangianStressCauchy::validParams();
      18             : 
      19        4792 :   params.addClassDescription("Stress update based on the small (engineering) stress");
      20             : 
      21        9584 :   MooseEnum objectiveRate("truesdell jaumann green_naghdi", "truesdell");
      22        9584 :   params.addParam<MooseEnum>(
      23             :       "objective_rate", objectiveRate, "Which type of objective integration to use");
      24             : 
      25        4792 :   return params;
      26        4792 : }
      27             : 
      28        3594 : ComputeLagrangianObjectiveStress::ComputeLagrangianObjectiveStress(
      29        3594 :     const InputParameters & parameters)
      30             :   : ComputeLagrangianStressCauchy(parameters),
      31        3594 :     _small_stress(declareProperty<RankTwoTensor>(_base_name + "small_stress")),
      32        7188 :     _small_stress_old(getMaterialPropertyOld<RankTwoTensor>(_base_name + "small_stress")),
      33        3594 :     _small_jacobian(declareProperty<RankFourTensor>(_base_name + "small_jacobian")),
      34        7188 :     _cauchy_stress_old(getMaterialPropertyOld<RankTwoTensor>(_base_name + "cauchy_stress")),
      35        7188 :     _mechanical_strain(getMaterialPropertyByName<RankTwoTensor>(_base_name + "mechanical_strain")),
      36        7188 :     _strain_increment(getMaterialPropertyByName<RankTwoTensor>(_base_name + "strain_increment")),
      37        3594 :     _vorticity_increment(
      38        3594 :         getMaterialPropertyByName<RankTwoTensor>(_base_name + "vorticity_increment")),
      39        7188 :     _def_grad(getMaterialPropertyByName<RankTwoTensor>(_base_name + "deformation_gradient")),
      40        7188 :     _def_grad_old(getMaterialPropertyOldByName<RankTwoTensor>(_base_name + "deformation_gradient")),
      41        7188 :     _rate(getParam<MooseEnum>("objective_rate").getEnum<ObjectiveRate>()),
      42        3594 :     _polar_decomp(_rate == ObjectiveRate::GreenNaghdi),
      43        3594 :     _rotation(_polar_decomp ? &declareProperty<RankTwoTensor>(_base_name + "rotation") : nullptr),
      44        3648 :     _rotation_old(_polar_decomp ? &getMaterialPropertyOld<RankTwoTensor>(_base_name + "rotation")
      45             :                                 : nullptr),
      46        3594 :     _d_rotation_d_def_grad(
      47        7458 :         _polar_decomp ? &declareProperty<RankFourTensor>(derivativePropertyName(
      48        3702 :                             _base_name + "rotation", {_base_name + "deformation_gradient"}))
      49             :                       : nullptr),
      50        7188 :     _stretch(_polar_decomp ? &declareProperty<RankTwoTensor>(_base_name + "stretch") : nullptr)
      51             : {
      52        3648 : }
      53             : 
      54             : void
      55      893952 : ComputeLagrangianObjectiveStress::initQpStatefulProperties()
      56             : {
      57      893952 :   ComputeLagrangianStressBase::initQpStatefulProperties();
      58             : 
      59      893952 :   _small_stress[_qp].zero();
      60      893952 :   _cauchy_stress[_qp].zero();
      61             : 
      62      893952 :   if (_polar_decomp)
      63        5216 :     (*_rotation)[_qp] = RankTwoTensor::Identity();
      64      893952 : }
      65             : 
      66             : void
      67    76266044 : ComputeLagrangianObjectiveStress::computeQpCauchyStress()
      68             : {
      69    76266044 :   computeQpSmallStress();
      70             : 
      71    76266044 :   if (!_large_kinematics)
      72             :   {
      73    41058580 :     _cauchy_stress[_qp] = _small_stress[_qp];
      74    41058580 :     _cauchy_jacobian[_qp] = _small_jacobian[_qp];
      75             :   }
      76             :   else
      77             :   {
      78             :     // If large_kinematics = true, do the objective integration
      79    35207464 :     RankTwoTensor dS = _small_stress[_qp] - _small_stress_old[_qp];
      80             : 
      81    35207464 :     if (_rate == ObjectiveRate::Truesdell)
      82    33156008 :       _cauchy_stress[_qp] = objectiveUpdateTruesdell(dS);
      83     2051456 :     else if (_rate == ObjectiveRate::Jaumann)
      84     1025728 :       _cauchy_stress[_qp] = objectiveUpdateJaumann(dS);
      85     1025728 :     else if (_rate == ObjectiveRate::GreenNaghdi)
      86     1025728 :       _cauchy_stress[_qp] = objectiveUpdateGreenNaghdi(dS);
      87             :     else
      88           0 :       mooseError("Internal error: unsupported objective rate.");
      89             :   }
      90    76266044 : }
      91             : 
      92             : RankTwoTensor
      93    33156008 : ComputeLagrangianObjectiveStress::objectiveUpdateTruesdell(const RankTwoTensor & dS)
      94             : {
      95             :   // Get the kinematic tensor
      96    33156008 :   RankTwoTensor dL = RankTwoTensor::Identity() - _inv_df[_qp];
      97             : 
      98             :   // Update the Cauchy stress
      99    33156008 :   auto [S, Jinv] = advectStress(_cauchy_stress_old[_qp] + dS, dL);
     100             : 
     101             :   // Get the appropriate tangent tensor
     102    33156008 :   RankFourTensor U = stressAdvectionDerivative(S);
     103    33156008 :   _cauchy_jacobian[_qp] = cauchyJacobian(Jinv, U);
     104             : 
     105    33156008 :   return S;
     106             : }
     107             : 
     108             : RankTwoTensor
     109     1025728 : ComputeLagrangianObjectiveStress::objectiveUpdateJaumann(const RankTwoTensor & dS)
     110             : {
     111             :   usingTensorIndices(i, j, k, l);
     112             : 
     113             :   // Get the kinematic tensor
     114     1025728 :   RankTwoTensor dL = RankTwoTensor::Identity() - _inv_df[_qp];
     115     1025728 :   RankTwoTensor dW = 0.5 * (dL - dL.transpose());
     116             : 
     117             :   // Update the Cauchy stress
     118     1025728 :   auto [S, Jinv] = advectStress(_cauchy_stress_old[_qp] + dS, dW);
     119             : 
     120             :   // Get the appropriate tangent tensor
     121             :   RankTwoTensor I = RankTwoTensor::Identity();
     122     1025728 :   RankFourTensor ddW_ddL = 0.5 * (I.times<i, k, j, l>(I) - I.times<i, l, j, k>(I));
     123     1025728 :   RankFourTensor U = stressAdvectionDerivative(S) * ddW_ddL;
     124     1025728 :   _cauchy_jacobian[_qp] = cauchyJacobian(Jinv, U);
     125             : 
     126     1025728 :   return S;
     127             : }
     128             : 
     129             : RankTwoTensor
     130     1025728 : ComputeLagrangianObjectiveStress::objectiveUpdateGreenNaghdi(const RankTwoTensor & dS)
     131             : {
     132             :   usingTensorIndices(i, j, k, l, m);
     133             : 
     134             :   // The kinematic tensor for the Green-Naghdi rate is
     135             :   // Omega = dot(R) R^T
     136     1025728 :   polarDecomposition();
     137             :   RankTwoTensor I = RankTwoTensor::Identity();
     138     1025728 :   RankTwoTensor dR = (*_rotation)[_qp] * (*_rotation_old)[_qp].transpose() - I;
     139     1025728 :   RankTwoTensor dO = dR * _inv_df[_qp];
     140             : 
     141             :   // Update the Cauchy stress
     142     1025728 :   auto [S, Jinv] = advectStress(_cauchy_stress_old[_qp] + dS, dO);
     143             : 
     144             :   // Get the appropriate tangent tensor
     145     1025728 :   RankFourTensor d_R_d_F = (*_d_rotation_d_def_grad)[_qp];
     146     1025728 :   RankFourTensor d_F_d_dL = _inv_df[_qp].inverse().times<i, k, l, j>(_def_grad[_qp]);
     147     1025728 :   RankTwoTensor T = (*_rotation_old)[_qp].transpose() * _inv_df[_qp];
     148             :   RankFourTensor d_dO_d_dL =
     149     1025728 :       T.times<m, j, i, m, k, l>(d_R_d_F * d_F_d_dL) - dR.times<i, k, j, l>(I);
     150     1025728 :   RankFourTensor U = stressAdvectionDerivative(S) * d_dO_d_dL;
     151     1025728 :   _cauchy_jacobian[_qp] = cauchyJacobian(Jinv, U);
     152             : 
     153     1025728 :   return S;
     154             : }
     155             : 
     156             : std::tuple<RankTwoTensor, RankFourTensor>
     157    35207464 : ComputeLagrangianObjectiveStress::advectStress(const RankTwoTensor & S0,
     158             :                                                const RankTwoTensor & dQ) const
     159             : {
     160    35207464 :   RankFourTensor J = updateTensor(dQ);
     161    35207464 :   RankFourTensor Jinv = J.inverse();
     162    35207464 :   RankTwoTensor S = Jinv * S0;
     163    35207464 :   return {S, Jinv};
     164             : }
     165             : 
     166             : RankFourTensor
     167    35207464 : ComputeLagrangianObjectiveStress::updateTensor(const RankTwoTensor & dQ) const
     168             : {
     169             :   auto I = RankTwoTensor::Identity();
     170             :   usingTensorIndices(i, j, k, l);
     171    70414928 :   return (1.0 + dQ.trace()) * I.times<i, k, j, l>(I) - dQ.times<i, k, j, l>(I) -
     172    70414928 :          I.times<i, k, j, l>(dQ);
     173             : }
     174             : 
     175             : RankFourTensor
     176    35207464 : ComputeLagrangianObjectiveStress::stressAdvectionDerivative(const RankTwoTensor & S) const
     177             : {
     178             :   auto I = RankTwoTensor::Identity();
     179             :   usingTensorIndices(i, j, k, l);
     180    35207464 :   return S.times<i, j, k, l>(I) - I.times<i, k, l, j>(S) - S.times<i, l, j, k>(I);
     181             : }
     182             : 
     183             : RankFourTensor
     184    35207464 : ComputeLagrangianObjectiveStress::cauchyJacobian(const RankFourTensor & Jinv,
     185             :                                                  const RankFourTensor & U) const
     186             : {
     187    35207464 :   return Jinv * (_small_jacobian[_qp] - U);
     188             : }
     189             : 
     190             : void
     191     1025728 : ComputeLagrangianObjectiveStress::polarDecomposition()
     192             : {
     193     1025728 :   FactorizedRankTwoTensor C = _def_grad[_qp].transpose() * _def_grad[_qp];
     194     2051456 :   (*_stretch)[_qp] = MathUtils::sqrt(C).get();
     195     1025728 :   RankTwoTensor Uinv = MathUtils::sqrt(C).inverse().get();
     196     1025728 :   (*_rotation)[_qp] = _def_grad[_qp] * Uinv;
     197             : 
     198             :   // Derivative of rotation w.r.t. the deformation gradient
     199             :   RankTwoTensor I = RankTwoTensor::Identity();
     200     1025728 :   RankTwoTensor Y = (*_stretch)[_qp].trace() * I - (*_stretch)[_qp];
     201     1025728 :   RankTwoTensor Z = (*_rotation)[_qp] * Y;
     202     1025728 :   RankTwoTensor O = Z * (*_rotation)[_qp].transpose();
     203             :   usingTensorIndices(i, j, k, l);
     204     2051456 :   (*_d_rotation_d_def_grad)[_qp] = (O.times<i, k, l, j>(Y) - Z.times<i, l, k, j>(Z)) / Y.det();
     205     1025728 : }

Generated by: LCOV version 1.14