LCOV - code coverage report
Current view: top level - src/physics - QuasiStaticSolidMechanicsPhysics.C (source / functions) Hit Total Coverage
Test: idaholab/moose solid_mechanics: f45d79 Lines: 479 558 85.8 %
Date: 2025-07-25 05:00:39 Functions: 17 18 94.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14