LCOV - code coverage report
Current view: top level - src/kernels/lagrangian - UpdatedLagrangianStressDivergence.C (source / functions) Hit Total Coverage
Test: idaholab/moose solid_mechanics: f45d79 Lines: 48 51 94.1 %
Date: 2025-07-25 05:00:39 Functions: 10 10 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 "UpdatedLagrangianStressDivergence.h"
      11             : 
      12             : registerMooseObject("SolidMechanicsApp", UpdatedLagrangianStressDivergence);
      13             : 
      14             : template <class G>
      15         728 : UpdatedLagrangianStressDivergenceBase<G>::UpdatedLagrangianStressDivergenceBase(
      16             :     const InputParameters & parameters)
      17             :   : LagrangianStressDivergenceBase(parameters),
      18         728 :     _stress(getMaterialPropertyByName<RankTwoTensor>(_base_name + "cauchy_stress")),
      19        1456 :     _material_jacobian(getMaterialPropertyByName<RankFourTensor>(_base_name + "cauchy_jacobian")),
      20             : 
      21             :     // Assembly quantities in the reference frame for stabilization
      22         728 :     _assembly_undisplaced(_fe_problem.assembly(_tid, this->_sys.number())),
      23         728 :     _grad_phi_undisplaced(_assembly_undisplaced.gradPhi()),
      24         728 :     _JxW_undisplaced(_assembly_undisplaced.JxW()),
      25         728 :     _coord_undisplaced(_assembly_undisplaced.coordTransformation()),
      26         728 :     _q_point_undisplaced(_assembly_undisplaced.qPoints())
      27             : {
      28             :   // This kernel requires used_displaced_mesh to be true if large kinematics
      29             :   // is on
      30        1742 :   if (_large_kinematics && (!getParam<bool>("use_displaced_mesh")))
      31           0 :     mooseError("The UpdatedLagrangianStressDivergence kernels requires "
      32             :                "used_displaced_mesh = true for large_kinematics = true");
      33             : 
      34             :   // Similarly, if large kinematics is off so should use_displaced_mesh
      35        1508 :   if (!_large_kinematics && (getParam<bool>("use_displaced_mesh")))
      36           0 :     mooseError("The UpdatedLagrangianStressDivergence kernels requires "
      37             :                "used_displaced_mesh = false for large_kinematics = false");
      38             : 
      39             :   // TODO: add weak plane stress support
      40         728 :   if (_out_of_plane_strain)
      41           0 :     mooseError("The UpdatedLagrangianStressDivergence kernels do not yet support the weak plane "
      42             :                "stress formulation. Please use the TotalLagrangianStressDivergecen kernels.");
      43         728 : }
      44             : 
      45             : template <class G>
      46             : RankTwoTensor
      47   498518272 : UpdatedLagrangianStressDivergenceBase<G>::gradTest(unsigned int component)
      48             : {
      49             :   // F-bar doesn't modify the test function
      50   498518272 :   return G::gradOp(component, _grad_test[_i][_qp], _test[_i][_qp], _q_point[_qp]);
      51             : }
      52             : 
      53             : template <class G>
      54             : RankTwoTensor
      55   256109760 : UpdatedLagrangianStressDivergenceBase<G>::gradTrial(unsigned int component)
      56             : {
      57   256109760 :   return _stabilize_strain ? gradTrialStabilized(component) : gradTrialUnstabilized(component);
      58             : }
      59             : 
      60             : template <class G>
      61             : RankTwoTensor
      62   398456704 : UpdatedLagrangianStressDivergenceBase<G>::gradTrialUnstabilized(unsigned int component)
      63             : {
      64             :   // Without F-bar stabilization, simply return the gradient of the trial functions
      65   398456704 :   return G::gradOp(component, _grad_phi[_j][_qp], _phi[_j][_qp], _q_point[_qp]);
      66             : }
      67             : 
      68             : template <class G>
      69             : RankTwoTensor
      70    29799680 : UpdatedLagrangianStressDivergenceBase<G>::gradTrialStabilized(unsigned int component)
      71             : {
      72             :   // The base unstabilized trial function gradient
      73    29799680 :   const auto Gb = G::gradOp(component, _grad_phi[_j][_qp], _phi[_j][_qp], _q_point[_qp]);
      74             :   // The average trial function gradient
      75    29799680 :   const auto Ga = _avg_grad_trial[component][_j];
      76             :   // For updated Lagrangian, the modification is always linear
      77    29799680 :   return Gb + (Ga.trace() - Gb.trace()) / 3.0 * RankTwoTensor::Identity();
      78             : }
      79             : 
      80             : template <class G>
      81             : void
      82       62560 : UpdatedLagrangianStressDivergenceBase<G>::precalculateJacobianDisplacement(unsigned int component)
      83             : {
      84             :   // For updated Lagrangian, the averaging is taken on the reference frame. If large kinematics is
      85             :   // used, the averaged gradients should be pushed forward to the current frame.
      86      542880 :   for (auto j : make_range(_phi.size()))
      87             :   {
      88      480320 :     _avg_grad_trial[component][j] = StabilizationUtils::elementAverage(
      89     4244160 :         [this, component, j](unsigned int qp)
      90             :         {
      91             :           return G::gradOp(
      92     3763840 :               component, _grad_phi_undisplaced[j][qp], _phi[j][qp], _q_point_undisplaced[qp]);
      93             :         },
      94             :         _JxW_undisplaced,
      95             :         _coord_undisplaced);
      96      480320 :     if (_large_kinematics)
      97             :       // Push forward to the current frame.
      98             :       // The average deformation gradient is the same at all qps.
      99       51104 :       _avg_grad_trial[component][j] *= _F_avg[0].inverse();
     100             :   }
     101       62560 : }
     102             : 
     103             : template <class G>
     104             : Real
     105   242211904 : UpdatedLagrangianStressDivergenceBase<G>::computeQpResidual()
     106             : {
     107   242211904 :   return gradTest(_alpha).doubleContraction(_stress[_qp]);
     108             : }
     109             : 
     110             : template <class G>
     111             : Real
     112   256109760 : UpdatedLagrangianStressDivergenceBase<G>::computeQpJacobianDisplacement(unsigned int alpha,
     113             :                                                                         unsigned int beta)
     114             : {
     115   256109760 :   const auto grad_test = gradTest(alpha);
     116   256109760 :   const auto grad_trial = gradTrial(beta);
     117             : 
     118             :   //           J^{alpha beta} = J^{alpha beta}_material + J^{alpha beta}_geometric
     119             :   //  J^{alpha beta}_material = phi^alpha_{i, j} T_{ijkl} f^{-1}_{km} g^beta_{ml}
     120             :   // J^{alpha beta}_geometric = sigma_{ij} (phi^alpha_{k, k} psi^beta_{i, j} -
     121             :   //                                        phi^alpha_{k, j} psi^beta_{i, k})
     122             : 
     123             :   // The material jacobian
     124   256109760 :   Real J = grad_test.doubleContraction(_material_jacobian[_qp] * (_f_inv[_qp] * grad_trial));
     125             : 
     126             :   // The geometric jacobian
     127   256109760 :   if (_large_kinematics)
     128             :   {
     129             :     // No stablization in the geometric jacobian
     130   172146624 :     const auto grad_trial_ust = gradTrialUnstabilized(beta);
     131   344293248 :     J += _stress[_qp].doubleContraction(grad_test) * grad_trial_ust.trace() -
     132   172146624 :          _stress[_qp].doubleContraction(grad_test * grad_trial_ust);
     133             :   }
     134             : 
     135   256109760 :   return J;
     136             : }
     137             : 
     138             : template <class G>
     139             : Real
     140      196608 : UpdatedLagrangianStressDivergenceBase<G>::computeQpJacobianTemperature(unsigned int cvar)
     141             : {
     142             :   // Multiple eigenstrains may depend on the same coupled var
     143      196608 :   RankTwoTensor total_deigen;
     144      393216 :   for (const auto deigen_darg : _deigenstrain_dargs[cvar])
     145      196608 :     total_deigen += (*deigen_darg)[_qp];
     146             : 
     147      196608 :   RankFourTensor C = _material_jacobian[_qp];
     148      196608 :   RankFourTensor Csym = 0.5 * (C + C.transposeMajor().transposeIj().transposeMajor());
     149             : 
     150      196608 :   return -(Csym * total_deigen).doubleContraction(gradTest(_alpha)) * _temperature->phi()[_j][_qp];
     151             : }
     152             : 
     153             : template class UpdatedLagrangianStressDivergenceBase<GradientOperatorCartesian>;

Generated by: LCOV version 1.14