https://mooseframework.inl.gov
ComputeLagrangianObjectiveStress.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 small (engineering) stress");
18 
19  MooseEnum objectiveRate("truesdell jaumann green_naghdi rashid", "truesdell");
20  params.addParam<MooseEnum>(
21  "objective_rate", objectiveRate, "Which type of objective integration to use");
22  params.addParam<bool>(
23  "rotate_old_stress",
24  false,
25  "If true, the rate runs in passthrough mode: `cauchy_stress = small_stress` (no outer "
26  "rotation applied). Use when wrapping a material with `perform_finite_strain_rotations = "
27  "true` whose own internal rotation already produces the correct cumulative Cauchy stress "
28  "(needs the strain calculator to publish a non-identity `rotation_increment` via "
29  "`publish_rotation_increment = true`). `cauchy_jacobian` is still computed via the rate's "
30  "chain rule. Default false preserves the standard objective-rate pipeline.");
31 
32  return params;
33 }
34 
36  const InputParameters & parameters)
37  : ComputeLagrangianStressCauchy(parameters),
38  _small_stress(declareProperty<RankTwoTensor>(_base_name + "small_stress")),
39  _small_stress_old(getMaterialPropertyOld<RankTwoTensor>(_base_name + "small_stress")),
40  _small_jacobian(declareProperty<RankFourTensor>(_base_name + "small_jacobian")),
41  _dcauchy_stress_d_eigenstrain(
42  declareProperty<RankFourTensor>(_base_name + "dcauchy_stress_d_eigenstrain")),
43  _cauchy_stress_old(getMaterialPropertyOld<RankTwoTensor>(_base_name + "cauchy_stress")),
44  _mechanical_strain(getMaterialPropertyByName<RankTwoTensor>(_base_name + "mechanical_strain")),
45  _strain_increment(getMaterialPropertyByName<RankTwoTensor>(_base_name + "strain_increment")),
46  _vorticity_increment(
47  getMaterialPropertyByName<RankTwoTensor>(_base_name + "vorticity_increment")),
48  _deformation_gradient_increment(getMaterialPropertyByName<RankTwoTensor>(
49  _base_name + "spatial_deformation_gradient_increment")),
50  _d_deformation_gradient_increment_d_F(getMaterialPropertyByName<RankFourTensor>(
51  _base_name + "d_spatial_deformation_gradient_increment_d_deformation_gradient")),
52  _d_vorticity_increment_d_F(getMaterialPropertyByName<RankFourTensor>(
53  _base_name + "d_vorticity_increment_d_deformation_gradient")),
54  _def_grad(getMaterialPropertyByName<RankTwoTensor>(_base_name + "deformation_gradient")),
55  _def_grad_old(getMaterialPropertyOldByName<RankTwoTensor>(_base_name + "deformation_gradient")),
56  _objective_rate(getParam<MooseEnum>("objective_rate")),
57  _rotate_old_stress(getParam<bool>("rotate_old_stress"))
58 {
59  // Only the Green-Naghdi rate consumes the polar-decomposition rotation. Fetch these
60  // (which marks `rotation` active and triggers the strain calc's polar decomposition) only
61  // for that rate -- Truesdell/Jaumann/Rashid leave them null and skip the eigensolve.
62  if (_objective_rate == "green_naghdi")
63  {
64  _rotation = &getMaterialPropertyByName<RankTwoTensor>(_base_name + "rotation");
65  _rotation_old = &getMaterialPropertyOldByName<RankTwoTensor>(_base_name + "rotation");
66  _d_rotation_d_F = &getMaterialPropertyByName<RankFourTensor>(
67  _base_name + "d_rotation_d_deformation_gradient");
68  }
69 }
70 
71 void
73 {
75 
76  _small_stress[_qp].zero();
77  _cauchy_stress[_qp].zero();
78 }
79 
80 void
82 {
84 
85  const bool need_jacobian = _fe_problem.currentlyComputingJacobian() ||
87 
88  if (!_large_kinematics)
89  {
91  // Small kinematics: no objective advection. dsigma/d_eigenstrain = -small_jacobian
92  // (the negative because mechanical_strain = total_strain - eigenstrain).
93  // Both Jacobian-side assignments are skipped on residual-only sweeps; the kernel
94  // consumes neither during residual assembly.
95  if (need_jacobian)
96  {
99  }
100  }
101  else
102  {
104 
105  // Gather the per-qp quantities the rate needs, dispatch to the selected objective rate, and
106  // scatter the outputs back into our properties.
108  in.dS = dS;
115  // Green-Naghdi only: the rotation properties (and inv_df / F^{-1}) are fetched only for that
116  // rate, so `_rotation` is non-null exactly when `greenNaghdi` will read them.
117  if (_rotation)
118  {
119  in.rotation = (*_rotation)[_qp];
120  in.rotation_old = (*_rotation_old)[_qp];
121  in.d_rotation_d_F = (*_d_rotation_d_F)[_qp];
122  in.inv_df = _inv_df[_qp];
124  }
125 
126  const auto out = LagrangianObjectiveRates::compute(_objective_rate, in, need_jacobian);
127  _cauchy_stress[_qp] = out.cauchy_stress;
128  if (need_jacobian)
129  {
130  _cauchy_jacobian[_qp] = out.cauchy_jacobian;
131  _dcauchy_stress_d_eigenstrain[_qp] = out.dcauchy_stress_d_eigenstrain;
132  }
133 
134  if (_rotate_old_stress)
135  {
136  // Passthrough mode: the wrapped stress material (e.g. `ComputeMultiPlasticityStress`
137  // with `perform_finite_strain_rotations = true`, fed our published
138  // `_rotation_increment`) has already produced the correctly-rotated cumulative Cauchy
139  // stress. Use `_small_stress` directly and discard the rate's own outer rotation of
140  // the stress. `_cauchy_jacobian` from the rate's chain rule is still correct because
141  // it computes `d sigma_cauchy / d(dL)` from `_small_jacobian = dDeltasigma_const/deps` plus
142  // the same rotation-derivative terms -- algebraically the same chain whether we view sigma as
143  // produced by the rate's `R * (sigma_old + Deltasigma_const) * R^T` formula or by the wrapped
144  // material's `R * (s_old + Deltasigma_const) * R^T = small_stress` storage.
146  }
147  }
148 }
FEProblemBase & _fe_problem
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
const MaterialProperty< RankTwoTensor > * _rotation
Polar-decomposition rotation R of F (and its old value and derivative), published by the strain calcu...
const MaterialProperty< RankTwoTensor > & _inv_def_grad
Inverse F-bar-stabilized deformation gradient (= _F^{-1}).
RankFourTensor d_dL_d_F
d(dL)/dF and d(dW)/dF from the strain calculator.
const MaterialProperty< RankFourTensor > & _d_deformation_gradient_increment_d_F
d(dL)/dF, stored by the strain calculator
Per-qp quantities a rate reads.
bool _large_kinematics
If true use large deformations.
const bool & currentlyComputingResidualAndJacobian() const
const std::string _base_name
Prepend to the material properties.
RankTwoTensor dS
Constitutive small-stress increment (_small_stress - _small_stress_old).
RankTwoTensor cauchy_stress_old
Cumulative Cauchy stress at step n.
virtual void computeQpSmallStress()=0
Method to implement to provide the small stress update.
unsigned int _qp
virtual void initQpStatefulProperties() override
Initialize everything with zeros.
const MaterialProperty< RankTwoTensor > & _vorticity_increment
Provided for material models that use the vorticity increment.
const MooseEnum & _objective_rate
Which objective rate to use (truesdell / jaumann / green_naghdi / rashid).
const bool _rotate_old_stress
If true, the rate runs in passthrough mode – the host discards the rate&#39;s own outer rotation and set...
virtual void initQpStatefulProperties() override
Initialize the new (small) stress.
const MaterialProperty< RankTwoTensor > * _rotation_old
MaterialProperty< RankTwoTensor > & _cauchy_stress
The Cauchy stress.
const MaterialProperty< RankTwoTensor > & _cauchy_stress_old
We need the old Cauchy stress to do the objective integration.
const MaterialProperty< RankTwoTensor > & _deformation_gradient_increment
The spatial velocity gradient increment (dL)
Native interface for providing the Cauchy stress.
const MaterialProperty< RankTwoTensor > & _small_stress_old
We need the old value to get the increment.
RankFourTensor d_rotation_d_F
Green-Naghdi only: dR/dF.
virtual void computeQpCauchyStress() override
Implement the objective update.
const MaterialProperty< RankTwoTensor > & _inv_df
Inverse incremental deformation gradient.
RankTwoTensor rotation
Green-Naghdi only: polar-decomposition rotation R (n+1 and n), the inverse incremental deformation gr...
MaterialProperty< RankFourTensor > & _small_jacobian
The updated small algorithmic tangent.
OStreamProxy out
ComputeLagrangianObjectiveStress(const InputParameters &parameters)
const MaterialProperty< RankFourTensor > * _d_rotation_d_F
MaterialProperty< RankTwoTensor > & _small_stress
The updated small stress.
const MaterialProperty< RankFourTensor > & _d_vorticity_increment_d_F
d(dW)/dF from the strain calculator, consumed by Jaumann and Rashid
void addClassDescription(const std::string &doc_string)
RankTwoTensor dL
Spatial velocity gradient increment dL and its vorticity (skew) part dW.
RankFourTensor small_jacobian
Small-strain algorithmic tangent.
const bool & currentlyComputingJacobian() const
MaterialProperty< RankFourTensor > & _dcauchy_stress_d_eigenstrain
Derivative of the Cauchy stress with respect to the eigenstrain at this step, d_sigma/d_eigenstrain =...
MaterialProperty< RankFourTensor > & _cauchy_jacobian
The derivative of the Cauchy stress wrt the increment in the spatial velocity gradient.
Outputs compute(const MooseEnum &rate, const Inputs &in, bool need_jacobian)
Dispatch to the rate selected by the objective_rate enum (truesdell / jaumann / green_naghdi / rashid...