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 : #pragma once 11 : 12 : #include "Action.h" 13 : #include "Registry.h" 14 : #include "Conversion.h" 15 : #include "SerialAccess.h" 16 : #include "RankTwoTensorForward.h" 17 : #include "RankFourTensorForward.h" 18 : #include "libmesh/fe_type.h" 19 : 20 : // created types 21 : #include "InterpolatedStatefulMaterial.h" 22 : #include "ProjectedStatefulMaterialAux.h" 23 : #include "ProjectedStatefulMaterialNodalPatchRecovery.h" 24 : 25 : /** 26 : * Set up AuxKernels and AuxVariables for projected material property storage (PoMPS). 27 : */ 28 : class ProjectedStatefulMaterialStorageAction : public Action 29 : { 30 : public: 31 : static InputParameters validParams(); 32 : 33 : ProjectedStatefulMaterialStorageAction(const InputParameters & parameters); 34 : 35 : virtual void act() override; 36 : 37 : using Action::addRelationshipManagers; 38 : virtual void addRelationshipManagers(Moose::RelationshipManagerType input_rm_type) override; 39 : 40 : /// List of supported raw types (equivalent AD types are also supported) 41 : typedef Moose::TypeList<Real, RealVectorValue, RankTwoTensor, RankFourTensor> SupportedTypes; 42 : 43 : /// get an enum with all supported types 44 : static MooseEnum getTypeEnum(); 45 : 46 : template <typename T, bool is_ad> 47 : void processProperty(const MaterialPropertyName & prop_name); 48 : 49 : protected: 50 : template <typename T, int I> 51 : struct ProcessProperty 52 : { 53 1152 : static void apply(ProjectedStatefulMaterialStorageAction * self, 54 : const MaterialPropertyName & prop_name) 55 : { 56 1152 : self->processProperty<T, false>(prop_name); 57 1152 : self->processProperty<T, true>(prop_name); 58 1152 : } 59 : }; 60 : 61 : template <typename... Ts> 62 : static MooseEnum getTypeEnum(typename Moose::TypeList<Ts...>); 63 : 64 : /// Property names for which we will do stateful material property projection 65 : const std::vector<MaterialPropertyName> & _prop_names; 66 : 67 : /// Variable order to project the properties into 68 : const MooseEnum _order; 69 : 70 : /// FEType for the variables to project the properties into 71 : FEType _fe_type; 72 : 73 : /// MooseObject name for the underlying variable type 74 : const std::string _var_type; 75 : }; 76 : 77 : template <typename... Ts> 78 : MooseEnum 79 0 : ProjectedStatefulMaterialStorageAction::getTypeEnum(Moose::TypeList<Ts...>) 80 : { 81 0 : return MooseEnum(Moose::stringify(std::vector<std::string>{typeid(Ts).name()...}, " ")); 82 0 : } 83 : 84 : template <typename T, bool is_ad> 85 : void 86 2304 : ProjectedStatefulMaterialStorageAction::processProperty(const MaterialPropertyName & prop_name) 87 : { 88 : // check if a property of type T exists 89 2304 : const auto & block_data = _problem->getMaterialData(Moose::BLOCK_MATERIAL_DATA); 90 2304 : const auto & boundary_data = _problem->getMaterialData(Moose::BOUNDARY_MATERIAL_DATA); 91 4320 : if (!block_data.haveGenericProperty<T, is_ad>(prop_name) && 92 2016 : !boundary_data.haveGenericProperty<T, is_ad>(prop_name)) 93 2016 : return; 94 : 95 : // number of scalar components 96 288 : const auto size = Moose::SerialAccess<T>::size(); 97 : 98 : // generate variable names 99 288 : std::vector<VariableName> vars; 100 7056 : for (const auto i : make_range(size)) 101 6768 : vars.push_back("_var_" + prop_name + '_' + Moose::stringify(i)); 102 : 103 288 : if (_current_task == "setup_projected_properties") 104 : { 105 : // add the AuxVars for storage 106 3528 : for (const auto & var : vars) 107 : { 108 3384 : auto params = _factory.getValidParams(_var_type); 109 3384 : params.applyParameters(parameters()); 110 6768 : params.set<std::vector<OutputName>>("outputs") = {"none"}; 111 3384 : _problem->addAuxVariable(_var_type, var, params); 112 : } 113 : 114 : // add material 115 : { 116 144 : const auto type = Registry::getClassName<InterpolatedStatefulMaterialTempl<T>>(); 117 144 : auto params = _factory.getValidParams(type); 118 288 : params.applySpecificParameters(parameters(), {"block"}); 119 144 : params.template set<std::vector<VariableName>>("old_state") = vars; 120 144 : params.template set<MaterialPropertyName>("prop_name") = prop_name; 121 144 : _problem->addMaterial(type, "_mat_" + prop_name, params); 122 144 : } 123 : 124 : // use nodal patch recovery for lagrange 125 144 : if (_fe_type.family == LAGRANGE) 126 : { 127 : // nodal variables require patch recovery (add user object) 128 48 : const auto & type = 129 : Registry::getClassName<ProjectedStatefulMaterialNodalPatchRecoveryTempl<T, is_ad>>(); 130 48 : auto params = _factory.getValidParams(type); 131 96 : params.applySpecificParameters(parameters(), {"block"}); 132 48 : params.template set<MaterialPropertyName>("property") = prop_name; 133 48 : params.template set<MooseEnum>("patch_polynomial_order") = _order; 134 144 : params.template set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_TIMESTEP_END}; 135 48 : params.template set<bool>("force_preaux") = true; 136 48 : _problem->addUserObject(type, "_npruo_" + prop_name, params); 137 48 : } 138 : } 139 : 140 288 : if (_current_task == "add_aux_kernel") 141 : { 142 : // create variables 143 144 : std::vector<std::string> auxnames; 144 3528 : for (const auto i : make_range(size)) 145 3384 : auxnames.push_back("_aux_" + prop_name + '_' + Moose::stringify(i)); 146 : 147 : // use nodal patch recovery for lagrange 148 144 : if (_fe_type.family == LAGRANGE) 149 : { 150 : // nodal variables require patch recovery (add aux kernel) 151 48 : const auto & type = "ProjectedMaterialPropertyNodalPatchRecoveryAux"; 152 1176 : for (const auto i : make_range(size)) 153 : { 154 1128 : auto params = _factory.getValidParams(type); 155 2256 : params.applySpecificParameters(parameters(), {"block"}); 156 1128 : params.template set<AuxVariableName>("variable") = vars[i]; 157 1128 : params.template set<unsigned int>("component") = i; 158 1128 : params.template set<UserObjectName>("nodal_patch_recovery_uo") = "_npruo_" + prop_name; 159 3384 : params.template set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_TIMESTEP_END}; 160 1128 : _problem->addAuxKernel(type, auxnames[i], params); 161 : } 162 : } 163 : else 164 : { 165 : // elemental variables 166 96 : const auto & type = Registry::getClassName<ProjectedStatefulMaterialAuxTempl<T, is_ad>>(); 167 2352 : for (const auto i : make_range(size)) 168 : { 169 2256 : auto params = _factory.getValidParams(type); 170 4512 : params.applySpecificParameters(parameters(), {"block"}); 171 2256 : params.template set<AuxVariableName>("variable") = vars[i]; 172 2256 : params.template set<unsigned int>("component") = i; 173 2256 : params.template set<MaterialPropertyName>("prop") = prop_name; 174 6768 : params.template set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_TIMESTEP_END}; 175 2256 : _problem->addAuxKernel(type, auxnames[i], params); 176 : } 177 96 : } 178 144 : } 179 14256 : }