https://mooseframework.inl.gov
ComputeLagrangianStressPK1.C
Go to the documentation of this file.
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 
11 
14 {
16 
17  params.addClassDescription("Stress update based on the first Piola-Kirchhoff stress");
18 
19  return params;
20 }
21 
23  : ComputeLagrangianStressBase(parameters),
24  _inv_df(getMaterialPropertyByName<RankTwoTensor>(_base_name +
25  "inverse_incremental_deformation_gradient")),
26  _inv_def_grad(
27  getMaterialPropertyByName<RankTwoTensor>(_base_name + "inverse_deformation_gradient")),
28  _F(getMaterialPropertyByName<RankTwoTensor>(_base_name + "deformation_gradient"))
29 {
30 }
31 
32 void
34 {
36  computeQpCauchyStress(); // This could be "switched"
37 }
38 
39 void
41 {
42  // Wrap PK1 -> sigma using the *unstabilized* F. F-bar enters only through the constitutive
43  // PK1's strain dependence (via the F-bar'd `_f_inv`); the geometric wrap uses F_ust so
44  // the residual matches OLD.
45  //
46  // All RankFourTensor algebra below builds Jacobian-only quantities
47  // (`_cauchy_jacobian`, the post-multiplied `_pk1_jacobian`, and `_pk1_jacobian_bypass_fbar`).
48  // Skip them on residual-only sweeps.
49  const bool need_jacobian = _fe_problem.currentlyComputingJacobian() ||
52  {
53  const RankTwoTensor F_ust_inv = _F_ust[_qp].inverse();
54  const RankTwoTensor F_ust_invT = F_ust_inv.transpose();
55  const Real J_ust = _F_ust[_qp].det();
56  _cauchy_stress[_qp] = _pk1_stress[_qp] * _F_ust[_qp].transpose() / J_ust;
57 
58  if (!need_jacobian)
59  return;
60 
61  usingTensorIndices(i_, j_, m_, n_);
62  const auto I = RankTwoTensor::Identity();
63 
64  // dsigma/d(F_ust) via the constitutive PK1's F_stab chain plus the geometric F_ust pieces.
65  // sigma = (1/J(F_ust)) * PK1(F_stab) * F_ust^T
66  // dsigma/d(F_ust) = (1/J) * dPK1/d(F_stab) * d(F_stab)/d(F_ust) * F_ust^T
67  // + (1/J) * PK1 * d(F_ust^T)/d(F_ust)
68  // - sigma (x) F_ust^{-T}.
69  // The middle factor `_d_F_stab_d_F_ust` is IdentityFour when F-bar is off, so the
70  // first line collapses to the original PK1-jacobian chain.
71  // Common geometric pieces (independent of F-bar):
72  const RankFourTensor dsigma_dF_geom = _pk1_stress[_qp].times<i_, n_, j_, m_>(I) / J_ust -
73  _cauchy_stress[_qp].times<i_, j_, n_, m_>(F_ust_inv);
74  // dsigma_dF with the constitutive PK1 jacobian chained via F-bar (default path).
75  RankFourTensor dsigma_dF =
76  (_pk1_jacobian[_qp] * _d_F_stab_d_F_ust[_qp]).singleProductJ(_F_ust[_qp]) / J_ust;
77  dsigma_dF += dsigma_dF_geom;
79 
80  // Bypass-F-bar variant: sigma chain without the `_d_F_stab_d_F_ust` factor. Same
81  // geometric pieces; constitutive PK1 jacobian used directly.
82  RankFourTensor dsigma_dF_no_fbar = _pk1_jacobian[_qp].singleProductJ(_F_ust[_qp]) / J_ust;
83  dsigma_dF_no_fbar += dsigma_dF_geom;
84 
85  // Update _pk1_jacobian and publish the bypass variant.
86  const RankFourTensor pk1_jac_no_fbar = _pk1_jacobian[_qp];
88  _pk1_jacobian_bypass_fbar[_qp] = pk1_jac_no_fbar;
89  }
90  // Small deformations: sigma = PK1 (no wrap). For TL, the kernel chain wants
91  // dPK1/d(F_ust) -- pk1_jacobian (constitutive's dPK1/d(F_stab)) must be chained to
92  // F_ust via `_d_F_stab_d_F_ust`. For UL, cauchy_jacobian = dsigma/d(dL) = pk1_jacobian
93  // (since the constitutive's dPK1/d(F_stab) is essentially dsigma/d(dL) at small kin).
94  else
95  {
97  if (!need_jacobian)
98  return;
102  }
103 }
const MaterialProperty< RankFourTensor > & _d_F_stab_d_F_ust
d(F_stab)/d(F_ust).
FEProblemBase & _fe_problem
static InputParameters validParams()
bool _large_kinematics
If true use large deformations.
const MaterialProperty< RankTwoTensor > & _F_ust
Unstabilized deformation gradient (= F_actual at alpha = 1).
MaterialProperty< RankTwoTensor > & _pk1_stress
The 1st Piola-Kirchhoff stress.
const bool & currentlyComputingResidualAndJacobian() const
static RankTwoTensorTempl Identity()
unsigned int _qp
MaterialProperty< RankFourTensor > & _pk1_jacobian
The derivative of the 1st PK stress wrt the deformation gradient (F that the stress material consumes...
MaterialProperty< RankFourTensor > & _pk1_jacobian_bypass_fbar
Variant of _pk1_jacobian computed WITHOUT the F-bar chain factor _d_F_stab_d_F_ust in the sigma-via-d...
virtual void computeQpCauchyStress()
Wrap the PK stress to get the Cauchy stress.
const MaterialProperty< RankFourTensor > & _d_deformation_gradient_increment_d_F
d(spatial velocity gradient increment)/d(F_stab).
MaterialProperty< RankTwoTensor > & _cauchy_stress
The Cauchy stress.
Provide stresses in the form required for the Lagrangian kernels.
ComputeLagrangianStressPK1(const InputParameters &parameters)
virtual void computeQpStressUpdate() override
Calculate the stress update to provide both measures (cauchy and pk1)
RankTwoTensorTempl< Real > transpose() const
virtual void computeQpPK1Stress()=0
Provide for the actual PK stress update (just PK1)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static InputParameters validParams()
void addClassDescription(const std::string &doc_string)
const bool & currentlyComputingJacobian() const
MaterialProperty< RankFourTensor > & _cauchy_jacobian
The derivative of the Cauchy stress wrt the increment in the spatial velocity gradient.