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