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 "QuasiStaticSolidMechanicsPhysics.h"
16 : #include "Material.h"
17 : #include "CommonSolidMechanicsAction.h"
18 :
19 : #include "BlockRestrictable.h"
20 :
21 : #include "HomogenizationInterface.h"
22 : #include "AddVariableAction.h"
23 :
24 : #include "libmesh/string_to_enum.h"
25 : #include <algorithm>
26 :
27 : registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "meta_action");
28 :
29 : registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "setup_mesh_complete");
30 :
31 : registerMooseAction("SolidMechanicsApp",
32 : QuasiStaticSolidMechanicsPhysics,
33 : "validate_coordinate_systems");
34 :
35 : registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "add_variable");
36 :
37 : registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "add_aux_variable");
38 :
39 : registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "add_kernel");
40 :
41 : registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "add_aux_kernel");
42 :
43 : registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "add_material");
44 :
45 : registerMooseAction("SolidMechanicsApp",
46 : QuasiStaticSolidMechanicsPhysics,
47 : "add_master_action_material");
48 :
49 : registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "add_scalar_kernel");
50 :
51 : registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "add_user_object");
52 :
53 : InputParameters
54 4497 : QuasiStaticSolidMechanicsPhysics::validParams()
55 : {
56 4497 : InputParameters params = QuasiStaticSolidMechanicsPhysicsBase::validParams();
57 4497 : 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 8994 : 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 8994 : params.addParamNamesToGroup("block", "Advanced");
67 :
68 8994 : params.addParam<MultiMooseEnum>("additional_generate_output",
69 8994 : QuasiStaticSolidMechanicsPhysicsBase::outputPropertiesType(),
70 : "Add scalar quantity output for stress and/or strain (will be "
71 : "appended to the list in `generate_output`)");
72 8994 : params.addParam<MultiMooseEnum>(
73 : "additional_material_output_order",
74 8994 : QuasiStaticSolidMechanicsPhysicsBase::materialOutputOrders(),
75 : "Specifies the order of the FE shape function to use for this variable.");
76 :
77 8994 : params.addParam<MultiMooseEnum>(
78 : "additional_material_output_family",
79 8994 : QuasiStaticSolidMechanicsPhysicsBase::materialOutputFamilies(),
80 : "Specifies the family of FE shape functions to use for this variable.");
81 :
82 8994 : params.addParamNamesToGroup("additional_generate_output additional_material_output_order "
83 : "additional_material_output_family",
84 : "Output");
85 8994 : 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 8994 : params.addParam<std::vector<TagName>>(
89 : "extra_vector_tags",
90 : "The tag names for extra vectors that residual data should be saved into");
91 8994 : 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 8994 : params.addParam<Real>("scaling", "The scaling to apply to the displacement variables");
95 8994 : params.addParam<Point>(
96 : "cylindrical_axis_point1",
97 : "Starting point for direction of axis of rotation for cylindrical stress/strain.");
98 8994 : params.addParam<Point>(
99 : "cylindrical_axis_point2",
100 : "Ending point for direction of axis of rotation for cylindrical stress/strain.");
101 8994 : params.addParam<Point>("spherical_center_point",
102 : "Center point of the spherical coordinate system.");
103 8994 : params.addParam<Point>("direction", "Direction stress/strain is calculated in");
104 8994 : params.addParam<bool>("automatic_eigenstrain_names",
105 8994 : false,
106 : "Collects all material eigenstrains and passes to required strain "
107 : "calculator within TMA internally.");
108 :
109 : // Homogenization system input
110 8994 : params.addParam<MultiMooseEnum>(
111 : "constraint_types",
112 : Homogenization::constraintType,
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 8994 : params.addParam<std::vector<FunctionName>>(
116 : "targets", {}, "Functions giving the targets to hit for constraint types that are not none.");
117 8994 : params.addParam<bool>(
118 : "homogenized_off_diagonal_jacobian",
119 8994 : true,
120 : "Whether to include the off-diagonal scalar contributions to the homogenized jacobian");
121 :
122 8994 : params.addParamNamesToGroup("scaling", "Variables");
123 8994 : params.addParamNamesToGroup("strain_base_name automatic_eigenstrain_names", "Strain");
124 8994 : params.addParamNamesToGroup(
125 : "cylindrical_axis_point1 cylindrical_axis_point2 spherical_center_point direction",
126 : "Coordinate system");
127 :
128 4497 : return params;
129 0 : }
130 :
131 4497 : QuasiStaticSolidMechanicsPhysics::QuasiStaticSolidMechanicsPhysics(const InputParameters & params)
132 : : QuasiStaticSolidMechanicsPhysicsBase(params),
133 8994 : _displacements(getParam<std::vector<VariableName>>("displacements")),
134 4497 : _ndisp(_displacements.size()),
135 4497 : _coupled_displacements(_ndisp),
136 8994 : _save_in(getParam<std::vector<AuxVariableName>>("save_in")),
137 8994 : _diag_save_in(getParam<std::vector<AuxVariableName>>("diag_save_in")),
138 13491 : _subdomain_names(getParam<std::vector<SubdomainName>>("block")),
139 : _subdomain_ids(),
140 8994 : _strain(getParam<MooseEnum>("strain").getEnum<Strain>()),
141 8994 : _planar_formulation(getParam<MooseEnum>("planar_formulation").getEnum<PlanarFormulation>()),
142 4497 : _out_of_plane_direction(
143 4497 : getParam<MooseEnum>("out_of_plane_direction").getEnum<OutOfPlaneDirection>()),
144 9078 : _base_name(isParamValid("base_name") ? getParam<std::string>("base_name") + "_" : ""),
145 8994 : _material_output_order(getParam<MultiMooseEnum>("material_output_order")),
146 8994 : _material_output_family(getParam<MultiMooseEnum>("material_output_family")),
147 4497 : _cylindrical_axis_point1_valid(params.isParamSetByUser("cylindrical_axis_point1")),
148 4497 : _cylindrical_axis_point2_valid(params.isParamSetByUser("cylindrical_axis_point2")),
149 4497 : _direction_valid(params.isParamSetByUser("direction")),
150 8994 : _verbose(getParam<bool>("verbose")),
151 4497 : _spherical_center_point_valid(params.isParamSetByUser("spherical_center_point")),
152 8994 : _auto_eigenstrain(getParam<bool>("automatic_eigenstrain_names")),
153 8994 : _lagrangian_kernels(getParam<bool>("new_system")),
154 4497 : _lk_large_kinematics(_strain == Strain::Finite),
155 8994 : _lk_formulation(getParam<MooseEnum>("formulation").getEnum<LKFormulation>()),
156 8994 : _lk_locking(getParam<bool>("volumetric_locking_correction")),
157 4497 : _lk_homogenization(false),
158 4497 : _constraint_types(getParam<MultiMooseEnum>("constraint_types")),
159 8994 : _targets(getParam<std::vector<FunctionName>>("targets")),
160 17988 : _lk_h_off_jac(getParam<bool>("homogenized_off_diagonal_jacobian"))
161 : {
162 : // determine if incremental strains are to be used
163 8994 : if (isParamValid("incremental"))
164 : {
165 2478 : const bool incremental = getParam<bool>("incremental");
166 1239 : if (!incremental && _strain == Strain::Small)
167 61 : _strain_and_increment = StrainAndIncrement::SmallTotal;
168 0 : else if (!incremental && _strain == Strain::Finite)
169 0 : _strain_and_increment = StrainAndIncrement::FiniteTotal;
170 1178 : else if (incremental && _strain == Strain::Small)
171 570 : _strain_and_increment = StrainAndIncrement::SmallIncremental;
172 608 : else if (incremental && _strain == Strain::Finite)
173 608 : _strain_and_increment = StrainAndIncrement::FiniteIncremental;
174 : else
175 0 : mooseError("Internal error");
176 : }
177 : else
178 : {
179 3258 : if (_strain == Strain::Small)
180 : {
181 1845 : _strain_and_increment = StrainAndIncrement::SmallTotal;
182 1845 : mooseInfo("SolidMechanics Action: selecting 'total small strain' formulation. Use "
183 : "`incremental = true` to select 'incremental small strain' instead.");
184 : }
185 1413 : else if (_strain == Strain::Finite)
186 : {
187 1413 : _strain_and_increment = StrainAndIncrement::FiniteIncremental;
188 1413 : mooseInfo("SolidMechanics Action: selecting 'incremental finite strain' formulation.");
189 : }
190 : else
191 0 : mooseError("Internal error");
192 : }
193 :
194 : // determine if displaced mesh is to be used
195 4497 : _use_displaced_mesh = (_strain == Strain::Finite);
196 8994 : if (params.isParamSetByUser("use_displaced_mesh") && !_lagrangian_kernels)
197 : {
198 516 : bool use_displaced_mesh_param = getParam<bool>("use_displaced_mesh");
199 481 : if (use_displaced_mesh_param != _use_displaced_mesh && params.isParamSetByUser("strain"))
200 0 : mooseError("Wrong combination of use displaced mesh and strain model");
201 258 : _use_displaced_mesh = use_displaced_mesh_param;
202 : }
203 :
204 : // convert vector of VariableName to vector of VariableName
205 16687 : for (unsigned int i = 0; i < _ndisp; ++i)
206 12190 : _coupled_displacements[i] = _displacements[i];
207 :
208 4497 : if (_save_in.size() != 0 && _save_in.size() != _ndisp)
209 0 : mooseError("Number of save_in variables should equal to the number of displacement variables ",
210 0 : _ndisp);
211 :
212 4497 : if (_diag_save_in.size() != 0 && _diag_save_in.size() != _ndisp)
213 0 : mooseError(
214 : "Number of diag_save_in variables should equal to the number of displacement variables ",
215 0 : _ndisp);
216 :
217 : // plane strain consistency check
218 4497 : if (_planar_formulation != PlanarFormulation::None)
219 : {
220 368 : if (_lagrangian_kernels)
221 0 : mooseDocumentedError(
222 : "moose",
223 : 27340,
224 : "Planar formulations are not yet available through the Physics syntax with new_system = "
225 : "true. They can be enabled by manually setting up the appropriate objects. Please refer "
226 : "to the documentation and regression tests for examples.");
227 736 : if (params.isParamSetByUser("out_of_plane_strain") &&
228 48 : _planar_formulation != PlanarFormulation::WeakPlaneStress)
229 0 : mooseError(
230 : "out_of_plane_strain should only be specified with planar_formulation=WEAK_PLANE_STRESS");
231 736 : else if (!params.isParamSetByUser("out_of_plane_strain") &&
232 320 : _planar_formulation == PlanarFormulation::WeakPlaneStress)
233 0 : mooseError("out_of_plane_strain must be specified with planar_formulation=WEAK_PLANE_STRESS");
234 : }
235 :
236 : // convert output variable names to lower case
237 19595 : for (const auto & out : getParam<MultiMooseEnum>("generate_output"))
238 : {
239 : std::string lower(out);
240 : std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
241 10601 : _generate_output.push_back(lower);
242 : }
243 :
244 4497 : if (!_generate_output.empty())
245 2270 : verifyOrderAndFamilyOutputs();
246 :
247 : // Error if volumetric locking correction is true for 1D problems
248 4768 : if (_ndisp == 1 && getParam<bool>("volumetric_locking_correction"))
249 0 : mooseError("Volumetric locking correction should be set to false for 1D problems.");
250 :
251 10462 : if (!getParam<bool>("add_variables") && params.isParamSetByUser("scaling"))
252 0 : paramError("scaling",
253 : "The scaling parameter has no effect unless add_variables is set to true. Did you "
254 : "mean to set 'add_variables = true'?");
255 :
256 : // Get cylindrical axis points if set by user
257 4496 : if (_cylindrical_axis_point1_valid && _cylindrical_axis_point2_valid)
258 : {
259 24 : _cylindrical_axis_point1 = getParam<Point>("cylindrical_axis_point1");
260 24 : _cylindrical_axis_point2 = getParam<Point>("cylindrical_axis_point2");
261 : }
262 :
263 : // Get spherical center point if set by user
264 4496 : if (_spherical_center_point_valid)
265 66 : _spherical_center_point = getParam<Point>("spherical_center_point");
266 :
267 : // Get direction for tensor component if set by user
268 4496 : if (_direction_valid)
269 34 : _direction = getParam<Point>("direction");
270 :
271 : // Get eigenstrain names if passed by user
272 8992 : _eigenstrain_names = getParam<std::vector<MaterialPropertyName>>("eigenstrain_names");
273 :
274 : // Determine if we're going to use the homogenization system for the new
275 : // lagrangian kernels
276 4496 : bool ctype_set = params.isParamSetByUser("constraint_types");
277 4496 : bool targets_set = params.isParamSetByUser("targets");
278 4496 : if (ctype_set || targets_set)
279 : {
280 8 : if (!(ctype_set && targets_set))
281 0 : mooseError("To use the Lagrangian kernel homogenization system you "
282 : "most provide both the constraint_types and the targets "
283 : "parameters");
284 8 : _lk_homogenization = true;
285 : // Do consistency checking on the kernel options
286 8 : if (_lk_homogenization && (_lk_formulation == LKFormulation::Updated))
287 0 : mooseError("The Lagrangian kernel homogenization system requires the "
288 : "use of formulation = TOTAL");
289 : }
290 :
291 : // Cross check options to weed out incompatible choices for the new lagrangian
292 : // kernel system
293 4496 : if (_lagrangian_kernels)
294 : {
295 260 : if (_use_ad)
296 0 : mooseError("The Lagrangian kernel system is not yet compatible with AD. "
297 : "Do not set the use_automatic_differentiation flag.");
298 :
299 520 : if (params.isParamSetByUser("use_finite_deform_jacobian"))
300 0 : mooseError("The Lagrangian kernel system always produces the exact "
301 : "Jacobian. use_finite_deform_jacobian is redundant and "
302 : " should not be set");
303 520 : if (params.isParamSetByUser("global_strain"))
304 0 : mooseError("The Lagrangian kernel system is not compatible with "
305 : "the global_strain option. Use the homogenization "
306 : " system instead");
307 520 : if (params.isParamSetByUser("decomposition_method"))
308 0 : mooseError("The decomposition_method parameter should not be used "
309 : " with the Lagrangian kernel system. Similar options "
310 : " for native small deformation material models are "
311 : " available as part of the ComputeLagrangianStress "
312 : " material system.");
313 : }
314 : else
315 : {
316 8472 : if (params.isParamSetByUser("formulation"))
317 0 : mooseError("The StressDiveregenceTensor system always uses an "
318 : " updated Lagrangian formulation. Do not set the "
319 : " formulation parameter, it is only used with the "
320 : " new Lagrangian kernel system.");
321 4236 : if (_lk_homogenization)
322 0 : mooseError("The homogenization system can only be used with the "
323 : "new Lagrangian kernels");
324 : }
325 4496 : }
326 :
327 : void
328 38043 : QuasiStaticSolidMechanicsPhysics::act()
329 : {
330 38043 : std::string ad_prepend = "";
331 38043 : if (_use_ad)
332 : ad_prepend = "AD";
333 :
334 : // Consistency checks across subdomains
335 38043 : actSubdomainChecks();
336 :
337 : // Gather info from all other QuasiStaticSolidMechanicsPhysics
338 38041 : actGatherActionParameters();
339 :
340 : // Deal with the optional AuxVariable based tensor quantity output
341 38037 : actOutputGeneration();
342 :
343 : // Meta action which optionally spawns other actions
344 38037 : if (_current_task == "meta_action")
345 : {
346 3271 : if (_planar_formulation == PlanarFormulation::GeneralizedPlaneStrain)
347 : {
348 89 : if (_use_ad)
349 0 : paramError("use_automatic_differentiation", "AD not setup for use with PlaneStrain");
350 : // Set the action parameters
351 89 : const std::string type = "GeneralizedPlaneStrainAction";
352 89 : auto action_params = _action_factory.getValidParams(type);
353 89 : action_params.set<bool>("_built_by_moose") = true;
354 89 : action_params.set<std::string>("registered_identifier") = "(AutoBuilt)";
355 :
356 : // Skipping selected parameters in applyParameters() and then manually setting them only if
357 : // they are set by the user is just to prevent both the current and deprecated variants of
358 : // these parameters from both getting passed to the UserObject. Once we get rid of the
359 : // deprecated versions, we can just set them all with applyParameters().
360 89 : action_params.applyParameters(parameters(),
361 : {"use_displaced_mesh",
362 : "out_of_plane_pressure",
363 : "out_of_plane_pressure_function",
364 : "factor",
365 : "pressure_factor"});
366 89 : action_params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
367 :
368 178 : if (parameters().isParamSetByUser("out_of_plane_pressure"))
369 0 : action_params.set<FunctionName>("out_of_plane_pressure") =
370 0 : getParam<FunctionName>("out_of_plane_pressure");
371 178 : if (parameters().isParamSetByUser("out_of_plane_pressure_function"))
372 0 : action_params.set<FunctionName>("out_of_plane_pressure_function") =
373 0 : getParam<FunctionName>("out_of_plane_pressure_function");
374 178 : if (parameters().isParamSetByUser("factor"))
375 0 : action_params.set<Real>("factor") = getParam<Real>("factor");
376 178 : if (parameters().isParamSetByUser("pressure_factor"))
377 0 : action_params.set<Real>("pressure_factor") = getParam<Real>("pressure_factor");
378 :
379 : // Create and add the action to the warehouse
380 : auto action = MooseSharedNamespace::static_pointer_cast<MooseObjectAction>(
381 89 : _action_factory.create(type, name() + "_gps", action_params));
382 267 : _awh.addActionBlock(action);
383 89 : }
384 : }
385 :
386 : // Add variables
387 34766 : else if (_current_task == "add_variable")
388 : {
389 : // Add variables here only if the CommonSolidMechanicsAction does not exist.
390 : // This happens notably if the QuasiStaticSolidMechanics was created by a meta_action
391 3259 : const auto common_actions = _awh.getActions<CommonSolidMechanicsAction>();
392 3259 : if (common_actions.empty() && getParam<bool>("add_variables"))
393 : {
394 0 : auto params = _factory.getValidParams("MooseVariable");
395 : // determine necessary order
396 0 : const bool second = _problem->mesh().hasSecondOrderElements();
397 :
398 0 : params.set<MooseEnum>("order") = second ? "SECOND" : "FIRST";
399 0 : params.set<MooseEnum>("family") = "LAGRANGE";
400 0 : if (isParamValid("scaling"))
401 0 : params.set<std::vector<Real>>("scaling") = {getParam<Real>("scaling")};
402 :
403 : // Note how we do not add the block restriction because BISON's meta-actions
404 : // currently rely on them not being added.
405 :
406 : // Loop through the displacement variables
407 0 : for (const auto & disp : _displacements)
408 : {
409 : // Create displacement variables
410 0 : _problem->addVariable("MooseVariable", disp, params);
411 : }
412 0 : }
413 :
414 : // Homogenization scalar
415 3259 : if (_lk_homogenization)
416 : {
417 8 : InputParameters params = _factory.getValidParams("MooseVariable");
418 : const std::map<bool, std::vector<unsigned int>> mg_order_max{{true, {1, 4, 9}},
419 24 : {false, {1, 3, 6}}};
420 : std::size_t mg_order = 0;
421 80 : for (auto i : index_range(_constraint_types))
422 : {
423 72 : const auto ctype = static_cast<Homogenization::ConstraintType>(_constraint_types.get(i));
424 72 : if (ctype != Homogenization::ConstraintType::None)
425 40 : mg_order++;
426 : }
427 8 : if (mg_order > mg_order_max.at(_lk_large_kinematics)[_ndisp - 1])
428 0 : paramError("constraint_types",
429 : "Number of non-none constraint types must not be greater than ",
430 0 : mg_order_max.at(_lk_large_kinematics)[_ndisp - 1],
431 : ", but ",
432 : mg_order,
433 : " are provided.");
434 16 : params.set<MooseEnum>("family") = "SCALAR";
435 8 : params.set<MooseEnum>("order") = mg_order;
436 8 : auto fe_type = AddVariableAction::feType(params);
437 8 : auto var_type = AddVariableAction::variableType(fe_type);
438 8 : _problem->addVariable(var_type, _hname, params);
439 8 : }
440 3259 : }
441 : // Add Materials
442 31507 : else if (_current_task == "add_master_action_material")
443 : {
444 : // Automatic eigenstrain names
445 3222 : if (_auto_eigenstrain)
446 31 : actEigenstrainNames();
447 :
448 : // Easiest just to branch on type here, as the strain systems are completely
449 : // different
450 3222 : if (_lagrangian_kernels)
451 260 : actLagrangianKernelStrain();
452 : else
453 2962 : actStressDivergenceTensorsStrain();
454 : }
455 :
456 : // Add Stress Divergence (and optionally WeakPlaneStress) Kernels
457 28285 : else if (_current_task == "add_kernel")
458 : {
459 16418 : for (unsigned int i = 0; i < _ndisp; ++i)
460 : {
461 11992 : auto tensor_kernel_type = getKernelType();
462 23984 : auto params = getKernelParameters(ad_prepend + tensor_kernel_type);
463 :
464 23984 : std::string kernel_name = "TM_" + name() + Moose::stringify(i);
465 :
466 : // Set appropriate components for kernels, including in the cases where a planar model is
467 : // running in planes other than the x-y plane (defined by _out_of_plane_strain_direction).
468 11992 : if (_out_of_plane_direction == OutOfPlaneDirection::x && i == 0)
469 30 : continue;
470 11962 : else if (_out_of_plane_direction == OutOfPlaneDirection::y && i == 1)
471 30 : continue;
472 :
473 11932 : params.set<unsigned int>("component") = i;
474 :
475 23864 : params.set<NonlinearVariableName>("variable") = _displacements[i];
476 :
477 11932 : if (_save_in.size() == _ndisp)
478 564 : params.set<std::vector<AuxVariableName>>("save_in") = {_save_in[i]};
479 11932 : if (_diag_save_in.size() == _ndisp)
480 0 : params.set<std::vector<AuxVariableName>>("diag_save_in") = {_diag_save_in[i]};
481 35796 : if (isParamValid("out_of_plane_strain") && !_lagrangian_kernels)
482 192 : params.set<std::vector<VariableName>>("out_of_plane_strain") = {
483 384 : getParam<VariableName>("out_of_plane_strain")};
484 :
485 11932 : if (_lk_homogenization)
486 : {
487 60 : params.set<std::vector<VariableName>>("scalar_variable") = {_hname};
488 20 : params.set<MultiMooseEnum>("constraint_types") = _constraint_types;
489 40 : params.set<std::vector<FunctionName>>("targets") = _targets;
490 : }
491 :
492 23864 : _problem->addKernel(ad_prepend + tensor_kernel_type, kernel_name, params);
493 11992 : }
494 :
495 4426 : if (_planar_formulation == PlanarFormulation::WeakPlaneStress)
496 : {
497 96 : auto params = getKernelParameters(ad_prepend + "WeakPlaneStress");
498 48 : std::string wps_kernel_name = "TM_WPS_" + name();
499 144 : params.set<NonlinearVariableName>("variable") = getParam<VariableName>("out_of_plane_strain");
500 :
501 96 : _problem->addKernel(ad_prepend + "WeakPlaneStress", wps_kernel_name, params);
502 48 : }
503 : }
504 38252 : }
505 :
506 : void
507 38043 : QuasiStaticSolidMechanicsPhysics::actSubdomainChecks()
508 : {
509 : // Do the coordinate system check only once the problem is created
510 38043 : if (_current_task == "setup_mesh_complete")
511 : {
512 : // get subdomain IDs
513 3593 : for (auto & name : _subdomain_names)
514 : {
515 318 : auto id = _mesh->getSubdomainID(name);
516 318 : if (id == Moose::INVALID_BLOCK_ID)
517 0 : paramError("block", "Subdomain \"" + name + "\" not found in mesh.");
518 : else
519 318 : _subdomain_ids.insert(id);
520 : }
521 : }
522 :
523 38043 : if (_current_task == "validate_coordinate_systems")
524 : {
525 : // use either block restriction list or list of all subdomains in the mesh
526 : const auto & check_subdomains =
527 4490 : _subdomain_ids.empty() ? _problem->mesh().meshSubdomains() : _subdomain_ids;
528 4490 : if (check_subdomains.empty())
529 0 : mooseError("No subdomains found");
530 :
531 : // make sure all subdomains are using the same coordinate system
532 4490 : _coord_system = _problem->getCoordSystem(*check_subdomains.begin());
533 9763 : for (auto subdomain : check_subdomains)
534 5275 : if (_problem->getCoordSystem(subdomain) != _coord_system)
535 2 : mooseError("The SolidMechanics action requires all subdomains to have the same coordinate "
536 : "system.");
537 :
538 4488 : if (_coord_system == Moose::COORD_RZ)
539 : {
540 235 : if (_out_of_plane_direction != OutOfPlaneDirection::z)
541 0 : mooseError("'out_of_plane_direction' must be 'z' for axisymmetric simulations");
542 : }
543 4253 : else if (_planar_formulation != PlanarFormulation::None)
544 : {
545 344 : if (_out_of_plane_direction == OutOfPlaneDirection::z && _ndisp != 2)
546 0 : mooseError(
547 : "Must specify two displacements for plane strain when the out of plane direction is z");
548 344 : else if (_out_of_plane_direction != OutOfPlaneDirection::z && _ndisp != 3)
549 0 : mooseError("Must specify three displacements for plane strain when the out of plane "
550 : "direction is x or y");
551 : }
552 : }
553 38041 : }
554 :
555 : void
556 38037 : QuasiStaticSolidMechanicsPhysics::actOutputGeneration()
557 : {
558 38037 : if (_current_task == "add_material")
559 3256 : actOutputMatProp();
560 :
561 : // Add variables (optional)
562 38037 : if (_current_task == "add_aux_variable")
563 : {
564 : unsigned int index = 0;
565 13845 : for (auto out : _generate_output)
566 : {
567 10586 : const auto & order = _material_output_order[index];
568 10586 : const auto & family = _material_output_family[index];
569 :
570 10564 : std::string type = (order == "CONSTANT" && family == "MONOMIAL")
571 : ? "MooseVariableConstMonomial"
572 21172 : : "MooseVariable";
573 :
574 : // Create output helper aux variables
575 10586 : auto params = _factory.getValidParams(type);
576 10586 : params.set<MooseEnum>("order") = order;
577 10586 : params.set<MooseEnum>("family") = family;
578 :
579 10586 : if (family == "MONOMIAL")
580 21146 : _problem->addAuxVariable(type, _base_name + out, params);
581 : else
582 26 : _problem->addVariable(type, _base_name + out, params);
583 :
584 10586 : index++;
585 10586 : }
586 : }
587 :
588 : // Add output AuxKernels
589 34778 : else if (_current_task == "add_aux_kernel")
590 : {
591 5751 : std::string ad_prepend = _use_ad ? "AD" : "";
592 : // Loop through output aux variables
593 : unsigned int index = 0;
594 13707 : for (auto out : _generate_output)
595 : {
596 10489 : if (_material_output_family[index] == "MONOMIAL")
597 : {
598 10476 : InputParameters params = emptyInputParameters();
599 :
600 20952 : params = _factory.getValidParams("MaterialRealAux");
601 10476 : params.applyParameters(parameters());
602 31428 : params.set<MaterialPropertyName>("property") = _base_name + out;
603 31428 : params.set<AuxVariableName>("variable") = _base_name + out;
604 10476 : params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
605 :
606 20952 : _problem->addAuxKernel(
607 20952 : ad_prepend + "MaterialRealAux", _base_name + out + '_' + name(), params);
608 10476 : }
609 10489 : index++;
610 : }
611 : }
612 31560 : else if (_current_task == "add_kernel")
613 : {
614 8146 : std::string ad_prepend = _use_ad ? "AD" : "";
615 : // Loop through output aux variables
616 : unsigned int index = 0;
617 14907 : for (auto out : _generate_output)
618 : {
619 10481 : if (_material_output_family[index] != "MONOMIAL")
620 : {
621 13 : InputParameters params = emptyInputParameters();
622 :
623 26 : params = _factory.getValidParams("MaterialPropertyValue");
624 13 : params.applyParameters(parameters());
625 39 : params.set<MaterialPropertyName>("prop_name") = _base_name + out;
626 39 : params.set<NonlinearVariableName>("variable") = _base_name + out;
627 :
628 26 : _problem->addKernel(
629 26 : ad_prepend + "MaterialPropertyValue", _base_name + out + '_' + name(), params);
630 13 : }
631 10481 : index++;
632 : }
633 : }
634 38037 : }
635 :
636 : void
637 31 : QuasiStaticSolidMechanicsPhysics::actEigenstrainNames()
638 : {
639 : // Create containers for collecting blockIDs and eigenstrain names from materials
640 : std::map<std::string, std::set<SubdomainID>> material_eigenstrain_map;
641 : std::set<std::string> eigenstrain_set;
642 :
643 : std::set<MaterialPropertyName> verified_eigenstrain_names;
644 :
645 : std::map<std::string, std::string> remove_add_map;
646 : std::set<std::string> remove_reduced_set;
647 :
648 : // Loop over all the materials(eigenstrains) already created
649 31 : auto materials = _problem->getMaterialWarehouse().getObjects();
650 300 : for (auto & mat : materials)
651 : {
652 269 : std::shared_ptr<BlockRestrictable> blk = std::dynamic_pointer_cast<BlockRestrictable>(mat);
653 : const InputParameters & mat_params = mat->parameters();
654 : auto & mat_name = mat->type();
655 :
656 : // Check for eigenstrain names, only deal with those materials
657 538 : if (mat_params.isParamValid("eigenstrain_name"))
658 : {
659 : std::shared_ptr<MaterialData> mat_dat;
660 59 : auto name = mat_params.get<std::string>("eigenstrain_name");
661 :
662 : // Check for base_name prefix
663 118 : if (mat_params.isParamValid("base_name"))
664 0 : name = mat_params.get<std::string>("base_name") + '_' + name;
665 :
666 : // Check block restrictions
667 59 : if (!blk)
668 0 : mooseError("Internal error, Material object that does not inherit form BlockRestricted");
669 : const std::set<SubdomainID> & blocks =
670 59 : blk->blockRestricted() ? blk->blockIDs() : blk->meshBlockIDs();
671 :
672 59 : if (std::includes(blocks.begin(), blocks.end(), _subdomain_ids.begin(), _subdomain_ids.end()))
673 : {
674 47 : material_eigenstrain_map[name].insert(blocks.begin(), blocks.end());
675 47 : eigenstrain_set.insert(name);
676 : }
677 : }
678 :
679 : // Account for reduced eigenstrains and CompositeEigenstrains
680 269 : if (mat_name == "ComputeReducedOrderEigenstrain")
681 : {
682 : auto input_eigenstrain_names =
683 3 : mat_params.get<std::vector<MaterialPropertyName>>("input_eigenstrain_names");
684 : remove_reduced_set.insert(input_eigenstrain_names.begin(), input_eigenstrain_names.end());
685 3 : }
686 : // Account for CompositeEigenstrains
687 269 : if (mat_name == "CompositeEigenstrain")
688 : {
689 3 : auto remove_list = mat_params.get<std::vector<MaterialPropertyName>>("tensors");
690 9 : for (auto i : remove_list)
691 6 : remove_reduced_set.insert(i);
692 3 : }
693 :
694 : // Account for MaterialADConverter , add or remove later
695 269 : if (mat_name == "RankTwoTensorMaterialADConverter")
696 : {
697 : std::vector<MaterialPropertyName> remove_list;
698 : std::vector<MaterialPropertyName> add_list;
699 :
700 18 : if (mat_params.isParamValid("ad_props_out") && mat_params.isParamValid("reg_props_in") &&
701 6 : _use_ad)
702 : {
703 6 : remove_list = mat_params.get<std::vector<MaterialPropertyName>>("reg_props_in");
704 6 : add_list = mat_params.get<std::vector<MaterialPropertyName>>("ad_props_out");
705 : }
706 18 : if (mat_params.isParamValid("ad_props_in") && mat_params.isParamValid("reg_props_out") &&
707 6 : !_use_ad)
708 : {
709 0 : remove_list = mat_params.get<std::vector<MaterialPropertyName>>("ad_props_in");
710 0 : add_list = mat_params.get<std::vector<MaterialPropertyName>>("reg_props_out");
711 : }
712 :
713 : // These vectors are the same size as checked in MaterialADConverter
714 12 : for (unsigned int index = 0; index < remove_list.size(); index++)
715 : remove_add_map.emplace(remove_list[index], add_list[index]);
716 6 : }
717 : }
718 : // All the materials have been accounted for, now remove or add parts
719 :
720 : // Remove names which aren't eigenstrains (converter properties)
721 37 : for (auto remove_add_index : remove_add_map)
722 : {
723 : const bool is_in = eigenstrain_set.find(remove_add_index.first) != eigenstrain_set.end();
724 6 : if (is_in)
725 : {
726 : eigenstrain_set.erase(remove_add_index.first);
727 3 : eigenstrain_set.insert(remove_add_index.second);
728 : }
729 : }
730 40 : for (auto index : remove_reduced_set)
731 : eigenstrain_set.erase(index);
732 :
733 : // Compare the blockIDs set of eigenstrain names with the vector of _eigenstrain_names for the
734 : // current subdomainID
735 31 : std::set_union(eigenstrain_set.begin(),
736 : eigenstrain_set.end(),
737 : _eigenstrain_names.begin(),
738 : _eigenstrain_names.end(),
739 : std::inserter(verified_eigenstrain_names, verified_eigenstrain_names.begin()));
740 :
741 : // Ensure the eigenstrain names previously passed include any missing names
742 31 : _eigenstrain_names.resize(verified_eigenstrain_names.size());
743 : std::copy(verified_eigenstrain_names.begin(),
744 : verified_eigenstrain_names.end(),
745 : _eigenstrain_names.begin());
746 :
747 31 : Moose::out << COLOR_CYAN << "*** Automatic Eigenstrain Names ***"
748 : << "\n"
749 93 : << _name << ": " << Moose::stringify(_eigenstrain_names) << "\n"
750 31 : << COLOR_DEFAULT << std::flush;
751 62 : }
752 :
753 : void
754 2270 : QuasiStaticSolidMechanicsPhysics::verifyOrderAndFamilyOutputs()
755 : {
756 : // Ensure material output order and family vectors are same size as generate output
757 :
758 : // check number of supplied orders and families
759 2270 : if (_material_output_order.size() > 1 && _material_output_order.size() < _generate_output.size())
760 0 : paramError("material_output_order",
761 : "The number of orders assigned to material outputs must be: 0 to be assigned "
762 : "CONSTANT; 1 to assign all outputs the same value, or the same size as the number "
763 : "of generate outputs listed.");
764 :
765 2277 : if (_material_output_family.size() > 1 &&
766 7 : _material_output_family.size() < _generate_output.size())
767 1 : paramError("material_output_family",
768 : "The number of families assigned to material outputs must be: 0 to be assigned "
769 : "MONOMIAL; 1 to assign all outputs the same value, or the same size as the number "
770 : "of generate outputs listed.");
771 :
772 : // if no value was provided, chose the default CONSTANT
773 2269 : if (_material_output_order.size() == 0)
774 4514 : _material_output_order.setAdditionalValue("CONSTANT");
775 :
776 : // For only one order, make all orders the same magnitude
777 2269 : if (_material_output_order.size() == 1)
778 : _material_output_order =
779 2263 : std::vector<std::string>(_generate_output.size(), _material_output_order[0]);
780 :
781 2269 : if (_verbose)
782 9 : Moose::out << COLOR_CYAN << "*** Automatic applied material output orders ***"
783 : << "\n"
784 27 : << _name << ": " << Moose::stringify(_material_output_order) << "\n"
785 9 : << COLOR_DEFAULT << std::flush;
786 :
787 : // if no value was provided, chose the default MONOMIAL
788 2269 : if (_material_output_family.size() == 0)
789 4520 : _material_output_family.setAdditionalValue("MONOMIAL");
790 :
791 : // For only one family, make all families that value
792 2269 : if (_material_output_family.size() == 1)
793 : _material_output_family =
794 2263 : std::vector<std::string>(_generate_output.size(), _material_output_family[0]);
795 :
796 2269 : if (_verbose)
797 9 : Moose::out << COLOR_CYAN << "*** Automatic applied material output families ***"
798 : << "\n"
799 27 : << _name << ": " << Moose::stringify(_material_output_family) << "\n"
800 9 : << COLOR_DEFAULT << std::flush;
801 2269 : }
802 :
803 : void
804 3256 : QuasiStaticSolidMechanicsPhysics::actOutputMatProp()
805 : {
806 5825 : std::string ad_prepend = _use_ad ? "AD" : "";
807 :
808 3256 : if (_current_task == "add_material")
809 : {
810 : // Add output Materials
811 13830 : for (auto out : _generate_output)
812 : {
813 10574 : InputParameters params = emptyInputParameters();
814 :
815 : // RankTwoCartesianComponent
816 20107 : if (
817 21148 : [&]()
818 : {
819 117401 : for (const auto & r2q : _rank_two_cartesian_component_table)
820 444519 : for (unsigned int a = 0; a < 3; ++a)
821 1333025 : for (unsigned int b = 0; b < 3; ++b)
822 2009732 : if (r2q.first + '_' + _component_table[a] + _component_table[b] == out)
823 : {
824 9533 : auto type = ad_prepend + "RankTwoCartesianComponent";
825 9533 : params = _factory.getValidParams(type);
826 28599 : params.set<MaterialPropertyName>("rank_two_tensor") = _base_name + r2q.second;
827 9533 : params.set<unsigned int>("index_i") = a;
828 9533 : params.set<unsigned int>("index_j") = b;
829 :
830 9533 : params.applyParameters(parameters());
831 28599 : params.set<MaterialPropertyName>("property_name") = _base_name + out;
832 19066 : _problem->addMaterial(type, _base_name + out + '_' + name(), params);
833 : return true;
834 : }
835 : return false;
836 10574 : }())
837 9533 : continue;
838 :
839 : // RankTwoDirectionalComponent
840 2082 : if (setupOutput(out,
841 : _rank_two_directional_component_table,
842 0 : [&](std::string prop_name, std::string invariant)
843 : {
844 0 : auto type = ad_prepend + "RankTwoDirectionalComponent";
845 0 : params = _factory.getValidParams(type);
846 0 : params.set<MaterialPropertyName>("rank_two_tensor") =
847 0 : _base_name + prop_name;
848 0 : params.set<MooseEnum>("invariant") = invariant;
849 0 : params.applyParameters(parameters());
850 0 : params.set<MaterialPropertyName>("property_name") = _base_name + out;
851 0 : _problem->addMaterial(type, _base_name + out + '_' + name(), params);
852 0 : }))
853 0 : continue;
854 :
855 : // RankTwoInvariant
856 2082 : if (setupOutput(out,
857 : _rank_two_invariant_table,
858 962 : [&](std::string prop_name, std::string invariant)
859 : {
860 962 : auto type = ad_prepend + "RankTwoInvariant";
861 962 : params = _factory.getValidParams(type);
862 1924 : params.set<MaterialPropertyName>("rank_two_tensor") =
863 962 : _base_name + prop_name;
864 962 : params.set<MooseEnum>("invariant") = invariant;
865 962 : params.applyParameters(parameters());
866 2886 : params.set<MaterialPropertyName>("property_name") = _base_name + out;
867 1924 : _problem->addMaterial(type, _base_name + out + '_' + name(), params);
868 962 : }))
869 962 : continue;
870 :
871 : // RankTwoCylindricalComponent
872 158 : if (setupOutput(
873 : out,
874 : _rank_two_cylindrical_component_table,
875 24 : [&](std::string prop_name, std::string component)
876 : {
877 24 : if (_coord_system == Moose::COORD_RSPHERICAL)
878 0 : mooseError(
879 : "Cannot use cylindrical component output in a spherical coordinate system.");
880 24 : auto type = ad_prepend + "RankTwoCylindricalComponent";
881 24 : params = _factory.getValidParams(type);
882 72 : params.set<MaterialPropertyName>("rank_two_tensor") = _base_name + prop_name;
883 24 : params.set<MooseEnum>("cylindrical_component") = component;
884 24 : params.applyParameters(parameters());
885 72 : params.set<MaterialPropertyName>("property_name") = _base_name + out;
886 48 : _problem->addMaterial(type, _base_name + out + '_' + name(), params);
887 24 : }))
888 24 : continue;
889 :
890 : // RankTwoSphericalComponent
891 110 : if (setupOutput(out,
892 : _rank_two_spherical_component_table,
893 55 : [&](std::string prop_name, std::string component)
894 : {
895 55 : auto type = ad_prepend + "RankTwoSphericalComponent";
896 55 : params = _factory.getValidParams(type);
897 110 : params.set<MaterialPropertyName>("rank_two_tensor") =
898 55 : _base_name + prop_name;
899 55 : params.set<MooseEnum>("spherical_component") = component;
900 55 : params.applyParameters(parameters());
901 165 : params.set<MaterialPropertyName>("property_name") = _base_name + out;
902 110 : _problem->addMaterial(type, _base_name + out + '_' + name(), params);
903 55 : }))
904 55 : continue;
905 :
906 0 : paramError("generate_output", "Unable to add output Material for '", out, "'");
907 10574 : }
908 : }
909 3256 : }
910 :
911 : void
912 38041 : QuasiStaticSolidMechanicsPhysics::actGatherActionParameters()
913 : {
914 : // Gather info about all other solid mechanics physics when we add variables
915 47017 : if (_current_task == "validate_coordinate_systems" && getParam<bool>("add_variables"))
916 : {
917 3018 : auto actions = _awh.getActions<QuasiStaticSolidMechanicsPhysics>();
918 6150 : for (const auto & action : actions)
919 : {
920 : const auto size_before = _subdomain_id_union.size();
921 3136 : const auto added_size = action->_subdomain_ids.size();
922 3136 : _subdomain_id_union.insert(action->_subdomain_ids.begin(), action->_subdomain_ids.end());
923 : const auto size_after = _subdomain_id_union.size();
924 :
925 3136 : if (size_after != size_before + added_size)
926 2 : mooseError("The block restrictions in the SolidMechanics/QuasiStatic actions must be "
927 : "non-overlapping.");
928 :
929 3134 : if (added_size == 0 && actions.size() > 1)
930 2 : mooseError(
931 : "No SolidMechanics/QuasiStatic action can be block unrestricted if more than one "
932 : "SolidMechanics/QuasiStatic action is specified.");
933 : }
934 3014 : }
935 38037 : }
936 :
937 : void
938 260 : QuasiStaticSolidMechanicsPhysics::actLagrangianKernelStrain()
939 : {
940 : std::string type;
941 260 : if (_coord_system == Moose::COORD_XYZ)
942 : type = "ComputeLagrangianStrain";
943 28 : else if (_coord_system == Moose::COORD_RZ)
944 : type = "ComputeLagrangianStrainAxisymmetricCylindrical";
945 8 : else if (_coord_system == Moose::COORD_RSPHERICAL)
946 : type = "ComputeLagrangianStrainCentrosymmetricSpherical";
947 : else
948 0 : mooseError("Unsupported coordinate system");
949 :
950 260 : auto params = _factory.getValidParams(type);
951 :
952 520 : if (isParamValid("strain_base_name"))
953 0 : params.set<std::string>("base_name") = getParam<std::string>("strain_base_name");
954 :
955 260 : params.set<std::vector<VariableName>>("displacements") = _coupled_displacements;
956 260 : params.set<std::vector<MaterialPropertyName>>("eigenstrain_names") = _eigenstrain_names;
957 260 : params.set<bool>("large_kinematics") = _lk_large_kinematics;
958 260 : params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
959 :
960 : // Error if volumetric locking correction is on for higher-order elements
961 260 : if (_problem->mesh().hasSecondOrderElements() && _lk_locking)
962 1 : mooseError("Volumetric locking correction should not be used for "
963 : "higher-order elements.");
964 :
965 259 : params.set<bool>("stabilize_strain") = _lk_locking;
966 :
967 259 : if (_lk_homogenization)
968 : {
969 16 : params.set<std::vector<MaterialPropertyName>>("homogenization_gradient_names") = {
970 32 : _homogenization_strain_name};
971 : }
972 :
973 259 : _problem->addMaterial(type, name() + "_strain", params);
974 :
975 : // Add the homogenization strain calculator
976 259 : if (_lk_homogenization)
977 : {
978 8 : std::string type = "ComputeHomogenizedLagrangianStrain";
979 8 : auto params = _factory.getValidParams(type);
980 :
981 16 : params.set<MaterialPropertyName>("homogenization_gradient_name") = _homogenization_strain_name;
982 24 : params.set<std::vector<VariableName>>("macro_gradient") = {_hname};
983 8 : params.set<MultiMooseEnum>("constraint_types") = _constraint_types;
984 8 : params.set<std::vector<FunctionName>>("targets") = _targets;
985 :
986 8 : _problem->addMaterial(type, name() + "_compute_" + _homogenization_strain_name, params);
987 8 : }
988 518 : }
989 :
990 : void
991 2962 : QuasiStaticSolidMechanicsPhysics::actStressDivergenceTensorsStrain()
992 : {
993 5239 : std::string ad_prepend = _use_ad ? "AD" : "";
994 :
995 : std::string type;
996 :
997 : // no plane strain
998 2962 : if (_planar_formulation == PlanarFormulation::None)
999 : {
1000 : std::map<std::pair<Moose::CoordinateSystemType, StrainAndIncrement>, std::string> type_map = {
1001 : {{Moose::COORD_XYZ, StrainAndIncrement::SmallTotal}, "ComputeSmallStrain"},
1002 : {{Moose::COORD_XYZ, StrainAndIncrement::SmallIncremental}, "ComputeIncrementalStrain"},
1003 : {{Moose::COORD_XYZ, StrainAndIncrement::FiniteIncremental}, "ComputeFiniteStrain"},
1004 : {{Moose::COORD_RZ, StrainAndIncrement::SmallTotal}, "ComputeAxisymmetricRZSmallStrain"},
1005 : {{Moose::COORD_RZ, StrainAndIncrement::SmallIncremental},
1006 : "ComputeAxisymmetricRZIncrementalStrain"},
1007 : {{Moose::COORD_RZ, StrainAndIncrement::FiniteIncremental},
1008 : "ComputeAxisymmetricRZFiniteStrain"},
1009 : {{Moose::COORD_RSPHERICAL, StrainAndIncrement::SmallTotal}, "ComputeRSphericalSmallStrain"},
1010 : {{Moose::COORD_RSPHERICAL, StrainAndIncrement::SmallIncremental},
1011 : "ComputeRSphericalIncrementalStrain"},
1012 : {{Moose::COORD_RSPHERICAL, StrainAndIncrement::FiniteIncremental},
1013 25950 : "ComputeRSphericalFiniteStrain"}};
1014 :
1015 2595 : auto type_it = type_map.find(std::make_pair(_coord_system, _strain_and_increment));
1016 2595 : if (type_it != type_map.end())
1017 2595 : type = type_it->second;
1018 : else
1019 0 : mooseError("Unsupported strain formulation");
1020 : }
1021 367 : else if (_planar_formulation == PlanarFormulation::WeakPlaneStress ||
1022 367 : _planar_formulation == PlanarFormulation::PlaneStrain ||
1023 : _planar_formulation == PlanarFormulation::GeneralizedPlaneStrain)
1024 : {
1025 367 : if (_use_ad && (_planar_formulation == PlanarFormulation::PlaneStrain ||
1026 : _planar_formulation == PlanarFormulation::GeneralizedPlaneStrain))
1027 0 : paramError("use_automatic_differentiation",
1028 : "AD not setup for use with PlaneStrain or GeneralizedPlaneStrain");
1029 :
1030 : std::map<std::pair<Moose::CoordinateSystemType, StrainAndIncrement>, std::string> type_map = {
1031 : {{Moose::COORD_XYZ, StrainAndIncrement::SmallTotal}, "ComputePlaneSmallStrain"},
1032 : {{Moose::COORD_XYZ, StrainAndIncrement::SmallIncremental}, "ComputePlaneIncrementalStrain"},
1033 : {{Moose::COORD_XYZ, StrainAndIncrement::FiniteIncremental}, "ComputePlaneFiniteStrain"},
1034 : {{Moose::COORD_RZ, StrainAndIncrement::SmallTotal}, "ComputeAxisymmetric1DSmallStrain"},
1035 : {{Moose::COORD_RZ, StrainAndIncrement::SmallIncremental},
1036 : "ComputeAxisymmetric1DIncrementalStrain"},
1037 : {{Moose::COORD_RZ, StrainAndIncrement::FiniteIncremental},
1038 2569 : "ComputeAxisymmetric1DFiniteStrain"}};
1039 :
1040 : // choose kernel type based on coordinate system
1041 367 : auto type_it = type_map.find(std::make_pair(_coord_system, _strain_and_increment));
1042 367 : if (type_it != type_map.end())
1043 367 : type = type_it->second;
1044 : else
1045 0 : mooseError("Unsupported coordinate system for plane strain.");
1046 : }
1047 : else
1048 0 : mooseError("Unsupported planar formulation");
1049 :
1050 : // set material parameters
1051 2962 : auto params = _factory.getValidParams(ad_prepend + type);
1052 2962 : params.applyParameters(
1053 : parameters(),
1054 : {"displacements", "use_displaced_mesh", "out_of_plane_strain", "scalar_out_of_plane_strain"});
1055 :
1056 5924 : if (isParamValid("strain_base_name"))
1057 0 : params.set<std::string>("base_name") = getParam<std::string>("strain_base_name");
1058 :
1059 2962 : params.set<std::vector<VariableName>>("displacements") = _coupled_displacements;
1060 2962 : params.set<bool>("use_displaced_mesh") = false;
1061 :
1062 5924 : if (isParamValid("scalar_out_of_plane_strain"))
1063 186 : params.set<std::vector<VariableName>>("scalar_out_of_plane_strain") = {
1064 372 : getParam<VariableName>("scalar_out_of_plane_strain")};
1065 :
1066 5924 : if (isParamValid("out_of_plane_strain"))
1067 96 : params.set<std::vector<VariableName>>("out_of_plane_strain") = {
1068 192 : getParam<VariableName>("out_of_plane_strain")};
1069 :
1070 2962 : params.set<std::vector<MaterialPropertyName>>("eigenstrain_names") = _eigenstrain_names;
1071 :
1072 5924 : _problem->addMaterial(ad_prepend + type, name() + "_strain", params);
1073 34725 : }
1074 :
1075 : std::string
1076 11513 : QuasiStaticSolidMechanicsPhysics::getKernelType()
1077 : {
1078 11513 : if (_lagrangian_kernels)
1079 : {
1080 : std::string type;
1081 706 : if (_coord_system == Moose::COORD_XYZ)
1082 : {
1083 658 : if (_lk_homogenization)
1084 : type = "HomogenizedTotalLagrangianStressDivergence";
1085 638 : else if (_lk_formulation == LKFormulation::Total)
1086 : type = "TotalLagrangianStressDivergence";
1087 52 : else if (_lk_formulation == LKFormulation::Updated)
1088 : type = "UpdatedLagrangianStressDivergence";
1089 : else
1090 0 : mooseError("Unknown formulation type");
1091 : }
1092 48 : else if (_coord_system == Moose::COORD_RZ)
1093 : {
1094 40 : if (_lk_homogenization)
1095 0 : mooseError("The Lagrangian mechanics kernels do not yet support homogenization in "
1096 : "coordinate systems other than Cartesian.");
1097 40 : else if (_lk_formulation == LKFormulation::Total)
1098 : type = "TotalLagrangianStressDivergenceAxisymmetricCylindrical";
1099 0 : else if (_lk_formulation == LKFormulation::Updated)
1100 0 : mooseError("The Lagrangian mechanics kernels do not yet support the updated Lagrangian "
1101 : "formulation in RZ coordinates.");
1102 : }
1103 8 : else if (_coord_system == Moose::COORD_RSPHERICAL)
1104 : {
1105 8 : if (_lk_homogenization)
1106 0 : mooseError("The Lagrangian mechanics kernels do not yet support homogenization in "
1107 : "coordinate systems other than Cartesian.");
1108 8 : else if (_lk_formulation == LKFormulation::Total)
1109 : type = "TotalLagrangianStressDivergenceCentrosymmetricSpherical";
1110 0 : else if (_lk_formulation == LKFormulation::Updated)
1111 0 : mooseError("The Lagrangian mechanics kernels do not yet support the updated Lagrangian "
1112 : "formulation in RZ coordinates.");
1113 : }
1114 : else
1115 0 : mooseError("Unsupported coordinate system");
1116 706 : return type;
1117 : }
1118 : else
1119 : {
1120 : std::map<Moose::CoordinateSystemType, std::string> type_map = {
1121 : {Moose::COORD_XYZ, "StressDivergenceTensors"},
1122 : {Moose::COORD_RZ, "StressDivergenceRZTensors"},
1123 43228 : {Moose::COORD_RSPHERICAL, "StressDivergenceRSphericalTensors"}};
1124 :
1125 : // choose kernel type based on coordinate system
1126 10807 : auto type_it = type_map.find(_coord_system);
1127 10807 : if (type_it != type_map.end())
1128 10807 : return type_it->second;
1129 : else
1130 0 : mooseError("Unsupported coordinate system");
1131 : }
1132 0 : }
1133 :
1134 : InputParameters
1135 12040 : QuasiStaticSolidMechanicsPhysics::getKernelParameters(std::string type)
1136 : {
1137 12040 : InputParameters params = _factory.getValidParams(type);
1138 12040 : params.applyParameters(
1139 : parameters(),
1140 : {"displacements", "use_displaced_mesh", "save_in", "diag_save_in", "out_of_plane_strain"});
1141 :
1142 12040 : params.set<std::vector<VariableName>>("displacements") = _coupled_displacements;
1143 :
1144 12040 : if (_lagrangian_kernels)
1145 : {
1146 706 : params.set<bool>("use_displaced_mesh") =
1147 706 : (_lk_large_kinematics && (_lk_formulation == LKFormulation::Updated));
1148 706 : params.set<bool>("large_kinematics") = _lk_large_kinematics;
1149 706 : params.set<bool>("stabilize_strain") = _lk_locking;
1150 706 : if (_lk_homogenization)
1151 20 : params.set<bool>("off_diagonal_jacobian") = _lk_h_off_jac;
1152 : }
1153 : else
1154 11334 : params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
1155 :
1156 12040 : return params;
1157 0 : }
|