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