LCOV - code coverage report
Current view: top level - src/kernels - InertialForce.C (source / functions) Hit Total Coverage
Test: idaholab/moose solid_mechanics: f45d79 Lines: 78 88 88.6 %
Date: 2025-07-25 05:00:39 Functions: 8 10 80.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : 
      10             : #include "InertialForce.h"
      11             : #include "SubProblem.h"
      12             : #include "TimeIntegrator.h"
      13             : #include "NonlinearSystemBase.h"
      14             : 
      15             : registerMooseObject("SolidMechanicsApp", InertialForce);
      16             : registerMooseObject("SolidMechanicsApp", ADInertialForce);
      17             : 
      18             : template <bool is_ad>
      19             : InputParameters
      20        1430 : InertialForceTempl<is_ad>::validParams()
      21             : {
      22        1430 :   InputParameters params = InertialForceParent<is_ad>::validParams();
      23        1430 :   params.addClassDescription("Calculates the residual for the inertial force "
      24             :                              "($M \\cdot acceleration$) and the contribution of mass"
      25             :                              " dependent Rayleigh damping and HHT time "
      26             :                              " integration scheme ($\\eta \\cdot M \\cdot"
      27             :                              " ((1+\\alpha)velq2-\\alpha \\cdot vel-old) $)");
      28        1430 :   params.set<bool>("use_displaced_mesh") = true;
      29        2860 :   params.addCoupledVar("velocity", "velocity variable");
      30        2860 :   params.addCoupledVar("acceleration", "acceleration variable");
      31        2860 :   params.addParam<Real>("beta", "beta parameter for Newmark Time integration");
      32        2860 :   params.addParam<Real>("gamma", "gamma parameter for Newmark Time integration");
      33        2860 :   params.addParam<MaterialPropertyName>("eta",
      34        2860 :                                         0.0,
      35             :                                         "Name of material property or a constant real "
      36             :                                         "number defining the eta parameter for the "
      37             :                                         "Rayleigh damping.");
      38        2860 :   params.addParam<MaterialPropertyName>(
      39             :       "density_scaling",
      40        2860 :       0.0,
      41             :       "Name of material property to add mass scaling in explicit simulations.");
      42        2860 :   params.addParam<Real>("alpha",
      43        2860 :                         0,
      44             :                         "alpha parameter for mass dependent numerical damping induced "
      45             :                         "by HHT time integration scheme");
      46        2860 :   params.addParam<MaterialPropertyName>(
      47             :       "density", "density", "Name of Material Property that provides the density");
      48        1430 :   return params;
      49           0 : }
      50             : 
      51             : template <bool is_ad>
      52         714 : InertialForceTempl<is_ad>::InertialForceTempl(const InputParameters & parameters)
      53             :   : InertialForceParent<is_ad>(parameters),
      54         714 :     _density(this->template getGenericMaterialProperty<Real, is_ad>("density")),
      55        1428 :     _has_beta(this->isParamValid("beta")),
      56        1428 :     _has_gamma(this->isParamValid("gamma")),
      57        1176 :     _beta(_has_beta ? this->template getParam<Real>("beta") : 0.1),
      58        1176 :     _gamma(_has_gamma ? this->template getParam<Real>("gamma") : 0.1),
      59        1428 :     _has_velocity(this->isParamValid("velocity")),
      60        1428 :     _has_acceleration(this->isParamValid("acceleration")),
      61        1428 :     _eta(this->template getGenericMaterialProperty<Real, is_ad>("eta")),
      62        1428 :     _density_scaling(this->template getMaterialProperty<Real>("density_scaling")),
      63        1428 :     _alpha(this->template getParam<Real>("alpha")),
      64        1428 :     _time_integrator(_sys.getTimeIntegrator(this->_var.number()))
      65             : {
      66         714 :   if (_has_beta && _has_gamma && _has_velocity && _has_acceleration)
      67             :   {
      68         462 :     _vel_old = &this->coupledValueOld("velocity");
      69         462 :     _accel_old = &this->coupledValueOld("acceleration");
      70         462 :     _u_old = &this->valueOld();
      71             :   }
      72         252 :   else if (!_has_beta && !_has_gamma && !_has_velocity && !_has_acceleration)
      73             :   {
      74         252 :     _u_dot_old = &(_var.uDotOld());
      75         252 :     _du_dot_du = &(_var.duDotDu());
      76         252 :     _du_dotdot_du = &(_var.duDotDotDu());
      77             : 
      78         252 :     this->addFEVariableCoupleableVectorTag(_time_integrator.uDotFactorTag());
      79         252 :     this->addFEVariableCoupleableVectorTag(_time_integrator.uDotDotFactorTag());
      80             : 
      81         252 :     _u_dot_factor = &_var.vectorTagValue(_time_integrator.uDotFactorTag());
      82         252 :     _u_dotdot_factor = &_var.vectorTagValue(_time_integrator.uDotDotFactorTag());
      83             : 
      84         252 :     if (_time_integrator.isLumped())
      85             :     {
      86         108 :       _u_dot_factor_dof = &_var.vectorTagDofValue(_time_integrator.uDotFactorTag());
      87         108 :       _u_dotdot_factor_dof = &_var.vectorTagDofValue(_time_integrator.uDotDotFactorTag());
      88             :     }
      89             :   }
      90             :   else
      91           0 :     mooseError("InertialForce: Either all or none of `beta`, `gamma`, `velocity`and `acceleration` "
      92             :                "should be provided as input.");
      93             : 
      94             :   // Check if HHT and explicit are being used simultaneously
      95         714 :   if (_alpha != 0 && _time_integrator.isExplicit())
      96           0 :     mooseError("InertialForce: HHT time integration parameter can only be used with Newmark-Beta "
      97             :                "time integration.");
      98             : 
      99             :   // Check if beta and explicit are being used simultaneously
     100         714 :   if (_has_beta && _time_integrator.isExplicit())
     101           0 :     mooseError("InertialForce: Newmark-beta integration parameter, beta, cannot be provided along "
     102             :                "with an explicit time "
     103             :                "integrator.");
     104             : 
     105         714 :   if (!(_time_integrator.isLumped() && _time_integrator.isExplicit()))
     106        1212 :     if (parameters.isParamSetByUser("density_scaling"))
     107           0 :       this->paramError(
     108             :           "density_scaling",
     109             :           "Density (mass) scaling can only be used in lumped mass, explicit simulations");
     110         714 : }
     111             : 
     112             : template <bool is_ad>
     113             : GenericReal<is_ad>
     114    41598752 : InertialForceTempl<is_ad>::computeQpResidual()
     115             : {
     116    41598752 :   if (_dt == 0)
     117           0 :     return 0;
     118    41598752 :   else if (_has_beta)
     119             :   {
     120    39017088 :     auto accel = 1.0 / _beta *
     121    38971008 :                  (((_u[_qp] - (*_u_old)[_qp]) / (_dt * _dt)) - (*_vel_old)[_qp] / _dt -
     122    38971008 :                   (*_accel_old)[_qp] * (0.5 - _beta));
     123    38971008 :     auto vel =
     124    39063168 :         (*_vel_old)[_qp] + (_dt * (1.0 - _gamma)) * (*_accel_old)[_qp] + _gamma * _dt * accel;
     125    38971008 :     return _test[_i][_qp] * _density[_qp] *
     126    39063168 :            (accel + vel * _eta[_qp] * (1.0 + _alpha) - _alpha * _eta[_qp] * (*_vel_old)[_qp]);
     127             :   }
     128             : 
     129             :   // Lumped mass option
     130             :   // Only lumping the masses here
     131             :   // will multiply by corresponding residual multiplier after lumping the matrix
     132             :   // Density scaling is a fictitious added density to increase the time step
     133     2627744 :   else if (_time_integrator.isLumped() && _time_integrator.isExplicit() && !is_ad)
     134       84544 :     return _test[_i][_qp] * (_density[_qp] + _density_scaling[_qp]);
     135             : 
     136             :   // Consistent mass option
     137             :   // Same for explicit, implicit, and implicit with HHT
     138             :   else
     139     2543200 :     return _test[_i][_qp] * _density[_qp] *
     140     2543200 :            ((*_u_dotdot_factor)[_qp] + (*_u_dot_factor)[_qp] * _eta[_qp] * (1.0 + _alpha) -
     141     2543200 :             _alpha * _eta[_qp] * (*_u_dot_old)[_qp]);
     142             : }
     143             : 
     144             : template <>
     145             : void
     146           0 : InertialForceTempl<true>::computeResidualAdditional()
     147             : {
     148           0 :   mooseError("Internal error");
     149             : }
     150             : 
     151             : template <>
     152             : void
     153     1020428 : InertialForceTempl<false>::computeResidualAdditional()
     154             : {
     155     1020428 :   if (_dt == 0)
     156             :     return;
     157             : 
     158             :   // Explicit lumped only
     159     1020428 :   if (!_time_integrator.isLumped() || !_time_integrator.isExplicit())
     160     1017796 :     return;
     161             : 
     162       15816 :   for (unsigned int i = 0; i < _test.size(); ++i)
     163       13184 :     this->_local_re(i) *= (*_u_dotdot_factor_dof)[i] + _eta[0] * (*_u_dot_factor_dof)[i];
     164             : }
     165             : 
     166             : template <>
     167             : Real
     168           0 : InertialForceTempl<true>::computeQpJacobian()
     169             : {
     170           0 :   mooseError("Internal error");
     171             : }
     172             : 
     173             : template <>
     174             : Real
     175    60277248 : InertialForceTempl<false>::computeQpJacobian()
     176             : {
     177    60277248 :   if (_dt == 0)
     178             :     return 0;
     179             :   else
     180             :   {
     181    60277248 :     if (_has_beta)
     182    56037376 :       return _test[_i][_qp] * _density[_qp] / (_beta * _dt * _dt) * _phi[this->_j][_qp] +
     183    56037376 :              _eta[_qp] * (1 + _alpha) * _test[_i][_qp] * _density[_qp] * _gamma / _beta / _dt *
     184    56037376 :                  _phi[this->_j][_qp];
     185             :     else
     186     4239872 :       return _test[_i][_qp] * _density[_qp] * (*_du_dotdot_du)[_qp] * _phi[this->_j][_qp] +
     187     4239872 :              _eta[_qp] * (1 + _alpha) * _test[_i][_qp] * _density[_qp] * (*_du_dot_du)[_qp] *
     188     4239872 :                  _phi[this->_j][_qp];
     189             :   }
     190             : }
     191             : 
     192             : template class InertialForceTempl<false>;
     193             : template class InertialForceTempl<true>;

Generated by: LCOV version 1.14