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

Generated by: LCOV version 1.14