LCOV - code coverage report
Current view: top level - src/actions - LineElementAction.C (source / functions) Hit Total Coverage
Test: idaholab/moose solid_mechanics: f45d79 Lines: 344 363 94.8 %
Date: 2025-07-25 05:00:39 Functions: 11 11 100.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 "Conversion.h"
      11             : #include "FEProblem.h"
      12             : #include "Factory.h"
      13             : #include "MooseMesh.h"
      14             : #include "MooseObjectAction.h"
      15             : #include "LineElementAction.h"
      16             : #include "CommonLineElementAction.h"
      17             : #include "MooseApp.h"
      18             : #include "InputParameterWarehouse.h"
      19             : 
      20             : #include "libmesh/string_to_enum.h"
      21             : #include <algorithm>
      22             : 
      23             : using namespace libMesh;
      24             : 
      25             : registerMooseAction("SolidMechanicsApp", LineElementAction, "create_problem");
      26             : registerMooseAction("SolidMechanicsApp", LineElementAction, "add_variable");
      27             : registerMooseAction("SolidMechanicsApp", LineElementAction, "add_aux_variable");
      28             : registerMooseAction("SolidMechanicsApp", LineElementAction, "add_kernel");
      29             : registerMooseAction("SolidMechanicsApp", LineElementAction, "add_aux_kernel");
      30             : registerMooseAction("SolidMechanicsApp", LineElementAction, "add_nodal_kernel");
      31             : registerMooseAction("SolidMechanicsApp", LineElementAction, "add_material");
      32             : 
      33             : InputParameters
      34         380 : LineElementAction::validParams()
      35             : {
      36         380 :   InputParameters params = Action::validParams();
      37         380 :   params.addClassDescription("Sets up variables, stress divergence kernels and materials required "
      38             :                              "for a static analysis with beam or truss elements. Also sets up aux "
      39             :                              "variables, aux kernels, and consistent or nodal inertia kernels for "
      40             :                              "dynamic analysis with beam elements.");
      41             : 
      42         760 :   params.addParam<bool>(
      43             :       "truss",
      44         760 :       false,
      45             :       "Set to true if the line elements are truss elements instead of the default beam elements.");
      46         760 :   params.addParam<bool>("add_variables",
      47         760 :                         false,
      48             :                         "Add the displacement variables for truss elements "
      49             :                         "and both displacement and rotation variables for "
      50             :                         "beam elements.");
      51         760 :   params.addParam<std::vector<VariableName>>(
      52             :       "displacements", "The nonlinear displacement variables for the problem");
      53             : 
      54             :   // Common geometry parameters between beam and truss
      55         760 :   params.addCoupledVar(
      56             :       "area",
      57             :       "Cross-section area of the beam. Can be supplied as either a number or a variable name.");
      58             : 
      59             :   // Beam Parameters
      60         380 :   params += LineElementAction::beamParameters();
      61             : 
      62         760 :   params.addParam<bool>(
      63         760 :       "use_displaced_mesh", false, "Whether to use displaced mesh in the kernels");
      64             :   // parameters specified here only appear in the input file sub-blocks of the
      65             :   // Master action, not in the common parameters area
      66         760 :   params.addParam<std::vector<SubdomainName>>(
      67             :       "block",
      68             :       {},
      69             :       "The list of ids of the blocks (subdomain) "
      70             :       "that the stress divergence, inertia kernels and materials will be "
      71             :       "applied to");
      72             :   // Advanced
      73         760 :   params.addParam<std::vector<AuxVariableName>>(
      74             :       "save_in", {}, "The displacement and rotational residuals");
      75         760 :   params.addParam<std::vector<AuxVariableName>>(
      76             :       "diag_save_in", {}, "The displacement and rotational diagonal preconditioner terms");
      77         760 :   params.addParamNamesToGroup("block", "Advanced");
      78         380 :   return params;
      79           0 : }
      80             : 
      81             : InputParameters
      82         380 : LineElementAction::beamParameters()
      83             : {
      84         380 :   InputParameters params = emptyInputParameters();
      85             : 
      86         760 :   params.addParam<std::vector<VariableName>>(
      87             :       "rotations", "The rotations appropriate for the simulation geometry and coordinate system");
      88             : 
      89         760 :   MooseEnum strainType("SMALL FINITE", "SMALL");
      90         760 :   params.addParam<MooseEnum>("strain_type", strainType, "Strain formulation");
      91         760 :   params.addParam<MooseEnum>("rotation_type", strainType, "Rotation formulation");
      92         760 :   params.addParam<std::vector<MaterialPropertyName>>(
      93             :       "eigenstrain_names", "List of beam eigenstrains to be applied in this strain calculation.");
      94             : 
      95             :   // Beam geometry
      96         760 :   params.addParam<RealGradient>("y_orientation",
      97             :                                 "Orientation of the y direction along "
      98             :                                 "which Iyy is provided. This should be "
      99             :                                 "perpendicular to the axis of the beam.");
     100         760 :   params.addCoupledVar(
     101             :       "area",
     102             :       "Cross-section area of the beam. Can be supplied as either a number or a variable name.");
     103         760 :   params.addCoupledVar("Ay",
     104             :                        0.0,
     105             :                        "First moment of area of the beam about y axis. Can be supplied "
     106             :                        "as either a number or a variable name.");
     107         760 :   params.addCoupledVar("Az",
     108             :                        0.0,
     109             :                        "First moment of area of the beam about z axis. Can be supplied "
     110             :                        "as either a number or a variable name.");
     111         760 :   params.addCoupledVar("Ix",
     112             :                        "Second moment of area of the beam about x axis. Can be supplied as "
     113             :                        "either a number or a variable name.");
     114         760 :   params.addCoupledVar("Iy",
     115             :                        "Second moment of area of the beam about y axis. Can be supplied as "
     116             :                        "either a number or a variable name.");
     117         760 :   params.addCoupledVar("Iz",
     118             :                        "Second moment of area of the beam about z axis. Can be supplied as "
     119             :                        "either a number or a variable name.");
     120             : 
     121             :   // Common parameters for both dynamic consistent and nodal mass/inertia
     122         760 :   params.addParam<bool>("add_dynamic_variables",
     123             :                         "Adds translational and rotational velocity and acceleration aux variables "
     124             :                         "and sets up the corresponding AuxKernels for calculating these variables "
     125             :                         "using Newmark time integration. When dynamic_consistent_inertia, "
     126             :                         "dynamic_nodal_rotational_inertia or dynamic_nodal_translational_inertia "
     127             :                         "are set to true, these variables are automatically set up.");
     128             : 
     129         760 :   params.addParam<std::vector<VariableName>>("velocities", "Translational velocity variables");
     130         760 :   params.addParam<std::vector<VariableName>>("accelerations",
     131             :                                              "Translational acceleration variables");
     132         760 :   params.addParam<std::vector<VariableName>>("rotational_velocities",
     133             :                                              "Rotational velocity variables");
     134         760 :   params.addParam<std::vector<VariableName>>("rotational_accelerations",
     135             :                                              "Rotational acceleration variables");
     136         760 :   params.addRangeCheckedParam<Real>(
     137             :       "beta", "beta>0.0", "beta parameter for Newmark Time integration");
     138         760 :   params.addRangeCheckedParam<Real>(
     139             :       "gamma", "gamma>0.0", "gamma parameter for Newmark Time integration");
     140         760 :   params.addParam<MaterialPropertyName>("eta",
     141         760 :                                         0.0,
     142             :                                         "Name of material property or a constant real "
     143             :                                         "number defining the eta parameter for mass proportional "
     144             :                                         "Rayleigh damping.");
     145         760 :   params.addParam<MaterialPropertyName>(
     146             :       "zeta",
     147         760 :       0.0,
     148             :       "Name of material property or a constant real "
     149             :       "number defining the zeta parameter for stiffness proportional "
     150             :       "Rayleigh damping.");
     151         760 :   params.addRangeCheckedParam<Real>("alpha",
     152             :                                     0,
     153             :                                     "alpha>=-0.3333 & alpha<=0.0",
     154             :                                     "alpha parameter for mass dependent numerical damping induced "
     155             :                                     "by HHT time integration scheme");
     156             : 
     157             :   // dynamic consistent mass/inertia
     158         760 :   params.addParam<bool>("dynamic_consistent_inertia",
     159         760 :                         false,
     160             :                         "If set to true, consistent mass and "
     161             :                         "inertia matrices are used for the "
     162             :                         "inertial force/torque calculations.");
     163         760 :   params.addParam<MaterialPropertyName>(
     164             :       "density",
     165             :       "Name of Material Property or a constant real number defining the density of the beam.");
     166             : 
     167             :   // dynamic nodal translational inertia
     168         760 :   params.addParam<bool>(
     169             :       "dynamic_nodal_translational_inertia",
     170         760 :       false,
     171             :       "If set to true, nodal mass matrix is used for the inertial force calculation.");
     172         760 :   params.addRangeCheckedParam<Real>(
     173             :       "nodal_mass", "nodal_mass>0.0", "Mass associated with the node");
     174         760 :   params.addParam<FileName>(
     175             :       "nodal_mass_file",
     176             :       "The file containing the nodal positions and the corresponding nodal masses.");
     177             : 
     178             :   // dynamic nodal rotational inertia
     179         760 :   params.addParam<bool>(
     180             :       "dynamic_nodal_rotational_inertia",
     181         760 :       false,
     182             :       "If set to true, nodal inertia matrix is used for the inertial torque calculation.");
     183         760 :   params.addRangeCheckedParam<Real>(
     184             :       "nodal_Ixx", "nodal_Ixx>=0.0", "Nodal moment of inertia in the x direction.");
     185         760 :   params.addRangeCheckedParam<Real>(
     186             :       "nodal_Iyy", "nodal_Iyy>=0.0", "Nodal moment of inertia in the y direction.");
     187         760 :   params.addRangeCheckedParam<Real>(
     188             :       "nodal_Izz", "nodal_Izz>=0.0", "Nodal moment of inertia in the z direction.");
     189         760 :   params.addParam<Real>("nodal_Ixy", 0.0, "Nodal moment of inertia in the xy direction.");
     190         760 :   params.addParam<Real>("nodal_Ixz", 0.0, "Nodal moment of inertia in the xz direction.");
     191         760 :   params.addParam<Real>("nodal_Iyz", 0.0, "Nodal moment of inertia in the yz direction.");
     192         760 :   params.addParam<RealGradient>(
     193             :       "nodal_x_orientation",
     194             :       "Unit vector along the x direction if different from global x direction.");
     195         760 :   params.addParam<RealGradient>(
     196             :       "nodal_y_orientation",
     197             :       "Unit vector along the y direction if different from global y direction.");
     198         760 :   params.addParam<std::vector<BoundaryName>>(
     199             :       "boundary",
     200             :       {},
     201             :       "The list of boundary IDs from the mesh where the nodal "
     202             :       "mass/inertia will be applied.");
     203         380 :   return params;
     204         380 : }
     205             : 
     206         198 : LineElementAction::LineElementAction(const InputParameters & params)
     207             :   : Action(params),
     208         198 :     _rotations(0),
     209         198 :     _velocities(0),
     210         198 :     _accelerations(0),
     211         198 :     _rot_velocities(0),
     212         198 :     _rot_accelerations(0),
     213         594 :     _subdomain_names(getParam<std::vector<SubdomainName>>("block")),
     214             :     _subdomain_ids(),
     215         396 :     _add_dynamic_variables(false)
     216             : {
     217             :   // FIXME: suggest to use action of action to add this to avoid changing the input parameters in
     218             :   // the warehouse.
     219         198 :   const auto & parameters = _app.getInputParameterWarehouse().getInputParameters();
     220         198 :   InputParameters & pars(*(parameters.find(uniqueActionName())->second.get()));
     221             : 
     222             :   // check if a container block with common parameters is found
     223         198 :   auto action = _awh.getActions<CommonLineElementAction>();
     224         198 :   if (action.size() == 1)
     225         198 :     pars.applyParameters(action[0]->parameters());
     226             : 
     227             :   // Set values to variables after common parameters are applied
     228         396 :   _save_in = getParam<std::vector<AuxVariableName>>("save_in");
     229         396 :   _diag_save_in = getParam<std::vector<AuxVariableName>>("diag_save_in");
     230         396 :   _strain_type = getParam<MooseEnum>("strain_type").getEnum<Strain>();
     231         396 :   _rotation_type = getParam<MooseEnum>("rotation_type").getEnum<Strain>();
     232         396 :   _dynamic_consistent_inertia = getParam<bool>("dynamic_consistent_inertia");
     233         396 :   _dynamic_nodal_translational_inertia = getParam<bool>("dynamic_nodal_translational_inertia");
     234         396 :   _dynamic_nodal_rotational_inertia = getParam<bool>("dynamic_nodal_rotational_inertia");
     235         198 :   if (_dynamic_consistent_inertia || _dynamic_nodal_rotational_inertia ||
     236         152 :       _dynamic_nodal_translational_inertia)
     237          48 :     _add_dynamic_variables = true;
     238             : 
     239         396 :   if (params.isParamSetByUser("add_dynamic_variables"))
     240             :   {
     241          16 :     bool user_defined_add_dynamic_variables = getParam<bool>("add_dynamic_variables");
     242           8 :     if (!_add_dynamic_variables && user_defined_add_dynamic_variables)
     243           6 :       _add_dynamic_variables = true;
     244           2 :     else if (_add_dynamic_variables && !user_defined_add_dynamic_variables)
     245           2 :       mooseError("LineElementAction: When using 'dynamic_consistent_inertia', "
     246             :                  "'dynamic_nodal_rotational_inertia' or '_dynamic_nodal_translational_inertia', "
     247             :                  "the velocity and acceleration AuxVariables and the corresponding AuxKernels are "
     248             :                  "automatically set by the action and this cannot be turned off by setting "
     249             :                  "'add_dynamic_variables' to false.");
     250             :   }
     251         392 :   _truss = getParam<bool>("truss");
     252             : 
     253         392 :   if (!isParamValid("displacements"))
     254           2 :     paramError("displacements",
     255             :                "LineElementAction: A vector of displacement variable names should be provided as "
     256             :                "input using `displacements`.");
     257             : 
     258         582 :   _displacements = getParam<std::vector<VariableName>>("displacements");
     259         194 :   _ndisp = _displacements.size();
     260             : 
     261             :   // determine if displaced mesh is to be used
     262         194 :   _use_displaced_mesh = (_strain_type != Strain::SMALL && _rotation_type != Strain::SMALL);
     263         388 :   if (params.isParamSetByUser("use_displaced_mesh"))
     264             :   {
     265           4 :     bool use_displaced_mesh_param = getParam<bool>("use_displaced_mesh");
     266           4 :     if (use_displaced_mesh_param != _use_displaced_mesh && params.isParamSetByUser("strain_type") &&
     267           4 :         params.isParamSetByUser("rotation_type"))
     268           2 :       paramError("use_displaced_mesh",
     269             :                  "LineElementAction: Wrong combination of "
     270             :                  "`use_displaced_mesh`, `strain_type` and `rotation_type`.");
     271           0 :     _use_displaced_mesh = use_displaced_mesh_param;
     272             :   }
     273             : 
     274         192 :   if (_save_in.size() != 0 && _save_in.size() != _ndisp)
     275           2 :     paramError("save_in",
     276             :                "LineElementAction: Number of save_in variables should equal to the number of "
     277             :                "displacement variables ",
     278             :                _ndisp);
     279             : 
     280         190 :   if (_diag_save_in.size() != 0 && _diag_save_in.size() != _ndisp)
     281           2 :     paramError("diag_save_in",
     282             :                "LineElementAction: Number of diag_save_in variables should equal to the number of "
     283             :                "displacement variables ",
     284             :                _ndisp);
     285             : 
     286             :   // Check if all the parameters required for static and dynamic beam simulation are provided as
     287             :   // input
     288         188 :   if (!_truss)
     289             :   {
     290             :     // Parameters required for static simulation using beams
     291         336 :     if (!isParamValid("rotations"))
     292           2 :       paramError("rotations",
     293             :                  "LineElementAction: Rotational variable names should be provided for beam "
     294             :                  "elements using `rotations` parameter.");
     295             : 
     296         498 :     _rotations = getParam<std::vector<VariableName>>("rotations");
     297             : 
     298         166 :     if (_rotations.size() != _ndisp)
     299           2 :       paramError("rotations",
     300             :                  "LineElementAction: Number of rotational and displacement variable names provided "
     301             :                  "as input for beam should be same.");
     302             : 
     303        1144 :     if (!isParamValid("y_orientation") || !isParamValid("area") || !isParamValid("Iy") ||
     304         488 :         !isParamValid("Iz"))
     305           2 :       mooseError("LineElementAction: `y_orientation`, `area`, `Iy` and `Iz` should be provided for "
     306             :                  "beam elements.");
     307             : 
     308             :     // Parameters required for dynamic simulation using beams
     309         162 :     if (_add_dynamic_variables)
     310             :     {
     311         184 :       if (!isParamValid("velocities") || !isParamValid("accelerations") ||
     312         214 :           !isParamValid("rotational_velocities") || !isParamValid("rotational_accelerations"))
     313           4 :         mooseError(
     314             :             "LineElementAction: Variable names for translational and rotational velocities "
     315             :             "and accelerations should be provided as input to perform dynamic simulation "
     316             :             "using beam elements using `velocities`, `accelerations`, `rotational_velocities` and "
     317             :             "`rotational_accelerations`.");
     318             : 
     319          68 :       _velocities = getParam<std::vector<VariableName>>("velocities");
     320          68 :       _accelerations = getParam<std::vector<VariableName>>("accelerations");
     321          68 :       _rot_velocities = getParam<std::vector<VariableName>>("rotational_velocities");
     322         102 :       _rot_accelerations = getParam<std::vector<VariableName>>("rotational_accelerations");
     323             : 
     324          34 :       if (_velocities.size() != _ndisp || _accelerations.size() != _ndisp ||
     325          66 :           _rot_velocities.size() != _ndisp || _rot_accelerations.size() != _ndisp)
     326           2 :         mooseError("LineElementAction: Number of translational and rotational velocity and "
     327             :                    "acceleration variable names provided as input for the beam should be same as "
     328             :                    "number of displacement variables.");
     329             : 
     330         124 :       if (!isParamValid("beta") || !isParamValid("gamma"))
     331           2 :         mooseError("LineElementAction: Newmark time integration parameters `beta` and `gamma` "
     332             :                    "should be provided as input to perform dynamic simulations using beams.");
     333             :     }
     334             : 
     335         200 :     if (_dynamic_consistent_inertia && !isParamValid("density"))
     336           2 :       paramError("density",
     337             :                  "LineElementAction: Either name of the density material property or a constant "
     338             :                  "density value should be provided as input using `density` for creating the "
     339             :                  "consistent mass/inertia matrix required for dynamic beam simulation.");
     340             : 
     341         168 :     if (_dynamic_nodal_translational_inertia &&
     342         188 :         (!isParamValid("nodal_mass") && !isParamValid("nodal_mass_file")))
     343           2 :       paramError("nodal_mass",
     344             :                  "LineElementAction: `nodal_mass` or `nodal_mass_file` should be provided as input "
     345             :                  "to calculate "
     346             :                  "inertial forces on beam due to nodal mass.");
     347             : 
     348         164 :     if (_dynamic_nodal_rotational_inertia &&
     349         226 :         ((!isParamValid("nodal_Ixx") || !isParamValid("nodal_Iyy") || !isParamValid("nodal_Izz"))))
     350           2 :       mooseError("LineElementAction: `nodal_Ixx`, `nodal_Iyy`, `nodal_Izz` should be provided as "
     351             :                  "input to calculate inertial torque on beam due to nodal inertia.");
     352             :   }
     353             :   else // if truss
     354             :   {
     355          40 :     if (!isParamValid("area"))
     356           2 :       paramError("area",
     357             :                  "LineElementAction: `area` should be provided as input for "
     358             :                  "truss elements.");
     359             : 
     360          36 :     if (isParamValid("rotations"))
     361           2 :       paramError("rotations",
     362             :                  "LineElementAction: Rotational variables cannot be set for truss elements.");
     363             :   }
     364         164 : }
     365             : 
     366             : void
     367        1112 : LineElementAction::act()
     368             : {
     369             :   // Get the subdomain involved in the action once the mesh setup is complete
     370        1112 :   if (_current_task == "create_problem")
     371             :   {
     372             :     // get subdomain IDs
     373         236 :     for (auto & name : _subdomain_names)
     374          72 :       _subdomain_ids.insert(_mesh->getSubdomainID(name));
     375             :   }
     376             : 
     377        1112 :   if (_current_task == "add_variable")
     378             :   {
     379             :     //
     380             :     // Gather info from all other LineElementAction
     381             :     //
     382         160 :     actGatherActionParameters();
     383             : 
     384             :     //
     385             :     // Add variables (optional)
     386             :     //
     387         156 :     actAddVariables();
     388             :   }
     389             : 
     390             :   //
     391             :   // Add Materials - ComputeIncrementalBeamStrain or ComputeFiniteBeamStrain
     392             :   // for beam elements
     393             :   //
     394        1108 :   if (_current_task == "add_material")
     395         156 :     actAddMaterials();
     396             : 
     397             :   //
     398             :   // Add Kernels - StressDivergenceBeam and InertialForceBeam (if dynamic_consistent_inertia is
     399             :   // turned on) for beams and StressDivergenceTensorsTruss for truss elements
     400             :   //
     401        1108 :   if (_current_task == "add_kernel")
     402         156 :     actAddKernels();
     403             : 
     404             :   //
     405             :   // Add aux variables for translational and Rotational velocities and acceleration for dynamic
     406             :   // analysis using beams
     407             :   //
     408        1108 :   if (_current_task == "add_aux_variable")
     409         164 :     actAddAuxVariables();
     410             : 
     411             :   //
     412             :   // Add NewmarkVelAux and NewarkAccelAux auxkernels for dynamic simulation using beams
     413             :   //
     414        1108 :   if (_current_task == "add_aux_kernel")
     415         156 :     actAddAuxKernels();
     416             : 
     417             :   //
     418             :   // Add NodalKernels - NodalTranslationalInertia (if dynamic_nodal_translational_inertia is turned
     419             :   // on) and NodalRotattionalInertia (if dynamic_nodal_rotational_inertia) for dynamic simulations
     420             :   // using beams
     421             :   //
     422        1108 :   if (_current_task == "add_nodal_kernel")
     423         156 :     actAddNodalKernels();
     424        1106 : }
     425             : 
     426             : void
     427         160 : LineElementAction::actGatherActionParameters()
     428             : {
     429             :   //
     430             :   // Gather info about all other master actions when we add variables
     431             :   //
     432         320 :   if (getParam<bool>("add_variables"))
     433             :   {
     434         154 :     auto actions = _awh.getActions<LineElementAction>();
     435         332 :     for (const auto & action : actions)
     436             :     {
     437             :       const auto size_before = _subdomain_id_union.size();
     438         182 :       const auto added_size = action->_subdomain_ids.size();
     439         182 :       _subdomain_id_union.insert(action->_subdomain_ids.begin(), action->_subdomain_ids.end());
     440             :       const auto size_after = _subdomain_id_union.size();
     441             : 
     442         182 :       if (size_after != size_before + added_size)
     443           2 :         paramError("block",
     444             :                    "LineElementAction: The block restrictions in the LineElement actions must be "
     445             :                    "non-overlapping.");
     446             : 
     447         180 :       if (added_size == 0 && actions.size() > 1)
     448           2 :         paramError(
     449             :             "block",
     450             :             "LineElementAction: No LineElement action can be block unrestricted if more than one "
     451             :             "LineElement action is specified.");
     452             :     }
     453             :   }
     454         156 : }
     455             : 
     456             : void
     457         156 : LineElementAction::actAddVariables()
     458             : {
     459         312 :   if (getParam<bool>("add_variables"))
     460             :   {
     461         150 :     auto params = _factory.getValidParams("MooseVariable");
     462             : 
     463             :     // determine order of elements in mesh
     464         150 :     const bool second = _problem->mesh().hasSecondOrderElements();
     465         150 :     if (second)
     466           0 :       mooseError("LineElementAction: Only linear truss and beam elements are currently supported. "
     467             :                  "Please change the order of elements in the mesh to use first order elements.");
     468             : 
     469         300 :     params.set<MooseEnum>("order") = "FIRST";
     470         300 :     params.set<MooseEnum>("family") = "LAGRANGE";
     471             : 
     472             :     // Loop through the displacement variables
     473         596 :     for (const auto & disp : _displacements)
     474             :     {
     475             :       // Create displacement variables
     476         446 :       if (!_problem->hasVariable(disp))
     477         820 :         _problem->addVariable("MooseVariable", disp, params);
     478             :     }
     479             : 
     480             :     // Add rotation variables if line element is a beam.
     481         150 :     if (!_truss)
     482             :     {
     483         560 :       for (const auto & rot : _rotations)
     484             :       {
     485             :         // Create rotation variables
     486         420 :         if (!_problem->hasVariable(rot))
     487         768 :           _problem->addVariable("MooseVariable", rot, params);
     488             :       }
     489             :     }
     490         150 :   }
     491         156 : }
     492             : 
     493             : void
     494         156 : LineElementAction::actAddMaterials()
     495             : {
     496         156 :   if (!_truss)
     497             :   {
     498             :     // Add Strain
     499         140 :     if (_rotation_type == Strain::SMALL)
     500             :     {
     501         134 :       auto params = _factory.getValidParams("ComputeIncrementalBeamStrain");
     502         402 :       params.applyParameters(parameters(), {"boundary", "use_displaced_mesh"});
     503         134 :       params.set<bool>("use_displaced_mesh") = false;
     504             : 
     505         134 :       if (_strain_type == Strain::FINITE)
     506           0 :         params.set<bool>("large_strain") = true;
     507             : 
     508         268 :       _problem->addMaterial("ComputeIncrementalBeamStrain", name() + "_strain", params);
     509         134 :     }
     510           6 :     else if (_rotation_type == Strain::FINITE)
     511             :     {
     512           6 :       auto params = _factory.getValidParams("ComputeFiniteBeamStrain");
     513          18 :       params.applyParameters(parameters(), {"boundary", "use_displaced_mesh"});
     514           6 :       params.set<bool>("use_displaced_mesh") = false;
     515             : 
     516           6 :       if (_strain_type == Strain::FINITE)
     517           6 :         params.set<bool>("large_strain") = true;
     518             : 
     519          12 :       _problem->addMaterial("ComputeFiniteBeamStrain", name() + "_strain", params);
     520           6 :     }
     521             :   }
     522         436 : }
     523             : 
     524             : void
     525         156 : LineElementAction::actAddKernels()
     526             : {
     527         156 :   if (!_truss)
     528             :   {
     529             :     // add StressDivergenceBeam kernels
     530         140 :     auto params = _factory.getValidParams("StressDivergenceBeam");
     531         560 :     params.applyParameters(parameters(), {"use_displaced_mesh", "save_in", "diag_save_in"});
     532         140 :     params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
     533             : 
     534         980 :     for (unsigned int i = 0; i < 2 * _ndisp; ++i)
     535             :     {
     536        1680 :       std::string kernel_name = name() + "_stress_divergence_beam_" + Moose::stringify(i);
     537             : 
     538         840 :       if (i < _ndisp)
     539             :       {
     540         420 :         params.set<unsigned int>("component") = i;
     541         840 :         params.set<NonlinearVariableName>("variable") = _displacements[i];
     542             : 
     543         420 :         if (_save_in.size() == 2 * _ndisp)
     544           0 :           params.set<std::vector<AuxVariableName>>("save_in") = {_save_in[i]};
     545         420 :         if (_diag_save_in.size() == 2 * _ndisp)
     546           0 :           params.set<std::vector<AuxVariableName>>("diag_save_in") = {_diag_save_in[i]};
     547             : 
     548         840 :         _problem->addKernel("StressDivergenceBeam", kernel_name, params);
     549             :       }
     550             :       else
     551             :       {
     552         420 :         params.set<unsigned int>("component") = i;
     553         840 :         params.set<NonlinearVariableName>("variable") = _rotations[i - 3];
     554             : 
     555         420 :         if (_save_in.size() == 2 * _ndisp)
     556           0 :           params.set<std::vector<AuxVariableName>>("save_in") = {_save_in[i]};
     557         420 :         if (_diag_save_in.size() == 2 * _ndisp)
     558           0 :           params.set<std::vector<AuxVariableName>>("diag_save_in") = {_diag_save_in[i]};
     559             : 
     560         840 :         _problem->addKernel("StressDivergenceBeam", kernel_name, params);
     561             :       }
     562             :     }
     563             :     // Add InertialForceBeam if dynamic simulation using consistent mass/inertia matrix has to be
     564             :     // performed
     565         140 :     if (_dynamic_consistent_inertia)
     566             :     {
     567             :       // add InertialForceBeam
     568           6 :       params = _factory.getValidParams("InertialForceBeam");
     569          24 :       params.applyParameters(parameters(), {"use_displaced_mesh", "save_in", "diag_save_in"});
     570           6 :       params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
     571             : 
     572          42 :       for (unsigned int i = 0; i < 2 * _ndisp; ++i)
     573             :       {
     574          72 :         std::string kernel_name = name() + "_inertial_force_beam_" + Moose::stringify(i);
     575             : 
     576          36 :         if (i < _ndisp)
     577             :         {
     578          18 :           params.set<unsigned int>("component") = i;
     579          36 :           params.set<NonlinearVariableName>("variable") = _displacements[i];
     580             : 
     581          18 :           if (_save_in.size() == 2 * _ndisp)
     582           0 :             params.set<std::vector<AuxVariableName>>("save_in") = {_save_in[i]};
     583          18 :           if (_diag_save_in.size() == 2 * _ndisp)
     584           0 :             params.set<std::vector<AuxVariableName>>("diag_save_in") = {_diag_save_in[i]};
     585             : 
     586          36 :           _problem->addKernel("InertialForceBeam", kernel_name, params);
     587             :         }
     588             :         else
     589             :         {
     590          18 :           params.set<unsigned int>("component") = i;
     591          36 :           params.set<NonlinearVariableName>("variable") = _rotations[i - 3];
     592             : 
     593          18 :           if (_save_in.size() == 2 * _ndisp)
     594           0 :             params.set<std::vector<AuxVariableName>>("save_in") = {_save_in[i]};
     595          18 :           if (_diag_save_in.size() == 2 * _ndisp)
     596           0 :             params.set<std::vector<AuxVariableName>>("diag_save_in") = {_diag_save_in[i]};
     597             : 
     598          36 :           _problem->addKernel("InertialForceBeam", kernel_name, params);
     599             :         }
     600             :       }
     601             :     }
     602         140 :   }
     603             :   else
     604             :   {
     605             :     // Add StressDivergenceTensorsTruss kernels
     606          16 :     auto params = _factory.getValidParams("StressDivergenceTensorsTruss");
     607          64 :     params.applyParameters(parameters(), {"use_displaced_mesh", "save_in", "diag_save_in"});
     608          16 :     params.set<bool>("use_displaced_mesh") = true;
     609             : 
     610          60 :     for (unsigned int i = 0; i < _ndisp; ++i)
     611             :     {
     612          88 :       std::string kernel_name = name() + "_stress_divergence_truss_" + Moose::stringify(i);
     613          44 :       params.set<unsigned int>("component") = i;
     614          88 :       params.set<NonlinearVariableName>("variable") = _displacements[i];
     615             : 
     616          44 :       if (_save_in.size() == _ndisp)
     617         132 :         params.set<std::vector<AuxVariableName>>("save_in") = {_save_in[i]};
     618          44 :       if (_diag_save_in.size() == _ndisp)
     619           0 :         params.set<std::vector<AuxVariableName>>("diag_save_in") = {_diag_save_in[i]};
     620             : 
     621          88 :       _problem->addKernel("StressDivergenceTensorsTruss", kernel_name, params);
     622             :     }
     623          16 :   }
     624         480 : }
     625             : 
     626             : void
     627         164 : LineElementAction::actAddAuxVariables()
     628             : {
     629         164 :   if (_add_dynamic_variables && !_truss)
     630             :   {
     631          24 :     auto params = _factory.getValidParams("MooseVariable");
     632             : 
     633          48 :     params.set<MooseEnum>("order") = "FIRST";
     634          48 :     params.set<MooseEnum>("family") = "LAGRANGE";
     635             : 
     636          88 :     for (auto vel : _velocities)
     637         128 :       _problem->addAuxVariable("MooseVariable", vel, params);
     638             : 
     639          88 :     for (auto accel : _accelerations)
     640         128 :       _problem->addAuxVariable("MooseVariable", accel, params);
     641             : 
     642          88 :     for (auto rot_vel : _rot_velocities)
     643         128 :       _problem->addAuxVariable("MooseVariable", rot_vel, params);
     644             : 
     645          88 :     for (auto rot_accel : _rot_accelerations)
     646         128 :       _problem->addAuxVariable("MooseVariable", rot_accel, params);
     647          24 :   }
     648         164 : }
     649             : 
     650             : void
     651         156 : LineElementAction::actAddAuxKernels()
     652             : {
     653         156 :   if (_add_dynamic_variables && !_truss)
     654             :   {
     655          20 :     auto params = _factory.getValidParams("NewmarkAccelAux");
     656          40 :     params.applyParameters(parameters(), {"boundary"});
     657          20 :     params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
     658             : 
     659         140 :     for (unsigned i = 0; i < 2 * _ndisp; ++i)
     660             :     {
     661         240 :       std::string aux_kernel_name = name() + "_newmark_accel_" + Moose::stringify(i);
     662             : 
     663         120 :       if (i < _ndisp)
     664             :       {
     665         120 :         params.set<AuxVariableName>("variable") = _accelerations[i];
     666         180 :         params.set<std::vector<VariableName>>("velocity") = {_velocities[i]};
     667         180 :         params.set<std::vector<VariableName>>("displacement") = {_displacements[i]};
     668             : 
     669         120 :         _problem->addAuxKernel("NewmarkAccelAux", aux_kernel_name, params);
     670             :       }
     671             :       else
     672             :       {
     673         120 :         params.set<AuxVariableName>("variable") = _rot_accelerations[i - _ndisp];
     674         180 :         params.set<std::vector<VariableName>>("velocity") = {_rot_velocities[i - _ndisp]};
     675         180 :         params.set<std::vector<VariableName>>("displacement") = {_rotations[i - _ndisp]};
     676             : 
     677         120 :         _problem->addAuxKernel("NewmarkAccelAux", aux_kernel_name, params);
     678             :       }
     679             :     }
     680             : 
     681          20 :     params = _factory.getValidParams("NewmarkVelAux");
     682          40 :     params.applyParameters(parameters(), {"boundary"});
     683          20 :     params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
     684             : 
     685         140 :     for (unsigned i = 0; i < 2 * _ndisp; ++i)
     686             :     {
     687         240 :       std::string aux_kernel_name = name() + "_newmark_vel_" + Moose::stringify(i);
     688             : 
     689         120 :       if (i < _ndisp)
     690             :       {
     691         120 :         params.set<AuxVariableName>("variable") = _velocities[i];
     692         180 :         params.set<std::vector<VariableName>>("acceleration") = {_accelerations[i]};
     693         120 :         _problem->addAuxKernel("NewmarkVelAux", aux_kernel_name, params);
     694             :       }
     695             :       else
     696             :       {
     697         120 :         params.set<AuxVariableName>("variable") = _rot_velocities[i - _ndisp];
     698         180 :         params.set<std::vector<VariableName>>("acceleration") = {_rot_accelerations[i - _ndisp]};
     699         120 :         _problem->addAuxKernel("NewmarkVelAux", aux_kernel_name, params);
     700             :       }
     701             :     }
     702          20 :   }
     703         236 : }
     704             : 
     705             : void
     706         156 : LineElementAction::actAddNodalKernels()
     707             : {
     708         156 :   if (!_truss)
     709             :   {
     710             :     // NodalTranslationalInertia and NodalRotattionalInertia currently accept only constant real
     711             :     // numbers for eta
     712             :     Real eta = 0.0;
     713         140 :     if (_dynamic_nodal_rotational_inertia || _dynamic_nodal_translational_inertia)
     714             :     {
     715          16 :       std::string ss(getParam<MaterialPropertyName>("eta"));
     716           8 :       Real real_value = MooseUtils::convert<Real>(ss);
     717             : 
     718             :       eta = real_value;
     719             :     }
     720             : 
     721         140 :     if (_dynamic_nodal_translational_inertia)
     722             :     {
     723           8 :       auto params = _factory.getValidParams("NodalTranslationalInertia");
     724          40 :       params.applyParameters(parameters(),
     725             :                              {"save_in", "diag_save_in", "use_displaced_mesh", "eta"});
     726           8 :       params.set<Real>("mass") = getParam<Real>("nodal_mass");
     727           8 :       params.set<Real>("eta") = eta;
     728           8 :       params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
     729             : 
     730          26 :       for (unsigned i = 0; i < _ndisp; ++i)
     731             :       {
     732             :         std::string nodal_kernel_name =
     733          40 :             name() + "_nodal_translational_inertia_" + Moose::stringify(i);
     734             : 
     735          40 :         params.set<NonlinearVariableName>("variable") = _displacements[i];
     736          60 :         params.set<std::vector<VariableName>>("velocity") = {_velocities[i]};
     737          60 :         params.set<std::vector<VariableName>>("acceleration") = {_accelerations[i]};
     738             : 
     739          20 :         if (_save_in.size() == 2 * _ndisp)
     740           0 :           params.set<std::vector<AuxVariableName>>("save_in") = {_save_in[i]};
     741             : 
     742          20 :         if (_diag_save_in.size() == 2 * _ndisp)
     743           0 :           params.set<std::vector<AuxVariableName>>("diag_save_in") = {_diag_save_in[i]};
     744             : 
     745          38 :         _problem->addNodalKernel("NodalTranslationalInertia", nodal_kernel_name, params);
     746             :       }
     747           6 :     }
     748             : 
     749         138 :     if (_dynamic_nodal_rotational_inertia)
     750             :     {
     751           6 :       auto params = _factory.getValidParams("NodalRotationalInertia");
     752          42 :       params.applyParameters(parameters(),
     753             :                              {"save_in",
     754             :                               "diag_save_in",
     755             :                               "use_displaced_mesh",
     756             :                               "eta",
     757             :                               "x_orientation",
     758             :                               "y_orientation"});
     759           6 :       params.set<Real>("Ixx") = getParam<Real>("nodal_Ixx");
     760          12 :       params.set<Real>("Iyy") = getParam<Real>("nodal_Iyy");
     761          12 :       params.set<Real>("Izz") = getParam<Real>("nodal_Izz");
     762           6 :       params.set<Real>("eta") = eta;
     763           6 :       params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
     764             : 
     765          12 :       if (isParamValid("nodal_Ixy"))
     766          12 :         params.set<Real>("Ixy") = getParam<Real>("nodal_Ixy");
     767             : 
     768          12 :       if (isParamValid("nodal_Ixz"))
     769          12 :         params.set<Real>("Ixz") = getParam<Real>("nodal_Ixz");
     770             : 
     771          12 :       if (isParamValid("nodal_Iyz"))
     772          12 :         params.set<Real>("Iyz") = getParam<Real>("nodal_Iyz");
     773             : 
     774          12 :       if (isParamValid("nodal_x_orientation"))
     775           0 :         params.set<Real>("x_orientation") = getParam<Real>("nodal_x_orientation");
     776             : 
     777          12 :       if (isParamValid("nodal_y_orientation"))
     778           0 :         params.set<Real>("y_orientation") = getParam<Real>("nodal_y_orientation");
     779             : 
     780          24 :       for (unsigned i = 0; i < _ndisp; ++i)
     781             :       {
     782          36 :         std::string nodal_kernel_name = name() + "_nodal_rotational_inertia_" + Moose::stringify(i);
     783             : 
     784          18 :         params.set<unsigned int>("component") = i;
     785          36 :         params.set<NonlinearVariableName>("variable") = _rotations[i];
     786             : 
     787          18 :         if (_save_in.size() == 2 * _ndisp)
     788           0 :           params.set<std::vector<AuxVariableName>>("save_in") = {_save_in[i + _ndisp]};
     789             : 
     790          18 :         if (_diag_save_in.size() == 2 * _ndisp)
     791           0 :           params.set<std::vector<AuxVariableName>>("diag_save_in") = {_diag_save_in[i + _ndisp]};
     792             : 
     793          36 :         _problem->addNodalKernel("NodalRotationalInertia", nodal_kernel_name, params);
     794             :       }
     795           6 :     }
     796             :   }
     797         182 : }

Generated by: LCOV version 1.14