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