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