https://mooseframework.inl.gov
UpdatedLagrangianStressDivergence.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 
13 
14 template <class G>
16  const InputParameters & parameters)
17  : LagrangianStressDivergenceBase(parameters),
18  _stress(getMaterialPropertyByName<RankTwoTensor>(_base_name + "cauchy_stress")),
19  _material_jacobian(getMaterialPropertyByName<RankFourTensor>(_base_name + "cauchy_jacobian")),
20 
21  // Assembly quantities in the reference frame for stabilization
22  _assembly_undisplaced(_fe_problem.assembly(_tid, this->_sys.number())),
23  _grad_phi_undisplaced(_assembly_undisplaced.gradPhi()),
24  _JxW_undisplaced(_assembly_undisplaced.JxW()),
25  _coord_undisplaced(_assembly_undisplaced.coordTransformation()),
26  _q_point_undisplaced(_assembly_undisplaced.qPoints())
27 {
28  // This kernel requires used_displaced_mesh to be true if large kinematics
29  // is on
30  if (_large_kinematics && (!getParam<bool>("use_displaced_mesh")))
31  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  if (!_large_kinematics && (getParam<bool>("use_displaced_mesh")))
36  mooseError("The UpdatedLagrangianStressDivergence kernels requires "
37  "used_displaced_mesh = false for large_kinematics = false");
38 
39  // TODO: add weak plane stress support
41  mooseError("The UpdatedLagrangianStressDivergence kernels do not yet support the weak plane "
42  "stress formulation. Please use the TotalLagrangianStressDivergecen kernels.");
43 }
44 
45 template <class G>
48 {
49  // F-bar doesn't modify the test function
50  return G::gradOp(component, _grad_test[_i][_qp], _test[_i][_qp], _q_point[_qp]);
51 }
52 
53 template <class G>
56 {
57  return _stabilize_strain ? gradTrialStabilized(component) : gradTrialUnstabilized(component);
58 }
59 
60 template <class G>
63 {
64  // Without F-bar stabilization, simply return the gradient of the trial functions
65  return G::gradOp(component, _grad_phi[_j][_qp], _phi[_j][_qp], _q_point[_qp]);
66 }
67 
68 template <class G>
71 {
72  // The base unstabilized trial function gradient
73  const auto Gb = G::gradOp(component, _grad_phi[_j][_qp], _phi[_j][_qp], _q_point[_qp]);
74  // The average trial function gradient
75  const auto Ga = _avg_grad_trial[component][_j];
76  // For updated Lagrangian, the modification is always linear
77  return Gb + (Ga.trace() - Gb.trace()) / 3.0 * RankTwoTensor::Identity();
78 }
79 
80 template <class G>
81 void
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  for (auto j : make_range(_phi.size()))
87  {
89  [this, component, j](unsigned int qp)
90  {
91  return G::gradOp(
92  component, _grad_phi_undisplaced[j][qp], _phi[j][qp], _q_point_undisplaced[qp]);
93  },
94  _JxW_undisplaced,
95  _coord_undisplaced);
96  if (_large_kinematics)
97  // Push forward to the current frame.
98  // The average deformation gradient is the same at all qps.
99  _avg_grad_trial[component][j] *= _F_avg[0].inverse();
100  }
101 }
102 
103 template <class G>
104 Real
106 {
107  return gradTest(_alpha).doubleContraction(_stress[_qp]);
108 }
109 
110 template <class G>
111 Real
113  unsigned int beta)
114 {
115  const auto grad_test = gradTest(alpha);
116  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  Real J = grad_test.doubleContraction(_material_jacobian[_qp] * (_f_inv[_qp] * grad_trial));
125 
126  // The geometric jacobian
127  if (_large_kinematics)
128  {
129  // No stablization in the geometric jacobian
130  const auto grad_trial_ust = gradTrialUnstabilized(beta);
131  J += _stress[_qp].doubleContraction(grad_test) * grad_trial_ust.trace() -
132  _stress[_qp].doubleContraction(grad_test * grad_trial_ust);
133  }
134 
135  return J;
136 }
137 
138 template <class G>
139 Real
141 {
142  // Multiple eigenstrains may depend on the same coupled var
143  RankTwoTensor total_deigen;
144  for (const auto deigen_darg : _deigenstrain_dargs[cvar])
145  total_deigen += (*deigen_darg)[_qp];
146 
147  RankFourTensor C = _material_jacobian[_qp];
148  RankFourTensor Csym = 0.5 * (C + C.transposeMajor().transposeIj().transposeMajor());
149 
150  return -(Csym * total_deigen).doubleContraction(gradTest(_alpha)) * _temperature->phi()[_j][_qp];
151 }
152 
virtual RankTwoTensor gradTrial(unsigned int component) override
virtual RankTwoTensor gradTest(unsigned int component) override
void mooseError(Args &&... args)
static const std::string component
Definition: NS.h:153
virtual Real computeQpJacobianDisplacement(unsigned int alpha, unsigned int beta) override
const MooseVariable * _out_of_plane_strain
Out-of-plane strain, if provided.
static RankTwoTensorTempl Identity()
virtual RankTwoTensor gradTrialStabilized(unsigned int component)
The stabilized trial function gradient.
const bool _large_kinematics
If true use large deformation kinematics.
virtual RankTwoTensor gradTrialUnstabilized(unsigned int component)
The unstabilized trial function gradient.
registerMooseObject("SolidMechanicsApp", UpdatedLagrangianStressDivergence)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const std::string alpha
Definition: NS.h:134
IntRange< T > make_range(T beg, T end)
auto elementAverage(const Functor &f, const MooseArray< Real > &JxW, const MooseArray< Real > &coord)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
virtual void precalculateJacobianDisplacement(unsigned int component) override
Prepare the average shape function gradients for stabilization.
UpdatedLagrangianStressDivergenceBase(const InputParameters &parameters)
virtual Real computeQpJacobianTemperature(unsigned int cvar) override
Base class of the "Lagrangian" kernel system.
static const std::string C
Definition: NS.h:168
Enforce equilibrium with an updated Lagrangian formulation.