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>;