https://mooseframework.inl.gov
Loading...
Searching...
No Matches
QuasiStaticSolidMechanicsPhysics.C
Go to the documentation of this file.
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"
16#include "Material.h"
18
19#include "BlockRestrictable.h"
20
22#include "AddVariableAction.h"
23
24#include "libmesh/string_to_enum.h"
25#include <algorithm>
26
27registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "meta_action");
28
29registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "setup_mesh_complete");
30
31registerMooseAction("SolidMechanicsApp",
33 "validate_coordinate_systems");
34
35registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "add_variable");
36
37registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "add_aux_variable");
38
39registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "add_kernel");
40
41registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "add_aux_kernel");
42
43registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "add_material");
44
45registerMooseAction("SolidMechanicsApp",
47 "add_master_action_material");
48
49registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "add_scalar_kernel");
50
51registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "add_user_object");
52
55{
57 params.addClassDescription("Set up stress divergence kernels with coordinate system aware logic");
58
59 // parameters specified here only appear in the input file sub-blocks of the solid mechanics
60 // action, not in the common parameters area
61 params.addParam<std::vector<SubdomainName>>("block",
62 {},
63 "The list of ids of the blocks (subdomain) "
64 "that the stress divergence kernels will be "
65 "applied to");
66 params.addParamNamesToGroup("block", "Advanced");
67
68 params.addParam<MultiMooseEnum>("additional_generate_output",
70 "Add scalar quantity output for stress and/or strain (will be "
71 "appended to the list in `generate_output`)");
73 "additional_material_output_order",
75 "Specifies the order of the FE shape function to use for this variable.");
76
78 "additional_material_output_family",
80 "Specifies the family of FE shape functions to use for this variable.");
81
82 params.addParamNamesToGroup("additional_generate_output additional_material_output_order "
83 "additional_material_output_family",
84 "Output");
85 params.addParam<std::string>(
86 "strain_base_name",
87 "The base name used for the strain. If not provided, it will be set equal to base_name");
88 params.addParam<std::vector<TagName>>(
89 "extra_vector_tags",
90 "The tag names for extra vectors that residual data should be saved into");
91 params.addParam<std::vector<TagName>>("absolute_value_vector_tags",
92 "The tag names for extra vectors that the absolute value "
93 "of the residual should be accumulated into");
94 params.addParam<Real>("scaling", "The scaling to apply to the displacement variables");
95 params.addParam<Point>(
96 "cylindrical_axis_point1",
97 "Starting point for direction of axis of rotation for cylindrical stress/strain.");
98 params.addParam<Point>(
99 "cylindrical_axis_point2",
100 "Ending point for direction of axis of rotation for cylindrical stress/strain.");
101 params.addParam<Point>("spherical_center_point",
102 "Center point of the spherical coordinate system.");
103 params.addParam<Point>("direction", "Direction stress/strain is calculated in");
104 params.addParam<bool>("automatic_eigenstrain_names",
105 false,
106 "Collects all material eigenstrains and passes to required strain "
107 "calculator within TMA internally.");
108
109 // Homogenization system input
110 params.addParam<MultiMooseEnum>(
111 "constraint_types",
113 "Type of each constraint: strain, stress, or none. The types are specified in the "
114 "column-major order, and there must be 9 entries in total.");
115 params.addParam<std::vector<FunctionName>>(
116 "targets", {}, "Functions giving the targets to hit for constraint types that are not none.");
117 params.addParam<bool>(
118 "homogenized_off_diagonal_jacobian",
119 true,
120 "Whether to include the off-diagonal scalar contributions to the homogenized jacobian");
121
122 params.addParamNamesToGroup("scaling", "Variables");
123 params.addParamNamesToGroup("strain_base_name automatic_eigenstrain_names", "Strain");
125 "cylindrical_axis_point1 cylindrical_axis_point2 spherical_center_point direction",
126 "Coordinate system");
127 params.addParamNamesToGroup("constraint_types targets homogenized_off_diagonal_jacobian",
128 "Homogenization");
129
130 return params;
131}
132
135 _displacements(getParam<std::vector<VariableName>>("displacements")),
136 _ndisp(_displacements.size()),
137 _coupled_displacements(_ndisp),
138 _save_in(getParam<std::vector<AuxVariableName>>("save_in")),
139 _diag_save_in(getParam<std::vector<AuxVariableName>>("diag_save_in")),
140 _subdomain_names(getParam<std::vector<SubdomainName>>("block")),
141 _subdomain_ids(),
142 _strain(getParam<MooseEnum>("strain").getEnum<Strain>()),
143 _planar_formulation(getParam<MooseEnum>("planar_formulation").getEnum<PlanarFormulation>()),
144 _out_of_plane_direction(
145 getParam<MooseEnum>("out_of_plane_direction").getEnum<OutOfPlaneDirection>()),
146 _base_name(isParamValid("base_name") ? getParam<std::string>("base_name") + "_" : ""),
147 _material_output_order(getParam<MultiMooseEnum>("material_output_order")),
148 _material_output_family(getParam<MultiMooseEnum>("material_output_family")),
149 _cylindrical_axis_point1_valid(params.isParamSetByUser("cylindrical_axis_point1")),
150 _cylindrical_axis_point2_valid(params.isParamSetByUser("cylindrical_axis_point2")),
151 _direction_valid(params.isParamSetByUser("direction")),
152 _verbose(getParam<bool>("verbose")),
153 _spherical_center_point_valid(params.isParamSetByUser("spherical_center_point")),
154 _auto_eigenstrain(getParam<bool>("automatic_eigenstrain_names")),
155 _compatibility_mode(getParam<bool>("compatibility_mode")),
156 _lagrangian_kernels(getParam<bool>("new_system") || _compatibility_mode),
157 _lk_large_kinematics(_strain == Strain::Finite),
158 // compatibility_mode mandates the total Lagrangian kernel; otherwise honor the user choice.
159 _lk_formulation(_compatibility_mode
160 ? LKFormulation::Total
161 : getParam<MooseEnum>("formulation").getEnum<LKFormulation>()),
162 _lk_locking(getParam<bool>("volumetric_locking_correction")),
163 _lk_homogenization(false),
164 _constraint_types(getParam<MultiMooseEnum>("constraint_types")),
165 _targets(getParam<std::vector<FunctionName>>("targets")),
166 _lk_h_off_jac(getParam<bool>("homogenized_off_diagonal_jacobian"))
167{
168 // determine if incremental strains are to be used
169 if (isParamValid("incremental"))
170 {
171 const bool incremental = getParam<bool>("incremental");
172 if (!incremental && _strain == Strain::Small)
174 else if (!incremental && _strain == Strain::Finite)
176 else if (incremental && _strain == Strain::Small)
178 else if (incremental && _strain == Strain::Finite)
180 else
181 mooseError("Internal error");
182 }
183 else
184 {
185 if (_strain == Strain::Small)
186 {
188 mooseInfo("SolidMechanics Action: selecting 'total small strain' formulation. Use "
189 "`incremental = true` to select 'incremental small strain' instead.");
190 }
191 else if (_strain == Strain::Finite)
192 {
194 mooseInfo("SolidMechanics Action: selecting 'incremental finite strain' formulation.");
195 }
196 else
197 mooseError("Internal error");
198 }
199
200 // determine if displaced mesh is to be used
202 if (params.isParamSetByUser("use_displaced_mesh") && !_lagrangian_kernels)
203 {
204 bool use_displaced_mesh_param = getParam<bool>("use_displaced_mesh");
205 if (use_displaced_mesh_param != _use_displaced_mesh && params.isParamSetByUser("strain"))
206 mooseError("Wrong combination of use displaced mesh and strain model");
207 _use_displaced_mesh = use_displaced_mesh_param;
208 }
209
210 // convert vector of VariableName to vector of VariableName
211 for (unsigned int i = 0; i < _ndisp; ++i)
213
214 if (_save_in.size() != 0 && _save_in.size() != _ndisp)
215 mooseError("Number of save_in variables should equal to the number of displacement variables ",
216 _ndisp);
217
218 if (_diag_save_in.size() != 0 && _diag_save_in.size() != _ndisp)
220 "Number of diag_save_in variables should equal to the number of displacement variables ",
221 _ndisp);
222
223 // plane strain consistency check
225 {
228 "moose",
229 27340,
230 "Planar formulations are not yet available through the Physics syntax with new_system = "
231 "true. They can be enabled by manually setting up the appropriate objects. Please refer "
232 "to the documentation and regression tests for examples.");
233 if (params.isParamSetByUser("out_of_plane_strain") &&
236 "out_of_plane_strain should only be specified with planar_formulation=WEAK_PLANE_STRESS");
237 else if (!params.isParamSetByUser("out_of_plane_strain") &&
239 mooseError("out_of_plane_strain must be specified with planar_formulation=WEAK_PLANE_STRESS");
240 }
241
242 // convert output variable names to lower case
243 for (const auto & out : getParam<MultiMooseEnum>("generate_output"))
244 {
245 std::string lower(out);
246 std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
247 _generate_output.push_back(lower);
248 }
249
250 if (!_generate_output.empty())
252
253 // Error if volumetric locking correction is true for 1D problems
254 if (_ndisp == 1 && getParam<bool>("volumetric_locking_correction"))
255 mooseError("Volumetric locking correction should be set to false for 1D problems.");
256
257 if (!getParam<bool>("add_variables") && params.isParamSetByUser("scaling"))
258 paramError("scaling",
259 "The scaling parameter has no effect unless add_variables is set to true. Did you "
260 "mean to set 'add_variables = true'?");
261
262 // Get cylindrical axis points if set by user
264 {
265 _cylindrical_axis_point1 = getParam<Point>("cylindrical_axis_point1");
266 _cylindrical_axis_point2 = getParam<Point>("cylindrical_axis_point2");
267 }
268
269 // Get spherical center point if set by user
271 _spherical_center_point = getParam<Point>("spherical_center_point");
272
273 // Get direction for tensor component if set by user
275 _direction = getParam<Point>("direction");
276
277 // Get eigenstrain names if passed by user
278 _eigenstrain_names = getParam<std::vector<MaterialPropertyName>>("eigenstrain_names");
279
280 // Determine if we're going to use the homogenization system for the new
281 // lagrangian kernels
282 bool ctype_set = params.isParamSetByUser("constraint_types");
283 bool targets_set = params.isParamSetByUser("targets");
284 if (ctype_set || targets_set)
285 {
286 if (!(ctype_set && targets_set))
287 mooseError("To use the Lagrangian kernel homogenization system you "
288 "most provide both the constraint_types and the targets "
289 "parameters");
290 _lk_homogenization = true;
291 // Do consistency checking on the kernel options
293 mooseError("The Lagrangian kernel homogenization system requires the "
294 "use of formulation = TOTAL");
295 }
296
297 // The action drives two mutually exclusive kernel systems: the legacy
298 // StressDivergenceTensors + ComputeFiniteStrain system, and the new Lagrangian kernel system
299 // (new_system / compatibility_mode). Many parameters belong exclusively to one system; setting
300 // one that does not match the active system is almost always a copy-paste error, so reject it
301 // explicitly with a clear message instead of silently ignoring it. The lists below are the
302 // single place to register a parameter as system-specific.
303 static const std::vector<std::string> new_system_only = {
304 "formulation", "constraint_types", "targets", "homogenized_off_diagonal_jacobian"};
305 static const std::vector<std::string> legacy_only = {"use_finite_deform_jacobian",
306 "global_strain"};
307
309 {
310 for (const auto & p : legacy_only)
311 if (params.isParamSetByUser(p))
313 "'",
314 p,
315 "' belongs to the legacy StressDivergenceTensors kernel system and cannot be "
316 "combined with new_system = true or compatibility_mode = true. The Lagrangian "
317 "kernel system produces the exact Jacobian natively; homogenization replaces "
318 "global_strain.");
319
320 // use_automatic_differentiation is a value (defaults false); reject only when requested.
321 if (_use_ad)
322 paramError("use_automatic_differentiation",
323 "The Lagrangian kernel system is not yet compatible with automatic "
324 "differentiation.");
325
326 // decomposition_method is legal only in compatibility_mode, where it maps to the strain
327 // calculator's kinematic_approximation; plain new_system exposes those options directly on the
328 // ComputeLagrangianStrain material via `kinematic_approximation`.
329 if (params.isParamSetByUser("decomposition_method") && !_compatibility_mode)
330 paramError("decomposition_method",
331 "decomposition_method is not used by the Lagrangian kernel system. Set the "
332 "equivalent option on the ComputeLagrangianStrain material via "
333 "kinematic_approximation instead.");
334
335 // compatibility_mode-specific consistency checks.
337 {
338 if (params.isParamSetByUser("formulation") &&
339 getParam<MooseEnum>("formulation").getEnum<LKFormulation>() != LKFormulation::Total)
340 paramError("formulation",
341 "compatibility_mode requires formulation = TOTAL (the OLD kernel system is "
342 "always total Lagrangian on the displaced mesh).");
343
344 if (_lk_large_kinematics && params.isParamSetByUser("kinematic_approximation"))
345 paramError("kinematic_approximation",
346 "compatibility_mode derives kinematic_approximation from decomposition_method; "
347 "do not set it explicitly.");
349 params.isParamSetByUser("volumetric_locking_correction_mode"))
350 paramError("volumetric_locking_correction_mode",
351 "compatibility_mode derives the F-bar mode from volumetric_locking_correction; "
352 "do not set volumetric_locking_correction_mode explicitly.");
353 if (params.isParamSetByUser("generalized_midpoint_alpha"))
354 paramError("generalized_midpoint_alpha",
355 "compatibility_mode reproduces the legacy backward-Euler update; do not set "
356 "generalized_midpoint_alpha explicitly.");
357
358 // Validate decomposition_method <-> kinematic_approximation mapping. The NEW strain
359 // calculator's `rashid_approximate` and `rashid_eigen` reproduce OLD's `TaylorExpansion`
360 // and `EigenSolution` exactly; OLD's `HughesWinget` has no NEW counterpart.
362 {
363 const std::string decomp = getParam<MooseEnum>("decomposition_method");
364 if (decomp != "TaylorExpansion" && decomp != "EigenSolution")
365 paramError("decomposition_method",
366 "compatibility_mode + strain = FINITE supports only "
367 "decomposition_method = TaylorExpansion or EigenSolution; '",
368 decomp,
369 "' has no Lagrangian kinematic_approximation counterpart.");
370 }
371 }
372 }
373 else
374 {
375 for (const auto & p : new_system_only)
376 if (params.isParamSetByUser(p))
378 "'",
379 p,
380 "' belongs to the new Lagrangian kernel system. Set new_system = true (or "
381 "compatibility_mode = true) to use it.");
382 }
383}
384
385void
387{
388 std::string ad_prepend = "";
389 if (_use_ad)
390 ad_prepend = "AD";
391
392 // Consistency checks across subdomains
394
395 // Gather info from all other QuasiStaticSolidMechanicsPhysics
397
398 // Deal with the optional AuxVariable based tensor quantity output
400
401 // Meta action which optionally spawns other actions
402 if (_current_task == "meta_action")
403 {
405 {
406 // Set the action parameters
407 const std::string type = "GeneralizedPlaneStrainAction";
408 auto action_params = _action_factory.getValidParams(type);
409 action_params.set<bool>("_built_by_moose") = true;
410 action_params.set<std::string>("registered_identifier") = "(AutoBuilt)";
411
412 // Skipping selected parameters in applyParameters() and then manually setting them only if
413 // they are set by the user is just to prevent both the current and deprecated variants of
414 // these parameters from both getting passed to the UserObject. Once we get rid of the
415 // deprecated versions, we can just set them all with applyParameters().
416 action_params.applyParameters(parameters(),
417 {"use_displaced_mesh",
418 "out_of_plane_pressure",
419 "out_of_plane_pressure_function",
420 "factor",
421 "pressure_factor"});
422 action_params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
423 action_params.set<bool>("use_automatic_differentiation") = _use_ad;
424
425 if (parameters().isParamSetByUser("out_of_plane_pressure"))
426 action_params.set<FunctionName>("out_of_plane_pressure") =
427 getParam<FunctionName>("out_of_plane_pressure");
428 if (parameters().isParamSetByUser("out_of_plane_pressure_function"))
429 action_params.set<FunctionName>("out_of_plane_pressure_function") =
430 getParam<FunctionName>("out_of_plane_pressure_function");
431 if (parameters().isParamSetByUser("factor"))
432 action_params.set<Real>("factor") = getParam<Real>("factor");
433 if (parameters().isParamSetByUser("pressure_factor"))
434 action_params.set<Real>("pressure_factor") = getParam<Real>("pressure_factor");
435
436 // Create and add the action to the warehouse
437 auto action = MooseSharedNamespace::static_pointer_cast<MooseObjectAction>(
438 _action_factory.create(type, name() + "_gps", action_params));
439 _awh.addActionBlock(action);
440 }
441 }
442
443 // Add variables
444 else if (_current_task == "add_variable")
445 {
446 // Add variables here only if the CommonSolidMechanicsAction does not exist.
447 // This happens notably if the QuasiStaticSolidMechanics was created by a meta_action
448 const auto common_actions = _awh.getActions<CommonSolidMechanicsAction>();
449 if (common_actions.empty() && getParam<bool>("add_variables"))
450 {
451 auto params = _factory.getValidParams("MooseVariable");
452 // determine necessary order
453 const bool second = _problem->mesh().hasSecondOrderElements();
454
455 params.set<MooseEnum>("order") = second ? "SECOND" : "FIRST";
456 params.set<MooseEnum>("family") = "LAGRANGE";
457 if (isParamValid("scaling"))
458 params.set<std::vector<Real>>("scaling") = {getParam<Real>("scaling")};
459
460 // Note how we do not add the block restriction because BISON's meta-actions
461 // currently rely on them not being added.
462
463 // Loop through the displacement variables
464 for (const auto & disp : _displacements)
465 {
466 // Create displacement variables
467 _problem->addVariable("MooseVariable", disp, params);
468 }
469 }
470
471 // Homogenization scalar
473 {
474 InputParameters params = _factory.getValidParams("MooseVariable");
475 const std::map<bool, std::vector<unsigned int>> mg_order_max{{true, {1, 4, 9}},
476 {false, {1, 3, 6}}};
477 std::size_t mg_order = 0;
478 for (auto i : index_range(_constraint_types))
479 {
480 const auto ctype = static_cast<Homogenization::ConstraintType>(_constraint_types.get(i));
482 mg_order++;
483 }
484 if (mg_order > mg_order_max.at(_lk_large_kinematics)[_ndisp - 1])
485 paramError("constraint_types",
486 "Number of non-none constraint types must not be greater than ",
487 mg_order_max.at(_lk_large_kinematics)[_ndisp - 1],
488 ", but ",
489 mg_order,
490 " are provided.");
491 params.set<MooseEnum>("family") = "SCALAR";
492 params.set<MooseEnum>("order") = mg_order;
493 auto fe_type = AddVariableAction::feType(params);
494 auto var_type = AddVariableAction::variableType(fe_type);
495 _problem->addVariable(var_type, _hname, params);
496 }
497 }
498 // Add Materials
499 else if (_current_task == "add_master_action_material")
500 {
501 // Automatic eigenstrain names
504
505 // Easiest just to branch on type here, as the strain systems are completely
506 // different
509 else
511 }
512
513 // Add Stress Divergence (and optionally WeakPlaneStress) Kernels
514 else if (_current_task == "add_kernel")
515 {
516 for (unsigned int i = 0; i < _ndisp; ++i)
517 {
518 auto tensor_kernel_type = getKernelType();
519 auto params = getKernelParameters(ad_prepend + tensor_kernel_type);
520
521 std::string kernel_name = "TM_" + name() + Moose::stringify(i);
522
523 // Set appropriate components for kernels, including in the cases where a planar model is
524 // running in planes other than the x-y plane (defined by _out_of_plane_strain_direction).
526 continue;
528 continue;
529
530 params.set<unsigned int>("component") = i;
531
532 params.set<NonlinearVariableName>("variable") = _displacements[i];
533
534 if (_save_in.size() == _ndisp)
535 params.set<std::vector<AuxVariableName>>("save_in") = {_save_in[i]};
536 if (_diag_save_in.size() == _ndisp)
537 params.set<std::vector<AuxVariableName>>("diag_save_in") = {_diag_save_in[i]};
538 if (isParamValid("out_of_plane_strain") && !_lagrangian_kernels)
539 params.set<std::vector<VariableName>>("out_of_plane_strain") = {
540 getParam<VariableName>("out_of_plane_strain")};
541
543 {
544 params.set<std::vector<VariableName>>("scalar_variable") = {_hname};
545 params.set<MultiMooseEnum>("constraint_types") = _constraint_types;
546 params.set<std::vector<FunctionName>>("targets") = _targets;
547 }
548
549 _problem->addKernel(ad_prepend + tensor_kernel_type, kernel_name, params);
550 }
551
553 {
554 auto params = getKernelParameters(ad_prepend + "WeakPlaneStress");
555 std::string wps_kernel_name = "TM_WPS_" + name();
556 params.set<NonlinearVariableName>("variable") = getParam<VariableName>("out_of_plane_strain");
557
558 _problem->addKernel(ad_prepend + "WeakPlaneStress", wps_kernel_name, params);
559 }
560 }
561}
562
563void
565{
566 // Do the coordinate system check only once the problem is created
567 if (_current_task == "setup_mesh_complete")
568 {
569 // get subdomain IDs
570 for (auto & name : _subdomain_names)
571 {
572 auto id = _mesh->getSubdomainID(name);
573 if (id == Moose::INVALID_BLOCK_ID)
574 paramError("block", "Subdomain \"" + name + "\" not found in mesh.");
575 else
576 _subdomain_ids.insert(id);
577 }
578 }
579
580 if (_current_task == "validate_coordinate_systems")
581 {
582 // use either block restriction list or list of all subdomains in the mesh
583 const auto & check_subdomains =
584 _subdomain_ids.empty() ? _problem->mesh().meshSubdomains() : _subdomain_ids;
585 if (check_subdomains.empty())
586 mooseError("No subdomains found");
587
588 // make sure all subdomains are using the same coordinate system
589 _coord_system = _problem->getCoordSystem(*check_subdomains.begin());
590 for (auto subdomain : check_subdomains)
591 if (_problem->getCoordSystem(subdomain) != _coord_system)
592 mooseError("The SolidMechanics action requires all subdomains to have the same coordinate "
593 "system.");
594
596 {
598 mooseError("'out_of_plane_direction' must be 'z' for axisymmetric simulations");
599 }
601 {
604 "Must specify two displacements for plane strain when the out of plane direction is z");
606 mooseError("Must specify three displacements for plane strain when the out of plane "
607 "direction is x or y");
608 }
609 }
610}
611
612void
614{
615 if (_current_task == "add_material")
617
618 // Add variables (optional)
619 if (_current_task == "add_aux_variable")
620 {
621 unsigned int index = 0;
622 for (auto out : _generate_output)
623 {
624 const auto & order = _material_output_order[index];
625 const auto & family = _material_output_family[index];
626
627 std::string type = (order == "CONSTANT" && family == "MONOMIAL")
628 ? "MooseVariableConstMonomial"
629 : "MooseVariable";
630
631 // Create output helper aux variables
632 auto params = _factory.getValidParams(type);
633 params.set<MooseEnum>("order") = order;
634 params.set<MooseEnum>("family") = family;
635
636 if (family == "MONOMIAL")
637 _problem->addAuxVariable(type, _base_name + out, params);
638 else
639 _problem->addVariable(type, _base_name + out, params);
640
641 index++;
642 }
643 }
644
645 // Add output AuxKernels
646 else if (_current_task == "add_aux_kernel")
647 {
648 std::string ad_prepend = _use_ad ? "AD" : "";
649 // Loop through output aux variables
650 unsigned int index = 0;
651 for (auto out : _generate_output)
652 {
653 if (_material_output_family[index] == "MONOMIAL")
654 {
656
657 params = _factory.getValidParams("MaterialRealAux");
658 params.applyParameters(parameters());
659 params.set<MaterialPropertyName>("property") = _base_name + out;
660 params.set<AuxVariableName>("variable") = _base_name + out;
661 params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
662
663 _problem->addAuxKernel(
664 ad_prepend + "MaterialRealAux", _base_name + out + '_' + name(), params);
665 }
666 index++;
667 }
668 }
669 else if (_current_task == "add_kernel")
670 {
671 std::string ad_prepend = _use_ad ? "AD" : "";
672 // Loop through output aux variables
673 unsigned int index = 0;
674 for (auto out : _generate_output)
675 {
676 if (_material_output_family[index] != "MONOMIAL")
677 {
679
680 params = _factory.getValidParams("MaterialPropertyValue");
681 params.applyParameters(parameters());
682 params.set<MaterialPropertyName>("prop_name") = _base_name + out;
683 params.set<NonlinearVariableName>("variable") = _base_name + out;
684
685 _problem->addKernel(
686 ad_prepend + "MaterialPropertyValue", _base_name + out + '_' + name(), params);
687 }
688 index++;
689 }
690 }
691}
692
693void
695{
696 // Create containers for collecting blockIDs and eigenstrain names from materials
697 std::map<std::string, std::set<SubdomainID>> material_eigenstrain_map;
698 std::set<std::string> eigenstrain_set;
699
700 std::set<MaterialPropertyName> verified_eigenstrain_names;
701
702 std::map<std::string, std::string> remove_add_map;
703 std::set<std::string> remove_reduced_set;
704
705 // Loop over all the materials(eigenstrains) already created
706 auto materials = _problem->getMaterialWarehouse().getObjects();
707 for (auto & mat : materials)
708 {
709 std::shared_ptr<BlockRestrictable> blk = std::dynamic_pointer_cast<BlockRestrictable>(mat);
710 const InputParameters & mat_params = mat->parameters();
711 auto & mat_name = mat->type();
712
713 // Check for eigenstrain names, only deal with those materials
714 if (mat_params.isParamValid("eigenstrain_name"))
715 {
716 std::shared_ptr<MaterialData> mat_dat;
717 auto name = mat_params.get<std::string>("eigenstrain_name");
718
719 // Check for base_name prefix
720 if (mat_params.isParamValid("base_name"))
721 name = mat_params.get<std::string>("base_name") + '_' + name;
722
723 // Check block restrictions
724 if (!blk)
725 mooseError("Internal error, Material object that does not inherit form BlockRestricted");
726 const std::set<SubdomainID> & blocks =
727 blk->blockRestricted() ? blk->blockIDs() : blk->meshBlockIDs();
728
729 if (std::includes(blocks.begin(), blocks.end(), _subdomain_ids.begin(), _subdomain_ids.end()))
730 {
731 material_eigenstrain_map[name].insert(blocks.begin(), blocks.end());
732 eigenstrain_set.insert(name);
733 }
734 }
735
736 // Account for reduced eigenstrains and CompositeEigenstrains
737 if (mat_name == "ComputeReducedOrderEigenstrain")
738 {
739 auto input_eigenstrain_names =
740 mat_params.get<std::vector<MaterialPropertyName>>("input_eigenstrain_names");
741 remove_reduced_set.insert(input_eigenstrain_names.begin(), input_eigenstrain_names.end());
742 }
743 // Account for CompositeEigenstrains
744 if (mat_name == "CompositeEigenstrain")
745 {
746 auto remove_list = mat_params.get<std::vector<MaterialPropertyName>>("tensors");
747 for (auto i : remove_list)
748 remove_reduced_set.insert(i);
749 }
750
751 // Account for MaterialADConverter , add or remove later
752 if (mat_name == "RankTwoTensorMaterialADConverter")
753 {
754 std::vector<MaterialPropertyName> remove_list;
755 std::vector<MaterialPropertyName> add_list;
756
757 if (mat_params.isParamValid("ad_props_out") && mat_params.isParamValid("reg_props_in") &&
758 _use_ad)
759 {
760 remove_list = mat_params.get<std::vector<MaterialPropertyName>>("reg_props_in");
761 add_list = mat_params.get<std::vector<MaterialPropertyName>>("ad_props_out");
762 }
763 if (mat_params.isParamValid("ad_props_in") && mat_params.isParamValid("reg_props_out") &&
764 !_use_ad)
765 {
766 remove_list = mat_params.get<std::vector<MaterialPropertyName>>("ad_props_in");
767 add_list = mat_params.get<std::vector<MaterialPropertyName>>("reg_props_out");
768 }
769
770 // These vectors are the same size as checked in MaterialADConverter
771 for (unsigned int index = 0; index < remove_list.size(); index++)
772 remove_add_map.emplace(remove_list[index], add_list[index]);
773 }
774 }
775 // All the materials have been accounted for, now remove or add parts
776
777 // Remove names which aren't eigenstrains (converter properties)
778 for (auto remove_add_index : remove_add_map)
779 {
780 const bool is_in = eigenstrain_set.find(remove_add_index.first) != eigenstrain_set.end();
781 if (is_in)
782 {
783 eigenstrain_set.erase(remove_add_index.first);
784 eigenstrain_set.insert(remove_add_index.second);
785 }
786 }
787 for (auto index : remove_reduced_set)
788 eigenstrain_set.erase(index);
789
790 // Compare the blockIDs set of eigenstrain names with the vector of _eigenstrain_names for the
791 // current subdomainID
792 std::set_union(eigenstrain_set.begin(),
793 eigenstrain_set.end(),
794 _eigenstrain_names.begin(),
795 _eigenstrain_names.end(),
796 std::inserter(verified_eigenstrain_names, verified_eigenstrain_names.begin()));
797
798 // Ensure the eigenstrain names previously passed include any missing names
799 _eigenstrain_names.resize(verified_eigenstrain_names.size());
800 std::copy(verified_eigenstrain_names.begin(),
801 verified_eigenstrain_names.end(),
802 _eigenstrain_names.begin());
803
804 Moose::out << COLOR_CYAN << "*** Automatic Eigenstrain Names ***"
805 << "\n"
806 << _name << ": " << Moose::stringify(_eigenstrain_names) << "\n"
807 << COLOR_DEFAULT << std::flush;
808}
809
810void
812{
813 // Ensure material output order and family vectors are same size as generate output
814
815 // check number of supplied orders and families
817 paramError("material_output_order",
818 "The number of orders assigned to material outputs must be: 0 to be assigned "
819 "CONSTANT; 1 to assign all outputs the same value, or the same size as the number "
820 "of generate outputs listed.");
821
822 if (_material_output_family.size() > 1 &&
824 paramError("material_output_family",
825 "The number of families assigned to material outputs must be: 0 to be assigned "
826 "MONOMIAL; 1 to assign all outputs the same value, or the same size as the number "
827 "of generate outputs listed.");
828
829 // if no value was provided, chose the default CONSTANT
830 if (_material_output_order.size() == 0)
832
833 // For only one order, make all orders the same magnitude
834 if (_material_output_order.size() == 1)
836 std::vector<std::string>(_generate_output.size(), _material_output_order[0]);
837
838 if (_verbose)
839 Moose::out << COLOR_CYAN << "*** Automatic applied material output orders ***"
840 << "\n"
841 << _name << ": " << Moose::stringify(_material_output_order) << "\n"
842 << COLOR_DEFAULT << std::flush;
843
844 // if no value was provided, chose the default MONOMIAL
845 if (_material_output_family.size() == 0)
847
848 // For only one family, make all families that value
849 if (_material_output_family.size() == 1)
851 std::vector<std::string>(_generate_output.size(), _material_output_family[0]);
852
853 if (_verbose)
854 Moose::out << COLOR_CYAN << "*** Automatic applied material output families ***"
855 << "\n"
856 << _name << ": " << Moose::stringify(_material_output_family) << "\n"
857 << COLOR_DEFAULT << std::flush;
858}
859
860std::string
862{
863 // The OLD pipeline publishes `stress` and `mechanical_strain` directly. The NEW pipeline
864 // publishes Cauchy stress under `cauchy_stress` and (when the strain calc is configured for
865 // OLD compatibility) the OLD-equivalent mechanical strain under `rotated_mechanical_strain`.
866 // Redirect the underlying property name so user output requests like `stress_xx` keep their
867 // OLD-style aux variable name but read from the NEW-style source.
869 return prop_name;
870 if (prop_name == "stress")
871 return "cauchy_stress";
872 if (prop_name == "mechanical_strain")
873 return "rotated_mechanical_strain";
874 return prop_name;
875}
876
877void
879{
880 std::string ad_prepend = _use_ad ? "AD" : "";
881
882 if (_current_task == "add_material")
883 {
884 // Add output Materials
885 for (auto out : _generate_output)
886 {
888
889 // RankTwoCartesianComponent
890 if (
891 [&]()
892 {
893 for (const auto & r2q : _rank_two_cartesian_component_table)
894 for (unsigned int a = 0; a < 3; ++a)
895 for (unsigned int b = 0; b < 3; ++b)
896 if (r2q.first + '_' + _component_table[a] + _component_table[b] == out)
897 {
898 auto type = ad_prepend + "RankTwoCartesianComponent";
899 params = _factory.getValidParams(type);
900 params.set<MaterialPropertyName>("rank_two_tensor") =
901 _base_name + remapCompatOutputProp(r2q.second);
902 params.set<unsigned int>("index_i") = a;
903 params.set<unsigned int>("index_j") = b;
904
905 params.applyParameters(parameters());
906 params.set<MaterialPropertyName>("property_name") = _base_name + out;
907 _problem->addMaterial(type, _base_name + out + '_' + name(), params);
908 return true;
909 }
910 return false;
911 }())
912 continue;
913
914 // RankTwoDirectionalComponent
915 if (setupOutput(out,
917 [&](std::string prop_name, std::string invariant)
918 {
919 auto type = ad_prepend + "RankTwoDirectionalComponent";
920 params = _factory.getValidParams(type);
921 params.set<MaterialPropertyName>("rank_two_tensor") =
923 params.set<MooseEnum>("invariant") = invariant;
924 params.applyParameters(parameters());
925 params.set<MaterialPropertyName>("property_name") = _base_name + out;
926 _problem->addMaterial(type, _base_name + out + '_' + name(), params);
927 }))
928 continue;
929
930 // RankTwoInvariant
931 if (setupOutput(out,
933 [&](std::string prop_name, std::string invariant)
934 {
935 auto type = ad_prepend + "RankTwoInvariant";
936 params = _factory.getValidParams(type);
937 params.set<MaterialPropertyName>("rank_two_tensor") =
939 params.set<MooseEnum>("invariant") = invariant;
940 params.applyParameters(parameters());
941 params.set<MaterialPropertyName>("property_name") = _base_name + out;
942 _problem->addMaterial(type, _base_name + out + '_' + name(), params);
943 }))
944 continue;
945
946 // RankTwoCylindricalComponent
947 if (setupOutput(
948 out,
950 [&](std::string prop_name, std::string component)
951 {
954 "Cannot use cylindrical component output in a spherical coordinate system.");
955 auto type = ad_prepend + "RankTwoCylindricalComponent";
956 params = _factory.getValidParams(type);
957 params.set<MaterialPropertyName>("rank_two_tensor") =
959 params.set<MooseEnum>("cylindrical_component") = component;
960 params.applyParameters(parameters());
961 params.set<MaterialPropertyName>("property_name") = _base_name + out;
962 _problem->addMaterial(type, _base_name + out + '_' + name(), params);
963 }))
964 continue;
965
966 // RankTwoSphericalComponent
967 if (setupOutput(out,
969 [&](std::string prop_name, std::string component)
970 {
971 auto type = ad_prepend + "RankTwoSphericalComponent";
972 params = _factory.getValidParams(type);
973 params.set<MaterialPropertyName>("rank_two_tensor") =
975 params.set<MooseEnum>("spherical_component") = component;
976 params.applyParameters(parameters());
977 params.set<MaterialPropertyName>("property_name") = _base_name + out;
978 _problem->addMaterial(type, _base_name + out + '_' + name(), params);
979 }))
980 continue;
981
982 paramError("generate_output", "Unable to add output Material for '", out, "'");
983 }
984 }
985}
986
987void
989{
990 // Gather info about all other solid mechanics physics when we add variables
991 if (_current_task == "validate_coordinate_systems" && getParam<bool>("add_variables"))
992 {
994 for (const auto & action : actions)
995 {
996 const auto size_before = _subdomain_id_union.size();
997 const auto added_size = action->_subdomain_ids.size();
998 _subdomain_id_union.insert(action->_subdomain_ids.begin(), action->_subdomain_ids.end());
999 const auto size_after = _subdomain_id_union.size();
1000
1001 if (size_after != size_before + added_size)
1002 mooseError("The block restrictions in the SolidMechanics/QuasiStatic actions must be "
1003 "non-overlapping.");
1004
1005 if (added_size == 0 && actions.size() > 1)
1006 mooseError(
1007 "No SolidMechanics/QuasiStatic action can be block unrestricted if more than one "
1008 "SolidMechanics/QuasiStatic action is specified.");
1009 }
1010 }
1011}
1012
1013void
1015{
1016 std::string type;
1018 type = "ComputeLagrangianStrain";
1019 else if (_coord_system == Moose::COORD_RZ)
1020 type = "ComputeLagrangianStrainAxisymmetricCylindrical";
1022 type = "ComputeLagrangianStrainCentrosymmetricSpherical";
1023 else
1024 mooseError("Unsupported coordinate system");
1025
1026 auto params = _factory.getValidParams(type);
1027
1028 if (isParamValid("strain_base_name"))
1029 params.set<std::string>("base_name") = getParam<std::string>("strain_base_name");
1030
1031 params.set<std::vector<VariableName>>("displacements") = _coupled_displacements;
1032 params.set<std::vector<MaterialPropertyName>>("eigenstrain_names") = _eigenstrain_names;
1033 params.set<bool>("large_kinematics") = _lk_large_kinematics;
1034 params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
1035
1036 // Error if volumetric locking correction is on for higher-order elements
1037 if (_problem->mesh().hasSecondOrderElements() && _lk_locking)
1038 mooseError("Volumetric locking correction should not be used for "
1039 "higher-order elements.");
1040
1041 params.set<bool>("stabilize_strain") = _lk_locking;
1042
1043 // Forward the strain time-integration options. In compatibility mode kinematic_approximation
1044 // and F_bar_mode are overridden below (and the action errors if the user also set them).
1045 params.set<MooseEnum>("kinematic_approximation") = getParam<MooseEnum>("kinematic_approximation");
1046 params.set<Real>("alpha") = getParam<Real>("generalized_midpoint_alpha");
1047 params.set<MooseEnum>("F_bar_mode") = getParam<MooseEnum>("volumetric_locking_correction_mode");
1048
1050 {
1051 params.set<std::vector<MaterialPropertyName>>("homogenization_gradient_names") = {
1053 }
1054
1055 // OLD-compat configuration: map decomposition_method -> kinematic_approximation, switch the
1056 // F-bar to incremental mode (matches OLD `ComputeFiniteStrain`'s `_Fhat` F-bar), and have
1057 // the strain calc publish a real rotation_increment so the wrapped ComputeStressBase
1058 // material's FSR rotates correctly across steps.
1060 {
1062 {
1063 const std::string decomp = getParam<MooseEnum>("decomposition_method");
1064 if (decomp == "TaylorExpansion")
1065 params.set<MooseEnum>("kinematic_approximation") = "rashid_approximate";
1066 else if (decomp == "EigenSolution")
1067 params.set<MooseEnum>("kinematic_approximation") = "rashid_eigen";
1068 // HughesWinget rejected in the ctor; SMALL strain ignores kinematic_approximation.
1069 }
1070
1071 // OLD's `volumetric_locking_correction = true` in incremental finite strain maps to
1072 // `F_bar_mode = incremental` on the NEW strain calc. The strain calc rejects
1073 // `incremental` for small kinematics -- for SMALL + locking we leave `F_bar_mode` at its
1074 // default (`total`), which is the additive trace correction (matches OLD's small-strain
1075 // B-bar in the locked-flag-equivalent form).
1077 params.set<MooseEnum>("F_bar_mode") = "incremental";
1078
1079 // Only meaningful with FINITE -- in SMALL the wrap runs in passthrough-off mode and the
1080 // rotation increment isn't consumed downstream.
1081 params.set<bool>("publish_rotation_increment") = _lk_large_kinematics;
1082 }
1083
1084 _problem->addMaterial(type, name() + "_strain", params);
1085
1086 // OLD-compat configuration: auto-add ComputeLagrangianWrappedStress around the user's
1087 // ComputeStressBase-style stress material. `input_stress = "stress"` and
1088 // `input_jacobian = "Jacobian_mult"` default to the property names every
1089 // ComputeStressBase descendant publishes.
1091 {
1092 const std::string wrap_type = "ComputeLagrangianWrappedStress";
1093 auto wrap_params = _factory.getValidParams(wrap_type);
1094 if (isParamValid("base_name"))
1095 wrap_params.set<std::string>("base_name") = getParam<std::string>("base_name");
1096 wrap_params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
1097 // large_kinematics is derived from the strain calculator's LARGE_KINEMATICS guarantee.
1098 wrap_params.set<MooseEnum>("objective_rate") = "rashid";
1099 // FINITE: the wrap runs in passthrough mode (the wrapped material's FSR already produced
1100 // the correctly-rotated cumulative Cauchy stress, fed by our published rotation_increment).
1101 // SMALL: nothing to rotate, plain Cauchy passthrough via the rate's small-kinematics branch.
1102 wrap_params.set<bool>("rotate_old_stress") = _lk_large_kinematics;
1103 _problem->addMaterial(wrap_type, name() + "_compatibility_wrap", wrap_params);
1104 }
1105
1106 // Add the homogenization strain calculator
1108 {
1109 std::string type = "ComputeHomogenizedLagrangianStrain";
1110 auto params = _factory.getValidParams(type);
1111
1112 params.set<MaterialPropertyName>("homogenization_gradient_name") = _homogenization_strain_name;
1113 params.set<std::vector<VariableName>>("macro_gradient") = {_hname};
1114 params.set<MultiMooseEnum>("constraint_types") = _constraint_types;
1115 params.set<std::vector<FunctionName>>("targets") = _targets;
1116
1117 _problem->addMaterial(type, name() + "_compute_" + _homogenization_strain_name, params);
1118 }
1119}
1120
1121void
1123{
1124 std::string ad_prepend = _use_ad ? "AD" : "";
1125
1126 std::string type;
1127
1128 // no plane strain
1130 {
1131 std::map<std::pair<Moose::CoordinateSystemType, StrainAndIncrement>, std::string> type_map = {
1132 {{Moose::COORD_XYZ, StrainAndIncrement::SmallTotal}, "ComputeSmallStrain"},
1133 {{Moose::COORD_XYZ, StrainAndIncrement::SmallIncremental}, "ComputeIncrementalStrain"},
1134 {{Moose::COORD_XYZ, StrainAndIncrement::FiniteIncremental}, "ComputeFiniteStrain"},
1135 {{Moose::COORD_RZ, StrainAndIncrement::SmallTotal}, "ComputeAxisymmetricRZSmallStrain"},
1137 "ComputeAxisymmetricRZIncrementalStrain"},
1139 "ComputeAxisymmetricRZFiniteStrain"},
1140 {{Moose::COORD_RSPHERICAL, StrainAndIncrement::SmallTotal}, "ComputeRSphericalSmallStrain"},
1142 "ComputeRSphericalIncrementalStrain"},
1144 "ComputeRSphericalFiniteStrain"}};
1145
1146 auto type_it = type_map.find(std::make_pair(_coord_system, _strain_and_increment));
1147 if (type_it != type_map.end())
1148 type = type_it->second;
1149 else
1150 mooseError("Unsupported strain formulation");
1151 }
1155 {
1157 paramError("use_automatic_differentiation", "AD not setup for use with PlaneStrain");
1158
1159 std::map<std::pair<Moose::CoordinateSystemType, StrainAndIncrement>, std::string> type_map = {
1160 {{Moose::COORD_XYZ, StrainAndIncrement::SmallTotal}, "ComputePlaneSmallStrain"},
1161 {{Moose::COORD_XYZ, StrainAndIncrement::SmallIncremental}, "ComputePlaneIncrementalStrain"},
1162 {{Moose::COORD_XYZ, StrainAndIncrement::FiniteIncremental}, "ComputePlaneFiniteStrain"},
1163 {{Moose::COORD_RZ, StrainAndIncrement::SmallTotal}, "ComputeAxisymmetric1DSmallStrain"},
1165 "ComputeAxisymmetric1DIncrementalStrain"},
1167 "ComputeAxisymmetric1DFiniteStrain"}};
1168
1169 // choose kernel type based on coordinate system
1170 auto type_it = type_map.find(std::make_pair(_coord_system, _strain_and_increment));
1171 if (type_it != type_map.end())
1172 type = type_it->second;
1173 else
1174 mooseError("Unsupported coordinate system for plane strain.");
1175 }
1176 else
1177 mooseError("Unsupported planar formulation");
1178
1179 // set material parameters
1180 auto params = _factory.getValidParams(ad_prepend + type);
1181 params.applyParameters(
1182 parameters(),
1183 {"displacements", "use_displaced_mesh", "out_of_plane_strain", "scalar_out_of_plane_strain"});
1184
1185 if (isParamValid("strain_base_name"))
1186 params.set<std::string>("base_name") = getParam<std::string>("strain_base_name");
1187
1188 params.set<std::vector<VariableName>>("displacements") = _coupled_displacements;
1189 params.set<bool>("use_displaced_mesh") = false;
1190
1191 if (isParamValid("scalar_out_of_plane_strain"))
1192 params.set<std::vector<VariableName>>("scalar_out_of_plane_strain") = {
1193 getParam<VariableName>("scalar_out_of_plane_strain")};
1194
1195 if (isParamValid("out_of_plane_strain"))
1196 params.set<std::vector<VariableName>>("out_of_plane_strain") = {
1197 getParam<VariableName>("out_of_plane_strain")};
1198
1199 params.set<std::vector<MaterialPropertyName>>("eigenstrain_names") = _eigenstrain_names;
1200
1201 _problem->addMaterial(ad_prepend + type, name() + "_strain", params);
1202}
1203
1204std::string
1206{
1208 {
1209 std::string type;
1211 {
1213 type = "HomogenizedTotalLagrangianStressDivergence";
1215 type = "TotalLagrangianStressDivergence";
1217 type = "UpdatedLagrangianStressDivergence";
1218 else
1219 mooseError("Unknown formulation type");
1220 }
1221 else if (_coord_system == Moose::COORD_RZ)
1222 {
1224 mooseError("The Lagrangian mechanics kernels do not yet support homogenization in "
1225 "coordinate systems other than Cartesian.");
1227 type = "TotalLagrangianStressDivergenceAxisymmetricCylindrical";
1229 mooseError("The Lagrangian mechanics kernels do not yet support the updated Lagrangian "
1230 "formulation in RZ coordinates.");
1231 }
1233 {
1235 mooseError("The Lagrangian mechanics kernels do not yet support homogenization in "
1236 "coordinate systems other than Cartesian.");
1238 type = "TotalLagrangianStressDivergenceCentrosymmetricSpherical";
1240 mooseError("The Lagrangian mechanics kernels do not yet support the updated Lagrangian "
1241 "formulation in RZ coordinates.");
1242 }
1243 else
1244 mooseError("Unsupported coordinate system");
1245 return type;
1246 }
1247 else
1248 {
1249 std::map<Moose::CoordinateSystemType, std::string> type_map = {
1250 {Moose::COORD_XYZ, "StressDivergenceTensors"},
1251 {Moose::COORD_RZ, "StressDivergenceRZTensors"},
1252 {Moose::COORD_RSPHERICAL, "StressDivergenceRSphericalTensors"}};
1253
1254 // choose kernel type based on coordinate system
1255 auto type_it = type_map.find(_coord_system);
1256 if (type_it != type_map.end())
1257 return type_it->second;
1258 else
1259 mooseError("Unsupported coordinate system");
1260 }
1261}
1262
1265{
1267 params.applyParameters(
1268 parameters(),
1269 {"displacements", "use_displaced_mesh", "save_in", "diag_save_in", "out_of_plane_strain"});
1270
1271 params.set<std::vector<VariableName>>("displacements") = _coupled_displacements;
1272
1274 {
1275 params.set<bool>("use_displaced_mesh") =
1277 // large_kinematics is derived from the strain calculator's LARGE_KINEMATICS guarantee.
1278 params.set<bool>("stabilize_strain") = _lk_locking;
1279 params.set<MooseEnum>("F_bar_mode") = getParam<MooseEnum>("volumetric_locking_correction_mode");
1281 params.set<bool>("off_diagonal_jacobian") = _lk_h_off_jac;
1282 // Match the strain calc's F-bar mode on the kernel -- the TL kernel's OLD-compat B-bar
1283 // residual is gated on `F_bar_mode = incremental && stabilize_strain`. Setting it on
1284 // both keeps the kernel and the strain material on the same F-bar formulation. Only
1285 // applicable to large kinematics (the strain calc rejects `incremental` for small).
1287 params.set<MooseEnum>("F_bar_mode") = "incremental";
1288 }
1289 else
1290 params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
1291
1292 return params;
1293}
const Real p
InputParameters emptyInputParameters()
const ExecFlagType EXEC_TIMESTEP_END
char ** blocks
registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "meta_action")
std::shared_ptr< Action > create(const std::string &action, const std::string &action_name, InputParameters &parameters)
InputParameters getValidParams(const std::string &name)
std::vector< const T * > getActions()
void addActionBlock(std::shared_ptr< Action > blk)
std::shared_ptr< MooseMesh > & _mesh
std::shared_ptr< FEProblemBase > & _problem
const std::string & _current_task
ActionWarehouse & _awh
static libMesh::FEType feType(const InputParameters &params)
static std::string variableType(const libMesh::FEType &fe_type, const bool is_fv=false, const bool is_array=false)
Store common tensor mechanics parameters.
InputParameters getValidParams(const std::string &name) const
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
bool isParamSetByUser(const std::string &name) const
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
void addClassDescription(const std::string &doc_string)
T & set(const std::string &name, bool quiet_mode=false)
bool isParamValid(const std::string &name) const
void applyParameters(const InputParameters &common, const std::vector< std::string > &exclude={}, const bool allow_private=false)
const InputParameters & parameters() const
const std::string & type() const
void mooseDocumentedError(const std::string &repo_name, const unsigned int issue_num, Args &&... args) const
const std::string & name() const
void paramError(const std::string &param, Args... args) const
bool isParamSetByUser(const std::string &name) const
void mooseError(Args &&... args) const
const std::string & _name
void mooseInfo(Args &&... args) const
bool isParamValid(const std::string &name) const
std::set< MooseEnumItem >::const_iterator find(const MooseEnumItem &other) const
void setAdditionalValue(const std::string &names)
unsigned int get(unsigned int i) const
unsigned int size() const
ActionFactory & _action_factory
Factory & _factory
static std::map< std::string, std::string > _rank_two_cartesian_component_table
static const std::vector< char > _component_table
table data for output generation
static const std::map< std::string, std::pair< std::string, std::vector< std::string > > > _rank_two_invariant_table
static const std::map< std::string, std::pair< std::string, std::vector< std::string > > > _rank_two_spherical_component_table
static const std::map< std::string, std::pair< std::string, std::vector< std::string > > > _rank_two_directional_component_table
static const std::map< std::string, std::pair< std::string, std::vector< std::string > > > _rank_two_cylindrical_component_table
const bool _lk_h_off_jac
Whether to use the off diagonal scalar jacobian for the homogenization system.
bool _cylindrical_axis_point1_valid
booleans used to determine if cylindrical axis points are passed
std::set< SubdomainID > _subdomain_ids
set generated from the passed in vector of subdomain names
const bool _lk_large_kinematics
Simplified flag for small/large deformations, Lagrangian kernel system.
bool _lk_homogenization
Flag indicating if the homogenization system is present for new kernels.
LKFormulation
New kernel system kinematics types.
virtual InputParameters getKernelParameters(std::string type)
bool setupOutput(std::string out, T table, T2 setup)
Helper function to decode generate_outputs options using a "table" of scalar output quantities and a ...
Point _cylindrical_axis_point1
points used to determine axis of rotation for cylindrical stress/strain quantities
std::vector< VariableName > _coupled_displacements
Coupled displacement variables.
bool _spherical_center_point_valid
booleans used to determine if spherical center point is passed
std::set< SubdomainID > _subdomain_id_union
set generated from the combined block restrictions of all SolidMechanics/Master action blocks
enum QuasiStaticSolidMechanicsPhysics::Strain _strain
QuasiStaticSolidMechanicsPhysics(const InputParameters &params)
std::vector< std::string > _generate_output
output materials to generate scalar stress/strain tensor quantities
const bool _auto_eigenstrain
automatically gather names of eigenstrain tensors provided by simulation objects
const bool _compatibility_mode
OLD-compat shim: auto-configures the Lagrangian kernel system to reproduce StressDivergenceTensors + ...
const bool _lagrangian_kernels
New or old kernel system. True if new_system = true OR compatibility_mode = true.
PlanarFormulation
use an out of plane stress/strain formulation
std::vector< MaterialPropertyName > _eigenstrain_names
enum QuasiStaticSolidMechanicsPhysics::PlanarFormulation _planar_formulation
const std::string _base_name
base name for the current master action block
enum QuasiStaticSolidMechanicsPhysics::StrainAndIncrement _strain_and_increment
std::vector< VariableName > _displacements
displacement variables
bool _use_displaced_mesh
use displaced mesh (true unless _strain is SMALL)
unsigned int _ndisp
Number of displacement variables.
std::vector< AuxVariableName > _save_in
residual debugging
std::string remapCompatOutputProp(const std::string &prop_name) const
Apply compatibility_mode remapping to a property name pulled from the _rank_two_* output tables: in c...
std::vector< SubdomainName > _subdomain_names
if this vector is not empty the variables, kernels and materials are restricted to these subdomains
const bool _lk_locking
Simplified volumetric locking correction flag for new kernels.
Point _spherical_center_point
center point for spherical stress/strain quantities
const MultiMooseEnum constraintType("strain stress none")
ConstraintType
Constraint type: stress/PK stress or strain/deformation gradient.
std::string stringify(const T &t)
COORD_RSPHERICAL
const SubdomainID INVALID_BLOCK_ID