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

Generated by: LCOV version 1.14