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 : }
|