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 : #ifdef MOOSE_KOKKOS_ENABLED 13 : #include "KokkosTypes.h" 14 : #endif 15 : 16 : // MOOSE includes 17 : #include "InputParameters.h" 18 : #include "ParallelUniqueId.h" 19 : #include "MaterialData.h" 20 : #include "MooseObject.h" 21 : 22 : #define usingBlockRestrictableMembers using BlockRestrictable::getBlockCoordSystem 23 : 24 : class FEProblemBase; 25 : class MooseMesh; 26 : 27 : #ifdef MOOSE_KOKKOS_ENABLED 28 : namespace Moose::Kokkos 29 : { 30 : class Mesh; 31 : } 32 : #endif 33 : 34 : class MooseVariableFieldBase; 35 : 36 : /** 37 : * \class BlockRestrictable BlockRestrictable.h 38 : * \brief An interface that restricts an object to subdomains via the 'blocks' input parameter 39 : * 40 : * This class adds the 'blocks' input parameter and checks that it is populated, if it is not 41 : * populated 42 : * it will be populated with all valid block ids via two methods: 43 : * -# If a 'variable' parameter is present in the input parameters then by default the 'block' 44 : * input is set to all blocks associated with the variable. 45 : * -# If no 'variable' parameter is present then it utilizes all available blocks for the 46 : * associated mesh. 47 : * 48 : * When using with an object with a 'variable' parameter (e.g., Kernel), the following must also 49 : * exist within 50 : * the input parameters for the class to operate correctly 51 : * - '_fe_problem' = pointer to FEProblemBase 52 : * - '_tid' = THREAD_ID for the class 53 : * - '_sys' = pointer to the SystemBase 54 : * 55 : * In the general case (i.e., no 'variable') \b either \b one of the following must also exist 56 : * within the 57 : * input parameters for proper operation of the class: 58 : * - '_fe_problem' = a pointer to FEProblemBase 59 : * - '_mesh' = a pointer to MooseMesh 60 : * 61 : * When creating a new object, generally, this class should be inherited following MooseObject. 62 : * Also, the BlockRestricted::validParams() must be added to any other parameters for the 63 : * the class being created, since this is where the 'blocks' input parameter is created. 64 : * 65 : * \see Kernel 66 : * \see SideSetsAroundSubdomain 67 : */ 68 : class BlockRestrictable 69 : { 70 : public: 71 : /** 72 : * Class constructor 73 : * Populates the 'block' input parameters, see the general class documentation for details. 74 : * @param parameters The input parameters (see the detailed help for additional information) 75 : * @param initialize Disable initialization, MooseVariableBase was converted to a MooseObject, 76 : * this flag allows it to be constructed as if it wasn't to maintain backward compatibility, this 77 : * will be removed in the fugure. 78 : * TODO:MooseVariableToMooseObject (see #10601) 79 : */ 80 : BlockRestrictable(const MooseObject * moose_object, bool initialize = true); 81 : 82 : static InputParameters validParams(); 83 : 84 : /** 85 : * Class constructor 86 : * Populates the 'block' input parameters when an object is also boundary restricted, 87 : * see the general class documentation for details. 88 : * @param parameters The input parameters (see the detailed help for additional information) 89 : * @param boundary_ids The boundary ids that the object is restricted to 90 : */ 91 : BlockRestrictable(const MooseObject * moose_object, const std::set<BoundaryID> & boundary_ids); 92 : 93 : #ifdef MOOSE_KOKKOS_ENABLED 94 : /** 95 : * Special constructor used for Kokkos functor copy during parallel dispatch 96 : */ 97 : BlockRestrictable(const BlockRestrictable & object, const Moose::Kokkos::FunctorCopy & key); 98 : #endif 99 : 100 : /** 101 : * Destructor: does nothing but needs to be marked as virtual since 102 : * this class defines virtual functions. 103 : */ 104 600254 : virtual ~BlockRestrictable() {} 105 : 106 : /** 107 : * Return the block names for this object 108 : * 109 : * Note, if the 'blocks' input parameter was not utilized this will return an 110 : * empty vector. 111 : * 112 : * @return vector of SubdomainNames that are valid for this object 113 : */ 114 : const std::vector<SubdomainName> & blocks() const; 115 : 116 : /** 117 : * Return the number of blocks for this object 118 : * @return The number of subdomains 119 : */ 120 : unsigned int numBlocks() const; 121 : 122 : /** 123 : * Return the block subdomain ids for this object 124 : * Note, if this is not block restricted, this function returns all mesh subdomain ids. 125 : * @return a set of SubdomainIDs that are valid for this object 126 : */ 127 : virtual const std::set<SubdomainID> & blockIDs() const; 128 : 129 : /** 130 : * Return the largest mesh dimension of the elements in the blocks for this object 131 : */ 132 : unsigned int blocksMaxDimension() const; 133 : 134 : /** 135 : * Test if the supplied block name is valid for this object 136 : * @param name A SubdomainName to check 137 : * @return True if the given id is valid for this object 138 : */ 139 : bool hasBlocks(const SubdomainName & name) const; 140 : 141 : /** 142 : * Test if the supplied vector of block names are valid for this object 143 : * @param names A vector of SubdomainNames to check 144 : * @return True if the given ids are valid for this object 145 : */ 146 : bool hasBlocks(const std::vector<SubdomainName> & names) const; 147 : 148 : /** 149 : * Test if the supplied set of block names are valid for this object 150 : * @param names A set of SubdomainNames to check 151 : * @return True if the given ids are valid for this object 152 : */ 153 : bool hasBlocks(const std::set<SubdomainName> & names) const; 154 : 155 : /** 156 : * Test if the supplied block ids are valid for this object 157 : * @param id A SubdomainID to check 158 : * @return True if the given id is valid for this object 159 : */ 160 : bool hasBlocks(SubdomainID id) const; 161 : 162 : /** 163 : * Test if the supplied vector block ids are valid for this object 164 : * @param ids A vector of SubdomainIDs ids to check 165 : * @return True if all of the given ids are found within the ids for this object 166 : */ 167 : bool hasBlocks(const std::vector<SubdomainID> & ids) const; 168 : 169 : /** 170 : * Test if the supplied set of block ids are valid for this object 171 : * @param ids A std::set of SubdomainIDs to check 172 : * @return True if all of the given ids are found within the ids for this object 173 : * \see isSubset 174 : */ 175 : bool hasBlocks(const std::set<SubdomainID> & ids) const; 176 : 177 : /** 178 : * Test if the class block ids are a subset of the supplied objects 179 : * @param ids A std::set of Subdomains to check 180 : * @return True if all of the block ids for this class are found within the given ids (opposite of 181 : * hasBlocks) 182 : * \see hasBlocks 183 : */ 184 : bool isBlockSubset(const std::set<SubdomainID> & ids) const; 185 : 186 : /** 187 : * Test if the class block ids are a subset of the supplied objects 188 : * @param ids A std::vector of Subdomains to check 189 : * @return True if all of the block ids for this class are found within the given ids (opposite of 190 : * hasBlocks) 191 : * \see hasBlocks 192 : */ 193 : bool isBlockSubset(const std::vector<SubdomainID> & ids) const; 194 : 195 : /** 196 : * Check if a material property is valid for all blocks of this object 197 : * 198 : * This method returns true if the supplied property name has been declared 199 : * in a Material object on the block ids for this object. 200 : * 201 : * @tparam T The type of material property 202 : * @param prop_name the name of the property to query 203 : * @return true if the property exists for all block ids of the object, otherwise false 204 : * 205 : * @see Material::hasBlockMaterialProperty 206 : */ 207 : template <typename T, bool is_ad = false> 208 : bool hasBlockMaterialProperty(const std::string & prop_name); 209 : 210 : /** 211 : * Return all of the SubdomainIDs for the mesh 212 : * @return A set of all subdomians for the entire mesh 213 : */ 214 : const std::set<SubdomainID> & meshBlockIDs() const; 215 : 216 : /** 217 : * Returns true if this object has been restricted to a block 218 : * @see MooseObject 219 : */ 220 : virtual bool blockRestricted() const; 221 : 222 : /** 223 : * Helper for checking that the ids for this object are in agreement with the variables 224 : * on the supplied variable. 225 : * 226 : * @param variable The variable to check against. 227 : */ 228 : virtual void checkVariable(const MooseVariableFieldBase & variable) const; 229 : 230 : protected: 231 : /// Pointer to the MaterialData class for this object 232 : const MaterialData * _blk_material_data; 233 : 234 : /** 235 : * A helper method to allow the Material object to specialize the behavior 236 : * of hasBlockMaterialProperty. It also avoid circular \#include problems. 237 : * @see hasBlockMaterialProperty 238 : */ 239 : virtual bool hasBlockMaterialPropertyHelper(const std::string & prop_name); 240 : 241 : /** 242 : * An initialization routine needed for dual constructors 243 : */ 244 : void initializeBlockRestrictable(const MooseObject * moose_object); 245 : 246 : #ifdef MOOSE_KOKKOS_ENABLED 247 : void initializeKokkosBlockRestrictable(const Moose::Kokkos::Mesh * mesh); 248 : #endif 249 : 250 : /** 251 : * Check if the blocks this object operates on all have the same coordinate system, 252 : * and if so return it. 253 : */ 254 : Moose::CoordinateSystemType getBlockCoordSystem(); 255 : 256 : #ifdef MOOSE_KOKKOS_SCOPE 257 : /** 258 : * Get the number of elements this Kokkos object is operating on 259 : * @returns The number of elements local to this process 260 : */ 261 62543 : KOKKOS_FUNCTION dof_id_type numKokkosBlockElements() const { return _kokkos_element_ids.size(); } 262 : /** 263 : * Get the number of nodes this Kokkos object is operating on 264 : * @returns The number of nodes local to this process 265 : */ 266 26052 : KOKKOS_FUNCTION dof_id_type numKokkosBlockNodes() const { return _kokkos_node_ids.size(); } 267 : /** 268 : * Get the number of sides this Kokkos object is operating on 269 : * @returns The number of sides local to this process 270 : */ 271 : KOKKOS_FUNCTION dof_id_type numKokkosBlockSides() const 272 : { 273 : return _kokkos_element_side_ids.size(); 274 : } 275 : /** 276 : * Get the contiguous element ID this Kokkos thread is operating on 277 : * @param tid The thread ID 278 : * @returns The contiguous element ID 279 : */ 280 2872016 : KOKKOS_FUNCTION ContiguousElementID kokkosBlockElementID(ThreadID tid) const 281 : { 282 2872016 : return _kokkos_element_ids[tid]; 283 : } 284 : /** 285 : * Get the contiguous node index this Kokkos thread is operating on 286 : * @param tid The thread ID 287 : * @returns the contiguous node ID 288 : */ 289 1707046 : KOKKOS_FUNCTION ContiguousElementID kokkosBlockNodeID(ThreadID tid) const 290 : { 291 1707046 : return _kokkos_node_ids[tid]; 292 : } 293 : /** 294 : * Get the contiguous element ID - side index pair this Kokkos thread is operating on 295 : * @param tid The thread ID 296 : * @returns The contiguous element ID - side index pair 297 : */ 298 : KOKKOS_FUNCTION auto kokkosBlockElementSideID(ThreadID tid) const 299 : { 300 : return _kokkos_element_side_ids[tid]; 301 : } 302 : #endif 303 : 304 : private: 305 : /// Set of block ids supplied by the user via the input file (for error checking) 306 : std::set<SubdomainID> _blk_ids; 307 : 308 : /// Vector of block ids supplied by the user via the input file (for error reporting) 309 : std::vector<SubdomainID> _vec_ids; 310 : 311 : /// Vector the block names supplied by the user via the input file 312 : std::vector<SubdomainName> _blocks; 313 : 314 : /// Flag for allowing dual restriction 315 : const bool _blk_dual_restrictable; 316 : 317 : /// Pointer to FEProblemBase 318 : FEProblemBase * _blk_feproblem; 319 : 320 : /// Pointer to Mesh 321 : const MooseMesh * _blk_mesh; 322 : 323 : /// An empty set for referencing when boundary_ids is not included 324 : const std::set<BoundaryID> _empty_boundary_ids; 325 : 326 : /// Reference to the boundary_ids, defaults to an empty set if not provided 327 : const std::set<BoundaryID> & _boundary_ids; 328 : 329 : /// Thread id for this object 330 : THREAD_ID _blk_tid; 331 : 332 : /// Name of the object 333 : const std::string & _blk_name; 334 : 335 : /// Largest mesh dimension of the elements in the blocks for this object 336 : unsigned int _blk_dim; 337 : 338 : /// Pointer to the MOOSE object 339 : const MooseObject * _moose_object; 340 : 341 : #ifdef MOOSE_KOKKOS_ENABLED 342 : /** 343 : * List of contiguous element IDs this Kokkos object is operating on 344 : */ 345 : Moose::Kokkos::Array<ContiguousElementID> _kokkos_element_ids; 346 : /** 347 : * List of contiguous node IDs this Kokkos object is operating on 348 : */ 349 : Moose::Kokkos::Array<ContiguousNodeID> _kokkos_node_ids; 350 : /** 351 : * List of contiguous local element ID - side index pairs this Kokkos object is operating on 352 : */ 353 : Moose::Kokkos::Array<Moose::Kokkos::Pair<ContiguousElementID, unsigned int>> 354 : _kokkos_element_side_ids; 355 : #endif 356 : }; 357 : 358 : template <typename T, bool is_ad> 359 : bool 360 15687 : BlockRestrictable::hasBlockMaterialProperty(const std::string & prop_name) 361 : { 362 : mooseAssert(_blk_material_data != NULL, "MaterialData pointer is not defined"); 363 16435 : return hasBlockMaterialPropertyHelper(prop_name) && 364 16435 : _blk_material_data->haveGenericProperty<T, is_ad>(prop_name); 365 : }