https://mooseframework.inl.gov
Loading...
Searching...
No Matches
NodalRotationalInertia.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#include "MooseVariable.h"
12#include "AuxiliarySystem.h"
13#include "MooseMesh.h"
14#include "TimeIntegrator.h"
15#include "FEProblemBase.h"
16
18
21{
23 params.addClassDescription("Calculates the inertial torques and inertia proportional damping "
24 "corresponding to the nodal rotational inertia.");
25 params.addCoupledVar("rotations", "rotational displacement variables");
26 params.addCoupledVar("rotational_velocities", "rotational velocity variables");
27 params.addCoupledVar("rotational_accelerations", "rotational acceleration variables");
28 params.addRangeCheckedParam<Real>(
29 "beta", "beta>0.0", "beta parameter for Newmark Time integration");
30 params.addRangeCheckedParam<Real>(
31 "gamma", "gamma>0.0", "gamma parameter for Newmark Time integration");
32 params.addRangeCheckedParam<Real>("eta",
33 0.0,
34 "eta>=0.0",
35 "Constant real number defining the eta parameter for"
36 "Rayleigh damping.");
37 params.addRangeCheckedParam<Real>("alpha",
38 0.0,
39 "alpha >= -0.3333 & alpha <= 0.0",
40 "Alpha parameter for mass dependent numerical damping induced "
41 "by HHT time integration scheme");
43 "Ixx", "Ixx>0.0", "Moment of inertia in the x direction.");
45 "Iyy", "Iyy>0.0", "Moment of inertia in the y direction.");
47 "Izz", "Izz>0.0", "Moment of inertia in the z direction.");
48 params.addParam<Real>("Ixy", 0.0, "Moment of inertia in the xy direction.");
49 params.addParam<Real>("Ixz", 0.0, "Moment of inertia in the xz direction.");
50 params.addParam<Real>("Iyz", 0.0, "Moment of inertia in the yz direction.");
51 params.addParam<RealGradient>(
52 "x_orientation", "Unit vector along the x direction if different from global x direction.");
53 params.addParam<RealGradient>(
54 "y_orientation", "Unit vector along the y direction if different from global y direction.");
55 params.addRequiredRangeCheckedParam<unsigned int>(
56 "component",
57 "component<3",
58 "An integer corresponding to the direction "
59 "the variable this nodalkernel acts in. (0 for rot_x, "
60 "1 for rot_y, and 2 for rot_z).");
61 return params;
62}
63
65 : TimeNodalKernel(parameters),
66 _has_beta(isParamValid("beta")),
67 _has_gamma(isParamValid("gamma")),
68 _has_rot_velocities(isParamValid("rotational_velocities")),
69 _has_rot_accelerations(isParamValid("rotational_accelerations")),
70 _has_x_orientation(isParamValid("x_orientation")),
71 _has_y_orientation(isParamValid("y_orientation")),
72 _nrot(coupledComponents("rotations")),
73 _rot(_nrot),
74 _rot_old(_nrot),
75 _rot_vel_num(_nrot),
76 _rot_accel_num(_nrot),
77 _rot_variables(_nrot),
78 _rot_accel(_nrot),
79 _rot_vel(_nrot),
80 _rot_vel_old(_nrot),
81 _beta(_has_beta ? getParam<Real>("beta") : 0.1),
82 _gamma(_has_gamma ? getParam<Real>("gamma") : 0.1),
83 _eta(getParam<Real>("eta")),
84 _alpha(getParam<Real>("alpha")),
85 _component(getParam<unsigned int>("component")),
86 _rot_dot_residual(_nrot),
87 _rot_vel_old_value(_nrot),
88 _rot_dotdot_residual(_nrot),
89 _time_integrator(_sys.getTimeIntegrator(_var.number()))
90{
92 {
94 if (coupledComponents("rotational_velocities") != _nrot ||
95 coupledComponents("rotational_accelerations") != _nrot)
97 "NodalRotationalInertia: rotational_velocities and rotational_accelerations should "
98 "be same size "
99 "as rotations.");
100
101 for (unsigned int i = 0; i < _nrot; ++i)
102 {
103 MooseVariable * rot_var = getVar("rotations", i);
104 MooseVariable * rot_vel_var = getVar("rotational_velocities", i);
105 MooseVariable * rot_accel_var = getVar("rotational_accelerations", i);
106
107 _rot[i] = &rot_var->dofValues();
108 _rot_old[i] = &rot_var->dofValuesOld();
109
110 _rot_vel_num[i] = rot_vel_var->number();
111 _rot_accel_num[i] = rot_accel_var->number();
112
113 _rot_variables[i] = coupled("rotations", i);
114 }
115 }
117 {
118 for (unsigned int i = 0; i < _nrot; ++i)
119 {
120 MooseVariable * rot_var = getVar("rotations", i);
121 _rot_vel_old_value[i] = &rot_var->dofValuesDotOld();
126
127 if (i == 0)
128 {
129 _du_dot_du = &rot_var->dofValuesDuDotDu();
131 }
132 }
133 }
134 else
135 mooseError("NodalRotationalInertia: Either all or none of `beta`, `gamma`, "
136 "`rotational_velocities` and `rotational_accelerations` should be provided as "
137 "input.");
138
139 // Store inertia values in inertia tensor
140 _inertia.zero();
141 _inertia(0, 0) = getParam<Real>("Ixx");
142 _inertia(0, 1) = getParam<Real>("Ixy");
143 _inertia(0, 2) = getParam<Real>("Ixz");
144 _inertia(1, 0) = _inertia(0, 1);
145 _inertia(1, 1) = getParam<Real>("Iyy");
146 _inertia(1, 2) = getParam<Real>("Iyz");
147 _inertia(2, 0) = _inertia(0, 2);
148 _inertia(2, 1) = _inertia(1, 2);
149 _inertia(2, 2) = getParam<Real>("Izz");
150
151 // Check for positive definiteness of matrix using Sylvester's criterion.
152 const Real det1 = _inertia(0, 0);
153 const Real det2 = _inertia(0, 0) * _inertia(1, 1) - _inertia(0, 1) * _inertia(1, 0);
154 const Real det3 = _inertia.det();
155
156 if (det1 < 1e-6 || det2 < 1e-6 || det3 < 1e-6)
157 mooseError("NodalRotationalInertia: The moment of inertia tensor should be positive definite.");
159 {
160 const RealGradient x_orientation = getParam<RealGradient>("x_orientation");
161 const RealGradient y_orientation = getParam<RealGradient>("y_orientation");
162
163 if (std::abs(x_orientation.norm() - 1.0) > 1e-6 || std::abs(y_orientation.norm() - 1.0) > 1e-6)
164 mooseError("NodalRotationalInertia: x_orientation and y_orientation must be unit vectors.");
165
166 Real sum = x_orientation(0) * y_orientation(0) + x_orientation(1) * y_orientation(1) +
167 x_orientation(2) * y_orientation(2);
168
169 if (std::abs(sum) > 1e-4)
170 mooseError("NodalRotationalInertia: x_orientation and y_orientation should be perpendicular "
171 "to each other.");
172
173 // Calculate z orientation as a cross product of the x and y orientations
174 RealGradient z_orientation;
175 z_orientation(0) = (x_orientation(1) * y_orientation(2) - x_orientation(2) * y_orientation(1));
176 z_orientation(1) = (x_orientation(2) * y_orientation(0) - x_orientation(0) * y_orientation(2));
177 z_orientation(2) = (x_orientation(0) * y_orientation(1) - x_orientation(1) * y_orientation(0));
178
179 // Rotation matrix from global to original beam local configuration
180 RankTwoTensor orientation;
181 orientation(0, 0) = x_orientation(0);
182 orientation(0, 1) = x_orientation(1);
183 orientation(0, 2) = x_orientation(2);
184 orientation(1, 0) = y_orientation(0);
185 orientation(1, 1) = y_orientation(1);
186 orientation(1, 2) = y_orientation(2);
187 orientation(2, 0) = z_orientation(0);
188 orientation(2, 1) = z_orientation(1);
189 orientation(2, 2) = z_orientation(2);
190
191 RankTwoTensor global_inertia = orientation.transpose() * _inertia * orientation;
192 _inertia = global_inertia;
193 }
194 else if ((_has_x_orientation && !_has_y_orientation) ||
196 mooseError("NodalRotationalInertia: Both x_orientation and y_orientation should be provided if "
197 "x_orientation or "
198 "y_orientation is different from global x or y direction, respectively.");
199
200 // Check for Explicit and alpha parameter
201 if (_alpha != 0 && _time_integrator.isExplicit())
202 mooseError("NodalRotationalInertia: HHT time integration parameter can only be used with "
203 "Newmark-Beta time integration.");
204
205 // Check for Explicit and beta parameter
207 mooseError("NodalRotationalInertia: beta time integration parameter can only be used with "
208 "Newmark-Beta time integrator.");
209}
210
211Real
213{
214 if (_dt == 0)
215 return 0;
216 else
217 {
218 if (_has_beta)
219 {
220 const NumericVector<Number> & aux_sol_old = _aux_sys->solutionOld();
221
222 for (unsigned int i = 0; i < _nrot; ++i)
223 {
224 _rot_vel_old[i] =
225 aux_sol_old(_current_node->dof_number(_aux_sys->number(), _rot_vel_num[i], 0));
226 const Real rot_accel_old =
227 aux_sol_old(_current_node->dof_number(_aux_sys->number(), _rot_accel_num[i], 0));
228
229 _rot_accel[i] = 1.0 / _beta *
230 ((((*_rot[i])[_qp] - (*_rot_old[i])[_qp]) / (_dt * _dt)) -
231 _rot_vel_old[i] / _dt - rot_accel_old * (0.5 - _beta));
232 _rot_vel[i] =
233 _rot_vel_old[i] + (_dt * (1.0 - _gamma)) * rot_accel_old + _gamma * _dt * _rot_accel[i];
234 }
235
236 Real res = 0.0;
237 for (unsigned int i = 0; i < _nrot; ++i)
238 res += _inertia(_component, i) * (_rot_accel[i] + _rot_vel[i] * _eta * (1.0 + _alpha) -
239 _alpha * _eta * _rot_vel_old[i]);
240
241 return res;
242 }
243 else
244 {
245 // All cases (Explicit, implicit and implicit with HHT)
246 // Note that _alpha is ensured to be zero with explicit integration
247 Real res = 0.0;
248 for (unsigned int i = 0; i < _nrot; ++i)
249 res += _inertia(_component, i) * ((*_rot_dotdot_residual[i])[_qp] +
250 (*_rot_dot_residual[i])[_qp] * _eta * (1.0 + _alpha) -
251 _alpha * _eta * (*_rot_vel_old_value[i])[_qp]);
252 return res;
253 }
254 }
255}
256
257Real
259{
260 if (_dt == 0)
261 return 0.0;
262 else
263 {
264 if (_has_beta)
265 return _inertia(_component, _component) / (_beta * _dt * _dt) +
267 else if (_time_integrator.isExplicit())
268 // for explicit central difference integration, _eta does not appear in the
269 // Jacobian (mass matrix), and alpha is zero
270 return _inertia(_component, _component) * (*_du_dotdot_du)[_qp];
271 else
272 // for NewmarkBeta time integrator
273 return _inertia(_component, _component) * (*_du_dotdot_du)[_qp] +
274 _eta * (1.0 + _alpha) * _inertia(_component, _component) * (*_du_dot_du)[_qp];
275 }
276}
277
278Real
280{
281 unsigned int coupled_component = 0;
282 bool rot_coupled = false;
283
284 for (unsigned int i = 0; i < _nrot; ++i)
285 {
286 if (jvar == _rot_variables[i])
287 {
288 coupled_component = i;
289 rot_coupled = true;
290 break;
291 }
292 }
293
294 if (_dt == 0)
295 return 0.0;
296 else if (rot_coupled)
297 {
298 if (_has_beta)
299 return _inertia(_component, coupled_component) / (_beta * _dt * _dt) +
300 _eta * (1.0 + _alpha) * _inertia(_component, coupled_component) * _gamma / _beta / _dt;
301 else
302 return _inertia(_component, coupled_component) * (*_du_dotdot_du)[_qp] +
303 _eta * (1.0 + _alpha) * _inertia(_component, coupled_component) * (*_du_dot_du)[_qp];
304 }
305 else
306 return 0.0;
307}
registerMooseObject("SolidMechanicsApp", NodalRotationalInertia)
void ErrorVector unsigned int
MooseVariable * getVar(const std::string &var_name, unsigned int comp)
unsigned int coupledComponents(const std::string &var_name) const
virtual unsigned int coupled(const std::string &var_name, unsigned int comp=0) const
virtual const VariableValue & coupledVectorTagDofValue(const std::string &var_name, TagID tag, unsigned int index=0) const
AuxiliarySystem & getAuxiliarySystem()
void addRequiredRangeCheckedParam(const std::string &name, const std::string &parsed_function, 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)
void addCoupledVar(const std::string &name, const std::string &doc_string)
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
void mooseError(Args &&... args) const
unsigned int number() const
const MooseArray< libMesh::Number > & dofValuesDuDotDu() const override
const DofValues & dofValues() const override
const DofValues & dofValuesDotOld() const override
const MooseArray< libMesh::Number > & dofValuesDuDotDotDu() const override
const DofValues & dofValuesOld() const override
unsigned int _qp
const Node *const & _current_node
FEProblemBase & _fe_problem
Calculates the inertial torque and inertia proportional damping for nodal rotational inertia.
std::vector< Real > _rot_vel_old
Old velocity of the node.
std::vector< const VariableValue * > _rot_dot_residual
Rotational udot residual.
const VariableValue * _du_dot_du
du_dot_du value
std::vector< unsigned int > _rot_variables
Variable numbers for rotational variables.
RankTwoTensor _inertia
Moment of inertia tensor in global coordinate system.
virtual Real computeQpJacobian() override
const Real _beta
Newmark time integration parameter.
std::vector< const VariableValue * > _rot_vel_old_value
Old velocity value.
virtual Real computeQpOffDiagJacobian(unsigned int jvar) override
NodalRotationalInertia(const InputParameters &parameters)
const VariableValue * _du_dotdot_du
du_dotdot_du value
static InputParameters validParams()
std::vector< Real > _rot_vel
Current velocity of the node.
std::vector< unsigned int > _rot_vel_num
Variable numbers for rotational velocity aux variables.
const TimeIntegrator & _time_integrator
The TimeIntegrator.
const unsigned int _component
Component along which torque is applied.
std::vector< const VariableValue * > _rot_old
Old value of rotational displacements.
const Real & _eta
Mass proportional Rayliegh damping.
AuxiliarySystem * _aux_sys
Auxiliary system object.
const Real & _alpha
HHT time integration parameter.
const bool _has_beta
Booleans for validity of params.
std::vector< Real > _rot_accel
Current acceleration of the node.
virtual Real computeQpResidual() override
unsigned int _nrot
Number of coupled rotational variables.
std::vector< const VariableValue * > _rot_dotdot_residual
Rotational udotdot residual.
std::vector< const VariableValue * > _rot
Value of rotational displacements.
const Real _gamma
Newmark time integration parameter.
std::vector< unsigned int > _rot_accel_num
Variable numbers for rotational acceleration aux variables.
TagID uDotDotFactorTag() const
TagID uDotFactorTag() const
RankTwoTensorTempl< T > transpose() const
unsigned int number() const
NumericVector< Number > & solutionOld()
virtual bool isExplicit() const
static InputParameters validParams()