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 430 : LineElementAction::validParams()
35 : {
36 430 : InputParameters params = Action::validParams();
37 430 : 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 860 : params.addParam<bool>(
43 : "truss",
44 860 : false,
45 : "Set to true if the line elements are truss elements instead of the default beam elements.");
46 860 : params.addParam<bool>("add_variables",
47 860 : false,
48 : "Add the displacement variables for truss elements "
49 : "and both displacement and rotation variables for "
50 : "beam elements.");
51 860 : params.addParam<std::vector<VariableName>>(
52 : "displacements", "The nonlinear displacement variables for the problem");
53 :
54 : // Common geometry parameters between beam and truss
55 860 : 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 430 : params += LineElementAction::beamParameters();
61 :
62 860 : params.addParam<bool>(
63 860 : "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 860 : 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 860 : params.addParam<std::vector<AuxVariableName>>(
74 : "save_in", {}, "The displacement and rotational residuals");
75 860 : params.addParam<std::vector<AuxVariableName>>(
76 : "diag_save_in", {}, "The displacement and rotational diagonal preconditioner terms");
77 860 : params.addParamNamesToGroup("block", "Advanced");
78 430 : return params;
79 0 : }
80 :
81 : InputParameters
82 430 : LineElementAction::beamParameters()
83 : {
84 430 : InputParameters params = emptyInputParameters();
85 :
86 860 : params.addParam<std::vector<VariableName>>(
87 : "rotations", "The rotations appropriate for the simulation geometry and coordinate system");
88 :
89 860 : MooseEnum strainType("SMALL FINITE", "SMALL");
90 860 : params.addParam<MooseEnum>("strain_type", strainType, "Strain formulation");
91 860 : params.addParam<MooseEnum>("rotation_type", strainType, "Rotation formulation");
92 860 : params.addParam<std::vector<MaterialPropertyName>>(
93 : "eigenstrain_names", "List of beam eigenstrains to be applied in this strain calculation.");
94 :
95 : // Beam geometry
96 860 : 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 860 : params.addCoupledVar(
101 : "area",
102 : "Cross-section area of the beam. Can be supplied as either a number or a variable name.");
103 860 : 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 860 : 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 860 : 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 860 : 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 860 : 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 860 : 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 860 : params.addParam<std::vector<VariableName>>("velocities", "Translational velocity variables");
130 860 : params.addParam<std::vector<VariableName>>("accelerations",
131 : "Translational acceleration variables");
132 860 : params.addParam<std::vector<VariableName>>("rotational_velocities",
133 : "Rotational velocity variables");
134 860 : params.addParam<std::vector<VariableName>>("rotational_accelerations",
135 : "Rotational acceleration variables");
136 860 : params.addRangeCheckedParam<Real>(
137 : "beta", "beta>0.0", "beta parameter for Newmark Time integration");
138 860 : params.addRangeCheckedParam<Real>(
139 : "gamma", "gamma>0.0", "gamma parameter for Newmark Time integration");
140 860 : params.addParam<MaterialPropertyName>("eta",
141 860 : 0.0,
142 : "Name of material property or a constant real "
143 : "number defining the eta parameter for mass proportional "
144 : "Rayleigh damping.");
145 860 : params.addParam<MaterialPropertyName>(
146 : "zeta",
147 860 : 0.0,
148 : "Name of material property or a constant real "
149 : "number defining the zeta parameter for stiffness proportional "
150 : "Rayleigh damping.");
151 860 : 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 860 : params.addParam<bool>("dynamic_consistent_inertia",
159 860 : false,
160 : "If set to true, consistent mass and "
161 : "inertia matrices are used for the "
162 : "inertial force/torque calculations.");
163 860 : 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 860 : params.addParam<bool>(
169 : "dynamic_nodal_translational_inertia",
170 860 : false,
171 : "If set to true, nodal mass matrix is used for the inertial force calculation.");
172 860 : params.addRangeCheckedParam<Real>(
173 : "nodal_mass", "nodal_mass>0.0", "Mass associated with the node");
174 860 : 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 860 : params.addParam<bool>(
180 : "dynamic_nodal_rotational_inertia",
181 860 : false,
182 : "If set to true, nodal inertia matrix is used for the inertial torque calculation.");
183 860 : params.addRangeCheckedParam<Real>(
184 : "nodal_Ixx", "nodal_Ixx>=0.0", "Nodal moment of inertia in the x direction.");
185 860 : params.addRangeCheckedParam<Real>(
186 : "nodal_Iyy", "nodal_Iyy>=0.0", "Nodal moment of inertia in the y direction.");
187 860 : params.addRangeCheckedParam<Real>(
188 : "nodal_Izz", "nodal_Izz>=0.0", "Nodal moment of inertia in the z direction.");
189 860 : params.addParam<Real>("nodal_Ixy", 0.0, "Nodal moment of inertia in the xy direction.");
190 860 : params.addParam<Real>("nodal_Ixz", 0.0, "Nodal moment of inertia in the xz direction.");
191 860 : params.addParam<Real>("nodal_Iyz", 0.0, "Nodal moment of inertia in the yz direction.");
192 860 : params.addParam<RealGradient>(
193 : "nodal_x_orientation",
194 : "Unit vector along the x direction if different from global x direction.");
195 860 : params.addParam<RealGradient>(
196 : "nodal_y_orientation",
197 : "Unit vector along the y direction if different from global y direction.");
198 860 : 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 430 : return params;
204 430 : }
205 :
206 224 : LineElementAction::LineElementAction(const InputParameters & params)
207 : : Action(params),
208 224 : _rotations(0),
209 224 : _velocities(0),
210 224 : _accelerations(0),
211 224 : _rot_velocities(0),
212 224 : _rot_accelerations(0),
213 672 : _subdomain_names(getParam<std::vector<SubdomainName>>("block")),
214 : _subdomain_ids(),
215 224 : _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 224 : const auto & parameters = _app.getInputParameterWarehouse().getInputParameters();
220 224 : InputParameters & pars(*(parameters.find(uniqueActionName())->second.get()));
221 :
222 : // check if a container block with common parameters is found
223 224 : auto action = _awh.getActions<CommonLineElementAction>();
224 224 : if (action.size() == 1)
225 224 : pars.applyParameters(action[0]->parameters());
226 :
227 : // Set values to variables after common parameters are applied
228 448 : _save_in = getParam<std::vector<AuxVariableName>>("save_in");
229 448 : _diag_save_in = getParam<std::vector<AuxVariableName>>("diag_save_in");
230 448 : _strain_type = getParam<MooseEnum>("strain_type").getEnum<Strain>();
231 448 : _rotation_type = getParam<MooseEnum>("rotation_type").getEnum<Strain>();
232 448 : _dynamic_consistent_inertia = getParam<bool>("dynamic_consistent_inertia");
233 448 : _dynamic_nodal_translational_inertia = getParam<bool>("dynamic_nodal_translational_inertia");
234 448 : _dynamic_nodal_rotational_inertia = getParam<bool>("dynamic_nodal_rotational_inertia");
235 224 : if (_dynamic_consistent_inertia || _dynamic_nodal_rotational_inertia ||
236 176 : _dynamic_nodal_translational_inertia)
237 50 : _add_dynamic_variables = true;
238 :
239 448 : if (params.isParamSetByUser("add_dynamic_variables"))
240 : {
241 18 : bool user_defined_add_dynamic_variables = getParam<bool>("add_dynamic_variables");
242 9 : if (!_add_dynamic_variables && user_defined_add_dynamic_variables)
243 7 : _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 444 : _truss = getParam<bool>("truss");
252 :
253 444 : 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 660 : _displacements = getParam<std::vector<VariableName>>("displacements");
259 220 : _ndisp = _displacements.size();
260 :
261 : // determine if displaced mesh is to be used
262 220 : _use_displaced_mesh = (_strain_type != Strain::SMALL && _rotation_type != Strain::SMALL);
263 440 : 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 218 : 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 216 : 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 214 : if (!_truss)
289 : {
290 : // Parameters required for static simulation using beams
291 382 : if (!isParamValid("rotations"))
292 2 : paramError("rotations",
293 : "LineElementAction: Rotational variable names should be provided for beam "
294 : "elements using `rotations` parameter.");
295 :
296 567 : _rotations = getParam<std::vector<VariableName>>("rotations");
297 :
298 189 : 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 1305 : if (!isParamValid("y_orientation") || !isParamValid("area") || !isParamValid("Iy") ||
304 557 : !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 185 : if (_add_dynamic_variables)
310 : {
311 199 : if (!isParamValid("velocities") || !isParamValid("accelerations") ||
312 232 : !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 74 : _velocities = getParam<std::vector<VariableName>>("velocities");
320 74 : _accelerations = getParam<std::vector<VariableName>>("accelerations");
321 74 : _rot_velocities = getParam<std::vector<VariableName>>("rotational_velocities");
322 111 : _rot_accelerations = getParam<std::vector<VariableName>>("rotational_accelerations");
323 :
324 37 : if (_velocities.size() != _ndisp || _accelerations.size() != _ndisp ||
325 72 : _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 136 : 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 226 : 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 192 : if (_dynamic_nodal_translational_inertia &&
342 213 : (!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 188 : if (_dynamic_nodal_rotational_inertia &&
349 255 : ((!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 46 : if (!isParamValid("area"))
356 2 : paramError("area",
357 : "LineElementAction: `area` should be provided as input for "
358 : "truss elements.");
359 :
360 42 : if (isParamValid("rotations"))
361 2 : paramError("rotations",
362 : "LineElementAction: Rotational variables cannot be set for truss elements.");
363 : }
364 190 : }
365 :
366 : void
367 1294 : LineElementAction::act()
368 : {
369 : // Get the subdomain involved in the action once the mesh setup is complete
370 1294 : if (_current_task == "create_problem")
371 : {
372 : // get subdomain IDs
373 273 : for (auto & name : _subdomain_names)
374 83 : _subdomain_ids.insert(_mesh->getSubdomainID(name));
375 : }
376 :
377 1294 : if (_current_task == "add_variable")
378 : {
379 : //
380 : // Gather info from all other LineElementAction
381 : //
382 186 : actGatherActionParameters();
383 :
384 : //
385 : // Add variables (optional)
386 : //
387 182 : actAddVariables();
388 : }
389 :
390 : //
391 : // Add Materials - ComputeIncrementalBeamStrain or ComputeFiniteBeamStrain
392 : // for beam elements
393 : //
394 1290 : if (_current_task == "add_material")
395 182 : 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 1290 : if (_current_task == "add_kernel")
402 182 : actAddKernels();
403 :
404 : //
405 : // Add aux variables for translational and Rotational velocities and acceleration for dynamic
406 : // analysis using beams
407 : //
408 1290 : if (_current_task == "add_aux_variable")
409 190 : actAddAuxVariables();
410 :
411 : //
412 : // Add NewmarkVelAux and NewarkAccelAux auxkernels for dynamic simulation using beams
413 : //
414 1290 : if (_current_task == "add_aux_kernel")
415 182 : 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 1290 : if (_current_task == "add_nodal_kernel")
423 182 : actAddNodalKernels();
424 1288 : }
425 :
426 : void
427 186 : LineElementAction::actGatherActionParameters()
428 : {
429 : //
430 : // Gather info about all other master actions when we add variables
431 : //
432 372 : if (getParam<bool>("add_variables"))
433 : {
434 179 : auto actions = _awh.getActions<LineElementAction>();
435 386 : for (const auto & action : actions)
436 : {
437 : const auto size_before = _subdomain_id_union.size();
438 211 : const auto added_size = action->_subdomain_ids.size();
439 211 : _subdomain_id_union.insert(action->_subdomain_ids.begin(), action->_subdomain_ids.end());
440 : const auto size_after = _subdomain_id_union.size();
441 :
442 211 : 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 209 : 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 175 : }
454 182 : }
455 :
456 : void
457 182 : LineElementAction::actAddVariables()
458 : {
459 364 : if (getParam<bool>("add_variables"))
460 : {
461 175 : auto params = _factory.getValidParams("MooseVariable");
462 :
463 : // determine order of elements in mesh
464 175 : const bool second = _problem->mesh().hasSecondOrderElements();
465 175 : 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 350 : params.set<MooseEnum>("order") = "FIRST";
470 350 : params.set<MooseEnum>("family") = "LAGRANGE";
471 :
472 : // Loop through the displacement variables
473 695 : for (const auto & disp : _displacements)
474 : {
475 : // Create displacement variables
476 520 : if (!_problem->hasVariable(disp))
477 956 : _problem->addVariable("MooseVariable", disp, params);
478 : }
479 :
480 : // Add rotation variables if line element is a beam.
481 175 : if (!_truss)
482 : {
483 652 : for (const auto & rot : _rotations)
484 : {
485 : // Create rotation variables
486 489 : if (!_problem->hasVariable(rot))
487 894 : _problem->addVariable("MooseVariable", rot, params);
488 : }
489 : }
490 175 : }
491 182 : }
492 :
493 : void
494 182 : LineElementAction::actAddMaterials()
495 : {
496 182 : if (!_truss)
497 : {
498 : // Add Strain
499 163 : if (_rotation_type == Strain::SMALL)
500 : {
501 156 : auto params = _factory.getValidParams("ComputeIncrementalBeamStrain");
502 156 : params.applyParameters(parameters(), {"boundary", "use_displaced_mesh"});
503 156 : params.set<bool>("use_displaced_mesh") = false;
504 :
505 156 : if (_strain_type == Strain::FINITE)
506 0 : params.set<bool>("large_strain") = true;
507 :
508 312 : _problem->addMaterial("ComputeIncrementalBeamStrain", name() + "_strain", params);
509 156 : }
510 7 : else if (_rotation_type == Strain::FINITE)
511 : {
512 7 : auto params = _factory.getValidParams("ComputeFiniteBeamStrain");
513 7 : params.applyParameters(parameters(), {"boundary", "use_displaced_mesh"});
514 7 : params.set<bool>("use_displaced_mesh") = false;
515 :
516 7 : if (_strain_type == Strain::FINITE)
517 7 : params.set<bool>("large_strain") = true;
518 :
519 14 : _problem->addMaterial("ComputeFiniteBeamStrain", name() + "_strain", params);
520 7 : }
521 : }
522 182 : }
523 :
524 : void
525 182 : LineElementAction::actAddKernels()
526 : {
527 182 : if (!_truss)
528 : {
529 : // add StressDivergenceBeam kernels
530 163 : auto params = _factory.getValidParams("StressDivergenceBeam");
531 163 : params.applyParameters(parameters(), {"use_displaced_mesh", "save_in", "diag_save_in"});
532 163 : params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
533 :
534 1141 : for (unsigned int i = 0; i < 2 * _ndisp; ++i)
535 : {
536 1956 : std::string kernel_name = name() + "_stress_divergence_beam_" + Moose::stringify(i);
537 :
538 978 : if (i < _ndisp)
539 : {
540 489 : params.set<unsigned int>("component") = i;
541 978 : params.set<NonlinearVariableName>("variable") = _displacements[i];
542 :
543 489 : if (_save_in.size() == 2 * _ndisp)
544 0 : params.set<std::vector<AuxVariableName>>("save_in") = {_save_in[i]};
545 489 : if (_diag_save_in.size() == 2 * _ndisp)
546 0 : params.set<std::vector<AuxVariableName>>("diag_save_in") = {_diag_save_in[i]};
547 :
548 978 : _problem->addKernel("StressDivergenceBeam", kernel_name, params);
549 : }
550 : else
551 : {
552 489 : params.set<unsigned int>("component") = i;
553 978 : params.set<NonlinearVariableName>("variable") = _rotations[i - 3];
554 :
555 489 : if (_save_in.size() == 2 * _ndisp)
556 0 : params.set<std::vector<AuxVariableName>>("save_in") = {_save_in[i]};
557 489 : if (_diag_save_in.size() == 2 * _ndisp)
558 0 : params.set<std::vector<AuxVariableName>>("diag_save_in") = {_diag_save_in[i]};
559 :
560 978 : _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 163 : if (_dynamic_consistent_inertia)
566 : {
567 : // add InertialForceBeam
568 7 : params = _factory.getValidParams("InertialForceBeam");
569 7 : params.applyParameters(parameters(), {"use_displaced_mesh", "save_in", "diag_save_in"});
570 7 : params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
571 :
572 49 : for (unsigned int i = 0; i < 2 * _ndisp; ++i)
573 : {
574 84 : std::string kernel_name = name() + "_inertial_force_beam_" + Moose::stringify(i);
575 :
576 42 : if (i < _ndisp)
577 : {
578 21 : params.set<unsigned int>("component") = i;
579 42 : params.set<NonlinearVariableName>("variable") = _displacements[i];
580 :
581 21 : if (_save_in.size() == 2 * _ndisp)
582 0 : params.set<std::vector<AuxVariableName>>("save_in") = {_save_in[i]};
583 21 : if (_diag_save_in.size() == 2 * _ndisp)
584 0 : params.set<std::vector<AuxVariableName>>("diag_save_in") = {_diag_save_in[i]};
585 :
586 42 : _problem->addKernel("InertialForceBeam", kernel_name, params);
587 : }
588 : else
589 : {
590 21 : params.set<unsigned int>("component") = i;
591 42 : params.set<NonlinearVariableName>("variable") = _rotations[i - 3];
592 :
593 21 : if (_save_in.size() == 2 * _ndisp)
594 0 : params.set<std::vector<AuxVariableName>>("save_in") = {_save_in[i]};
595 21 : if (_diag_save_in.size() == 2 * _ndisp)
596 0 : params.set<std::vector<AuxVariableName>>("diag_save_in") = {_diag_save_in[i]};
597 :
598 42 : _problem->addKernel("InertialForceBeam", kernel_name, params);
599 : }
600 : }
601 : }
602 163 : }
603 : else
604 : {
605 : // Add StressDivergenceTensorsTruss kernels
606 19 : auto params = _factory.getValidParams("StressDivergenceTensorsTruss");
607 19 : params.applyParameters(parameters(), {"use_displaced_mesh", "save_in", "diag_save_in"});
608 19 : params.set<bool>("use_displaced_mesh") = true;
609 :
610 71 : for (unsigned int i = 0; i < _ndisp; ++i)
611 : {
612 104 : std::string kernel_name = name() + "_stress_divergence_truss_" + Moose::stringify(i);
613 52 : params.set<unsigned int>("component") = i;
614 104 : params.set<NonlinearVariableName>("variable") = _displacements[i];
615 :
616 52 : if (_save_in.size() == _ndisp)
617 156 : params.set<std::vector<AuxVariableName>>("save_in") = {_save_in[i]};
618 52 : if (_diag_save_in.size() == _ndisp)
619 0 : params.set<std::vector<AuxVariableName>>("diag_save_in") = {_diag_save_in[i]};
620 :
621 104 : _problem->addKernel("StressDivergenceTensorsTruss", kernel_name, params);
622 : }
623 19 : }
624 182 : }
625 :
626 : void
627 190 : LineElementAction::actAddAuxVariables()
628 : {
629 190 : if (_add_dynamic_variables && !_truss)
630 : {
631 27 : auto params = _factory.getValidParams("MooseVariable");
632 :
633 54 : params.set<MooseEnum>("order") = "FIRST";
634 54 : params.set<MooseEnum>("family") = "LAGRANGE";
635 :
636 100 : for (auto vel : _velocities)
637 146 : _problem->addAuxVariable("MooseVariable", vel, params);
638 :
639 100 : for (auto accel : _accelerations)
640 146 : _problem->addAuxVariable("MooseVariable", accel, params);
641 :
642 100 : for (auto rot_vel : _rot_velocities)
643 146 : _problem->addAuxVariable("MooseVariable", rot_vel, params);
644 :
645 100 : for (auto rot_accel : _rot_accelerations)
646 146 : _problem->addAuxVariable("MooseVariable", rot_accel, params);
647 27 : }
648 190 : }
649 :
650 : void
651 182 : LineElementAction::actAddAuxKernels()
652 : {
653 182 : if (_add_dynamic_variables && !_truss)
654 : {
655 23 : auto params = _factory.getValidParams("NewmarkAccelAux");
656 23 : params.applyParameters(parameters(), {"boundary"});
657 23 : params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
658 :
659 161 : for (unsigned i = 0; i < 2 * _ndisp; ++i)
660 : {
661 276 : std::string aux_kernel_name = name() + "_newmark_accel_" + Moose::stringify(i);
662 :
663 138 : if (i < _ndisp)
664 : {
665 138 : params.set<AuxVariableName>("variable") = _accelerations[i];
666 207 : params.set<std::vector<VariableName>>("velocity") = {_velocities[i]};
667 207 : params.set<std::vector<VariableName>>("displacement") = {_displacements[i]};
668 :
669 138 : _problem->addAuxKernel("NewmarkAccelAux", aux_kernel_name, params);
670 : }
671 : else
672 : {
673 138 : params.set<AuxVariableName>("variable") = _rot_accelerations[i - _ndisp];
674 207 : params.set<std::vector<VariableName>>("velocity") = {_rot_velocities[i - _ndisp]};
675 207 : params.set<std::vector<VariableName>>("displacement") = {_rotations[i - _ndisp]};
676 :
677 138 : _problem->addAuxKernel("NewmarkAccelAux", aux_kernel_name, params);
678 : }
679 : }
680 :
681 23 : params = _factory.getValidParams("NewmarkVelAux");
682 23 : params.applyParameters(parameters(), {"boundary"});
683 23 : params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
684 :
685 161 : for (unsigned i = 0; i < 2 * _ndisp; ++i)
686 : {
687 276 : std::string aux_kernel_name = name() + "_newmark_vel_" + Moose::stringify(i);
688 :
689 138 : if (i < _ndisp)
690 : {
691 138 : params.set<AuxVariableName>("variable") = _velocities[i];
692 207 : params.set<std::vector<VariableName>>("acceleration") = {_accelerations[i]};
693 138 : _problem->addAuxKernel("NewmarkVelAux", aux_kernel_name, params);
694 : }
695 : else
696 : {
697 138 : params.set<AuxVariableName>("variable") = _rot_velocities[i - _ndisp];
698 207 : params.set<std::vector<VariableName>>("acceleration") = {_rot_accelerations[i - _ndisp]};
699 138 : _problem->addAuxKernel("NewmarkVelAux", aux_kernel_name, params);
700 : }
701 : }
702 23 : }
703 182 : }
704 :
705 : void
706 182 : LineElementAction::actAddNodalKernels()
707 : {
708 182 : if (!_truss)
709 : {
710 : // NodalTranslationalInertia and NodalRotattionalInertia currently accept only constant real
711 : // numbers for eta
712 : Real eta = 0.0;
713 163 : if (_dynamic_nodal_rotational_inertia || _dynamic_nodal_translational_inertia)
714 : {
715 18 : std::string ss(getParam<MaterialPropertyName>("eta"));
716 9 : Real real_value = MooseUtils::convert<Real>(ss);
717 :
718 : eta = real_value;
719 : }
720 :
721 163 : if (_dynamic_nodal_translational_inertia)
722 : {
723 9 : auto params = _factory.getValidParams("NodalTranslationalInertia");
724 9 : params.applyParameters(parameters(),
725 : {"save_in", "diag_save_in", "use_displaced_mesh", "eta"});
726 18 : params.set<Real>("mass") = getParam<Real>("nodal_mass");
727 9 : params.set<Real>("eta") = eta;
728 9 : params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
729 :
730 30 : for (unsigned i = 0; i < _ndisp; ++i)
731 : {
732 : std::string nodal_kernel_name =
733 46 : name() + "_nodal_translational_inertia_" + Moose::stringify(i);
734 :
735 46 : params.set<NonlinearVariableName>("variable") = _displacements[i];
736 69 : params.set<std::vector<VariableName>>("velocity") = {_velocities[i]};
737 69 : params.set<std::vector<VariableName>>("acceleration") = {_accelerations[i]};
738 :
739 23 : if (_save_in.size() == 2 * _ndisp)
740 0 : params.set<std::vector<AuxVariableName>>("save_in") = {_save_in[i]};
741 :
742 23 : if (_diag_save_in.size() == 2 * _ndisp)
743 0 : params.set<std::vector<AuxVariableName>>("diag_save_in") = {_diag_save_in[i]};
744 :
745 44 : _problem->addNodalKernel("NodalTranslationalInertia", nodal_kernel_name, params);
746 : }
747 7 : }
748 :
749 161 : if (_dynamic_nodal_rotational_inertia)
750 : {
751 7 : auto params = _factory.getValidParams("NodalRotationalInertia");
752 7 : params.applyParameters(parameters(),
753 : {"save_in",
754 : "diag_save_in",
755 : "use_displaced_mesh",
756 : "eta",
757 : "x_orientation",
758 : "y_orientation"});
759 14 : params.set<Real>("Ixx") = getParam<Real>("nodal_Ixx");
760 14 : params.set<Real>("Iyy") = getParam<Real>("nodal_Iyy");
761 14 : params.set<Real>("Izz") = getParam<Real>("nodal_Izz");
762 7 : params.set<Real>("eta") = eta;
763 7 : params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
764 :
765 14 : if (isParamValid("nodal_Ixy"))
766 14 : params.set<Real>("Ixy") = getParam<Real>("nodal_Ixy");
767 :
768 14 : if (isParamValid("nodal_Ixz"))
769 14 : params.set<Real>("Ixz") = getParam<Real>("nodal_Ixz");
770 :
771 14 : if (isParamValid("nodal_Iyz"))
772 14 : params.set<Real>("Iyz") = getParam<Real>("nodal_Iyz");
773 :
774 14 : if (isParamValid("nodal_x_orientation"))
775 0 : params.set<Real>("x_orientation") = getParam<Real>("nodal_x_orientation");
776 :
777 14 : if (isParamValid("nodal_y_orientation"))
778 0 : params.set<Real>("y_orientation") = getParam<Real>("nodal_y_orientation");
779 :
780 28 : for (unsigned i = 0; i < _ndisp; ++i)
781 : {
782 42 : std::string nodal_kernel_name = name() + "_nodal_rotational_inertia_" + Moose::stringify(i);
783 :
784 21 : params.set<unsigned int>("component") = i;
785 42 : params.set<NonlinearVariableName>("variable") = _rotations[i];
786 :
787 21 : if (_save_in.size() == 2 * _ndisp)
788 0 : params.set<std::vector<AuxVariableName>>("save_in") = {_save_in[i + _ndisp]};
789 :
790 21 : if (_diag_save_in.size() == 2 * _ndisp)
791 0 : params.set<std::vector<AuxVariableName>>("diag_save_in") = {_diag_save_in[i + _ndisp]};
792 :
793 42 : _problem->addNodalKernel("NodalRotationalInertia", nodal_kernel_name, params);
794 : }
795 7 : }
796 : }
797 180 : }
|