https://mooseframework.inl.gov
Loading...
Searching...
No Matches
StressDivergenceBeam.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
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
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)");
36 "displacements",
37 "The displacements appropriate for the simulation geometry and coordinate system");
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)
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
100void
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
136void
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
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
176void
178{
179 if (jvar_num == _var.number())
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
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
250void
251StressDivergenceBeam::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
286void
289 const MaterialProperty<RankTwoTensor> * total_rotation,
290 std::vector<RealVectorValue> & global_force_res,
291 std::vector<RealVectorValue> & global_moment_res)
292{
293 RealVectorValue a;
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 {
310 for (unsigned int component = 0; component < 3; ++component)
311 {
312 for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
313 _local_force_res[_i](component) +=
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)
327 _local_moment_res[_i](component - 3) +=
328 (_i == 0 ? -1 : 1) * _moment_local_t[_qp](0) * 0.5;
329 else if (component == 4)
330 _local_moment_res[_i](component - 3) +=
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
334 _local_moment_res[_i](component - 3) +=
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}
registerMooseObject("SolidMechanicsApp", StressDivergenceBeam)
void ErrorVector unsigned int
virtual unsigned int coupled(const std::string &var_name, unsigned int comp=0) const
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
T & set(const std::string &name, bool quiet_mode=false)
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
std::vector< MooseVariableFEBase * > _save_in
bool _has_diag_save_in
unsigned int _qp
bool _has_save_in
std::vector< MooseVariableFEBase * > _diag_save_in
unsigned int _i
const QBase *const & _qrule
MooseVariable & _var
const VariablePhiValue & _phi
const VariableTestValue & _test
static InputParameters validParams()
void mooseError(Args &&... args) const
unsigned int number() const
Assembly & _assembly
const MaterialProperty< RankTwoTensor > * _total_rotation_older
Rotational transformation from global to older beam local coordinate system.
std::vector< RealVectorValue > _global_force_res
Residual corresponding to displacement DOFs at the nodes in global coordinate system.
const MaterialProperty< RealVectorValue > * _moment_old
Old moment vector in global coordinate system.
const MaterialProperty< RealVectorValue > * _force_old
Old force vector in global coordinate system.
std::vector< RealVectorValue > _global_moment_res
Residual corresponding to rotational DOFs at the nodes in global coordinate system.
virtual void computeResidual() override
const MaterialProperty< RealVectorValue > * _force_older
Older force vector in global coordinate system.
const MaterialProperty< RankTwoTensor > & _K22_cross
Stiffness matrix relating rotational DOFs across nodes.
const MaterialProperty< RankTwoTensor > & _K21
Stiffness matrix relating displacement and rotations of same node.
const MaterialProperty< Real > & _original_length
Initial length of beam.
const Real & _alpha
HHT time integration parameter.
const MaterialProperty< RankTwoTensor > & _total_rotation
Rotational transformation from global to current beam local coordinate system.
virtual void computeJacobian() override
std::vector< RealVectorValue > _local_force_res
Residual corresponding to displacement DOFs at the nodes in beam local coordinate system.
unsigned int _ndisp
Number of coupled displacement variables.
std::vector< RealVectorValue > _force_local_t
Forces at each Qp in the beam local configuration.
const MaterialProperty< RankTwoTensor > * _total_rotation_old
Rotational transformation from global to old beam local coordinate system.
const MaterialProperty< RankTwoTensor > & _K21_cross
Stiffness matrix relating displacement of one node to rotations of another node.
const MaterialProperty< RankTwoTensor > & _K22
Stiffness matrix relating rotational DOFs of same node.
const MaterialProperty< RealVectorValue > * _moment_older
Older moment vector in global coordinate system.
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...
const MaterialProperty< Real > & _zeta
Stiffness proportional Rayleigh damping parameter.
const unsigned int _component
Direction along which force/moment is calculated.
const MaterialProperty< RankTwoTensor > & _K11
Stiffness matrix relating displacement DOFs of same node or across nodes.
std::vector< RealVectorValue > _moment_local_t
Moments at each Qp in the beam local configuration.
std::vector< unsigned int > _rot_var
Variable numbers corresponding to rotational variables.
virtual void computeOffDiagJacobian(unsigned int jvar) override
const MaterialProperty< RealVectorValue > & _force
Current force vector in global coordinate system.
std::vector< unsigned int > _disp_var
Variable numbers corresponding to displacement variables.
StressDivergenceBeam(const InputParameters &parameters)
unsigned int _nrot
Number of coupled rotational variables.
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.
const bool _isDamped
Boolean flag to turn on Rayleigh damping or numerical damping due to HHT time integration.
std::vector< RealVectorValue > _local_moment_res
Residual corresponding to rotational DOFs at the nodes in beam local coordinate system.
static InputParameters validParams()
const MaterialProperty< RealVectorValue > & _moment
Current moment vector in global coordinate system.
DenseMatrix< Number > _local_ke
void accumulateTaggedLocalMatrix()
void prepareMatrixTag(Assembly &assembly, unsigned int ivar, unsigned int jvar)
void accumulateTaggedLocalResidual()
void prepareVectorTag(Assembly &assembly, unsigned int ivar)
DenseVector< Number > _local_re
Real & _dt
unsigned int m() const
virtual unsigned int size() const override final