https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
14template <class G>
16 const InputParameters & 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 // The use_displaced_mesh <-> large_kinematics consistency check lives in initialSetup(), since
29 // large_kinematics is now derived from the strain calculator's guarantee (not available in the
30 // constructor).
31
32 // TODO: add weak plane stress support
34 mooseError("The UpdatedLagrangianStressDivergence kernels do not yet support the weak plane "
35 "stress formulation. Please use the TotalLagrangianStressDivergecen kernels.");
36
37 // The UL push-forward in `precalculateJacobianDisplacement` uses `_F_avg` (= avg(F_ust))
38 // for the spatial-to-reference frame mapping; combining it with the incremental F-bar
39 // chain (which expects `_avg_grad_trial` to represent deltaf_avg, not deltaF_avg) hasn't been
40 // worked out yet. Use Total Lagrangian for incremental F-bar.
42 mooseError("`F_bar_mode = incremental` is not yet supported with the UpdatedLagrangian "
43 "kernels; use TotalLagrangianStressDivergence (or `F_bar_mode = total`).");
44}
45
46template <class G>
49{
50 // F-bar doesn't modify the test function
51 return G::gradOp(component, _grad_test[_i][_qp], _test[_i][_qp], _q_point[_qp]);
52}
53
54template <class G>
57{
58 // F-bar stabilization is handled explicitly in computeQpJacobianDisplacement via the stored
59 // partial derivatives _d_F_stab_d_F_ust and _d_F_stab_d_F_avg, so gradTrial always returns
60 // the unstabilized spatial gradient.
61 return gradTrialUnstabilized(component);
62}
63
64template <class G>
67{
68 // Without F-bar stabilization, simply return the gradient of the trial functions
69 return G::gradOp(component, _grad_phi[_j][_qp], _phi[_j][_qp], _q_point[_qp]);
70}
71
72template <class G>
73void
75{
76 // For updated Lagrangian, the averaging is taken on the reference frame. If large kinematics is
77 // used, the averaged gradients should be pushed forward to the current frame.
78 for (auto j : make_range(_phi.size()))
79 {
80 _avg_grad_trial[component][j] = StabilizationUtils::elementAverage(
81 [this, component, j](unsigned int qp)
82 {
83 return G::gradOp(
84 component, _grad_phi_undisplaced[j][qp], _phi[j][qp], _q_point_undisplaced[qp]);
85 },
86 _JxW_undisplaced,
87 _coord_undisplaced);
88 if (_large_kinematics)
89 // Push forward to the current frame.
90 // The average deformation gradient is the same at all qps.
91 _avg_grad_trial[component][j] *= _F_avg[0].inverse();
92 }
93}
94
95template <class G>
96Real
98{
99 return gradTest(_alpha).doubleContraction(_stress[_qp]);
100}
101
102template <class G>
103Real
105 unsigned int beta)
106{
107 const auto grad_test = gradTest(alpha);
108 const auto grad_trial = gradTrialUnstabilized(beta);
109
110 // J^{alpha beta} = J^{alpha beta}_material + J^{alpha beta}_geometric
111 // J^{alpha beta}_material = phi^alpha : T : d(dL)/d(grad u) * grad_trial
112 // J^{alpha beta}_geometric = sigma_{ij} (phi^alpha_{k, k} psi^beta_{i, j} -
113 // phi^alpha_{k, j} psi^beta_{i, k})
114
115 // Local contribution to delta(F_ust): pull the spatial trial gradient back through the
116 // literal n+1 deformation gradient (use_displaced_mesh = true uses F_actual, regardless
117 // of alpha or F-bar), then chain to F_ust via _d_F_d_grad_u (= alpha * I^(4)).
118 const RankTwoTensor delta_grad_u_local =
119 _large_kinematics ? grad_trial * _F_actual[_qp] : grad_trial;
120 const RankTwoTensor delta_F_ust_local = _d_F_d_grad_u[_qp] * delta_grad_u_local;
121
122 // Non-local F-bar contribution to delta(F_avg): _avg_grad_trial is stored as
123 // avg(gradTrial_reference) * F_avg^{-1} (see precalculateJacobianDisplacement). Multiply
124 // by F_avg to recover the reference-frame averaged gradient, then chain to F_ust the
125 // same way.
126 RankTwoTensor delta_F_avg;
127 if (_stabilize_strain)
128 {
129 const RankTwoTensor delta_grad_u_avg =
130 _large_kinematics ? _avg_grad_trial[beta][_j] * _F_avg[_qp] : _avg_grad_trial[beta][_j];
131 delta_F_avg = _d_F_d_grad_u[_qp] * delta_grad_u_avg;
132 }
133
134 // Stabilized delta(F_stab) through the F-bar tangent. With F-bar off, the partials are
135 // _d_F_stab_d_F_ust = I^(4) and _d_F_stab_d_F_avg = 0, so this reduces to delta_F_ust_local.
136 const RankTwoTensor delta_F_stab =
137 _d_F_stab_d_F_ust[_qp] * delta_F_ust_local + _d_F_stab_d_F_avg[_qp] * delta_F_avg;
138
139 const RankTwoTensor delta_dL = _d_deformation_gradient_increment_d_F[_qp] * delta_F_stab;
140
141 // The material jacobian
142 Real J = grad_test.doubleContraction(_material_jacobian[_qp] * delta_dL);
143
144 // The geometric jacobian (no F-bar stabilization in this term)
145 if (_large_kinematics)
146 {
147 J += _stress[_qp].doubleContraction(grad_test) * grad_trial.trace() -
148 _stress[_qp].doubleContraction(grad_test * grad_trial);
149 }
150
151 return J;
152}
153
154template <class G>
155Real
157{
158 // Multiple eigenstrains may depend on the same coupled var
159 RankTwoTensor total_deigen;
160 for (const auto deigen_darg : _deigenstrain_dargs[cvar])
161 total_deigen += (*deigen_darg)[_qp];
162
163 RankFourTensor C = _material_jacobian[_qp];
164 RankFourTensor Csym = 0.5 * (C + C.transposeMajor().transposeIj().transposeMajor());
165
166 return -(Csym * total_deigen).doubleContraction(gradTest(_alpha)) * _temperature->phi()[_j][_qp];
167}
168
void mooseError(Args &&... args)
registerMooseObject("SolidMechanicsApp", UpdatedLagrangianStressDivergence)
Base class of the "Lagrangian" kernel system.
const bool _stabilize_strain
If true calculate the deformation gradient derivatives for F_bar.
const MooseVariable * _out_of_plane_strain
Out-of-plane strain, if provided.
const FBarMode _F_bar_mode
What F gets F-bar volumetric correction (Total vs.
RankFourTensorTempl< T > transposeMajor() const
Enforce equilibrium with an updated Lagrangian formulation.
virtual RankTwoTensor gradTest(unsigned int component) override
virtual RankTwoTensor gradTrialUnstabilized(unsigned int component)
The unstabilized trial function gradient.
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
virtual RankTwoTensor gradTrial(unsigned int component) override
virtual Real computeQpJacobianDisplacement(unsigned int alpha, unsigned int beta) override
auto elementAverage(const Functor &f, const MooseArray< Real > &JxW, const MooseArray< Real > &coord)