LCOV - code coverage report
Current view: top level - src/nodalkernels - NodalTranslationalInertia.C (source / functions) Hit Total Coverage
Test: idaholab/moose tensor_mechanics: d6b47a Lines: 98 104 94.2 %
Date: 2024-02-27 11:53:14 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "NodalTranslationalInertia.h"
      11             : #include "MooseVariable.h"
      12             : #include "AuxiliarySystem.h"
      13             : #include "MooseUtils.h"
      14             : #include "DelimitedFileReader.h"
      15             : #include "TimeIntegrator.h"
      16             : 
      17             : registerMooseObject("TensorMechanicsApp", NodalTranslationalInertia);
      18             : 
      19             : InputParameters
      20         277 : NodalTranslationalInertia::validParams()
      21             : {
      22         277 :   InputParameters params = TimeNodalKernel::validParams();
      23         277 :   params.addClassDescription("Computes the inertial forces and mass proportional damping terms "
      24             :                              "corresponding to nodal mass.");
      25         554 :   params.addCoupledVar("velocity", "velocity variable");
      26         554 :   params.addCoupledVar("acceleration", "acceleration variable");
      27         554 :   params.addRangeCheckedParam<Real>(
      28             :       "beta", "beta>0.0", "beta parameter for Newmark Time integration");
      29         554 :   params.addRangeCheckedParam<Real>(
      30             :       "gamma", "gamma>0.0", "gamma parameter for Newmark Time integration");
      31         831 :   params.addRangeCheckedParam<Real>("eta",
      32         554 :                                     0.0,
      33             :                                     "eta>=0.0",
      34             :                                     "Constant real number defining the eta parameter for "
      35             :                                     "Rayleigh damping.");
      36         831 :   params.addRangeCheckedParam<Real>("alpha",
      37         554 :                                     0.0,
      38             :                                     "alpha >= -0.3333 & alpha <= 0.0",
      39             :                                     "Alpha parameter for mass dependent numerical damping induced "
      40             :                                     "by HHT time integration scheme");
      41         554 :   params.addParam<Real>("mass", "Mass associated with the node");
      42         554 :   params.addParam<FileName>(
      43             :       "nodal_mass_file",
      44             :       "The file containing the nodal positions and the corresponding nodal masses.");
      45         277 :   return params;
      46           0 : }
      47             : 
      48         134 : NodalTranslationalInertia::NodalTranslationalInertia(const InputParameters & parameters)
      49             :   : TimeNodalKernel(parameters),
      50         134 :     _has_mass(isParamValid("mass")),
      51         268 :     _has_beta(isParamValid("beta")),
      52         268 :     _has_gamma(isParamValid("gamma")),
      53         268 :     _has_velocity(isParamValid("velocity")),
      54         268 :     _has_acceleration(isParamValid("acceleration")),
      55         268 :     _has_nodal_mass_file(isParamValid("nodal_mass_file")),
      56         220 :     _mass(_has_mass ? getParam<Real>("mass") : 0.0),
      57         223 :     _beta(_has_beta ? getParam<Real>("beta") : 0.1),
      58         223 :     _gamma(_has_gamma ? getParam<Real>("gamma") : 0.1),
      59         268 :     _eta(getParam<Real>("eta")),
      60         268 :     _alpha(getParam<Real>("alpha")),
      61         268 :     _time_integrator(*_sys.getTimeIntegrator())
      62             : {
      63         134 :   if (_has_beta && _has_gamma && _has_velocity && _has_acceleration)
      64             :   {
      65          89 :     _u_old = &(_var.dofValuesOld());
      66          89 :     _aux_sys = &(_fe_problem.getAuxiliarySystem());
      67             : 
      68         178 :     MooseVariable * vel_variable = getVar("velocity", 0);
      69          89 :     _vel_num = vel_variable->number();
      70         178 :     MooseVariable * accel_variable = getVar("acceleration", 0);
      71          89 :     _accel_num = accel_variable->number();
      72          89 :   }
      73          45 :   else if (!_has_beta && !_has_gamma && !_has_velocity && !_has_acceleration)
      74             :   {
      75          45 :     _du_dot_du = &(_var.duDotDu());
      76          45 :     _du_dotdot_du = &(_var.duDotDotDu());
      77          45 :     _u_dot_old = &(_var.dofValuesDotOld());
      78             : 
      79          45 :     addFEVariableCoupleableVectorTag(_time_integrator.uDotFactorTag());
      80          45 :     addFEVariableCoupleableVectorTag(_time_integrator.uDotDotFactorTag());
      81             : 
      82          45 :     _u_dot_factor = &_var.vectorTagDofValue(_time_integrator.uDotFactorTag());
      83          45 :     _u_dotdot_factor = &_var.vectorTagDofValue(_time_integrator.uDotDotFactorTag());
      84             :   }
      85             :   else
      86           0 :     mooseError("NodalTranslationalInertia: Either all or none of `beta`, `gamma`, `velocity` and "
      87             :                "`acceleration` should be provided as input.");
      88             : 
      89         134 :   if (!_has_nodal_mass_file && !_has_mass)
      90           1 :     mooseError(
      91             :         "NodalTranslationalInertia: Please provide either mass or nodal_mass_file as input.");
      92         133 :   else if (_has_nodal_mass_file && _has_mass)
      93           2 :     mooseError("NodalTranslationalInertia: Please provide either mass or nodal_mass_file as input, "
      94             :                "not both.");
      95             : 
      96         131 :   if (_has_nodal_mass_file)
      97             :   {
      98         141 :     MooseUtils::DelimitedFileReader nodal_mass_file(getParam<FileName>("nodal_mass_file"));
      99             :     nodal_mass_file.setHeaderFlag(MooseUtils::DelimitedFileReader::HeaderFlag::OFF);
     100          47 :     nodal_mass_file.read();
     101          47 :     std::vector<std::vector<Real>> data = nodal_mass_file.getData();
     102          47 :     if (data.size() != 4)
     103           2 :       mooseError("NodalTranslationalInertia: The number of columns in ",
     104             :                  getParam<FileName>("nodal_mass_file"),
     105             :                  " should be 4.");
     106          46 :     unsigned int node_found = 0;
     107          46 :     const std::set<BoundaryID> bnd_ids = BoundaryRestrictable::boundaryIDs();
     108         101 :     for (auto & bnd_id : bnd_ids)
     109             :     {
     110          55 :       const std::vector<dof_id_type> & bnd_node_set = _mesh.getNodeList(bnd_id);
     111         398 :       for (auto & bnd_node : bnd_node_set)
     112             :       {
     113         343 :         const Node & node = _mesh.nodeRef(bnd_node);
     114         343 :         _node_id_to_mass[bnd_node] = 0.0;
     115             : 
     116        1811 :         for (unsigned int i = 0; i < data[0].size(); ++i)
     117             :         {
     118         955 :           if (MooseUtils::absoluteFuzzyEqual(data[0][i], node(0), 1e-6) &&
     119        2370 :               MooseUtils::absoluteFuzzyEqual(data[1][i], node(1), 1e-6) &&
     120             :               MooseUtils::absoluteFuzzyEqual(data[2][i], node(2), 1e-6))
     121             :           {
     122         343 :             _node_id_to_mass[bnd_node] = data[3][i];
     123         343 :             node_found += 1;
     124         343 :             break;
     125             :           }
     126             :         }
     127             :       }
     128             :     }
     129          46 :     if (node_found != data[0].size())
     130           1 :       mooseError("NodalTranslationalInertia: Out of ",
     131           1 :                  data[0].size(),
     132             :                  " nodal positions in ",
     133             :                  getParam<FileName>("nodal_mass_file"),
     134             :                  " only ",
     135             :                  node_found,
     136             :                  " nodes were found in the boundary.");
     137          45 :   }
     138             : 
     139             :   // Check for Explicit and alpha parameter
     140         129 :   if (_alpha != 0 && _time_integrator.isExplicit())
     141           0 :     mooseError("NodalTranslationalInertia: HHT time integration parameter can only be used with "
     142             :                "Newmark-Beta time integration.");
     143             : 
     144             :   // Check if beta and explicit are being used simultaneously
     145         129 :   if (_has_beta && _time_integrator.isExplicit())
     146           0 :     mooseError("NodalTranslationalInertia: Newmark-beta integration parameter, beta, cannot be "
     147             :                "provided along with an explicit time "
     148             :                "integrator.");
     149         129 : }
     150             : 
     151             : Real
     152       23559 : NodalTranslationalInertia::computeQpResidual()
     153             : {
     154       23559 :   if (_dt == 0)
     155             :     return 0;
     156             :   else
     157             :   {
     158             :     Real mass = 0.0;
     159       23559 :     if (_has_mass)
     160       11703 :       mass = _mass;
     161             :     else
     162             :     {
     163       11856 :       if (_node_id_to_mass.find(_current_node->id()) != _node_id_to_mass.end())
     164       11856 :         mass = _node_id_to_mass[_current_node->id()];
     165             :       else
     166           0 :         mooseError("NodalTranslationalInertia: Unable to find an entry for the current node in the "
     167             :                    "_node_id_to_mass map.");
     168             :     }
     169             : 
     170       23559 :     if (_has_beta)
     171             :     {
     172             :       mooseAssert(_beta > 0.0, "NodalTranslationalInertia: Beta parameter should be positive.");
     173       12600 :       const NumericVector<Number> & aux_sol_old = _aux_sys->solutionOld();
     174             : 
     175       12600 :       const Real vel_old = aux_sol_old(_current_node->dof_number(_aux_sys->number(), _vel_num, 0));
     176             :       const Real accel_old =
     177       12600 :           aux_sol_old(_current_node->dof_number(_aux_sys->number(), _accel_num, 0));
     178             : 
     179             :       const Real accel =
     180       12600 :           1. / _beta *
     181       12600 :           (((_u[_qp] - (*_u_old)[_qp]) / (_dt * _dt)) - vel_old / _dt - accel_old * (0.5 - _beta));
     182       12600 :       const Real vel = vel_old + (_dt * (1 - _gamma)) * accel_old + _gamma * _dt * accel;
     183       12600 :       return mass * (accel + vel * _eta * (1 + _alpha) - _alpha * _eta * vel_old);
     184             :     }
     185             : 
     186             :     else
     187             :       // all cases (Explicit, implicit and implicit with HHT)
     188             :       // Note that _alpha is enforced to be zero for explicit integration
     189       10959 :       return mass * ((*_u_dotdot_factor)[_qp] + (*_u_dot_factor)[_qp] * _eta * (1.0 + _alpha) -
     190       10959 :                      _alpha * _eta * (*_u_dot_old)[_qp]);
     191             :   }
     192             : }
     193             : 
     194             : Real
     195        9201 : NodalTranslationalInertia::computeQpJacobian()
     196             : {
     197             :   mooseAssert(_beta > 0.0, "NodalTranslationalInertia: Beta parameter should be positive.");
     198             : 
     199        9201 :   if (_dt == 0)
     200             :     return 0;
     201             :   else
     202             :   {
     203             :     Real mass = 0.0;
     204        9201 :     if (_has_mass)
     205        3903 :       mass = _mass;
     206             :     else
     207             :     {
     208        5298 :       if (_node_id_to_mass.find(_current_node->id()) != _node_id_to_mass.end())
     209        5298 :         mass = _node_id_to_mass[_current_node->id()];
     210             :       else
     211           0 :         mooseError("NodalTranslationalInertia: Unable to find an entry for the current node in the "
     212             :                    "_node_id_to_mass map.");
     213             :     }
     214        9201 :     if (_has_beta)
     215        4200 :       return mass / (_beta * _dt * _dt) + _eta * (1 + _alpha) * mass * _gamma / _beta / _dt;
     216             :     else
     217        5001 :       return mass * (*_du_dotdot_du)[_qp] + _eta * (1.0 + _alpha) * mass * (*_du_dot_du)[_qp];
     218             :   }
     219             : }

Generated by: LCOV version 1.14