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

Generated by: LCOV version 1.14