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