10 #include "Conversion.h"
11 #include "FEProblem.h"
13 #include "MooseMesh.h"
14 #include "MooseObjectAction.h"
17 #include "libmesh/string_to_enum.h"
42 params.addClassDescription(
"Set up stress divergence kernels with coordinate system aware logic");
46 params.addParam<std::vector<SubdomainName>>(
"block",
47 "The list of ids of the blocks (subdomain) "
48 "that the stress divergence kernels will be "
50 params.addParamNamesToGroup(
"block",
"Advanced");
52 params.addParam<MultiMooseEnum>(
"additional_generate_output",
54 "Add scalar quantity output for stress and/or strain (will be "
55 "appended to the list in `generate_output`)");
56 params.addParamNamesToGroup(
"additional_generate_output",
"Output");
57 params.addParam<std::string>(
59 "The base name used for the strain. If not provided, it will be set equal to base_name");
60 params.addParam<std::vector<TagName>>(
62 "The tag names for extra vectors that residual data should be saved into");
69 _displacements(getParam<std::vector<VariableName>>(
"displacements")),
70 _ndisp(_displacements.size()),
71 _coupled_displacements(_ndisp),
72 _save_in(getParam<std::vector<AuxVariableName>>(
"save_in")),
73 _diag_save_in(getParam<std::vector<AuxVariableName>>(
"diag_save_in")),
74 _subdomain_names(getParam<std::vector<SubdomainName>>(
"block")),
76 _strain(getParam<MooseEnum>(
"strain").getEnum<
Strain>()),
77 _planar_formulation(getParam<MooseEnum>(
"planar_formulation").getEnum<
PlanarFormulation>()),
78 _out_of_plane_direction(
80 _base_name(isParamValid(
"base_name") ? getParam<std::string>(
"base_name") +
"_" :
"")
83 if (isParamValid(
"incremental"))
85 const bool incremental = getParam<bool>(
"incremental");
95 mooseError(
"Internal error");
104 mooseError(
"Internal error");
109 if (params.isParamSetByUser(
"use_displaced_mesh"))
111 bool use_displaced_mesh_param = getParam<bool>(
"use_displaced_mesh");
113 mooseError(
"Wrong combination of use displaced mesh and strain model");
118 for (
unsigned int i = 0; i <
_ndisp; ++i)
122 mooseError(
"Number of save_in variables should equal to the number of displacement variables ",
127 "Number of diag_save_in variables should equal to the number of displacement variables ",
133 if (params.isParamSetByUser(
"out_of_plane_strain") &&
136 "out_of_plane_strain should only be specified with planar_formulation=WEAK_PLANE_STRESS");
137 else if (!params.isParamSetByUser(
"out_of_plane_strain") &&
139 mooseError(
"out_of_plane_strain must be specified with planar_formulation=WEAK_PLANE_STRESS");
143 for (
const auto & out : getParam<MultiMooseEnum>(
"generate_output"))
145 std::string lower(out);
146 std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
151 if (
_ndisp == 1 && getParam<bool>(
"volumetric_locking_correction"))
152 mooseError(
"Volumetric locking correction should be set to false for 1D problems.");
158 std::string ad_prepend =
"";
159 std::string ad_append =
"";
163 ad_append =
"<RESIDUAL>";
184 if (_current_task ==
"meta_action")
189 paramError(
"use_ad",
"AD not setup for use with PlaneStrain");
191 const std::string type =
"GeneralizedPlaneStrainAction";
192 auto action_params = _action_factory.getValidParams(type);
193 action_params.set<
bool>(
"_built_by_moose") =
true;
194 action_params.set<std::string>(
"registered_identifier") =
"(AutoBuilt)";
195 action_params.applyParameters(parameters(), {
"use_displaced_mesh"});
197 if (isParamValid(
"pressure_factor"))
198 action_params.set<Real>(
"factor") = getParam<Real>(
"pressure_factor");
200 auto action = MooseSharedNamespace::static_pointer_cast<MooseObjectAction>(
201 _action_factory.create(type,
name() +
"_gps", action_params));
202 _awh.addActionBlock(action);
203 if (isParamValid(
"extra_vector_tags"))
204 action_params.set<std::vector<TagName>>(
"extra_vector_tags") =
205 getParam<std::vector<TagName>>(
"extra_vector_tags");
212 else if (_current_task ==
"add_variable" && getParam<bool>(
"add_variables"))
214 auto params = _factory.getValidParams(
"MooseVariable");
216 const bool second = _problem->mesh().hasSecondOrderElements();
218 params.set<MooseEnum>(
"order") = second ?
"SECOND" :
"FIRST";
219 params.set<MooseEnum>(
"family") =
"LAGRANGE";
225 _problem->addVariable(
"MooseVariable", disp, params);
232 else if (_current_task ==
"add_material")
241 std::map<std::pair<Moose::CoordinateSystemType, StrainAndIncrement>, std::string> type_map = {
244 "ComputeIncrementalSmallStrain"},
248 "ComputeAxisymmetricRZIncrementalStrain"},
250 "ComputeAxisymmetricRZFiniteStrain"},
252 "ComputeRSphericalSmallStrain"},
254 "ComputeRSphericalIncrementalStrain"},
256 "ComputeRSphericalFiniteStrain"}};
259 if (type_it != type_map.end())
260 type = type_it->second;
262 mooseError(
"Unsupported strain formulation");
271 "AD not setup for use with WeakPlaneStress, PlaneStrain, or GeneralizedPlaneStrain");
273 std::map<std::pair<Moose::CoordinateSystemType, StrainAndIncrement>, std::string> type_map = {
276 "ComputePlaneIncrementalStrain"},
280 "ComputeAxisymmetric1DIncrementalStrain"},
282 "ComputeAxisymmetric1DFiniteStrain"}};
286 if (type_it != type_map.end())
287 type = type_it->second;
289 mooseError(
"Unsupported coordinate system for plane strain.");
292 mooseError(
"Unsupported planar formulation");
295 auto params = _factory.getValidParams(ad_prepend + type + ad_append);
296 params.applyParameters(parameters(),
298 "use_displaced_mesh",
299 "out_of_plane_strain",
300 "scalar_out_of_plane_strain"});
302 if (isParamValid(
"strain_base_name"))
303 params.set<std::string>(
"base_name") = getParam<std::string>(
"strain_base_name");
306 params.set<
bool>(
"use_displaced_mesh") =
false;
308 if (isParamValid(
"scalar_out_of_plane_strain"))
309 params.set<std::vector<VariableName>>(
"scalar_out_of_plane_strain") = {
310 getParam<VariableName>(
"scalar_out_of_plane_strain")};
312 if (isParamValid(
"out_of_plane_strain"))
313 params.set<std::vector<VariableName>>(
"out_of_plane_strain") = {
314 getParam<VariableName>(
"out_of_plane_strain")};
318 _problem->addADResidualMaterial(
319 ad_prepend + type +
"<RESIDUAL>",
name() +
"_strain" +
"_residual", params);
320 _problem->addADJacobianMaterial(
321 ad_prepend + type +
"<JACOBIAN>",
name() +
"_strain" +
"_jacobian", params);
322 _problem->haveADObjects(
true);
325 _problem->addMaterial(type,
name() +
"_strain", params);
331 else if (_current_task ==
"add_kernel")
333 for (
unsigned int i = 0; i <
_ndisp; ++i)
338 std::string kernel_name =
"TM_" +
name() + Moose::stringify(i);
347 params.set<
unsigned int>(
"component") = i;
349 params.set<NonlinearVariableName>(
"variable") =
_displacements[i];
352 params.set<std::vector<AuxVariableName>>(
"save_in") = {
_save_in[i]};
354 params.set<std::vector<AuxVariableName>>(
"diag_save_in") = {
_diag_save_in[i]};
355 if (isParamValid(
"out_of_plane_strain"))
356 params.set<std::vector<VariableName>>(
"out_of_plane_strain") = {
357 getParam<VariableName>(
"out_of_plane_strain")};
362 ad_prepend + tensor_kernel_type +
"<RESIDUAL>", kernel_name +
"_residual", params);
364 ad_prepend + tensor_kernel_type +
"<JACOBIAN>", kernel_name +
"_jacobian", params);
365 _problem->haveADObjects(
true);
368 _problem->addKernel(tensor_kernel_type, kernel_name, params);
374 std::string wps_kernel_name =
"TM_WPS_" +
name();
375 params.set<NonlinearVariableName>(
"variable") = getParam<VariableName>(
"out_of_plane_strain");
376 _problem->addKernel(
"WeakPlaneStress", wps_kernel_name, params);
387 if (_current_task ==
"setup_mesh_complete")
394 if (_current_task ==
"validate_coordinate_systems")
397 const auto & check_subdomains =
399 if (check_subdomains.empty())
400 mooseError(
"No subdomains found");
403 _coord_system = _problem->getCoordSystem(*check_subdomains.begin());
404 for (
auto subdomain : check_subdomains)
406 mooseError(
"The TensorMechanics action requires all subdomains to have the same coordinate "
412 mooseError(
"'out_of_plane_direction' must be 'z' for axisymmetric simulations");
418 "Must specify two displacements for plane strain when the out of plane direction is z");
420 mooseError(
"Must specify three displacements for plane strain when the out of plane "
421 "direction is x or y");
432 if (_current_task ==
"add_aux_variable")
434 auto params = _factory.getValidParams(
"MooseVariableConstMonomial");
435 params.set<MooseEnum>(
"order") =
"CONSTANT";
436 params.set<MooseEnum>(
"family") =
"MONOMIAL";
441 _problem->addAuxVariable(
"MooseVariableConstMonomial",
_base_name + out, params);
448 else if (_current_task ==
"add_aux_kernel")
453 std::string type =
"";
454 InputParameters params = emptyInputParameters();
458 for (
unsigned int a = 0; a < 3; ++a)
459 for (
unsigned int b = 0; b < 3; ++b)
463 params = _factory.getValidParams(type);
464 params.set<MaterialPropertyName>(
"rank_two_tensor") =
_base_name + r2a.second;
465 params.set<
unsigned int>(
"index_i") = a;
466 params.set<
unsigned int>(
"index_j") = b;
471 for (
const auto & t : r2sa.second.second)
472 if (r2sa.first +
'_' + t == out)
477 type =
"RankTwoScalarAux";
478 params = _factory.getValidParams(type);
479 params.set<MaterialPropertyName>(
"rank_two_tensor") =
_base_name + r2a->second;
480 params.set<MooseEnum>(
"scalar_type") = r2sa.second.first;
483 mooseError(
"Internal error. The permitted tensor shortcuts in "
484 "'_ranktwoscalaraux_table' must be keys in the '_ranktwoaux_table'.");
489 params.applyParameters(parameters());
490 params.set<AuxVariableName>(
"variable") =
_base_name + out;
491 params.set<ExecFlagEnum>(
"execute_on") = EXEC_TIMESTEP_END;
492 _problem->addAuxKernel(type,
_base_name + out +
'_' +
name(), params);
495 mooseError(
"Unable to add output AuxKernel");
506 if (_current_task ==
"validate_coordinate_systems" && getParam<bool>(
"add_variables"))
509 for (
const auto & action : actions)
512 const auto added_size = action->_subdomain_ids.size();
516 if (size_after != size_before + added_size)
517 mooseError(
"The block restrictions in the TensorMechanics/Master actions must be "
520 if (added_size == 0 && actions.size() > 1)
521 mooseError(
"No TensorMechanics/Master action can be block unrestricted if more than one "
522 "TensorMechanics/Master action is specified.");
530 std::map<Moose::CoordinateSystemType, std::string> type_map = {
531 {Moose::COORD_XYZ,
"StressDivergenceTensors"},
532 {Moose::COORD_RZ,
"StressDivergenceRZTensors"},
533 {Moose::COORD_RSPHERICAL,
"StressDivergenceRSphericalTensors"}};
537 if (type_it != type_map.end())
538 return type_it->second;
540 mooseError(
"Unsupported coordinate system");
546 InputParameters params = _factory.getValidParams(type);
547 params.applyParameters(parameters(),
549 "use_displaced_mesh",
552 "out_of_plane_strain"});