www.mooseframework.org
StressDivergenceBeam.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 "StressDivergenceBeam.h"
11 
12 // MOOSE includes
13 #include "Assembly.h"
14 #include "Material.h"
15 #include "MooseVariable.h"
16 #include "SystemBase.h"
17 #include "RankTwoTensor.h"
18 #include "NonlinearSystem.h"
19 #include "MooseMesh.h"
20 
21 #include "libmesh/quadrature.h"
22 
23 registerMooseObject("SolidMechanicsApp", StressDivergenceBeam);
24 
27 {
29  params.addClassDescription("Quasi-static and dynamic stress divergence kernel for Beam element");
30  params.addRequiredParam<unsigned int>(
31  "component",
32  "An integer corresponding to the direction "
33  "the variable this kernel acts in. (0 for disp_x, "
34  "1 for disp_y, 2 for disp_z, 3 for rot_x, 4 for rot_y and 5 for rot_z)");
35  params.addRequiredCoupledVar(
36  "displacements",
37  "The displacements appropriate for the simulation geometry and coordinate system");
38  params.addRequiredCoupledVar(
39  "rotations", "The rotations appropriate for the simulation geometry and coordinate system");
40  params.addParam<MaterialPropertyName>(
41  "zeta",
42  0.0,
43  "Name of material property or a constant real number defining the zeta parameter for the "
44  "Rayleigh damping.");
45  params.addRangeCheckedParam<Real>(
46  "alpha", 0.0, "alpha >= -0.3333 & alpha <= 0.0", "alpha parameter for HHT time integration");
47 
48  params.set<bool>("use_displaced_mesh") = true;
49  return params;
50 }
51 
53  : Kernel(parameters),
54  _component(getParam<unsigned int>("component")),
55  _ndisp(coupledComponents("displacements")),
56  _disp_var(_ndisp),
57  _nrot(coupledComponents("rotations")),
58  _rot_var(_nrot),
59  _force(getMaterialPropertyByName<RealVectorValue>("forces")),
60  _moment(getMaterialPropertyByName<RealVectorValue>("moments")),
61  _K11(getMaterialPropertyByName<RankTwoTensor>("Jacobian_11")),
62  _K22(getMaterialPropertyByName<RankTwoTensor>("Jacobian_22")),
63  _K22_cross(getMaterialPropertyByName<RankTwoTensor>("Jacobian_22_cross")),
64  _K21_cross(getMaterialPropertyByName<RankTwoTensor>("Jacobian_12")),
65  _K21(getMaterialPropertyByName<RankTwoTensor>("Jacobian_21")),
66  _original_length(getMaterialPropertyByName<Real>("original_length")),
67  _total_rotation(getMaterialPropertyByName<RankTwoTensor>("total_rotation")),
68  _zeta(getMaterialProperty<Real>("zeta")),
69  _alpha(getParam<Real>("alpha")),
70  _isDamped(getParam<MaterialPropertyName>("zeta") != "0.0" || std::abs(_alpha) > 0.0),
71  _force_old(_isDamped ? &getMaterialPropertyOld<RealVectorValue>("forces") : nullptr),
72  _moment_old(_isDamped ? &getMaterialPropertyOld<RealVectorValue>("moments") : nullptr),
73  _total_rotation_old(_isDamped ? &getMaterialPropertyOld<RankTwoTensor>("total_rotation")
74  : nullptr),
75  _force_older(std::abs(_alpha) > 0.0 ? &getMaterialPropertyOlder<RealVectorValue>("forces")
76  : nullptr),
77  _moment_older(std::abs(_alpha) > 0.0 ? &getMaterialPropertyOlder<RealVectorValue>("moments")
78  : nullptr),
79  _total_rotation_older(std::abs(_alpha) > 0.0
80  ? &getMaterialPropertyOlder<RankTwoTensor>("total_rotation")
81  : nullptr),
82  _global_force_res(0),
83  _global_moment_res(0),
84  _force_local_t(0),
85  _moment_local_t(0),
86  _local_force_res(0),
87  _local_moment_res(0)
88 {
89  if (_ndisp != _nrot)
90  mooseError(
91  "StressDivergenceBeam: The number of displacement and rotation variables should be same.");
92 
93  for (unsigned int i = 0; i < _ndisp; ++i)
94  _disp_var[i] = coupled("displacements", i);
95 
96  for (unsigned int i = 0; i < _nrot; ++i)
97  _rot_var[i] = coupled("rotations", i);
98 }
99 
100 void
102 {
104 
105  mooseAssert(_local_re.size() == 2,
106  "StressDivergenceBeam: Beam element must have two nodes only.");
107 
108  _global_force_res.resize(_test.size());
109  _global_moment_res.resize(_test.size());
110 
112 
113  // add contributions from stiffness proportional damping (non-zero _zeta) or HHT time integration
114  // (non-zero _alpha)
115  if (_isDamped && _dt > 0.0)
117 
118  for (_i = 0; _i < _test.size(); ++_i)
119  {
120  if (_component < 3)
122  else
124  }
125 
127 
128  if (_has_save_in)
129  {
130  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
131  for (_i = 0; _i < _save_in.size(); ++_i)
132  _save_in[_i]->sys().solution().add_vector(_local_re, _save_in[_i]->dofIndices());
133  }
134 }
135 
136 void
138 {
140 
141  for (unsigned int i = 0; i < _test.size(); ++i)
142  {
143  for (unsigned int j = 0; j < _phi.size(); ++j)
144  {
145  if (_component < 3)
146  _local_ke(i, j) = (i == j ? 1 : -1) * _K11[0](_component, _component);
147  else
148  {
149  if (i == j)
150  _local_ke(i, j) = _K22[0](_component - 3, _component - 3);
151  else
152  _local_ke(i, j) = _K22_cross[0](_component - 3, _component - 3);
153  }
154  }
155  }
156 
157  // scaling factor for Rayliegh damping and HHT time integration
158  if (_isDamped && _dt > 0.0)
159  _local_ke *= (1.0 + _alpha + (1.0 + _alpha) * _zeta[0] / _dt);
160 
162 
163  if (_has_diag_save_in)
164  {
165  unsigned int rows = _local_ke.m();
166  DenseVector<Number> diag(rows);
167  for (unsigned int i = 0; i < rows; ++i)
168  diag(i) = _local_ke(i, i);
169 
170  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
171  for (unsigned int i = 0; i < _diag_save_in.size(); ++i)
172  _diag_save_in[i]->sys().solution().add_vector(diag, _diag_save_in[i]->dofIndices());
173  }
174 }
175 
176 void
178 {
179  if (jvar_num == _var.number())
180  computeJacobian();
181  else
182  {
183  unsigned int coupled_component = 0;
184  bool disp_coupled = false;
185  bool rot_coupled = false;
186 
187  for (unsigned int i = 0; i < _ndisp; ++i)
188  {
189  if (jvar_num == _disp_var[i])
190  {
191  coupled_component = i;
192  disp_coupled = true;
193  break;
194  }
195  }
196 
197  for (unsigned int i = 0; i < _nrot; ++i)
198  {
199  if (jvar_num == _rot_var[i])
200  {
201  coupled_component = i + 3;
202  rot_coupled = true;
203  break;
204  }
205  }
206 
207  prepareMatrixTag(_assembly, _var.number(), jvar_num);
208 
209  if (disp_coupled || rot_coupled)
210  {
211  for (unsigned int i = 0; i < _test.size(); ++i)
212  {
213  for (unsigned int j = 0; j < _phi.size(); ++j)
214  {
215  if (_component < 3 && coupled_component < 3)
216  _local_ke(i, j) += (i == j ? 1 : -1) * _K11[0](_component, coupled_component);
217  else if (_component < 3 && coupled_component > 2)
218  {
219  if (i == 0)
220  _local_ke(i, j) += _K21[0](coupled_component - 3, _component);
221  else
222  _local_ke(i, j) += _K21_cross[0](coupled_component - 3, _component);
223  }
224  else if (_component > 2 && coupled_component < 3)
225  {
226  if (j == 0)
227  _local_ke(i, j) += _K21[0](_component - 3, coupled_component);
228  else
229  _local_ke(i, j) += _K21_cross[0](_component - 3, coupled_component);
230  }
231  else
232  {
233  if (i == j)
234  _local_ke(i, j) += _K22[0](_component - 3, coupled_component - 3);
235  else
236  _local_ke(i, j) += _K22_cross[0](_component - 3, coupled_component - 3);
237  }
238  }
239  }
240  }
241 
242  // scaling factor for Rayleigh damping and HHT time integration
243  if (_isDamped && _dt > 0.0)
244  _local_ke *= (1.0 + _alpha + (1.0 + _alpha) * _zeta[0] / _dt);
245 
247  }
248 }
249 
250 void
251 StressDivergenceBeam::computeDynamicTerms(std::vector<RealVectorValue> & global_force_res,
252  std::vector<RealVectorValue> & global_moment_res)
253 {
254  mooseAssert(_zeta[0] >= 0.0, "StressDivergenceBeam: Zeta parameter should be non-negative.");
255  std::vector<RealVectorValue> global_force_res_old(_test.size());
256  std::vector<RealVectorValue> global_moment_res_old(_test.size());
258  _force_old, _moment_old, _total_rotation_old, global_force_res_old, global_moment_res_old);
259 
260  // For HHT calculation, the global force and moment residual from t_older is required
261  std::vector<RealVectorValue> global_force_res_older(_test.size());
262  std::vector<RealVectorValue> global_moment_res_older(_test.size());
263 
264  if (std::abs(_alpha) > 0.0)
268  global_force_res_older,
269  global_moment_res_older);
270 
271  // Update the global_force_res and global_moment_res to include HHT and Rayleigh damping
272  // contributions
273  for (_i = 0; _i < _test.size(); ++_i)
274  {
275  global_force_res[_i] =
276  global_force_res[_i] * (1.0 + _alpha + (1.0 + _alpha) * _zeta[0] / _dt) -
277  global_force_res_old[_i] * (_alpha + (1.0 + 2.0 * _alpha) * _zeta[0] / _dt) +
278  global_force_res_older[_i] * (_alpha * _zeta[0] / _dt);
279  global_moment_res[_i] =
280  global_moment_res[_i] * (1.0 + _alpha + (1.0 + _alpha) * _zeta[0] / _dt) -
281  global_moment_res_old[_i] * (_alpha + (1.0 + 2.0 * _alpha) * _zeta[0] / _dt) +
282  global_moment_res_older[_i] * (_alpha * _zeta[0] / _dt);
283  }
284 }
285 
286 void
288  const MaterialProperty<RealVectorValue> * moment,
289  const MaterialProperty<RankTwoTensor> * total_rotation,
290  std::vector<RealVectorValue> & global_force_res,
291  std::vector<RealVectorValue> & global_moment_res)
292 {
294  _force_local_t.resize(_qrule->n_points());
295  _moment_local_t.resize(_qrule->n_points());
296  _local_force_res.resize(_test.size());
297  _local_moment_res.resize(_test.size());
298 
299  // convert forces/moments from global coordinate system to current beam local configuration
300  for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
301  {
302  _force_local_t[_qp] = (*total_rotation)[0] * (*force)[_qp];
303  _moment_local_t[_qp] = (*total_rotation)[0] * (*moment)[_qp];
304  }
305 
306  // residual for displacement variables
307  for (_i = 0; _i < _test.size(); ++_i)
308  {
309  _local_force_res[_i] = a;
310  for (unsigned int component = 0; component < 3; ++component)
311  {
312  for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
314  (_i == 0 ? -1 : 1) * _force_local_t[_qp](component) * 0.5;
315  }
316  }
317 
318  // residual for rotation variables
319  for (_i = 0; _i < _test.size(); ++_i)
320  {
322  for (unsigned int component = 3; component < 6; ++component)
323  {
324  for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
325  {
326  if (component == 3)
328  (_i == 0 ? -1 : 1) * _moment_local_t[_qp](0) * 0.5;
329  else if (component == 4)
331  (_i == 0 ? -1 : 1) * _moment_local_t[_qp](1) * 0.5 +
332  _force_local_t[_qp](2) * 0.25 * _original_length[0];
333  else
335  (_i == 0 ? -1 : 1) * _moment_local_t[_qp](2) * 0.5 -
336  _force_local_t[_qp](1) * 0.25 * _original_length[0];
337  }
338  }
339  }
340 
341  // convert residual for each variable from current beam local configuration to global
342  // configuration
343  for (_i = 0; _i < _test.size(); ++_i)
344  {
345  global_force_res[_i] = (*total_rotation)[0].transpose() * _local_force_res[_i];
346  global_moment_res[_i] = (*total_rotation)[0].transpose() * _local_moment_res[_i];
347  }
348 }
static InputParameters validParams()
const MaterialProperty< RealVectorValue > * _moment_older
Older moment vector in global coordinate system.
std::vector< RealVectorValue > _global_force_res
Residual corresponding to displacement DOFs at the nodes in global coordinate system.
unsigned int _ndisp
Number of coupled displacement variables.
virtual unsigned int coupled(const std::string &var_name, unsigned int comp=0) const
const MaterialProperty< RealVectorValue > & _force
Current force vector in global coordinate system.
StressDivergenceBeam(const InputParameters &parameters)
static InputParameters validParams()
void accumulateTaggedLocalResidual()
MooseVariable & _var
std::vector< MooseVariableFEBase *> _save_in
const MaterialProperty< RankTwoTensor > & _K11
Stiffness matrix relating displacement DOFs of same node or across nodes.
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
unsigned int number() const
const MaterialProperty< RankTwoTensor > & _K21
Stiffness matrix relating displacement and rotations of same node.
static const std::string component
Definition: NS.h:138
const MaterialProperty< RankTwoTensor > & _K22_cross
Stiffness matrix relating rotational DOFs across nodes.
T & set(const std::string &name, bool quiet_mode=false)
void computeDynamicTerms(std::vector< RealVectorValue > &global_force_res, std::vector< RealVectorValue > &global_moment_res)
Computes the force and moment due to stiffness proportional damping and HHT time integration.
unsigned int m() const
Real & _dt
std::vector< unsigned int > _disp_var
Variable numbers corresponding to displacement variables.
const MaterialProperty< RankTwoTensor > & _K22
Stiffness matrix relating rotational DOFs of same node.
const MaterialProperty< RealVectorValue > * _force_older
Older force vector in global coordinate system.
bool _has_diag_save_in
DenseMatrix< Number > _local_ke
void addRequiredParam(const std::string &name, const std::string &doc_string)
const MaterialProperty< RankTwoTensor > & _K21_cross
Stiffness matrix relating displacement of one node to rotations of another node.
const MaterialProperty< RankTwoTensor > * _total_rotation_old
Rotational transformation from global to old beam local coordinate system.
std::vector< RealVectorValue > _global_moment_res
Residual corresponding to rotational DOFs at the nodes in global coordinate system.
ADRealEigenVector< T, D, asd > abs(const ADRealEigenVector< T, D, asd > &)
std::vector< RealVectorValue > _local_force_res
Residual corresponding to displacement DOFs at the nodes in beam local coordinate system...
const VariableTestValue & _test
const MaterialProperty< RankTwoTensor > & _total_rotation
Rotational transformation from global to current beam local coordinate system.
std::vector< MooseVariableFEBase *> _diag_save_in
const unsigned int _component
Direction along which force/moment is calculated.
const QBase *const & _qrule
bool _has_save_in
const MaterialProperty< RankTwoTensor > * _total_rotation_older
Rotational transformation from global to older beam local coordinate system.
virtual void computeJacobian() override
virtual void computeResidual() override
unsigned int _i
void accumulateTaggedLocalMatrix()
const Real & _alpha
HHT time integration parameter.
registerMooseObject("SolidMechanicsApp", StressDivergenceBeam)
Assembly & _assembly
std::vector< RealVectorValue > _local_moment_res
Residual corresponding to rotational DOFs at the nodes in beam local coordinate system.
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
const MaterialProperty< RealVectorValue > * _moment_old
Old moment vector in global coordinate system.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void computeGlobalResidual(const MaterialProperty< RealVectorValue > *force, const MaterialProperty< RealVectorValue > *moment, const MaterialProperty< RankTwoTensor > *total_rotation, std::vector< RealVectorValue > &global_force_res, std::vector< RealVectorValue > &global_moment_res)
Computes the residual corresponding to displacement and rotational variables given the forces and mom...
std::vector< RealVectorValue > _force_local_t
Forces at each Qp in the beam local configuration.
const MaterialProperty< Real > & _original_length
Initial length of beam.
DenseVector< Number > _local_re
const MaterialProperty< Real > & _zeta
Stiffness proportional Rayleigh damping parameter.
void mooseError(Args &&... args) const
virtual unsigned int size() const override final
virtual void computeOffDiagJacobian(unsigned int jvar) override
std::vector< unsigned int > _rot_var
Variable numbers corresponding to rotational variables.
void addClassDescription(const std::string &doc_string)
std::vector< RealVectorValue > _moment_local_t
Moments at each Qp in the beam local configuration.
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
const bool _isDamped
Boolean flag to turn on Rayleigh damping or numerical damping due to HHT time integration.
void prepareVectorTag(Assembly &assembly, unsigned int ivar)
void prepareMatrixTag(Assembly &assembly, unsigned int ivar, unsigned int jvar)
const MaterialProperty< RealVectorValue > & _moment
Current moment vector in global coordinate system.
const VariablePhiValue & _phi
void ErrorVector unsigned int
unsigned int _nrot
Number of coupled rotational variables.
const MaterialProperty< RealVectorValue > * _force_old
Old force vector in global coordinate system.
unsigned int _qp