LCOV - code coverage report
Current view: top level - src/physics - QuasiStaticSolidMechanicsPhysics.C (source / functions) Hit Total Coverage
Test: idaholab/moose solid_mechanics: e605d5 Lines: 468 551 84.9 %
Date: 2025-09-16 22:05:57 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        7676 : QuasiStaticSolidMechanicsPhysics::validParams()
      55             : {
      56        7676 :   InputParameters params = QuasiStaticSolidMechanicsPhysicsBase::validParams();
      57        7676 :   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       15352 :   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       15352 :   params.addParamNamesToGroup("block", "Advanced");
      67             : 
      68       15352 :   params.addParam<MultiMooseEnum>("additional_generate_output",
      69       15352 :                                   QuasiStaticSolidMechanicsPhysicsBase::outputPropertiesType(),
      70             :                                   "Add scalar quantity output for stress and/or strain (will be "
      71             :                                   "appended to the list in `generate_output`)");
      72       15352 :   params.addParam<MultiMooseEnum>(
      73             :       "additional_material_output_order",
      74       15352 :       QuasiStaticSolidMechanicsPhysicsBase::materialOutputOrders(),
      75             :       "Specifies the order of the FE shape function to use for this variable.");
      76             : 
      77       15352 :   params.addParam<MultiMooseEnum>(
      78             :       "additional_material_output_family",
      79       15352 :       QuasiStaticSolidMechanicsPhysicsBase::materialOutputFamilies(),
      80             :       "Specifies the family of FE shape functions to use for this variable.");
      81             : 
      82       15352 :   params.addParamNamesToGroup("additional_generate_output additional_material_output_order "
      83             :                               "additional_material_output_family",
      84             :                               "Output");
      85       15352 :   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       15352 :   params.addParam<std::vector<TagName>>(
      89             :       "extra_vector_tags",
      90             :       "The tag names for extra vectors that residual data should be saved into");
      91       15352 :   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       15352 :   params.addParam<Real>("scaling", "The scaling to apply to the displacement variables");
      95       15352 :   params.addParam<Point>(
      96             :       "cylindrical_axis_point1",
      97             :       "Starting point for direction of axis of rotation for cylindrical stress/strain.");
      98       15352 :   params.addParam<Point>(
      99             :       "cylindrical_axis_point2",
     100             :       "Ending point for direction of axis of rotation for cylindrical stress/strain.");
     101       15352 :   params.addParam<Point>("spherical_center_point",
     102             :                          "Center point of the spherical coordinate system.");
     103       15352 :   params.addParam<Point>("direction", "Direction stress/strain is calculated in");
     104       15352 :   params.addParam<bool>("automatic_eigenstrain_names",
     105       15352 :                         false,
     106             :                         "Collects all material eigenstrains and passes to required strain "
     107             :                         "calculator within TMA internally.");
     108             : 
     109             :   // Homogenization system input
     110       15352 :   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       15352 :   params.addParam<std::vector<FunctionName>>(
     116             :       "targets", {}, "Functions giving the targets to hit for constraint types that are not none.");
     117             : 
     118       15352 :   params.addParamNamesToGroup("scaling", "Variables");
     119       15352 :   params.addParamNamesToGroup("strain_base_name automatic_eigenstrain_names", "Strain");
     120       15352 :   params.addParamNamesToGroup(
     121             :       "cylindrical_axis_point1 cylindrical_axis_point2 spherical_center_point direction",
     122             :       "Coordinate system");
     123             : 
     124        7676 :   return params;
     125           0 : }
     126             : 
     127        7676 : QuasiStaticSolidMechanicsPhysics::QuasiStaticSolidMechanicsPhysics(const InputParameters & params)
     128             :   : QuasiStaticSolidMechanicsPhysicsBase(params),
     129       15352 :     _displacements(getParam<std::vector<VariableName>>("displacements")),
     130        7676 :     _ndisp(_displacements.size()),
     131        7676 :     _coupled_displacements(_ndisp),
     132       15352 :     _save_in(getParam<std::vector<AuxVariableName>>("save_in")),
     133       15352 :     _diag_save_in(getParam<std::vector<AuxVariableName>>("diag_save_in")),
     134       23028 :     _subdomain_names(getParam<std::vector<SubdomainName>>("block")),
     135             :     _subdomain_ids(),
     136       15352 :     _strain(getParam<MooseEnum>("strain").getEnum<Strain>()),
     137       15352 :     _planar_formulation(getParam<MooseEnum>("planar_formulation").getEnum<PlanarFormulation>()),
     138        7676 :     _out_of_plane_direction(
     139        7676 :         getParam<MooseEnum>("out_of_plane_direction").getEnum<OutOfPlaneDirection>()),
     140       15502 :     _base_name(isParamValid("base_name") ? getParam<std::string>("base_name") + "_" : ""),
     141       15352 :     _material_output_order(getParam<MultiMooseEnum>("material_output_order")),
     142       15352 :     _material_output_family(getParam<MultiMooseEnum>("material_output_family")),
     143        7676 :     _cylindrical_axis_point1_valid(params.isParamSetByUser("cylindrical_axis_point1")),
     144        7676 :     _cylindrical_axis_point2_valid(params.isParamSetByUser("cylindrical_axis_point2")),
     145        7676 :     _direction_valid(params.isParamSetByUser("direction")),
     146       15352 :     _verbose(getParam<bool>("verbose")),
     147        7676 :     _spherical_center_point_valid(params.isParamSetByUser("spherical_center_point")),
     148       15352 :     _auto_eigenstrain(getParam<bool>("automatic_eigenstrain_names")),
     149       15352 :     _lagrangian_kernels(getParam<bool>("new_system")),
     150        7676 :     _lk_large_kinematics(_strain == Strain::Finite),
     151       15352 :     _lk_formulation(getParam<MooseEnum>("formulation").getEnum<LKFormulation>()),
     152       15352 :     _lk_locking(getParam<bool>("volumetric_locking_correction")),
     153        7676 :     _lk_homogenization(false),
     154        7676 :     _constraint_types(getParam<MultiMooseEnum>("constraint_types")),
     155       30704 :     _targets(getParam<std::vector<FunctionName>>("targets"))
     156             : {
     157             :   // determine if incremental strains are to be used
     158       15352 :   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        5483 :     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        2478 :     else if (_strain == Strain::Finite)
     181             :     {
     182        2478 :       _strain_and_increment = StrainAndIncrement::FiniteIncremental;
     183        2478 :       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        7676 :   _use_displaced_mesh = (_strain == Strain::Finite);
     191       15352 :   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       28381 :   for (unsigned int i = 0; i < _ndisp; ++i)
     201       20705 :     _coupled_displacements[i] = _displacements[i];
     202             : 
     203        7676 :   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        7676 :   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        7676 :   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       34239 :   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       18887 :     _generate_output.push_back(lower);
     237             :   }
     238             : 
     239        7676 :   if (!_generate_output.empty())
     240        4060 :     verifyOrderAndFamilyOutputs();
     241             : 
     242             :   // Error if volumetric locking correction is true for 1D problems
     243        8160 :   if (_ndisp == 1 && getParam<bool>("volumetric_locking_correction"))
     244           0 :     mooseError("Volumetric locking correction should be set to false for 1D problems.");
     245             : 
     246       17887 :   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        7674 :   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        7674 :   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        7674 :   if (_direction_valid)
     264          64 :     _direction = getParam<Point>("direction");
     265             : 
     266             :   // Get eigenstrain names if passed by user
     267       15348 :   _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        7674 :   bool ctype_set = params.isParamSetByUser("constraint_types");
     272        7674 :   bool targets_set = params.isParamSetByUser("targets");
     273        7674 :   if (ctype_set || targets_set)
     274             :   {
     275          14 :     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          14 :     _lk_homogenization = true;
     280             :     // Do consistency checking on the kernel options
     281          14 :     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        7674 :   if (_lagrangian_kernels)
     289             :   {
     290         198 :     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         396 :     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         396 :     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         396 :     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        7674 : }
     321             : 
     322             : void
     323       64745 : QuasiStaticSolidMechanicsPhysics::act()
     324             : {
     325       64745 :   std::string ad_prepend = "";
     326       64745 :   if (_use_ad)
     327             :     ad_prepend = "AD";
     328             : 
     329             :   // Consistency checks across subdomains
     330       64745 :   actSubdomainChecks();
     331             : 
     332             :   // Gather info from all other QuasiStaticSolidMechanicsPhysics
     333       64741 :   actGatherActionParameters();
     334             : 
     335             :   // Deal with the optional AuxVariable based tensor quantity output
     336       64733 :   actOutputGeneration();
     337             : 
     338             :   // Meta action which optionally spawns other actions
     339       64733 :   if (_current_task == "meta_action")
     340             :   {
     341        5572 :     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       59161 :   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        5548 :     const auto common_actions = _awh.getActions<CommonSolidMechanicsAction>();
     387        5548 :     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        5548 :     if (_lk_homogenization)
     411             :     {
     412          14 :       InputParameters params = _factory.getValidParams("MooseVariable");
     413             :       const std::map<bool, std::vector<unsigned int>> mg_order_max{{true, {1, 4, 9}},
     414          42 :                                                                    {false, {1, 3, 6}}};
     415             :       std::size_t mg_order = 0;
     416         140 :       for (auto i : index_range(_constraint_types))
     417             :       {
     418         126 :         const auto ctype = static_cast<Homogenization::ConstraintType>(_constraint_types.get(i));
     419         126 :         if (ctype != Homogenization::ConstraintType::None)
     420          70 :           mg_order++;
     421             :       }
     422          14 :       if (mg_order > mg_order_max.at(_lk_large_kinematics)[_ndisp - 1])
     423           0 :         paramError("constraint_types",
     424             :                    "Number of non-none constraint types must not be greater than ",
     425           0 :                    mg_order_max.at(_lk_large_kinematics)[_ndisp - 1],
     426             :                    ", but ",
     427             :                    mg_order,
     428             :                    " are provided.");
     429          28 :       params.set<MooseEnum>("family") = "SCALAR";
     430          14 :       params.set<MooseEnum>("order") = mg_order;
     431          14 :       auto fe_type = AddVariableAction::feType(params);
     432          14 :       auto var_type = AddVariableAction::variableType(fe_type);
     433          14 :       _problem->addVariable(var_type, _hname, params);
     434          14 :     }
     435        5548 :   }
     436             :   // Add Materials
     437       53613 :   else if (_current_task == "add_master_action_material")
     438             :   {
     439             :     // Automatic eigenstrain names
     440        5474 :     if (_auto_eigenstrain)
     441          61 :       actEigenstrainNames();
     442             : 
     443             :     // Easiest just to branch on type here, as the strain systems are completely
     444             :     // different
     445        5474 :     if (_lagrangian_kernels)
     446         198 :       actLagrangianKernelStrain();
     447             :     else
     448        5276 :       actStressDivergenceTensorsStrain();
     449             :   }
     450             : 
     451             :   // Add Stress Divergence (and optionally WeakPlaneStress) Kernels
     452       48139 :   else if (_current_task == "add_kernel")
     453             :   {
     454       27843 :     for (unsigned int i = 0; i < _ndisp; ++i)
     455             :     {
     456       20309 :       auto tensor_kernel_type = getKernelType();
     457       40618 :       auto params = getKernelParameters(ad_prepend + tensor_kernel_type);
     458             : 
     459       40618 :       std::string kernel_name = "TM_" + name() + Moose::stringify(i);
     460             : 
     461             :       // Set appropriate components for kernels, including in the cases where a planar model is
     462             :       // running in planes other than the x-y plane (defined by _out_of_plane_strain_direction).
     463       20309 :       if (_out_of_plane_direction == OutOfPlaneDirection::x && i == 0)
     464          54 :         continue;
     465       20255 :       else if (_out_of_plane_direction == OutOfPlaneDirection::y && i == 1)
     466          54 :         continue;
     467             : 
     468       20201 :       params.set<unsigned int>("component") = i;
     469             : 
     470       40402 :       params.set<NonlinearVariableName>("variable") = _displacements[i];
     471             : 
     472       20201 :       if (_save_in.size() == _ndisp)
     473         738 :         params.set<std::vector<AuxVariableName>>("save_in") = {_save_in[i]};
     474       20201 :       if (_diag_save_in.size() == _ndisp)
     475           0 :         params.set<std::vector<AuxVariableName>>("diag_save_in") = {_diag_save_in[i]};
     476       60603 :       if (isParamValid("out_of_plane_strain") && !_lagrangian_kernels)
     477         348 :         params.set<std::vector<VariableName>>("out_of_plane_strain") = {
     478         696 :             getParam<VariableName>("out_of_plane_strain")};
     479             : 
     480       20201 :       if (_lk_homogenization)
     481             :       {
     482         105 :         params.set<std::vector<VariableName>>("scalar_variable") = {_hname};
     483          35 :         params.set<MultiMooseEnum>("constraint_types") = _constraint_types;
     484          70 :         params.set<std::vector<FunctionName>>("targets") = _targets;
     485             :       }
     486             : 
     487       40402 :       _problem->addKernel(ad_prepend + tensor_kernel_type, kernel_name, params);
     488       20309 :     }
     489             : 
     490        7534 :     if (_planar_formulation == PlanarFormulation::WeakPlaneStress)
     491             :     {
     492         174 :       auto params = getKernelParameters(ad_prepend + "WeakPlaneStress");
     493          87 :       std::string wps_kernel_name = "TM_WPS_" + name();
     494         261 :       params.set<NonlinearVariableName>("variable") = getParam<VariableName>("out_of_plane_strain");
     495             : 
     496         174 :       _problem->addKernel(ad_prepend + "WeakPlaneStress", wps_kernel_name, params);
     497          87 :     }
     498             :   }
     499       65121 : }
     500             : 
     501             : void
     502       64745 : QuasiStaticSolidMechanicsPhysics::actSubdomainChecks()
     503             : {
     504             :   // Do the coordinate system check only once the problem is created
     505       64745 :   if (_current_task == "setup_mesh_complete")
     506             :   {
     507             :     // get subdomain IDs
     508        6127 :     for (auto & name : _subdomain_names)
     509             :     {
     510         548 :       auto id = _mesh->getSubdomainID(name);
     511         548 :       if (id == Moose::INVALID_BLOCK_ID)
     512           0 :         paramError("block", "Subdomain \"" + name + "\" not found in mesh.");
     513             :       else
     514         548 :         _subdomain_ids.insert(id);
     515             :     }
     516             :   }
     517             : 
     518       64745 :   if (_current_task == "validate_coordinate_systems")
     519             :   {
     520             :     // use either block restriction list or list of all subdomains in the mesh
     521             :     const auto & check_subdomains =
     522        7662 :         _subdomain_ids.empty() ? _problem->mesh().meshSubdomains() : _subdomain_ids;
     523        7662 :     if (check_subdomains.empty())
     524           0 :       mooseError("No subdomains found");
     525             : 
     526             :     // make sure all subdomains are using the same coordinate system
     527        7662 :     _coord_system = _problem->getCoordSystem(*check_subdomains.begin());
     528       16573 :     for (auto subdomain : check_subdomains)
     529        8915 :       if (_problem->getCoordSystem(subdomain) != _coord_system)
     530           4 :         mooseError("The SolidMechanics action requires all subdomains to have the same coordinate "
     531             :                    "system.");
     532             : 
     533        7658 :     if (_coord_system == Moose::COORD_RZ)
     534             :     {
     535         423 :       if (_out_of_plane_direction != OutOfPlaneDirection::z)
     536           0 :         mooseError("'out_of_plane_direction' must be 'z' for axisymmetric simulations");
     537             :     }
     538        7235 :     else if (_planar_formulation != PlanarFormulation::None)
     539             :     {
     540         604 :       if (_out_of_plane_direction == OutOfPlaneDirection::z && _ndisp != 2)
     541           0 :         mooseError(
     542             :             "Must specify two displacements for plane strain when the out of plane direction is z");
     543         604 :       else if (_out_of_plane_direction != OutOfPlaneDirection::z && _ndisp != 3)
     544           0 :         mooseError("Must specify three displacements for plane strain when the out of plane "
     545             :                    "direction is x or y");
     546             :     }
     547             :   }
     548       64741 : }
     549             : 
     550             : void
     551       64733 : QuasiStaticSolidMechanicsPhysics::actOutputGeneration()
     552             : {
     553       64733 :   if (_current_task == "add_material")
     554        5542 :     actOutputMatProp();
     555             : 
     556             :   // Add variables (optional)
     557       64733 :   if (_current_task == "add_aux_variable")
     558             :   {
     559             :     unsigned int index = 0;
     560       24405 :     for (auto out : _generate_output)
     561             :     {
     562       18857 :       const auto & order = _material_output_order[index];
     563       18857 :       const auto & family = _material_output_family[index];
     564             : 
     565       18814 :       std::string type = (order == "CONSTANT" && family == "MONOMIAL")
     566             :                              ? "MooseVariableConstMonomial"
     567       37714 :                              : "MooseVariable";
     568             : 
     569             :       // Create output helper aux variables
     570       18857 :       auto params = _factory.getValidParams(type);
     571       18857 :       params.set<MooseEnum>("order") = order;
     572       18857 :       params.set<MooseEnum>("family") = family;
     573             : 
     574       18857 :       if (family == "MONOMIAL")
     575       37664 :         _problem->addAuxVariable(type, _base_name + out, params);
     576             :       else
     577          50 :         _problem->addVariable(type, _base_name + out, params);
     578             : 
     579       18857 :       index++;
     580       18857 :     }
     581             :   }
     582             : 
     583             :   // Add output AuxKernels
     584       59185 :   else if (_current_task == "add_aux_kernel")
     585             :   {
     586        9684 :     std::string ad_prepend = _use_ad ? "AD" : "";
     587             :     // Loop through output aux variables
     588             :     unsigned int index = 0;
     589       24129 :     for (auto out : _generate_output)
     590             :     {
     591       18663 :       if (_material_output_family[index] == "MONOMIAL")
     592             :       {
     593       18638 :         InputParameters params = emptyInputParameters();
     594             : 
     595       37276 :         params = _factory.getValidParams("MaterialRealAux");
     596       18638 :         params.applyParameters(parameters());
     597       55914 :         params.set<MaterialPropertyName>("property") = _base_name + out;
     598       55914 :         params.set<AuxVariableName>("variable") = _base_name + out;
     599       18638 :         params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
     600             : 
     601       37276 :         _problem->addAuxKernel(
     602       37276 :             ad_prepend + "MaterialRealAux", _base_name + out + '_' + name(), params);
     603       18638 :       }
     604       18663 :       index++;
     605             :     }
     606             :   }
     607       53719 :   else if (_current_task == "add_kernel")
     608             :   {
     609       13781 :     std::string ad_prepend = _use_ad ? "AD" : "";
     610             :     // Loop through output aux variables
     611             :     unsigned int index = 0;
     612       26181 :     for (auto out : _generate_output)
     613             :     {
     614       18647 :       if (_material_output_family[index] != "MONOMIAL")
     615             :       {
     616          25 :         InputParameters params = emptyInputParameters();
     617             : 
     618          50 :         params = _factory.getValidParams("MaterialPropertyValue");
     619          25 :         params.applyParameters(parameters());
     620          75 :         params.set<MaterialPropertyName>("prop_name") = _base_name + out;
     621          75 :         params.set<NonlinearVariableName>("variable") = _base_name + out;
     622             : 
     623          50 :         _problem->addKernel(
     624          50 :             ad_prepend + "MaterialPropertyValue", _base_name + out + '_' + name(), params);
     625          25 :       }
     626       18647 :       index++;
     627             :     }
     628             :   }
     629       64733 : }
     630             : 
     631             : void
     632          61 : QuasiStaticSolidMechanicsPhysics::actEigenstrainNames()
     633             : {
     634             :   // Create containers for collecting blockIDs and eigenstrain names from materials
     635             :   std::map<std::string, std::set<SubdomainID>> material_eigenstrain_map;
     636             :   std::set<std::string> eigenstrain_set;
     637             : 
     638             :   std::set<MaterialPropertyName> verified_eigenstrain_names;
     639             : 
     640             :   std::map<std::string, std::string> remove_add_map;
     641             :   std::set<std::string> remove_reduced_set;
     642             : 
     643             :   // Loop over all the materials(eigenstrains) already created
     644          61 :   auto materials = _problem->getMaterialWarehouse().getObjects();
     645         594 :   for (auto & mat : materials)
     646             :   {
     647         533 :     std::shared_ptr<BlockRestrictable> blk = std::dynamic_pointer_cast<BlockRestrictable>(mat);
     648             :     const InputParameters & mat_params = mat->parameters();
     649             :     auto & mat_name = mat->type();
     650             : 
     651             :     // Check for eigenstrain names, only deal with those materials
     652        1066 :     if (mat_params.isParamValid("eigenstrain_name"))
     653             :     {
     654             :       std::shared_ptr<MaterialData> mat_dat;
     655         116 :       auto name = mat_params.get<std::string>("eigenstrain_name");
     656             : 
     657             :       // Check for base_name prefix
     658         232 :       if (mat_params.isParamValid("base_name"))
     659           0 :         name = mat_params.get<std::string>("base_name") + '_' + name;
     660             : 
     661             :       // Check block restrictions
     662         116 :       if (!blk)
     663           0 :         mooseError("Internal error, Material object that does not inherit form BlockRestricted");
     664             :       const std::set<SubdomainID> & blocks =
     665         116 :           blk->blockRestricted() ? blk->blockIDs() : blk->meshBlockIDs();
     666             : 
     667         116 :       if (std::includes(blocks.begin(), blocks.end(), _subdomain_ids.begin(), _subdomain_ids.end()))
     668             :       {
     669          92 :         material_eigenstrain_map[name].insert(blocks.begin(), blocks.end());
     670          92 :         eigenstrain_set.insert(name);
     671             :       }
     672             :     }
     673             : 
     674             :     // Account for reduced eigenstrains and CompositeEigenstrains
     675         533 :     if (mat_name == "ComputeReducedOrderEigenstrain")
     676             :     {
     677             :       auto input_eigenstrain_names =
     678           6 :           mat_params.get<std::vector<MaterialPropertyName>>("input_eigenstrain_names");
     679             :       remove_reduced_set.insert(input_eigenstrain_names.begin(), input_eigenstrain_names.end());
     680           6 :     }
     681             :     // Account for CompositeEigenstrains
     682         533 :     if (mat_name == "CompositeEigenstrain")
     683             :     {
     684           6 :       auto remove_list = mat_params.get<std::vector<MaterialPropertyName>>("tensors");
     685          18 :       for (auto i : remove_list)
     686          12 :         remove_reduced_set.insert(i);
     687           6 :     }
     688             : 
     689             :     // Account for MaterialADConverter , add or remove later
     690         533 :     if (mat_name == "RankTwoTensorMaterialADConverter")
     691             :     {
     692             :       std::vector<MaterialPropertyName> remove_list;
     693             :       std::vector<MaterialPropertyName> add_list;
     694             : 
     695          36 :       if (mat_params.isParamValid("ad_props_out") && mat_params.isParamValid("reg_props_in") &&
     696          12 :           _use_ad)
     697             :       {
     698          12 :         remove_list = mat_params.get<std::vector<MaterialPropertyName>>("reg_props_in");
     699          12 :         add_list = mat_params.get<std::vector<MaterialPropertyName>>("ad_props_out");
     700             :       }
     701          36 :       if (mat_params.isParamValid("ad_props_in") && mat_params.isParamValid("reg_props_out") &&
     702          12 :           !_use_ad)
     703             :       {
     704           0 :         remove_list = mat_params.get<std::vector<MaterialPropertyName>>("ad_props_in");
     705           0 :         add_list = mat_params.get<std::vector<MaterialPropertyName>>("reg_props_out");
     706             :       }
     707             : 
     708             :       // These vectors are the same size as checked in MaterialADConverter
     709          24 :       for (unsigned int index = 0; index < remove_list.size(); index++)
     710             :         remove_add_map.emplace(remove_list[index], add_list[index]);
     711          12 :     }
     712             :   }
     713             :   // All the materials have been accounted for, now remove or add parts
     714             : 
     715             :   // Remove names which aren't eigenstrains (converter properties)
     716          73 :   for (auto remove_add_index : remove_add_map)
     717             :   {
     718             :     const bool is_in = eigenstrain_set.find(remove_add_index.first) != eigenstrain_set.end();
     719          12 :     if (is_in)
     720             :     {
     721             :       eigenstrain_set.erase(remove_add_index.first);
     722           6 :       eigenstrain_set.insert(remove_add_index.second);
     723             :     }
     724             :   }
     725          79 :   for (auto index : remove_reduced_set)
     726             :     eigenstrain_set.erase(index);
     727             : 
     728             :   // Compare the blockIDs set of eigenstrain names with the vector of _eigenstrain_names for the
     729             :   // current subdomainID
     730          61 :   std::set_union(eigenstrain_set.begin(),
     731             :                  eigenstrain_set.end(),
     732             :                  _eigenstrain_names.begin(),
     733             :                  _eigenstrain_names.end(),
     734             :                  std::inserter(verified_eigenstrain_names, verified_eigenstrain_names.begin()));
     735             : 
     736             :   // Ensure the eigenstrain names previously passed include any missing names
     737          61 :   _eigenstrain_names.resize(verified_eigenstrain_names.size());
     738             :   std::copy(verified_eigenstrain_names.begin(),
     739             :             verified_eigenstrain_names.end(),
     740             :             _eigenstrain_names.begin());
     741             : 
     742          61 :   Moose::out << COLOR_CYAN << "*** Automatic Eigenstrain Names ***"
     743             :              << "\n"
     744         183 :              << _name << ": " << Moose::stringify(_eigenstrain_names) << "\n"
     745          61 :              << COLOR_DEFAULT << std::flush;
     746         122 : }
     747             : 
     748             : void
     749        4060 : QuasiStaticSolidMechanicsPhysics::verifyOrderAndFamilyOutputs()
     750             : {
     751             :   // Ensure material output order and family vectors are same size as generate output
     752             : 
     753             :   // check number of supplied orders and families
     754        4060 :   if (_material_output_order.size() > 1 && _material_output_order.size() < _generate_output.size())
     755           0 :     paramError("material_output_order",
     756             :                "The number of orders assigned to material outputs must be: 0 to be assigned "
     757             :                "CONSTANT; 1 to assign all outputs the same value, or the same size as the number "
     758             :                "of generate outputs listed.");
     759             : 
     760        4074 :   if (_material_output_family.size() > 1 &&
     761          14 :       _material_output_family.size() < _generate_output.size())
     762           2 :     paramError("material_output_family",
     763             :                "The number of families assigned to material outputs must be: 0 to be assigned "
     764             :                "MONOMIAL; 1 to assign all outputs the same value, or the same size as the number "
     765             :                "of generate outputs listed.");
     766             : 
     767             :   // if no value was provided, chose the default CONSTANT
     768        4058 :   if (_material_output_order.size() == 0)
     769        8068 :     _material_output_order.setAdditionalValue("CONSTANT");
     770             : 
     771             :   // For only one order, make all orders the same magnitude
     772        4058 :   if (_material_output_order.size() == 1)
     773             :     _material_output_order =
     774        4046 :         std::vector<std::string>(_generate_output.size(), _material_output_order[0]);
     775             : 
     776        4058 :   if (_verbose)
     777          18 :     Moose::out << COLOR_CYAN << "*** Automatic applied material output orders ***"
     778             :                << "\n"
     779          54 :                << _name << ": " << Moose::stringify(_material_output_order) << "\n"
     780          18 :                << COLOR_DEFAULT << std::flush;
     781             : 
     782             :   // if no value was provided, chose the default MONOMIAL
     783        4058 :   if (_material_output_family.size() == 0)
     784        8080 :     _material_output_family.setAdditionalValue("MONOMIAL");
     785             : 
     786             :   // For only one family, make all families that value
     787        4058 :   if (_material_output_family.size() == 1)
     788             :     _material_output_family =
     789        4046 :         std::vector<std::string>(_generate_output.size(), _material_output_family[0]);
     790             : 
     791        4058 :   if (_verbose)
     792          18 :     Moose::out << COLOR_CYAN << "*** Automatic applied material output families ***"
     793             :                << "\n"
     794          54 :                << _name << ": " << Moose::stringify(_material_output_family) << "\n"
     795          18 :                << COLOR_DEFAULT << std::flush;
     796        4058 : }
     797             : 
     798             : void
     799        5542 : QuasiStaticSolidMechanicsPhysics::actOutputMatProp()
     800             : {
     801        9832 :   std::string ad_prepend = _use_ad ? "AD" : "";
     802             : 
     803        5542 :   if (_current_task == "add_material")
     804             :   {
     805             :     // Add output Materials
     806       24375 :     for (auto out : _generate_output)
     807             :     {
     808       18833 :       InputParameters params = emptyInputParameters();
     809             : 
     810             :       // RankTwoCartesianComponent
     811       35778 :       if (
     812       37666 :           [&]()
     813             :           {
     814      209259 :             for (const auto & r2q : _rank_two_cartesian_component_table)
     815      792317 :               for (unsigned int a = 0; a < 3; ++a)
     816     2375976 :                 for (unsigned int b = 0; b < 3; ++b)
     817     3582060 :                   if (r2q.first + '_' + _component_table[a] + _component_table[b] == out)
     818             :                   {
     819       16945 :                     auto type = ad_prepend + "RankTwoCartesianComponent";
     820       16945 :                     params = _factory.getValidParams(type);
     821       50835 :                     params.set<MaterialPropertyName>("rank_two_tensor") = _base_name + r2q.second;
     822       16945 :                     params.set<unsigned int>("index_i") = a;
     823       16945 :                     params.set<unsigned int>("index_j") = b;
     824             : 
     825       16945 :                     params.applyParameters(parameters());
     826       50835 :                     params.set<MaterialPropertyName>("property_name") = _base_name + out;
     827       33890 :                     _problem->addMaterial(type, _base_name + out + '_' + name(), params);
     828             :                     return true;
     829             :                   }
     830             :             return false;
     831       18833 :           }())
     832       16945 :         continue;
     833             : 
     834             :       // RankTwoDirectionalComponent
     835        3776 :       if (setupOutput(out,
     836             :                       _rank_two_directional_component_table,
     837           0 :                       [&](std::string prop_name, std::string invariant)
     838             :                       {
     839           0 :                         auto type = ad_prepend + "RankTwoDirectionalComponent";
     840           0 :                         params = _factory.getValidParams(type);
     841           0 :                         params.set<MaterialPropertyName>("rank_two_tensor") =
     842           0 :                             _base_name + prop_name;
     843           0 :                         params.set<MooseEnum>("invariant") = invariant;
     844           0 :                         params.applyParameters(parameters());
     845           0 :                         params.set<MaterialPropertyName>("property_name") = _base_name + out;
     846           0 :                         _problem->addMaterial(type, _base_name + out + '_' + name(), params);
     847           0 :                       }))
     848           0 :         continue;
     849             : 
     850             :       // RankTwoInvariant
     851        3776 :       if (setupOutput(out,
     852             :                       _rank_two_invariant_table,
     853        1746 :                       [&](std::string prop_name, std::string invariant)
     854             :                       {
     855        1746 :                         auto type = ad_prepend + "RankTwoInvariant";
     856        1746 :                         params = _factory.getValidParams(type);
     857        3492 :                         params.set<MaterialPropertyName>("rank_two_tensor") =
     858        1746 :                             _base_name + prop_name;
     859        1746 :                         params.set<MooseEnum>("invariant") = invariant;
     860        1746 :                         params.applyParameters(parameters());
     861        5238 :                         params.set<MaterialPropertyName>("property_name") = _base_name + out;
     862        3492 :                         _problem->addMaterial(type, _base_name + out + '_' + name(), params);
     863        1746 :                       }))
     864        1746 :         continue;
     865             : 
     866             :       // RankTwoCylindricalComponent
     867         284 :       if (setupOutput(
     868             :               out,
     869             :               _rank_two_cylindrical_component_table,
     870          42 :               [&](std::string prop_name, std::string component)
     871             :               {
     872          42 :                 if (_coord_system == Moose::COORD_RSPHERICAL)
     873           0 :                   mooseError(
     874             :                       "Cannot use cylindrical component output in a spherical coordinate system.");
     875          42 :                 auto type = ad_prepend + "RankTwoCylindricalComponent";
     876          42 :                 params = _factory.getValidParams(type);
     877         126 :                 params.set<MaterialPropertyName>("rank_two_tensor") = _base_name + prop_name;
     878          42 :                 params.set<MooseEnum>("cylindrical_component") = component;
     879          42 :                 params.applyParameters(parameters());
     880         126 :                 params.set<MaterialPropertyName>("property_name") = _base_name + out;
     881          84 :                 _problem->addMaterial(type, _base_name + out + '_' + name(), params);
     882          42 :               }))
     883          42 :         continue;
     884             : 
     885             :       // RankTwoSphericalComponent
     886         200 :       if (setupOutput(out,
     887             :                       _rank_two_spherical_component_table,
     888         100 :                       [&](std::string prop_name, std::string component)
     889             :                       {
     890         100 :                         auto type = ad_prepend + "RankTwoSphericalComponent";
     891         100 :                         params = _factory.getValidParams(type);
     892         200 :                         params.set<MaterialPropertyName>("rank_two_tensor") =
     893         100 :                             _base_name + prop_name;
     894         100 :                         params.set<MooseEnum>("spherical_component") = component;
     895         100 :                         params.applyParameters(parameters());
     896         300 :                         params.set<MaterialPropertyName>("property_name") = _base_name + out;
     897         200 :                         _problem->addMaterial(type, _base_name + out + '_' + name(), params);
     898         100 :                       }))
     899         100 :         continue;
     900             : 
     901           0 :       paramError("generate_output", "Unable to add output Material for '", out, "'");
     902       18833 :     }
     903             :   }
     904        5542 : }
     905             : 
     906             : void
     907       64741 : QuasiStaticSolidMechanicsPhysics::actGatherActionParameters()
     908             : {
     909             :   // Gather info about all other solid mechanics physics when we add variables
     910       80057 :   if (_current_task == "validate_coordinate_systems" && getParam<bool>("add_variables"))
     911             :   {
     912        5119 :     auto actions = _awh.getActions<QuasiStaticSolidMechanicsPhysics>();
     913       10446 :     for (const auto & action : actions)
     914             :     {
     915             :       const auto size_before = _subdomain_id_union.size();
     916        5335 :       const auto added_size = action->_subdomain_ids.size();
     917        5335 :       _subdomain_id_union.insert(action->_subdomain_ids.begin(), action->_subdomain_ids.end());
     918             :       const auto size_after = _subdomain_id_union.size();
     919             : 
     920        5335 :       if (size_after != size_before + added_size)
     921           4 :         mooseError("The block restrictions in the SolidMechanics/QuasiStatic actions must be "
     922             :                    "non-overlapping.");
     923             : 
     924        5331 :       if (added_size == 0 && actions.size() > 1)
     925           4 :         mooseError(
     926             :             "No SolidMechanics/QuasiStatic action can be block unrestricted if more than one "
     927             :             "SolidMechanics/QuasiStatic action is specified.");
     928             :     }
     929        5111 :   }
     930       64733 : }
     931             : 
     932             : void
     933         198 : QuasiStaticSolidMechanicsPhysics::actLagrangianKernelStrain()
     934             : {
     935             :   std::string type;
     936         198 :   if (_coord_system == Moose::COORD_XYZ)
     937             :     type = "ComputeLagrangianStrain";
     938          49 :   else if (_coord_system == Moose::COORD_RZ)
     939             :     type = "ComputeLagrangianStrainAxisymmetricCylindrical";
     940          14 :   else if (_coord_system == Moose::COORD_RSPHERICAL)
     941             :     type = "ComputeLagrangianStrainCentrosymmetricSpherical";
     942             :   else
     943           0 :     mooseError("Unsupported coordinate system");
     944             : 
     945         198 :   auto params = _factory.getValidParams(type);
     946             : 
     947         396 :   if (isParamValid("strain_base_name"))
     948           0 :     params.set<std::string>("base_name") = getParam<std::string>("strain_base_name");
     949             : 
     950         198 :   params.set<std::vector<VariableName>>("displacements") = _coupled_displacements;
     951         198 :   params.set<std::vector<MaterialPropertyName>>("eigenstrain_names") = _eigenstrain_names;
     952         198 :   params.set<bool>("large_kinematics") = _lk_large_kinematics;
     953         198 :   params.set<std::vector<SubdomainName>>("block") = _subdomain_names;
     954             : 
     955             :   // Error if volumetric locking correction is on for higher-order elements
     956         198 :   if (_problem->mesh().hasSecondOrderElements() && _lk_locking)
     957           2 :     mooseError("Volumetric locking correction should not be used for "
     958             :                "higher-order elements.");
     959             : 
     960         196 :   params.set<bool>("stabilize_strain") = _lk_locking;
     961             : 
     962         196 :   if (_lk_homogenization)
     963             :   {
     964          28 :     params.set<std::vector<MaterialPropertyName>>("homogenization_gradient_names") = {
     965          56 :         _homogenization_strain_name};
     966             :   }
     967             : 
     968         196 :   _problem->addMaterial(type, name() + "_strain", params);
     969             : 
     970             :   // Add the homogenization strain calculator
     971         196 :   if (_lk_homogenization)
     972             :   {
     973          14 :     std::string type = "ComputeHomogenizedLagrangianStrain";
     974          14 :     auto params = _factory.getValidParams(type);
     975             : 
     976          28 :     params.set<MaterialPropertyName>("homogenization_gradient_name") = _homogenization_strain_name;
     977          42 :     params.set<std::vector<VariableName>>("macro_gradient") = {_hname};
     978          14 :     params.set<MultiMooseEnum>("constraint_types") = _constraint_types;
     979          14 :     params.set<std::vector<FunctionName>>("targets") = _targets;
     980             : 
     981          14 :     _problem->addMaterial(type, name() + "_compute_" + _homogenization_strain_name, params);
     982          14 :   }
     983         392 : }
     984             : 
     985             : void
     986        5276 : QuasiStaticSolidMechanicsPhysics::actStressDivergenceTensorsStrain()
     987             : {
     988        9304 :   std::string ad_prepend = _use_ad ? "AD" : "";
     989             : 
     990             :   std::string type;
     991             : 
     992             :   // no plane strain
     993        5276 :   if (_planar_formulation == PlanarFormulation::None)
     994             :   {
     995             :     std::map<std::pair<Moose::CoordinateSystemType, StrainAndIncrement>, std::string> type_map = {
     996             :         {{Moose::COORD_XYZ, StrainAndIncrement::SmallTotal}, "ComputeSmallStrain"},
     997             :         {{Moose::COORD_XYZ, StrainAndIncrement::SmallIncremental}, "ComputeIncrementalStrain"},
     998             :         {{Moose::COORD_XYZ, StrainAndIncrement::FiniteIncremental}, "ComputeFiniteStrain"},
     999             :         {{Moose::COORD_RZ, StrainAndIncrement::SmallTotal}, "ComputeAxisymmetricRZSmallStrain"},
    1000             :         {{Moose::COORD_RZ, StrainAndIncrement::SmallIncremental},
    1001             :          "ComputeAxisymmetricRZIncrementalStrain"},
    1002             :         {{Moose::COORD_RZ, StrainAndIncrement::FiniteIncremental},
    1003             :          "ComputeAxisymmetricRZFiniteStrain"},
    1004             :         {{Moose::COORD_RSPHERICAL, StrainAndIncrement::SmallTotal}, "ComputeRSphericalSmallStrain"},
    1005             :         {{Moose::COORD_RSPHERICAL, StrainAndIncrement::SmallIncremental},
    1006             :          "ComputeRSphericalIncrementalStrain"},
    1007             :         {{Moose::COORD_RSPHERICAL, StrainAndIncrement::FiniteIncremental},
    1008       46320 :          "ComputeRSphericalFiniteStrain"}};
    1009             : 
    1010        4632 :     auto type_it = type_map.find(std::make_pair(_coord_system, _strain_and_increment));
    1011        4632 :     if (type_it != type_map.end())
    1012        4632 :       type = type_it->second;
    1013             :     else
    1014           0 :       mooseError("Unsupported strain formulation");
    1015             :   }
    1016         644 :   else if (_planar_formulation == PlanarFormulation::WeakPlaneStress ||
    1017         644 :            _planar_formulation == PlanarFormulation::PlaneStrain ||
    1018             :            _planar_formulation == PlanarFormulation::GeneralizedPlaneStrain)
    1019             :   {
    1020         644 :     if (_use_ad && (_planar_formulation == PlanarFormulation::PlaneStrain ||
    1021             :                     _planar_formulation == PlanarFormulation::GeneralizedPlaneStrain))
    1022           0 :       paramError("use_automatic_differentiation",
    1023             :                  "AD not setup for use with PlaneStrain or GeneralizedPlaneStrain");
    1024             : 
    1025             :     std::map<std::pair<Moose::CoordinateSystemType, StrainAndIncrement>, std::string> type_map = {
    1026             :         {{Moose::COORD_XYZ, StrainAndIncrement::SmallTotal}, "ComputePlaneSmallStrain"},
    1027             :         {{Moose::COORD_XYZ, StrainAndIncrement::SmallIncremental}, "ComputePlaneIncrementalStrain"},
    1028             :         {{Moose::COORD_XYZ, StrainAndIncrement::FiniteIncremental}, "ComputePlaneFiniteStrain"},
    1029             :         {{Moose::COORD_RZ, StrainAndIncrement::SmallTotal}, "ComputeAxisymmetric1DSmallStrain"},
    1030             :         {{Moose::COORD_RZ, StrainAndIncrement::SmallIncremental},
    1031             :          "ComputeAxisymmetric1DIncrementalStrain"},
    1032             :         {{Moose::COORD_RZ, StrainAndIncrement::FiniteIncremental},
    1033        4508 :          "ComputeAxisymmetric1DFiniteStrain"}};
    1034             : 
    1035             :     // choose kernel type based on coordinate system
    1036         644 :     auto type_it = type_map.find(std::make_pair(_coord_system, _strain_and_increment));
    1037         644 :     if (type_it != type_map.end())
    1038         644 :       type = type_it->second;
    1039             :     else
    1040           0 :       mooseError("Unsupported coordinate system for plane strain.");
    1041             :   }
    1042             :   else
    1043           0 :     mooseError("Unsupported planar formulation");
    1044             : 
    1045             :   // set material parameters
    1046        5276 :   auto params = _factory.getValidParams(ad_prepend + type);
    1047        5276 :   params.applyParameters(
    1048             :       parameters(),
    1049             :       {"displacements", "use_displaced_mesh", "out_of_plane_strain", "scalar_out_of_plane_strain"});
    1050             : 
    1051       10552 :   if (isParamValid("strain_base_name"))
    1052           0 :     params.set<std::string>("base_name") = getParam<std::string>("strain_base_name");
    1053             : 
    1054        5276 :   params.set<std::vector<VariableName>>("displacements") = _coupled_displacements;
    1055        5276 :   params.set<bool>("use_displaced_mesh") = false;
    1056             : 
    1057       10552 :   if (isParamValid("scalar_out_of_plane_strain"))
    1058         330 :     params.set<std::vector<VariableName>>("scalar_out_of_plane_strain") = {
    1059         660 :         getParam<VariableName>("scalar_out_of_plane_strain")};
    1060             : 
    1061       10552 :   if (isParamValid("out_of_plane_strain"))
    1062         174 :     params.set<std::vector<VariableName>>("out_of_plane_strain") = {
    1063         348 :         getParam<VariableName>("out_of_plane_strain")};
    1064             : 
    1065        5276 :   params.set<std::vector<MaterialPropertyName>>("eigenstrain_names") = _eigenstrain_names;
    1066             : 
    1067       10552 :   _problem->addMaterial(ad_prepend + type, name() + "_strain", params);
    1068       61884 : }
    1069             : 
    1070             : std::string
    1071       19464 : QuasiStaticSolidMechanicsPhysics::getKernelType()
    1072             : {
    1073       19464 :   if (_lagrangian_kernels)
    1074             :   {
    1075             :     std::string type;
    1076         476 :     if (_coord_system == Moose::COORD_XYZ)
    1077             :     {
    1078         392 :       if (_lk_homogenization)
    1079             :         type = "HomogenizedTotalLagrangianStressDivergence";
    1080         357 :       else if (_lk_formulation == LKFormulation::Total)
    1081             :         type = "TotalLagrangianStressDivergence";
    1082          91 :       else if (_lk_formulation == LKFormulation::Updated)
    1083             :         type = "UpdatedLagrangianStressDivergence";
    1084             :       else
    1085           0 :         mooseError("Unknown formulation type");
    1086             :     }
    1087          84 :     else if (_coord_system == Moose::COORD_RZ)
    1088             :     {
    1089          70 :       if (_lk_homogenization)
    1090           0 :         mooseError("The Lagrangian mechanics kernels do not yet support homogenization in "
    1091             :                    "coordinate systems other than Cartesian.");
    1092          70 :       else if (_lk_formulation == LKFormulation::Total)
    1093             :         type = "TotalLagrangianStressDivergenceAxisymmetricCylindrical";
    1094           0 :       else if (_lk_formulation == LKFormulation::Updated)
    1095           0 :         mooseError("The Lagrangian mechanics kernels do not yet support the updated Lagrangian "
    1096             :                    "formulation in RZ coordinates.");
    1097             :     }
    1098          14 :     else if (_coord_system == Moose::COORD_RSPHERICAL)
    1099             :     {
    1100          14 :       if (_lk_homogenization)
    1101           0 :         mooseError("The Lagrangian mechanics kernels do not yet support homogenization in "
    1102             :                    "coordinate systems other than Cartesian.");
    1103          14 :       else if (_lk_formulation == LKFormulation::Total)
    1104             :         type = "TotalLagrangianStressDivergenceCentrosymmetricSpherical";
    1105           0 :       else if (_lk_formulation == LKFormulation::Updated)
    1106           0 :         mooseError("The Lagrangian mechanics kernels do not yet support the updated Lagrangian "
    1107             :                    "formulation in RZ coordinates.");
    1108             :     }
    1109             :     else
    1110           0 :       mooseError("Unsupported coordinate system");
    1111         476 :     return type;
    1112             :   }
    1113             :   else
    1114             :   {
    1115             :     std::map<Moose::CoordinateSystemType, std::string> type_map = {
    1116             :         {Moose::COORD_XYZ, "StressDivergenceTensors"},
    1117             :         {Moose::COORD_RZ, "StressDivergenceRZTensors"},
    1118       75952 :         {Moose::COORD_RSPHERICAL, "StressDivergenceRSphericalTensors"}};
    1119             : 
    1120             :     // choose kernel type based on coordinate system
    1121       18988 :     auto type_it = type_map.find(_coord_system);
    1122       18988 :     if (type_it != type_map.end())
    1123       18988 :       return type_it->second;
    1124             :     else
    1125           0 :       mooseError("Unsupported coordinate system");
    1126             :   }
    1127           0 : }
    1128             : 
    1129             : InputParameters
    1130       20396 : QuasiStaticSolidMechanicsPhysics::getKernelParameters(std::string type)
    1131             : {
    1132       20396 :   InputParameters params = _factory.getValidParams(type);
    1133       20396 :   params.applyParameters(
    1134             :       parameters(),
    1135             :       {"displacements", "use_displaced_mesh", "save_in", "diag_save_in", "out_of_plane_strain"});
    1136             : 
    1137       20396 :   params.set<std::vector<VariableName>>("displacements") = _coupled_displacements;
    1138             : 
    1139       20396 :   if (_lagrangian_kernels)
    1140             :   {
    1141         476 :     params.set<bool>("use_displaced_mesh") =
    1142         476 :         (_lk_large_kinematics && (_lk_formulation == LKFormulation::Updated));
    1143         476 :     params.set<bool>("large_kinematics") = _lk_large_kinematics;
    1144         476 :     params.set<bool>("stabilize_strain") = _lk_locking;
    1145             :   }
    1146             :   else
    1147       19920 :     params.set<bool>("use_displaced_mesh") = _use_displaced_mesh;
    1148             : 
    1149       20396 :   return params;
    1150           0 : }

Generated by: LCOV version 1.14