https://mooseframework.inl.gov
NodalTranslationalInertia.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 "MooseUtils.h"
14 #include "DelimitedFileReader.h"
15 #include "TimeIntegrator.h"
16 #include "FEProblemBase.h"
17 
19 
22 {
24  params.addClassDescription("Computes the inertial forces and mass proportional damping terms "
25  "corresponding to nodal mass.");
26  params.addCoupledVar("velocity", "velocity variable");
27  params.addCoupledVar("acceleration", "acceleration variable");
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");
42  params.addParam<Real>("mass", "Mass associated with the node");
43  params.addParam<FileName>(
44  "nodal_mass_file",
45  "The file containing the nodal positions and the corresponding nodal masses.");
46  return params;
47 }
48 
50  : TimeNodalKernel(parameters),
51  _has_mass(isParamValid("mass")),
52  _has_beta(isParamValid("beta")),
53  _has_gamma(isParamValid("gamma")),
54  _has_velocity(isParamValid("velocity")),
55  _has_acceleration(isParamValid("acceleration")),
56  _has_nodal_mass_file(isParamValid("nodal_mass_file")),
57  _mass(_has_mass ? getParam<Real>("mass") : 0.0),
58  _beta(_has_beta ? getParam<Real>("beta") : 0.1),
59  _gamma(_has_gamma ? getParam<Real>("gamma") : 0.1),
60  _eta(getParam<Real>("eta")),
61  _alpha(getParam<Real>("alpha")),
62  _time_integrator(_sys.getTimeIntegrator(_var.number()))
63 {
65  {
66  _u_old = &(_var.dofValuesOld());
68 
69  MooseVariable * vel_variable = getVar("velocity", 0);
70  _vel_num = vel_variable->number();
71  MooseVariable * accel_variable = getVar("acceleration", 0);
72  _accel_num = accel_variable->number();
73  }
75  {
76  _du_dot_du = &(_var.duDotDu());
79 
82 
85  }
86  else
87  mooseError("NodalTranslationalInertia: Either all or none of `beta`, `gamma`, `velocity` and "
88  "`acceleration` should be provided as input.");
89 
91  mooseError(
92  "NodalTranslationalInertia: Please provide either mass or nodal_mass_file as input.");
93  else if (_has_nodal_mass_file && _has_mass)
94  mooseError("NodalTranslationalInertia: Please provide either mass or nodal_mass_file as input, "
95  "not both.");
96 
98  {
99  MooseUtils::DelimitedFileReader nodal_mass_file(getParam<FileName>("nodal_mass_file"));
101  nodal_mass_file.read();
102  std::vector<std::vector<Real>> data = nodal_mass_file.getData();
103  if (data.size() != 4)
104  mooseError("NodalTranslationalInertia: The number of columns in ",
105  getParam<FileName>("nodal_mass_file"),
106  " should be 4.");
107  unsigned int node_found = 0;
108  const std::set<BoundaryID> bnd_ids = BoundaryRestrictable::boundaryIDs();
109  for (auto & bnd_id : bnd_ids)
110  {
111  const std::vector<dof_id_type> & bnd_node_set = _mesh.getNodeList(bnd_id);
112  for (auto & bnd_node : bnd_node_set)
113  {
114  const Node & node = _mesh.nodeRef(bnd_node);
115  _node_id_to_mass[bnd_node] = 0.0;
116 
117  for (unsigned int i = 0; i < data[0].size(); ++i)
118  {
119  if (MooseUtils::absoluteFuzzyEqual(data[0][i], node(0), 1e-6) &&
120  MooseUtils::absoluteFuzzyEqual(data[1][i], node(1), 1e-6) &&
121  MooseUtils::absoluteFuzzyEqual(data[2][i], node(2), 1e-6))
122  {
123  _node_id_to_mass[bnd_node] = data[3][i];
124  node_found += 1;
125  break;
126  }
127  }
128  }
129  }
130  if (node_found != data[0].size())
131  mooseError("NodalTranslationalInertia: Out of ",
132  data[0].size(),
133  " nodal positions in ",
134  getParam<FileName>("nodal_mass_file"),
135  " only ",
136  node_found,
137  " nodes were found in the boundary.");
138  }
139 
140  // Check for Explicit and alpha parameter
141  if (_alpha != 0 && _time_integrator.isExplicit())
142  mooseError("NodalTranslationalInertia: HHT time integration parameter can only be used with "
143  "Newmark-Beta time integration.");
144 
145  // Check if beta and explicit are being used simultaneously
147  mooseError("NodalTranslationalInertia: Newmark-beta integration parameter, beta, cannot be "
148  "provided along with an explicit time "
149  "integrator.");
150 }
151 
152 Real
154 {
155  if (_dt == 0)
156  return 0;
157  else
158  {
159  Real mass = 0.0;
160  if (_has_mass)
161  mass = _mass;
162  else
163  {
164  if (_node_id_to_mass.find(_current_node->id()) != _node_id_to_mass.end())
165  mass = _node_id_to_mass[_current_node->id()];
166  else
167  mooseError("NodalTranslationalInertia: Unable to find an entry for the current node in the "
168  "_node_id_to_mass map.");
169  }
170 
171  if (_has_beta)
172  {
173  mooseAssert(_beta > 0.0, "NodalTranslationalInertia: Beta parameter should be positive.");
174  const NumericVector<Number> & aux_sol_old = _aux_sys->solutionOld();
175 
176  const Real vel_old = aux_sol_old(_current_node->dof_number(_aux_sys->number(), _vel_num, 0));
177  const Real accel_old =
178  aux_sol_old(_current_node->dof_number(_aux_sys->number(), _accel_num, 0));
179 
180  const Real accel =
181  1. / _beta *
182  (((_u[_qp] - (*_u_old)[_qp]) / (_dt * _dt)) - vel_old / _dt - accel_old * (0.5 - _beta));
183  const Real vel = vel_old + (_dt * (1 - _gamma)) * accel_old + _gamma * _dt * accel;
184  return mass * (accel + vel * _eta * (1 + _alpha) - _alpha * _eta * vel_old);
185  }
186 
187  else
188  // all cases (Explicit, implicit and implicit with HHT)
189  // Note that _alpha is enforced to be zero for explicit integration
190  return mass * ((*_u_dotdot_factor)[_qp] + (*_u_dot_factor)[_qp] * _eta * (1.0 + _alpha) -
191  _alpha * _eta * (*_u_dot_old)[_qp]);
192  }
193 }
194 
195 Real
197 {
198  mooseAssert(_beta > 0.0, "NodalTranslationalInertia: Beta parameter should be positive.");
199 
200  if (_dt == 0)
201  return 0;
202  else
203  {
204  Real mass = 0.0;
205  if (_has_mass)
206  mass = _mass;
207  else
208  {
209  if (_node_id_to_mass.find(_current_node->id()) != _node_id_to_mass.end())
210  mass = _node_id_to_mass[_current_node->id()];
211  else
212  mooseError("NodalTranslationalInertia: Unable to find an entry for the current node in the "
213  "_node_id_to_mass map.");
214  }
215  if (_has_beta)
216  return mass / (_beta * _dt * _dt) + _eta * (1 + _alpha) * mass * _gamma / _beta / _dt;
217  else
218  return mass * (*_du_dotdot_du)[_qp] + _eta * (1.0 + _alpha) * mass * (*_du_dot_du)[_qp];
219  }
220 }
MooseMesh & _mesh
const bool _has_mass
Booleans for validity of params.
const DoFValue & dofValuesDotOld() const override
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
const Real _mass
Mass associated with the node.
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 Real _beta
Newmark time integration parameter.
static InputParameters validParams()
static InputParameters validParams()
const Real & _eta
Mass proportional Rayliegh damping.
MooseVariable * getVar(const std::string &var_name, unsigned int comp)
const Real & _alpha
HHT time integration parameter.
AuxiliarySystem * _aux_sys
Auxiliary system object.
MooseVariable & _var
virtual const Node & nodeRef(const dof_id_type i) const
virtual bool isExplicit() const
const VariableValue * _u_dotdot_factor
const VariableValue * _du_dotdot_du
Calculates the inertial force and mass proportional damping for a nodal mass.
const VariableValue & duDotDotDu() const
const TimeIntegrator & _time_integrator
The TimeIntegrator.
void addFEVariableCoupleableVectorTag(TagID tag)
unsigned int _accel_num
Variable number corresponding to the acceleration aux variable.
const std::vector< dof_id_type > & getNodeList(boundary_id_type nodeset_id) const
registerMooseObject("SolidMechanicsApp", NodalTranslationalInertia)
const DoFValue & dofValuesOld() const override
FEProblemBase & _fe_problem
const VariableValue & _u
TagID uDotDotFactorTag() const
unsigned int number() const
AuxiliarySystem & getAuxiliarySystem()
const std::vector< std::vector< T > > & getData() const
void addCoupledVar(const std::string &name, const std::string &doc_string)
const VariableValue * _u_old
Old value of displacement.
TagID uDotFactorTag() const
NodalTranslationalInertia(const InputParameters &parameters)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::map< dof_id_type, Real > _node_id_to_mass
Map between boundary nodes and nodal mass.
const DoFValue & vectorTagDofValue(TagID tag) const override
const VariableValue * _u_dot_factor
const VariableValue & duDotDu() const
void setHeaderFlag(HeaderFlag value)
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
unsigned int _vel_num
Variable number corresponding to the velocity aux variable.
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
const Node *const & _current_node
NumericVector< Number > & solutionOld()
virtual const std::set< BoundaryID > & boundaryIDs() const
const Real _gamma
Newmark time integration parameter.
unsigned int _qp
virtual Real computeQpResidual() override
virtual Real computeQpJacobian() override