www.mooseframework.org
StressDivergence.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 "StressDivergence.h"
11 
12 // MOOSE includes
13 #include "Assembly.h"
14 #include "Material.h"
15 #include "MooseMesh.h"
16 #include "MooseVariable.h"
17 #include "SymmElasticityTensor.h"
18 #include "SystemBase.h"
19 
20 #include "libmesh/quadrature.h"
21 
22 registerMooseObjectDeprecated("SolidMechanicsApp", StressDivergence, "07/30/2020 24:00");
23 
24 template <>
25 InputParameters
27 {
28  InputParameters params = validParams<Kernel>();
29  params.addRequiredParam<unsigned int>("component",
30  "An integer corresponding to the direction "
31  "the variable this kernel acts in. (0 for x, "
32  "1 for y, 2 for z)");
33  params.addCoupledVar("disp_x", "The x displacement");
34  params.addCoupledVar("disp_y", "The y displacement");
35  params.addCoupledVar("disp_z", "The z displacement");
36  params.addCoupledVar("temp", "The temperature");
37  params.addParam<Real>("zeta", 0.0, "Stiffness dependent Rayleigh damping coefficient");
38  params.addParam<Real>("alpha", 0.0, "alpha parameter required for HHT time integration");
39  params.addParam<std::string>(
40  "appended_property_name", "", "Name appended to material properties to make them unique");
41  params.addParam<bool>("volumetric_locking_correction",
42  true,
43  "Set to false to turn off volumetric locking correction");
44 
45  params.set<bool>("use_displaced_mesh") = true;
46 
47  return params;
48 }
49 
50 StressDivergence::StressDivergence(const InputParameters & parameters)
51  : Kernel(parameters),
52  _stress_older(getMaterialPropertyOlder<SymmTensor>(
53  "stress" + getParam<std::string>("appended_property_name"))),
54  _stress_old(getMaterialPropertyOld<SymmTensor>(
55  "stress" + getParam<std::string>("appended_property_name"))),
56  _stress(getMaterialProperty<SymmTensor>("stress" +
57  getParam<std::string>("appended_property_name"))),
58  _Jacobian_mult(getMaterialProperty<SymmElasticityTensor>(
59  "Jacobian_mult" + getParam<std::string>("appended_property_name"))),
60  _d_stress_dT(getMaterialProperty<SymmTensor>("d_stress_dT" +
61  getParam<std::string>("appended_property_name"))),
62  _component(getParam<unsigned int>("component")),
63  _xdisp_coupled(isCoupled("disp_x")),
64  _ydisp_coupled(isCoupled("disp_y")),
65  _zdisp_coupled(isCoupled("disp_z")),
66  _temp_coupled(isCoupled("temp")),
67  _xdisp_var(_xdisp_coupled ? coupled("disp_x") : 0),
68  _ydisp_var(_ydisp_coupled ? coupled("disp_y") : 0),
69  _zdisp_var(_zdisp_coupled ? coupled("disp_z") : 0),
70  _temp_var(_temp_coupled ? coupled("temp") : 0),
71  _zeta(getParam<Real>("zeta")),
72  _alpha(getParam<Real>("alpha")),
73  _avg_grad_test(_test.size(), std::vector<Real>(3, 0.0)),
74  _avg_grad_phi(_phi.size(), std::vector<Real>(3, 0.0)),
75  _volumetric_locking_correction(getParam<bool>("volumetric_locking_correction"))
76 {
77  mooseDeprecated(name(), ": StressDivergence is deprecated.\n\
78 The solid_mechanics module will be removed from MOOSE on July 31, 2020.\n\
79 Please update your input files to utilize the tensor_mechanics equivalents of\n\
80 models based on solid_mechanics. A detailed migration guide that was developed\n\
81 for BISON, but which is generally applicable to any MOOSE model is available at:\n\
82 https://mooseframework.org/bison/tutorials/mechanics_conversion/overview.html");
83 }
84 
85 void
87 {
88  prepareVectorTag(_assembly, _var.number());
89 
91  {
92  // calculate volume averaged value of shape function derivative
93  _avg_grad_test.resize(_test.size());
94  for (_i = 0; _i < _test.size(); _i++)
95  {
96  _avg_grad_test[_i].resize(3);
97  _avg_grad_test[_i][_component] = 0.0;
98  for (_qp = 0; _qp < _qrule->n_points(); _qp++)
99  _avg_grad_test[_i][_component] += _grad_test[_i][_qp](_component) * _JxW[_qp] * _coord[_qp];
100 
101  _avg_grad_test[_i][_component] /= _current_elem_volume;
102  }
103  }
104 
105  precalculateResidual();
106  for (_i = 0; _i < _test.size(); _i++)
107  for (_qp = 0; _qp < _qrule->n_points(); _qp++)
108  _local_re(_i) += _JxW[_qp] * _coord[_qp] * computeQpResidual();
109 
110  accumulateTaggedLocalResidual();
111 
112  if (_has_save_in)
113  {
114  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
115  for (const auto & var : _save_in)
116  var->sys().solution().add_vector(_local_re, var->dofIndices());
117  }
118 }
119 
120 Real
122 {
123  Real residual = 0.0;
124  if ((_dt > 0) && ((_zeta != 0) || (_alpha != 0)))
125  {
126  residual = _stress[_qp].rowDot(_component, _grad_test[_i][_qp]) *
127  (1 + _alpha + (1 + _alpha) * _zeta / _dt) -
128  (_alpha + (1 + 2 * _alpha) * _zeta / _dt) *
129  _stress_old[_qp].rowDot(_component, _grad_test[_i][_qp]) +
130  (_alpha * _zeta / _dt) * _stress_older[_qp].rowDot(_component, _grad_test[_i][_qp]);
131 
132  // volumetric locking correction
134  residual += (_stress[_qp].trace() * (1 + _alpha + (1 + _alpha) * _zeta / _dt) -
135  (_alpha + (1 + 2 * _alpha) * _zeta / _dt) * _stress_old[_qp].trace() +
136  (_alpha * _zeta / _dt) * _stress_older[_qp].trace()) /
137  3.0 * (_avg_grad_test[_i][_component] - _grad_test[_i][_qp](_component));
138  }
139  else
140  {
141  residual += _stress[_qp].rowDot(_component, _grad_test[_i][_qp]);
142 
143  // volumetric locking correction
145  residual += _stress[_qp].trace() / 3.0 *
146  (_avg_grad_test[_i][_component] - _grad_test[_i][_qp](_component));
147  }
148  return residual;
149 }
150 
151 void
153 {
154  prepareMatrixTag(_assembly, _var.number(), _var.number());
155 
157  {
158  // calculate volume averaged value of shape function derivative
159  _avg_grad_test.resize(_test.size());
160  for (_i = 0; _i < _test.size(); _i++)
161  {
162  _avg_grad_test[_i].resize(3);
163  _avg_grad_test[_i][_component] = 0.0;
164  for (_qp = 0; _qp < _qrule->n_points(); _qp++)
165  _avg_grad_test[_i][_component] += _grad_test[_i][_qp](_component) * _JxW[_qp] * _coord[_qp];
166 
167  _avg_grad_test[_i][_component] /= _current_elem_volume;
168  }
169 
170  _avg_grad_phi.resize(_phi.size());
171  for (_i = 0; _i < _phi.size(); _i++)
172  {
173  _avg_grad_phi[_i].resize(3);
174  for (unsigned int component = 0; component < _mesh.dimension(); component++)
175  {
176  _avg_grad_phi[_i][component] = 0.0;
177  for (_qp = 0; _qp < _qrule->n_points(); _qp++)
178  _avg_grad_phi[_i][component] += _grad_phi[_i][_qp](component) * _JxW[_qp] * _coord[_qp];
179 
180  _avg_grad_phi[_i][component] /= _current_elem_volume;
181  }
182  }
183  }
184 
185  for (_i = 0; _i < _test.size(); _i++)
186  for (_j = 0; _j < _phi.size(); _j++)
187  for (_qp = 0; _qp < _qrule->n_points(); _qp++)
188  _local_ke(_i, _j) += _JxW[_qp] * _coord[_qp] * computeQpJacobian();
189 
190  accumulateTaggedLocalMatrix();
191 
192  if (_has_diag_save_in)
193  {
194  unsigned int rows = _local_ke.m();
195  DenseVector<Number> diag(rows);
196  for (unsigned int i = 0; i < rows; i++)
197  diag(i) = _local_ke(i, i);
198 
199  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
200  for (const auto & var : _diag_save_in)
201  var->sys().solution().add_vector(diag, var->dofIndices());
202  }
203 }
204 
205 Real
207 {
208  Real sum_C3x3 = _Jacobian_mult[_qp].sum_3x3();
209  RealGradient sum_C3x1 = _Jacobian_mult[_qp].sum_3x1();
210 
211  Real jacobian = 0.0;
212  // B^T_i * C * B_j
213  jacobian += _Jacobian_mult[_qp].stiffness(
214  _component, _component, _grad_test[_i][_qp], _grad_phi[_j][_qp]); // B^T_i * C *B_j
215 
217  {
218  // jacobian = Bbar^T_i * C * Bbar_j where Bbar = B + Bvol
219  // jacobian = B^T_i * C * B_j + Bvol^T_i * C * Bvol_j + Bvol^T_i * C * B_j + B^T_i * C * Bvol_j
220 
221  // Bvol^T_i * C * Bvol_j
222  jacobian += sum_C3x3 * (_avg_grad_test[_i][_component] - _grad_test[_i][_qp](_component)) *
223  (_avg_grad_phi[_j][_component] - _grad_phi[_j][_qp](_component)) / 9.0;
224 
225  // B^T_i * C * Bvol_j
226  jacobian += sum_C3x1(_component) * _grad_test[_i][_qp](_component) *
227  (_avg_grad_phi[_j][_component] - _grad_phi[_j][_qp](_component)) / 3.0;
228 
229  // Bvol^T_i * C * B_j
230  SymmTensor phi;
231  if (_component == 0)
232  {
233  phi.xx() = _grad_phi[_j][_qp](0);
234  phi.xy() = _grad_phi[_j][_qp](1);
235  phi.xz() = _grad_phi[_j][_qp](2);
236  }
237  else if (_component == 1)
238  {
239  phi.yy() = _grad_phi[_j][_qp](1);
240  phi.xy() = _grad_phi[_j][_qp](0);
241  phi.yz() = _grad_phi[_j][_qp](2);
242  }
243  else if (_component == 2)
244  {
245  phi.zz() = _grad_phi[_j][_qp](2);
246  phi.xz() = _grad_phi[_j][_qp](0);
247  phi.yz() = _grad_phi[_j][_qp](1);
248  }
249 
250  SymmTensor tmp(_Jacobian_mult[_qp] * phi);
251 
252  jacobian += (tmp.xx() + tmp.yy() + tmp.zz()) *
253  (_avg_grad_test[_i][_component] - _grad_test[_i][_qp](_component)) / 3.0;
254  }
255 
256  if (_dt > 0)
257  return jacobian * (1 + _alpha + _zeta / _dt);
258  else
259  return jacobian;
260 }
261 
262 void
263 StressDivergence::computeOffDiagJacobian(MooseVariableFEBase & jvar)
264 {
265  size_t jvar_num = jvar.number();
266  if (jvar_num == _var.number())
267  computeJacobian();
268  else
269  {
270  // This (undisplaced) jvar could potentially yield the wrong phi size if this object is acting
271  // on the displaced mesh
272  auto phi_size = _sys.getVariable(_tid, jvar.number()).dofIndices().size();
273 
275  {
276  // calculate volume averaged value of shape function derivative
277  _avg_grad_test.resize(_test.size());
278  for (_i = 0; _i < _test.size(); _i++)
279  {
280  _avg_grad_test[_i].resize(3);
281  _avg_grad_test[_i][_component] = 0.0;
282  for (_qp = 0; _qp < _qrule->n_points(); _qp++)
283  _avg_grad_test[_i][_component] +=
284  _grad_test[_i][_qp](_component) * _JxW[_qp] * _coord[_qp];
285 
286  _avg_grad_test[_i][_component] /= _current_elem_volume;
287  }
288 
289  _avg_grad_phi.resize(phi_size);
290  for (_i = 0; _i < phi_size; _i++)
291  {
292  _avg_grad_phi[_i].resize(3);
293  for (unsigned int component = 0; component < _mesh.dimension(); component++)
294  {
295  _avg_grad_phi[_i][component] = 0.0;
296  for (_qp = 0; _qp < _qrule->n_points(); _qp++)
297  _avg_grad_phi[_i][component] += _grad_phi[_i][_qp](component) * _JxW[_qp] * _coord[_qp];
298 
299  _avg_grad_phi[_i][component] /= _current_elem_volume;
300  }
301  }
302  }
303 
304  prepareMatrixTag(_assembly, _var.number(), jvar_num);
305 
306  for (_i = 0; _i < _test.size(); _i++)
307  for (_j = 0; _j < phi_size; _j++)
308  for (_qp = 0; _qp < _qrule->n_points(); _qp++)
309  _local_ke(_i, _j) += _JxW[_qp] * _coord[_qp] * computeQpOffDiagJacobian(jvar_num);
310 
311  accumulateTaggedLocalMatrix();
312  }
313 }
314 
315 Real
317 {
318  unsigned int coupled_component = 0;
319 
320  bool active = false;
321 
322  if (_xdisp_coupled && jvar == _xdisp_var)
323  {
324  coupled_component = 0;
325  active = true;
326  }
327  else if (_ydisp_coupled && jvar == _ydisp_var)
328  {
329  coupled_component = 1;
330  active = true;
331  }
332  else if (_zdisp_coupled && jvar == _zdisp_var)
333  {
334  coupled_component = 2;
335  active = true;
336  }
337 
338  if (active)
339  {
340  Real sum_C3x3 = _Jacobian_mult[_qp].sum_3x3();
341  RealGradient sum_C3x1 = _Jacobian_mult[_qp].sum_3x1();
342  Real jacobian = 0.0;
343  jacobian += _Jacobian_mult[_qp].stiffness(
344  _component, coupled_component, _grad_test[_i][_qp], _grad_phi[_j][_qp]); // B^T_i * C *B_j
345 
347  {
348  // jacobian = Bbar^T_i * C * Bbar_j where Bbar = B + Bvol
349  // jacobian = B^T_i * C * B_j + Bvol^T_i * C * Bvol_j + Bvol^T_i * C * B_j + B^T_i * C *
350  // Bvol_j
351 
352  // Bvol^T_i * C * Bvol_j
353  jacobian += sum_C3x3 * (_avg_grad_test[_i][_component] - _grad_test[_i][_qp](_component)) *
354  (_avg_grad_phi[_j][coupled_component] - _grad_phi[_j][_qp](coupled_component)) /
355  9.0;
356 
357  // B^T_i * C * Bvol_j
358  jacobian += sum_C3x1(_component) * _grad_test[_i][_qp](_component) *
359  (_avg_grad_phi[_j][coupled_component] - _grad_phi[_j][_qp](coupled_component)) /
360  3.0;
361 
362  // Bvol^T_i * C * B_i
363  SymmTensor phi;
364  if (coupled_component == 0)
365  {
366  phi.xx() = _grad_phi[_j][_qp](0);
367  phi.xy() = _grad_phi[_j][_qp](1);
368  phi.xz() = _grad_phi[_j][_qp](2);
369  }
370  else if (coupled_component == 1)
371  {
372  phi.yy() = _grad_phi[_j][_qp](1);
373  phi.xy() = _grad_phi[_j][_qp](0);
374  phi.yz() = _grad_phi[_j][_qp](2);
375  }
376  else if (coupled_component == 2)
377  {
378  phi.zz() = _grad_phi[_j][_qp](2);
379  phi.xz() = _grad_phi[_j][_qp](0);
380  phi.yz() = _grad_phi[_j][_qp](1);
381  }
382 
383  SymmTensor tmp(_Jacobian_mult[_qp] * phi);
384 
385  jacobian += (tmp.xx() + tmp.yy() + tmp.zz()) *
386  (_avg_grad_test[_i][_component] - _grad_test[_i][_qp](_component)) / 3.0;
387  }
388 
389  if (_dt > 0)
390  return jacobian * (1 + _alpha + _zeta / _dt);
391  else
392  return jacobian;
393  }
394 
395  if (_temp_coupled && jvar == _temp_var)
396  return _d_stress_dT[_qp].rowDot(_component, _grad_test[_i][_qp]) * _phi[_j][_qp];
397 
398  return 0;
399 }
SymmElasticityTensor.h
SymmTensor::xx
Real xx() const
Definition: SymmTensor.h:131
StressDivergence::StressDivergence
StressDivergence(const InputParameters &parameters)
Definition: StressDivergence.C:50
StressDivergence::_alpha
const Real _alpha
Definition: StressDivergence.h:58
StressDivergence::_zdisp_coupled
const bool _zdisp_coupled
Definition: StressDivergence.h:50
StressDivergence::_stress_old
const MaterialProperty< SymmTensor > & _stress_old
Definition: StressDivergence.h:40
StressDivergence::computeJacobian
virtual void computeJacobian() override
Definition: StressDivergence.C:152
SymmTensor::zz
Real zz() const
Definition: SymmTensor.h:133
StressDivergence::computeResidual
virtual void computeResidual() override
Definition: StressDivergence.C:86
StressDivergence::_ydisp_var
const unsigned int _ydisp_var
Definition: StressDivergence.h:54
libMesh::RealGradient
VectorValue< Real > RealGradient
Definition: GrainForceAndTorqueInterface.h:17
registerMooseObjectDeprecated
registerMooseObjectDeprecated("SolidMechanicsApp", StressDivergence, "07/30/2020 24:00")
StressDivergence::_Jacobian_mult
const MaterialProperty< SymmElasticityTensor > & _Jacobian_mult
Definition: StressDivergence.h:42
StressDivergence::_component
const unsigned int _component
Definition: StressDivergence.h:46
StressDivergence::computeQpResidual
virtual Real computeQpResidual() override
Definition: StressDivergence.C:121
StressDivergence::_zeta
const Real _zeta
Definition: StressDivergence.h:57
StressDivergence::_zdisp_var
const unsigned int _zdisp_var
Definition: StressDivergence.h:55
StressDivergence::_avg_grad_test
std::vector< std::vector< Real > > _avg_grad_test
Definition: StressDivergence.h:59
SymmElasticityTensor
This class defines a basic set of capabilities any elasticity tensor should have.
Definition: SymmElasticityTensor.h:55
StressDivergence::computeQpJacobian
virtual Real computeQpJacobian() override
Definition: StressDivergence.C:206
StressDivergence::_stress_older
const MaterialProperty< SymmTensor > & _stress_older
Definition: StressDivergence.h:39
validParams< StressDivergence >
InputParameters validParams< StressDivergence >()
Definition: StressDivergence.C:26
StressDivergence
Definition: StressDivergence.h:22
name
const std::string name
Definition: Setup.h:21
StressDivergence::_xdisp_var
const unsigned int _xdisp_var
Definition: StressDivergence.h:53
StressDivergence::_xdisp_coupled
const bool _xdisp_coupled
Definition: StressDivergence.h:48
StressDivergence::_ydisp_coupled
const bool _ydisp_coupled
Definition: StressDivergence.h:49
MaterialTensorCalculatorTools::component
Real component(const SymmTensor &symm_tensor, unsigned int index)
Definition: MaterialTensorCalculatorTools.C:16
SymmTensor
Definition: SymmTensor.h:21
StressDivergence::_stress
const MaterialProperty< SymmTensor > & _stress
Definition: StressDivergence.h:41
StressDivergence::_avg_grad_phi
std::vector< std::vector< Real > > _avg_grad_phi
Definition: StressDivergence.h:60
StressDivergence::computeQpOffDiagJacobian
virtual Real computeQpOffDiagJacobian(unsigned int jvar) override
Definition: StressDivergence.C:316
SymmTensor::yy
Real yy() const
Definition: SymmTensor.h:132
StressDivergence::_d_stress_dT
const MaterialProperty< SymmTensor > & _d_stress_dT
Definition: StressDivergence.h:43
StressDivergence::_temp_coupled
const bool _temp_coupled
Definition: StressDivergence.h:51
StressDivergence::computeOffDiagJacobian
virtual void computeOffDiagJacobian(MooseVariableFEBase &jvar) override
Definition: StressDivergence.C:263
StressDivergence::_volumetric_locking_correction
bool _volumetric_locking_correction
Definition: StressDivergence.h:61
StressDivergence.h
StressDivergence::_temp_var
const unsigned int _temp_var
Definition: StressDivergence.h:56