https://mooseframework.inl.gov
QuasiStaticSolidMechanicsPhysics.C
Go to the documentation of this file.
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"
16 #include "Material.h"
18 
19 #include "BlockRestrictable.h"
20 
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",
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",
47  "add_master_action_material");
48 
49 registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "add_scalar_kernel");
50 
51 registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "add_user_object");
52 
55 {
57  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  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  params.addParamNamesToGroup("block", "Advanced");
67 
68  params.addParam<MultiMooseEnum>("additional_generate_output",
70  "Add scalar quantity output for stress and/or strain (will be "
71  "appended to the list in `generate_output`)");
72  params.addParam<MultiMooseEnum>(
73  "additional_material_output_order",
75  "Specifies the order of the FE shape function to use for this variable.");
76 
77  params.addParam<MultiMooseEnum>(
78  "additional_material_output_family",
80  "Specifies the family of FE shape functions to use for this variable.");
81 
82  params.addParamNamesToGroup("additional_generate_output additional_material_output_order "
83  "additional_material_output_family",
84  "Output");
85  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  params.addParam<std::vector<TagName>>(
89  "extra_vector_tags",
90  "The tag names for extra vectors that residual data should be saved into");
91  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  params.addParam<Real>("scaling", "The scaling to apply to the displacement variables");
95  params.addParam<Point>(
96  "cylindrical_axis_point1",
97  "Starting point for direction of axis of rotation for cylindrical stress/strain.");
98  params.addParam<Point>(
99  "cylindrical_axis_point2",
100  "Ending point for direction of axis of rotation for cylindrical stress/strain.");
101  params.addParam<Point>("spherical_center_point",
102  "Center point of the spherical coordinate system.");
103  params.addParam<Point>("direction", "Direction stress/strain is calculated in");
104  params.addParam<bool>("automatic_eigenstrain_names",
105  false,
106  "Collects all material eigenstrains and passes to required strain "
107  "calculator within TMA internally.");
108 
109  // Homogenization system input
110  MultiMooseEnum constraintType("strain stress");
111  params.addParam<MultiMooseEnum>("constraint_types",
113  "Type of each constraint: "
114  "stress or strain.");
115  params.addParam<std::vector<FunctionName>>("targets",
116  {},
117  "Functions giving the target "
118  "values of each constraint.");
119 
120  params.addParamNamesToGroup("scaling", "Variables");
121  params.addParamNamesToGroup("strain_base_name automatic_eigenstrain_names", "Strain");
122  params.addParamNamesToGroup(
123  "cylindrical_axis_point1 cylindrical_axis_point2 spherical_center_point direction",
124  "Coordinate system");
125 
126  return params;
127 }
128 
131  _displacements(getParam<std::vector<VariableName>>("displacements")),
132  _ndisp(_displacements.size()),
133  _coupled_displacements(_ndisp),
134  _save_in(getParam<std::vector<AuxVariableName>>("save_in")),
135  _diag_save_in(getParam<std::vector<AuxVariableName>>("diag_save_in")),
136  _subdomain_names(getParam<std::vector<SubdomainName>>("block")),
137  _subdomain_ids(),
138  _strain(getParam<MooseEnum>("strain").getEnum<Strain>()),
139  _planar_formulation(getParam<MooseEnum>("planar_formulation").getEnum<PlanarFormulation>()),
140  _out_of_plane_direction(
141  getParam<MooseEnum>("out_of_plane_direction").getEnum<OutOfPlaneDirection>()),
142  _base_name(isParamValid("base_name") ? getParam<std::string>("base_name") + "_" : ""),
143  _material_output_order(getParam<MultiMooseEnum>("material_output_order")),
144  _material_output_family(getParam<MultiMooseEnum>("material_output_family")),
145  _cylindrical_axis_point1_valid(params.isParamSetByUser("cylindrical_axis_point1")),
146  _cylindrical_axis_point2_valid(params.isParamSetByUser("cylindrical_axis_point2")),
147  _direction_valid(params.isParamSetByUser("direction")),
148  _verbose(getParam<bool>("verbose")),
149  _spherical_center_point_valid(params.isParamSetByUser("spherical_center_point")),
150  _auto_eigenstrain(getParam<bool>("automatic_eigenstrain_names")),
151  _lagrangian_kernels(getParam<bool>("new_system")),
152  _lk_large_kinematics(_strain == Strain::Finite),
153  _lk_formulation(getParam<MooseEnum>("formulation").getEnum<LKFormulation>()),
154  _lk_locking(getParam<bool>("volumetric_locking_correction")),
155  _lk_homogenization(false),
156  _constraint_types(getParam<MultiMooseEnum>("constraint_types")),
157  _targets(getParam<std::vector<FunctionName>>("targets"))
158 {
159  // determine if incremental strains are to be used
160  if (isParamValid("incremental"))
161  {
162  const bool incremental = getParam<bool>("incremental");
163  if (!incremental && _strain == Strain::Small)
165  else if (!incremental && _strain == Strain::Finite)
167  else if (incremental && _strain == Strain::Small)
169  else if (incremental && _strain == Strain::Finite)
171  else
172  mooseError("Internal error");
173  }
174  else
175  {
176  if (_strain == Strain::Small)
177  {
179  mooseInfo("SolidMechanics Action: selecting 'total small strain' formulation. Use "
180  "`incremental = true` to select 'incremental small strain' instead.");
181  }
182  else if (_strain == Strain::Finite)
183  {
185  mooseInfo("SolidMechanics Action: selecting 'incremental finite strain' formulation.");
186  }
187  else
188  mooseError("Internal error");
189  }
190 
191  // determine if displaced mesh is to be used
193  if (params.isParamSetByUser("use_displaced_mesh") && !_lagrangian_kernels)
194  {
195  bool use_displaced_mesh_param = getParam<bool>("use_displaced_mesh");
196  if (use_displaced_mesh_param != _use_displaced_mesh && params.isParamSetByUser("strain"))
197  mooseError("Wrong combination of use displaced mesh and strain model");
198  _use_displaced_mesh = use_displaced_mesh_param;
199  }
200 
201  // convert vector of VariableName to vector of VariableName
202  for (unsigned int i = 0; i < _ndisp; ++i)
204 
205  if (_save_in.size() != 0 && _save_in.size() != _ndisp)
206  mooseError("Number of save_in variables should equal to the number of displacement variables ",
207  _ndisp);
208 
209  if (_diag_save_in.size() != 0 && _diag_save_in.size() != _ndisp)
210  mooseError(
211  "Number of diag_save_in variables should equal to the number of displacement variables ",
212  _ndisp);
213 
214  // plane strain consistency check
216  {
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  if (params.isParamSetByUser("out_of_plane_strain") &&
226  mooseError(
227  "out_of_plane_strain should only be specified with planar_formulation=WEAK_PLANE_STRESS");
228  else if (!params.isParamSetByUser("out_of_plane_strain") &&
230  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  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  _generate_output.push_back(lower);
239  }
240 
241  if (!_generate_output.empty())
243 
244  // Error if volumetric locking correction is true for 1D problems
245  if (_ndisp == 1 && getParam<bool>("volumetric_locking_correction"))
246  mooseError("Volumetric locking correction should be set to false for 1D problems.");
247 
248  if (!getParam<bool>("add_variables") && params.isParamSetByUser("scaling"))
249  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
255  {
256  _cylindrical_axis_point1 = getParam<Point>("cylindrical_axis_point1");
257  _cylindrical_axis_point2 = getParam<Point>("cylindrical_axis_point2");
258  }
259 
260  // Get spherical center point if set by user
262  _spherical_center_point = getParam<Point>("spherical_center_point");
263 
264  // Get direction for tensor component if set by user
265  if (_direction_valid)
266  _direction = getParam<Point>("direction");
267 
268  // Get eigenstrain names if passed by user
269  _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  bool ctype_set = params.isParamSetByUser("constraint_types");
274  bool targets_set = params.isParamSetByUser("targets");
275  if (ctype_set || targets_set)
276  {
277  if (!(ctype_set && targets_set))
278  mooseError("To use the Lagrangian kernel homogenization system you "
279  "most provide both the constraint_types and the targets "
280  "parameters");
281  _lk_homogenization = true;
282  // Do consistency checking on the kernel options
284  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
291  {
292  if (_use_ad)
293  mooseError("The Lagrangian kernel system is not yet compatible with AD. "
294  "Do not set the use_automatic_differentiation flag.");
295 
296  if (params.isParamSetByUser("use_finite_deform_jacobian"))
297  mooseError("The Lagrangian kernel system always produces the exact "
298  "Jacobian. use_finite_deform_jacobian is redundant and "
299  " should not be set");
300  if (params.isParamSetByUser("global_strain"))
301  mooseError("The Lagrangian kernel system is not compatible with "
302  "the global_strain option. Use the homogenization "
303  " system instead");
304  if (params.isParamSetByUser("decomposition_method"))
305  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  if (params.isParamSetByUser("formulation"))
314  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  if (_lk_homogenization)
319  mooseError("The homogenization system can only be used with the "
320  "new Lagrangian kernels");
321  }
322 }
323 
324 void
326 {
327  std::string ad_prepend = "";
328  if (_use_ad)
329  ad_prepend = "AD";
330 
331  // Consistency checks across subdomains
333 
334  // Gather info from all other QuasiStaticSolidMechanicsPhysics
336 
337  // Deal with the optional AuxVariable based tensor quantity output
339 
340  // Meta action which optionally spawns other actions
341  if (_current_task == "meta_action")
342  {
344  {
345  if (_use_ad)
346  paramError("use_automatic_differentiation", "AD not setup for use with PlaneStrain");
347  // Set the action parameters
348  const std::string type = "GeneralizedPlaneStrainAction";
349  auto action_params = _action_factory.getValidParams(type);
350  action_params.set<bool>("_built_by_moose") = true;
351  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  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  action_params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
364 
365  if (parameters().isParamSetByUser("out_of_plane_pressure"))
366  action_params.set<FunctionName>("out_of_plane_pressure") =
367  getParam<FunctionName>("out_of_plane_pressure");
368  if (parameters().isParamSetByUser("out_of_plane_pressure_function"))
369  action_params.set<FunctionName>("out_of_plane_pressure_function") =
370  getParam<FunctionName>("out_of_plane_pressure_function");
371  if (parameters().isParamSetByUser("factor"))
372  action_params.set<Real>("factor") = getParam<Real>("factor");
373  if (parameters().isParamSetByUser("pressure_factor"))
374  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  _action_factory.create(type, name() + "_gps", action_params));
379  _awh.addActionBlock(action);
380  }
381  }
382 
383  // Add variables
384  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  const auto common_actions = _awh.getActions<CommonSolidMechanicsAction>();
389  if (common_actions.empty() && getParam<bool>("add_variables"))
390  {
391  auto params = _factory.getValidParams("MooseVariable");
392  // determine necessary order
393  const bool second = _problem->mesh().hasSecondOrderElements();
394 
395  params.set<MooseEnum>("order") = second ? "SECOND" : "FIRST";
396  params.set<MooseEnum>("family") = "LAGRANGE";
397  if (isParamValid("scaling"))
398  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  for (const auto & disp : _displacements)
405  {
406  // Create displacement variables
407  _problem->addVariable("MooseVariable", disp, params);
408  }
409  }
410 
411  // Homogenization scalar
412  if (_lk_homogenization)
413  {
414  InputParameters params = _factory.getValidParams("MooseVariable");
415  const std::map<bool, std::vector<unsigned int>> mg_order{{true, {1, 4, 9}},
416  {false, {1, 3, 6}}};
417  params.set<MooseEnum>("family") = "SCALAR";
418  params.set<MooseEnum>("order") = mg_order.at(_lk_large_kinematics)[_ndisp - 1];
419  auto fe_type = AddVariableAction::feType(params);
420  auto var_type = AddVariableAction::variableType(fe_type);
421  _problem->addVariable(var_type, _hname, params);
422  }
423  }
424  // Add Materials
425  else if (_current_task == "add_master_action_material")
426  {
427  // Automatic eigenstrain names
428  if (_auto_eigenstrain)
430 
431  // Easiest just to branch on type here, as the strain systems are completely
432  // different
435  else
437  }
438 
439  // Add Stress Divergence (and optionally WeakPlaneStress) Kernels
440  else if (_current_task == "add_kernel")
441  {
442  for (unsigned int i = 0; i < _ndisp; ++i)
443  {
444  auto tensor_kernel_type = getKernelType();
445  auto params = getKernelParameters(ad_prepend + tensor_kernel_type);
446 
447  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).
452  continue;
453  else if (_out_of_plane_direction == OutOfPlaneDirection::y && i == 1)
454  continue;
455 
456  params.set<unsigned int>("component") = i;
457 
458  params.set<NonlinearVariableName>("variable") = _displacements[i];
459 
460  if (_save_in.size() == _ndisp)
461  params.set<std::vector<AuxVariableName>>("save_in") = {_save_in[i]};
462  if (_diag_save_in.size() == _ndisp)
463  params.set<std::vector<AuxVariableName>>("diag_save_in") = {_diag_save_in[i]};
464  if (isParamValid("out_of_plane_strain") && !_lagrangian_kernels)
465  params.set<std::vector<VariableName>>("out_of_plane_strain") = {
466  getParam<VariableName>("out_of_plane_strain")};
467 
468  if (_lk_homogenization)
469  {
470  params.set<std::vector<VariableName>>("macro_gradient") = {_hname};
471  params.set<UserObjectName>("homogenization_constraint") = _integrator_name;
472  }
473 
474  _problem->addKernel(ad_prepend + tensor_kernel_type, kernel_name, params);
475  }
476 
478  {
479  auto params = getKernelParameters(ad_prepend + "WeakPlaneStress");
480  std::string wps_kernel_name = "TM_WPS_" + name();
481  params.set<NonlinearVariableName>("variable") = getParam<VariableName>("out_of_plane_strain");
482 
483  _problem->addKernel(ad_prepend + "WeakPlaneStress", wps_kernel_name, params);
484  }
485  }
486  else if (_current_task == "add_scalar_kernel")
487  {
488  if (_lk_homogenization)
489  {
490  InputParameters params = _factory.getValidParams("HomogenizationConstraintScalarKernel");
491  params.set<NonlinearVariableName>("variable") = _hname;
492  params.set<UserObjectName>("homogenization_constraint") = _integrator_name;
493 
494  _problem->addScalarKernel(
495  "HomogenizationConstraintScalarKernel", "HomogenizationConstraints", params);
496  }
497  }
498  else if (_current_task == "add_user_object")
499  {
500  if (_lk_homogenization)
501  {
502  InputParameters params = _factory.getValidParams("HomogenizationConstraint");
503  params.set<MultiMooseEnum>("constraint_types") = _constraint_types;
504  params.set<std::vector<FunctionName>>("targets") = _targets;
505  params.set<bool>("large_kinematics") = _lk_large_kinematics;
506  params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
507  params.set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_LINEAR, EXEC_NONLINEAR};
508 
509  _problem->addUserObject("HomogenizationConstraint", _integrator_name, params);
510  }
511  }
512 }
513 
514 void
516 {
517  // Do the coordinate system check only once the problem is created
518  if (_current_task == "setup_mesh_complete")
519  {
520  // get subdomain IDs
521  for (auto & name : _subdomain_names)
522  {
523  auto id = _mesh->getSubdomainID(name);
524  if (id == Moose::INVALID_BLOCK_ID)
525  paramError("block", "Subdomain \"" + name + "\" not found in mesh.");
526  else
527  _subdomain_ids.insert(id);
528  }
529  }
530 
531  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  _subdomain_ids.empty() ? _problem->mesh().meshSubdomains() : _subdomain_ids;
536  if (check_subdomains.empty())
537  mooseError("No subdomains found");
538 
539  // make sure all subdomains are using the same coordinate system
540  _coord_system = _problem->getCoordSystem(*check_subdomains.begin());
541  for (auto subdomain : check_subdomains)
542  if (_problem->getCoordSystem(subdomain) != _coord_system)
543  mooseError("The SolidMechanics action requires all subdomains to have the same coordinate "
544  "system.");
545 
547  {
549  mooseError("'out_of_plane_direction' must be 'z' for axisymmetric simulations");
550  }
552  {
554  mooseError(
555  "Must specify two displacements for plane strain when the out of plane direction is z");
557  mooseError("Must specify three displacements for plane strain when the out of plane "
558  "direction is x or y");
559  }
560  }
561 }
562 
563 void
565 {
566  if (_current_task == "add_material")
568 
569  // Add variables (optional)
570  if (_current_task == "add_aux_variable")
571  {
572  unsigned int index = 0;
573  for (auto out : _generate_output)
574  {
575  const auto & order = _material_output_order[index];
576  const auto & family = _material_output_family[index];
577 
578  std::string type = (order == "CONSTANT" && family == "MONOMIAL")
579  ? "MooseVariableConstMonomial"
580  : "MooseVariable";
581 
582  // Create output helper aux variables
583  auto params = _factory.getValidParams(type);
584  params.set<MooseEnum>("order") = order;
585  params.set<MooseEnum>("family") = family;
586 
587  if (family == "MONOMIAL")
588  _problem->addAuxVariable(type, _base_name + out, params);
589  else
590  _problem->addVariable(type, _base_name + out, params);
591 
592  index++;
593  }
594  }
595 
596  // Add output AuxKernels
597  else if (_current_task == "add_aux_kernel")
598  {
599  std::string ad_prepend = _use_ad ? "AD" : "";
600  // Loop through output aux variables
601  unsigned int index = 0;
602  for (auto out : _generate_output)
603  {
604  if (_material_output_family[index] == "MONOMIAL")
605  {
607 
608  params = _factory.getValidParams("MaterialRealAux");
609  params.applyParameters(parameters());
610  params.set<MaterialPropertyName>("property") = _base_name + out;
611  params.set<AuxVariableName>("variable") = _base_name + out;
612  params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
613 
614  _problem->addAuxKernel(
615  ad_prepend + "MaterialRealAux", _base_name + out + '_' + name(), params);
616  }
617  index++;
618  }
619  }
620  else if (_current_task == "add_kernel")
621  {
622  std::string ad_prepend = _use_ad ? "AD" : "";
623  // Loop through output aux variables
624  unsigned int index = 0;
625  for (auto out : _generate_output)
626  {
627  if (_material_output_family[index] != "MONOMIAL")
628  {
630 
631  params = _factory.getValidParams("MaterialPropertyValue");
632  params.applyParameters(parameters());
633  params.set<MaterialPropertyName>("prop_name") = _base_name + out;
634  params.set<NonlinearVariableName>("variable") = _base_name + out;
635 
636  _problem->addKernel(
637  ad_prepend + "MaterialPropertyValue", _base_name + out + '_' + name(), params);
638  }
639  index++;
640  }
641  }
642 }
643 
644 void
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  auto materials = _problem->getMaterialWarehouse().getObjects();
658  for (auto & mat : materials)
659  {
660  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  if (mat_params.isParamValid("eigenstrain_name"))
666  {
667  std::shared_ptr<MaterialData> mat_dat;
668  auto name = mat_params.get<std::string>("eigenstrain_name");
669 
670  // Check for base_name prefix
671  if (mat_params.isParamValid("base_name"))
672  name = mat_params.get<std::string>("base_name") + '_' + name;
673 
674  // Check block restrictions
675  if (!blk)
676  mooseError("Internal error, Material object that does not inherit form BlockRestricted");
677  const std::set<SubdomainID> & blocks =
678  blk->blockRestricted() ? blk->blockIDs() : blk->meshBlockIDs();
679 
680  if (std::includes(blocks.begin(), blocks.end(), _subdomain_ids.begin(), _subdomain_ids.end()))
681  {
682  material_eigenstrain_map[name].insert(blocks.begin(), blocks.end());
683  eigenstrain_set.insert(name);
684  }
685  }
686 
687  // Account for reduced eigenstrains and CompositeEigenstrains
688  if (mat_name == "ComputeReducedOrderEigenstrain")
689  {
690  auto input_eigenstrain_names =
691  mat_params.get<std::vector<MaterialPropertyName>>("input_eigenstrain_names");
692  remove_reduced_set.insert(input_eigenstrain_names.begin(), input_eigenstrain_names.end());
693  }
694  // Account for CompositeEigenstrains
695  if (mat_name == "CompositeEigenstrain")
696  {
697  auto remove_list = mat_params.get<std::vector<MaterialPropertyName>>("tensors");
698  for (auto i : remove_list)
699  remove_reduced_set.insert(i);
700  }
701 
702  // Account for MaterialADConverter , add or remove later
703  if (mat_name == "RankTwoTensorMaterialADConverter")
704  {
705  std::vector<MaterialPropertyName> remove_list;
706  std::vector<MaterialPropertyName> add_list;
707 
708  if (mat_params.isParamValid("ad_props_out") && mat_params.isParamValid("reg_props_in") &&
709  _use_ad)
710  {
711  remove_list = mat_params.get<std::vector<MaterialPropertyName>>("reg_props_in");
712  add_list = mat_params.get<std::vector<MaterialPropertyName>>("ad_props_out");
713  }
714  if (mat_params.isParamValid("ad_props_in") && mat_params.isParamValid("reg_props_out") &&
715  !_use_ad)
716  {
717  remove_list = mat_params.get<std::vector<MaterialPropertyName>>("ad_props_in");
718  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  for (unsigned int index = 0; index < remove_list.size(); index++)
723  remove_add_map.emplace(remove_list[index], add_list[index]);
724  }
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  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  if (is_in)
733  {
734  eigenstrain_set.erase(remove_add_index.first);
735  eigenstrain_set.insert(remove_add_index.second);
736  }
737  }
738  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  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  _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  Moose::out << COLOR_CYAN << "*** Automatic Eigenstrain Names ***"
756  << "\n"
757  << _name << ": " << Moose::stringify(_eigenstrain_names) << "\n"
758  << COLOR_DEFAULT << std::flush;
759 }
760 
761 void
763 {
764  // Ensure material output order and family vectors are same size as generate output
765 
766  // check number of supplied orders and families
768  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  if (_material_output_family.size() > 1 &&
775  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  if (_material_output_order.size() == 0)
783 
784  // For only one order, make all orders the same magnitude
785  if (_material_output_order.size() == 1)
787  std::vector<std::string>(_generate_output.size(), _material_output_order[0]);
788 
789  if (_verbose)
790  Moose::out << COLOR_CYAN << "*** Automatic applied material output orders ***"
791  << "\n"
792  << _name << ": " << Moose::stringify(_material_output_order) << "\n"
793  << COLOR_DEFAULT << std::flush;
794 
795  // if no value was provided, chose the default MONOMIAL
796  if (_material_output_family.size() == 0)
798 
799  // For only one family, make all families that value
800  if (_material_output_family.size() == 1)
802  std::vector<std::string>(_generate_output.size(), _material_output_family[0]);
803 
804  if (_verbose)
805  Moose::out << COLOR_CYAN << "*** Automatic applied material output families ***"
806  << "\n"
807  << _name << ": " << Moose::stringify(_material_output_family) << "\n"
808  << COLOR_DEFAULT << std::flush;
809 }
810 
811 void
813 {
814  std::string ad_prepend = _use_ad ? "AD" : "";
815 
816  if (_current_task == "add_material")
817  {
818  // Add output Materials
819  for (auto out : _generate_output)
820  {
822 
823  // RankTwoCartesianComponent
824  if (
825  [&]()
826  {
827  for (const auto & r2q : _rank_two_cartesian_component_table)
828  for (unsigned int a = 0; a < 3; ++a)
829  for (unsigned int b = 0; b < 3; ++b)
830  if (r2q.first + '_' + _component_table[a] + _component_table[b] == out)
831  {
832  auto type = ad_prepend + "RankTwoCartesianComponent";
833  params = _factory.getValidParams(type);
834  params.set<MaterialPropertyName>("rank_two_tensor") = _base_name + r2q.second;
835  params.set<unsigned int>("index_i") = a;
836  params.set<unsigned int>("index_j") = b;
837 
838  params.applyParameters(parameters());
839  params.set<MaterialPropertyName>("property_name") = _base_name + out;
840  _problem->addMaterial(type, _base_name + out + '_' + name(), params);
841  return true;
842  }
843  return false;
844  }())
845  continue;
846 
847  // RankTwoDirectionalComponent
848  if (setupOutput(out,
850  [&](std::string prop_name, std::string invariant)
851  {
852  auto type = ad_prepend + "RankTwoDirectionalComponent";
853  params = _factory.getValidParams(type);
854  params.set<MaterialPropertyName>("rank_two_tensor") =
855  _base_name + prop_name;
856  params.set<MooseEnum>("invariant") = invariant;
857  params.applyParameters(parameters());
858  params.set<MaterialPropertyName>("property_name") = _base_name + out;
859  _problem->addMaterial(type, _base_name + out + '_' + name(), params);
860  }))
861  continue;
862 
863  // RankTwoInvariant
864  if (setupOutput(out,
866  [&](std::string prop_name, std::string invariant)
867  {
868  auto type = ad_prepend + "RankTwoInvariant";
869  params = _factory.getValidParams(type);
870  params.set<MaterialPropertyName>("rank_two_tensor") =
871  _base_name + prop_name;
872  params.set<MooseEnum>("invariant") = invariant;
873  params.applyParameters(parameters());
874  params.set<MaterialPropertyName>("property_name") = _base_name + out;
875  _problem->addMaterial(type, _base_name + out + '_' + name(), params);
876  }))
877  continue;
878 
879  // RankTwoCylindricalComponent
880  if (setupOutput(
881  out,
883  [&](std::string prop_name, std::string component)
884  {
886  mooseError(
887  "Cannot use cylindrical component output in a spherical coordinate system.");
888  auto type = ad_prepend + "RankTwoCylindricalComponent";
889  params = _factory.getValidParams(type);
890  params.set<MaterialPropertyName>("rank_two_tensor") = _base_name + prop_name;
891  params.set<MooseEnum>("cylindrical_component") = component;
892  params.applyParameters(parameters());
893  params.set<MaterialPropertyName>("property_name") = _base_name + out;
894  _problem->addMaterial(type, _base_name + out + '_' + name(), params);
895  }))
896  continue;
897 
898  // RankTwoSphericalComponent
899  if (setupOutput(out,
901  [&](std::string prop_name, std::string component)
902  {
903  auto type = ad_prepend + "RankTwoSphericalComponent";
904  params = _factory.getValidParams(type);
905  params.set<MaterialPropertyName>("rank_two_tensor") =
906  _base_name + prop_name;
907  params.set<MooseEnum>("spherical_component") = component;
908  params.applyParameters(parameters());
909  params.set<MaterialPropertyName>("property_name") = _base_name + out;
910  _problem->addMaterial(type, _base_name + out + '_' + name(), params);
911  }))
912  continue;
913 
914  paramError("generate_output", "Unable to add output Material for '", out, "'");
915  }
916  }
917 }
918 
919 void
921 {
922  // Gather info about all other solid mechanics physics when we add variables
923  if (_current_task == "validate_coordinate_systems" && getParam<bool>("add_variables"))
924  {
926  for (const auto & action : actions)
927  {
928  const auto size_before = _subdomain_id_union.size();
929  const auto added_size = action->_subdomain_ids.size();
930  _subdomain_id_union.insert(action->_subdomain_ids.begin(), action->_subdomain_ids.end());
931  const auto size_after = _subdomain_id_union.size();
932 
933  if (size_after != size_before + added_size)
934  mooseError("The block restrictions in the SolidMechanics/QuasiStatic actions must be "
935  "non-overlapping.");
936 
937  if (added_size == 0 && actions.size() > 1)
938  mooseError(
939  "No SolidMechanics/QuasiStatic action can be block unrestricted if more than one "
940  "SolidMechanics/QuasiStatic action is specified.");
941  }
942  }
943 }
944 
945 void
947 {
948  std::string type;
950  type = "ComputeLagrangianStrain";
951  else if (_coord_system == Moose::COORD_RZ)
952  type = "ComputeLagrangianStrainAxisymmetricCylindrical";
954  type = "ComputeLagrangianStrainCentrosymmetricSpherical";
955  else
956  mooseError("Unsupported coordinate system");
957 
958  auto params = _factory.getValidParams(type);
959 
960  if (isParamValid("strain_base_name"))
961  params.set<std::string>("base_name") = getParam<std::string>("strain_base_name");
962 
963  params.set<std::vector<VariableName>>("displacements") = _coupled_displacements;
964  params.set<std::vector<MaterialPropertyName>>("eigenstrain_names") = _eigenstrain_names;
965  params.set<bool>("large_kinematics") = _lk_large_kinematics;
966  params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
967 
968  // Error if volumetric locking correction is on for higher-order elements
969  if (_problem->mesh().hasSecondOrderElements() && _lk_locking)
970  mooseError("Volumetric locking correction should not be used for "
971  "higher-order elements.");
972 
973  params.set<bool>("stabilize_strain") = _lk_locking;
974 
975  if (_lk_homogenization)
976  {
977  params.set<std::vector<MaterialPropertyName>>("homogenization_gradient_names") = {
979  }
980 
981  _problem->addMaterial(type, name() + "_strain", params);
982 
983  // Add the homogenization strain calculator
984  if (_lk_homogenization)
985  {
986  std::string type = "ComputeHomogenizedLagrangianStrain";
987  auto params = _factory.getValidParams(type);
988 
989  params.set<MaterialPropertyName>("homogenization_gradient_name") = _homogenization_strain_name;
990  params.set<std::vector<VariableName>>("macro_gradient") = {_hname};
991  params.set<UserObjectName>("homogenization_constraint") = _integrator_name;
992 
993  _problem->addMaterial(type, name() + "_compute_" + _homogenization_strain_name, params);
994  }
995 }
996 
997 void
999 {
1000  std::string ad_prepend = _use_ad ? "AD" : "";
1001 
1002  std::string type;
1003 
1004  // no plane strain
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"},
1013  "ComputeAxisymmetricRZIncrementalStrain"},
1015  "ComputeAxisymmetricRZFiniteStrain"},
1016  {{Moose::COORD_RSPHERICAL, StrainAndIncrement::SmallTotal}, "ComputeRSphericalSmallStrain"},
1018  "ComputeRSphericalIncrementalStrain"},
1020  "ComputeRSphericalFiniteStrain"}};
1021 
1022  auto type_it = type_map.find(std::make_pair(_coord_system, _strain_and_increment));
1023  if (type_it != type_map.end())
1024  type = type_it->second;
1025  else
1026  mooseError("Unsupported strain formulation");
1027  }
1031  {
1034  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"},
1043  "ComputeAxisymmetric1DIncrementalStrain"},
1045  "ComputeAxisymmetric1DFiniteStrain"}};
1046 
1047  // choose kernel type based on coordinate system
1048  auto type_it = type_map.find(std::make_pair(_coord_system, _strain_and_increment));
1049  if (type_it != type_map.end())
1050  type = type_it->second;
1051  else
1052  mooseError("Unsupported coordinate system for plane strain.");
1053  }
1054  else
1055  mooseError("Unsupported planar formulation");
1056 
1057  // set material parameters
1058  auto params = _factory.getValidParams(ad_prepend + type);
1059  params.applyParameters(
1060  parameters(),
1061  {"displacements", "use_displaced_mesh", "out_of_plane_strain", "scalar_out_of_plane_strain"});
1062 
1063  if (isParamValid("strain_base_name"))
1064  params.set<std::string>("base_name") = getParam<std::string>("strain_base_name");
1065 
1066  params.set<std::vector<VariableName>>("displacements") = _coupled_displacements;
1067  params.set<bool>("use_displaced_mesh") = false;
1068 
1069  if (isParamValid("scalar_out_of_plane_strain"))
1070  params.set<std::vector<VariableName>>("scalar_out_of_plane_strain") = {
1071  getParam<VariableName>("scalar_out_of_plane_strain")};
1072 
1073  if (isParamValid("out_of_plane_strain"))
1074  params.set<std::vector<VariableName>>("out_of_plane_strain") = {
1075  getParam<VariableName>("out_of_plane_strain")};
1076 
1077  params.set<std::vector<MaterialPropertyName>>("eigenstrain_names") = _eigenstrain_names;
1078 
1079  _problem->addMaterial(ad_prepend + type, name() + "_strain", params);
1080 }
1081 
1082 std::string
1084 {
1085  if (_lagrangian_kernels)
1086  {
1087  std::string type;
1089  {
1090  if (_lk_homogenization)
1091  type = "HomogenizedTotalLagrangianStressDivergence";
1093  type = "TotalLagrangianStressDivergence";
1095  type = "UpdatedLagrangianStressDivergence";
1096  else
1097  mooseError("Unknown formulation type");
1098  }
1099  else if (_coord_system == Moose::COORD_RZ)
1100  {
1101  if (_lk_homogenization)
1102  mooseError("The Lagrangian mechanics kernels do not yet support homogenization in "
1103  "coordinate systems other than Cartesian.");
1105  type = "TotalLagrangianStressDivergenceAxisymmetricCylindrical";
1107  mooseError("The Lagrangian mechanics kernels do not yet support the updated Lagrangian "
1108  "formulation in RZ coordinates.");
1109  }
1111  {
1112  if (_lk_homogenization)
1113  mooseError("The Lagrangian mechanics kernels do not yet support homogenization in "
1114  "coordinate systems other than Cartesian.");
1116  type = "TotalLagrangianStressDivergenceCentrosymmetricSpherical";
1118  mooseError("The Lagrangian mechanics kernels do not yet support the updated Lagrangian "
1119  "formulation in RZ coordinates.");
1120  }
1121  else
1122  mooseError("Unsupported coordinate system");
1123  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  {Moose::COORD_RSPHERICAL, "StressDivergenceRSphericalTensors"}};
1131 
1132  // choose kernel type based on coordinate system
1133  auto type_it = type_map.find(_coord_system);
1134  if (type_it != type_map.end())
1135  return type_it->second;
1136  else
1137  mooseError("Unsupported coordinate system");
1138  }
1139 }
1140 
1143 {
1145  params.applyParameters(
1146  parameters(),
1147  {"displacements", "use_displaced_mesh", "save_in", "diag_save_in", "out_of_plane_strain"});
1148 
1149  params.set<std::vector<VariableName>>("displacements") = _coupled_displacements;
1150 
1151  if (_lagrangian_kernels)
1152  {
1153  params.set<bool>("use_displaced_mesh") =
1155  params.set<bool>("large_kinematics") = _lk_large_kinematics;
1156  params.set<bool>("stabilize_strain") = _lk_locking;
1157  }
1158  else
1159  params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
1160 
1161  return params;
1162 }
const bool _lk_large_kinematics
Simplified flag for small/large deformations, Lagrangian kernel system.
std::set< SubdomainID > _subdomain_id_union
set generated from the combined block restrictions of all SolidMechanics/Master action blocks ...
enum QuasiStaticSolidMechanicsPhysics::StrainAndIncrement _strain_and_increment
std::vector< AuxVariableName > _save_in
residual debugging
virtual InputParameters getKernelParameters(std::string type)
bool setupOutput(std::string out, T table, T2 setup)
Helper function to decode generate_outputs options using a "table" of scalar output quantities and a ...
ActionWarehouse & _awh
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
std::vector< AuxVariableName > _diag_save_in
static const std::map< std::string, std::pair< std::string, std::vector< std::string > > > _rank_two_invariant_table
char ** blocks
std::set< SubdomainID > _subdomain_ids
set generated from the passed in vector of subdomain names
InputParameters getValidParams(const std::string &name)
void setAdditionalValue(const std::string &names)
void mooseInfo(Args &&... args) const
unsigned int _ndisp
Number of displacement variables.
static const std::string component
Definition: NS.h:153
LKFormulation
New kernel system kinematics types.
static const std::map< std::string, std::pair< std::string, std::vector< std::string > > > _rank_two_cylindrical_component_table
T & set(const std::string &name, bool quiet_mode=false)
InputParameters getValidParams(const std::string &name) const
const bool _auto_eigenstrain
automatically gather names of eigenstrain tensors provided by simulation objects
registerMooseAction("SolidMechanicsApp", QuasiStaticSolidMechanicsPhysics, "meta_action")
unsigned int size() const
void applyParameters(const InputParameters &common, const std::vector< std::string > &exclude={}, const bool allow_private=false)
void addActionBlock(std::shared_ptr< Action > blk)
Store common tensor mechanics parameters.
COORD_RSPHERICAL
const ExecFlagType EXEC_TIMESTEP_END
std::vector< VariableName > _displacements
displacement variables
std::vector< std::string > _generate_output
output materials to generate scalar stress/strain tensor quantities
virtual const std::string & name() const
static const std::vector< char > _component_table
table data for output generation
std::shared_ptr< Action > create(const std::string &action, const std::string &action_name, InputParameters &parameters)
InputParameters emptyInputParameters()
enum QuasiStaticSolidMechanicsPhysics::PlanarFormulation _planar_formulation
QuasiStaticSolidMechanicsPhysics(const InputParameters &params)
bool isParamValid(const std::string &name) const
Factory & _factory
const SubdomainID INVALID_BLOCK_ID
std::vector< SubdomainName > _subdomain_names
if this vector is not empty the variables, kernels and materials are restricted to these subdomains ...
void mooseDocumentedError(const std::string &repo_name, const unsigned int issue_num, Args &&... args) const
bool _use_displaced_mesh
use displaced mesh (true unless _strain is SMALL)
enum QuasiStaticSolidMechanicsPhysics::Strain _strain
std::vector< VariableName > _coupled_displacements
Coupled displacement variables.
bool _cylindrical_axis_point1_valid
booleans used to determine if cylindrical axis points are passed
const std::string & type() const
bool _lk_locking
Simplified volumetric locking correction flag for new kernels.
const std::string & _current_task
static std::string variableType(const libMesh::FEType &fe_type, const bool is_fv=false, const bool is_array=false)
void paramError(const std::string &param, Args... args) const
ActionFactory & _action_factory
const ExecFlagType EXEC_LINEAR
std::string stringify(const T &t)
static const std::map< std::string, std::pair< std::string, std::vector< std::string > > > _rank_two_directional_component_table
const std::string _name
static std::map< std::string, std::string > _rank_two_cartesian_component_table
std::vector< MaterialPropertyName > _eigenstrain_names
const ExecFlagType EXEC_NONLINEAR
bool isParamSetByUser(const std::string &name) const
std::shared_ptr< MooseMesh > & _mesh
static libMesh::FEType feType(const InputParameters &params)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
OStreamProxy out
const bool _lagrangian_kernels
New or old kernel system.
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
std::shared_ptr< FEProblemBase > & _problem
const InputParameters & parameters() const
Point _spherical_center_point
center point for spherical stress/strain quantities
const MultiMooseEnum constraintType("strain stress none")
Moose constraint type, for input.
bool _spherical_center_point_valid
booleans used to determine if spherical center point is passed
const std::string _base_name
base name for the current master action block
std::vector< const T *> getActions()
PlanarFormulation
use an out of plane stress/strain formulation
static const std::map< std::string, std::pair< std::string, std::vector< std::string > > > _rank_two_spherical_component_table
Point _cylindrical_axis_point1
points used to determine axis of rotation for cylindrical stress/strain quantities ...
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
bool _lk_homogenization
Flag indicating if the homogenization system is present for new kernels.
const ExecFlagType EXEC_INITIAL