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

Generated by: LCOV version 1.14