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 "InputParameters.h" 13 : #include "PerfGraphInterface.h" 14 : 15 : #include "libmesh/parallel_object.h" 16 : #include "libmesh/mesh_base.h" 17 : 18 : class MooseApp; 19 : class MeshGeneratorMesh; 20 : class MeshGenerator; 21 : namespace CSG 22 : { 23 : class CSGBase; 24 : } 25 : 26 : /** 27 : * System that manages MeshGenerators. 28 : * 29 : * To be owned by the MooseApp. 30 : */ 31 : class MeshGeneratorSystem : public PerfGraphInterface, public libMesh::ParallelObject 32 : { 33 : public: 34 : MeshGeneratorSystem(MooseApp & app); 35 : 36 : /// The name of the string parameter that sets the data driven generator 37 : static const std::string data_driven_generator_param; 38 : /// The name of the boolean parameter on the MooseApp that will enable data driven generation 39 : static const std::string allow_data_driven_param; 40 : 41 : /** 42 : * Execute and clear the Mesh Generators data structure 43 : */ 44 : void executeMeshGenerators(); 45 : 46 : /** 47 : * Add a mesh generator that will act on the meshes in the system 48 : * 49 : * @param type The type of MeshGenerator 50 : * @param name The name of the MeshGenerator 51 : * @param params The params used to construct the MeshGenerator 52 : * 53 : * Internally, this will store the parameters for future construction 54 : * during the "add_mesh_generator" task. When called during the 55 : * "create_mesh_generator" task (i.e., when creating mesh subgenerators), 56 : * it will also construct the generator. 57 : * 58 : * We don't construct them yet because we want to create them in order 59 : * during createMeshGenerators() as much as possible so that we don't 60 : * need lazy construction for things like mesh properties. 61 : */ 62 : void addMeshGenerator(const std::string & type, 63 : const std::string & name, 64 : const InputParameters & params); 65 : 66 : /** 67 : * Append a mesh generator that will act on the current final mesh generator in the system 68 : * 69 : * @param type The type of MeshGenerator 70 : * @param name The name of the MeshGenerator 71 : * @param params The params used to construct the MeshGenerator 72 : * 73 : * This MeshGenerator must have a parameter "input" of type MeshGeneratorName 74 : * for this to work, as said parameter is set to the current final generator 75 : * 76 : * Note: This function must be called during the append_mesh_generator task. 77 : */ 78 : const MeshGenerator & 79 : appendMeshGenerator(const std::string & type, const std::string & name, InputParameters params); 80 : 81 : /** 82 : * Get a reference to a pointer that will be the output of the 83 : * MeshGenerator named name 84 : */ 85 : [[nodiscard]] std::unique_ptr<libMesh::MeshBase> & 86 : getMeshGeneratorOutput(const MeshGeneratorName & name); 87 : 88 : /** 89 : * Creates (constructs) all of the MeshGenerators that have been 90 : * declared using addMeshGenerator(). 91 : * 92 : * This parses the input parameters of type <MeshGenerator> and 93 : * std::vector<MeshGeneratorName> to build the execution tree for 94 : * the generators, and constructs them in dependency order 95 : * 96 : * Sub generators are also generated within this phase, although the 97 : * dependency resolution described above is only for the dependencies 98 : * that we can parse using InputParameters. However, we require that 99 : * sub generators be constructed within _their_ dependency order 100 : * (except for the last one, which may be coupled to via the generator 101 : * creating said sub generator). 102 : * 103 : * Should only be called by the CreateAddedMeshGenerator action during 104 : * the create_added_mesh_generators task. 105 : */ 106 : void createAddedMeshGenerators(); 107 : 108 : /** 109 : * Get names of all mesh generators 110 : * Note: This function should be called after all mesh generators are added with the 111 : * 'add_mesh_generator' task. The returned value will be undefined and depends on the ordering 112 : * that mesh generators are added by MOOSE if the function is called during the 113 : * 'add_mesh_generator' task. 114 : */ 115 : std::vector<std::string> getMeshGeneratorNames() const; 116 : 117 : /** 118 : * Get the saved mesh by name 119 : */ 120 : [[nodiscard]] std::unique_ptr<libMesh::MeshBase> getSavedMesh(const std::string & name); 121 : 122 : /** 123 : * Get all user-defined saved meshes except main and main_displaced 124 : */ 125 : std::vector<std::string> getSavedMeshNames() const; 126 : 127 : /** 128 : * Set whether mesh generator system is running in CSG-only mode to true 129 : */ 130 : void setCSGOnly(); 131 : 132 : /** 133 : * Get whether mesh generator system is running in CSG-only mode 134 : */ 135 51261 : bool getCSGOnly() const { return _csg_only; } 136 : 137 31 : const std::vector<std::vector<MeshGenerator *>> & getOrderedMeshGenerators() const 138 : { 139 : mooseAssert(_ordered_mesh_generators.size(), "Mesh generator order has not been set"); 140 31 : return _ordered_mesh_generators; 141 : } 142 : 143 : /** 144 : * @returns Whether or not a mesh generator exists with the name \p name. 145 : */ 146 : bool hasMeshGenerator(const MeshGeneratorName & name) const; 147 : 148 : /** 149 : * @returns The MeshGenerator with the name \p name. 150 : */ 151 : const MeshGenerator & getMeshGenerator(const std::string & name) const; 152 : 153 : /** 154 : * Whether or not we know about the parameters for a MeshGenerator with the given name 155 : * 156 : * This is primarily for error checking. If MeshGenerator dependencies are screwed up, 157 : * someone could be looking for a MeshGenerator that hasn't been constructed yet. 158 : * With this, at least we can give the user some context that we know the generator 159 : * exists, just that the dependencies are hosed. 160 : */ 161 : bool hasMeshGeneratorParams(const MeshGeneratorName & name) const; 162 : 163 : /** 164 : * Whether or not mesh generators are currently being appended (append_mesh_generator task) 165 : */ 166 : bool appendingMeshGenerators() const; 167 : 168 : /** 169 : * The name reserved for the "main" mesh generator which is the one used for the numerical solver 170 : * downstream 171 : */ 172 396684 : static std::string mainMeshGeneratorName() { return "main"; }; 173 : 174 : /** 175 : * @return Whether any of our mesh generators were of type \p BreakMeshByBlockGenerator 176 : */ 177 293 : bool hasBreakMeshByBlockGenerator() const { return _has_bmbb; } 178 : 179 : /** 180 : * @return Whether or not data driven generation is enabled in the app 181 : */ 182 : bool hasDataDrivenAllowed() const; 183 : 184 : /** 185 : * Reports an error with the context of the data driven parameter, coming from the generator 186 : * \p generator with message \p message. 187 : * 188 : * Should be used to throw errors from within a MeshGenerator with more context. 189 : */ 190 : void dataDrivenError(const MeshGenerator & generator, const std::string & message) const; 191 : 192 : /// Get the name of the final mesh generator 193 165 : MeshGeneratorName getFinalMeshGeneratorName() const { return _final_generator_name; } 194 : 195 : /// Set the verbose flag 196 1811 : void setVerbose(const bool verbose) { _verbose = verbose; } 197 : 198 : /** 199 : * Saves the CSGBase object to the global map storage, _csg_base_output, for a particular mesh 200 : * generator. 201 : * Note that this moves the memory ownership of the CSGBase to the MeshGeneratorSystem. 202 : * 203 : * @param generator_name Name of mesh generator 204 : * @param csg_base Pointer to CSGBase object created by mesh generator 205 : */ 206 : void saveOutputCSGBase(const MeshGeneratorName generator_name, 207 : std::unique_ptr<CSG::CSGBase> & csg_base); 208 : 209 : /** 210 : * Returns the output CSGBase object associated with a particular mesh generator name 211 : * 212 : * @param name Name of mesh generator 213 : * @return Pointer to CSGBase object associated with mesh generator name 214 : */ 215 : std::unique_ptr<CSG::CSGBase> & getCSGBaseGeneratorOutput(const MeshGeneratorName & name); 216 : 217 : private: 218 : /** 219 : * Gets the MeshGeneratorNames that are referenced in an object's parameters. 220 : * 221 : * The result is returned as a pair of param name -> MeshGeneratorName in order 222 : * to provide context. 223 : * 224 : * The \p allow_empty param sets whether or not to report names that are empty. 225 : */ 226 : std::vector<std::pair<std::string, MeshGeneratorName>> 227 : getMeshGeneratorParamDependencies(const InputParameters & params, 228 : const bool allow_empty = false) const; 229 : 230 : /** 231 : * Order all of the _mesh_generators into _ordered_mesh_generators for later 232 : * execution in executeMeshGenerators 233 : */ 234 : void createMeshGeneratorOrder(); 235 : 236 : /** 237 : * Internal method for actually constructing a mesh generator after it 238 : * has been declared externally in addMeshGenerator (in Actions). 239 : */ 240 : std::shared_ptr<MeshGenerator> createMeshGenerator(const std::string & name); 241 : 242 : /** 243 : * Get a MeshGenerator with the name \p name. 244 : * 245 : * We add the "internal" here so that we allow objects that have non-const access to 246 : * MooseApp to call getMeshGenerator without a const_cast. If the name was the same, 247 : * you'd get an error about trying to access a private method. 248 : */ 249 60546 : MeshGenerator & getMeshGeneratorInternal(const std::string & name) 250 : { 251 60546 : return const_cast<MeshGenerator &>(std::as_const(*this).getMeshGenerator(name)); 252 : } 253 : 254 : /** 255 : * @return The data driven generator name (can only be called when set) 256 : */ 257 : const std::string & getDataDrivenGeneratorName() const; 258 : 259 : /// The MooseApp that owns this system 260 : MooseApp & _app; 261 : 262 : /// The MeshGenerators declared using addMeshGenerator(), cleared after createMeshGenerators() 263 : /// Key is the name, pair contains the type and the params 264 : std::unordered_map<std::string, std::pair<std::string, InputParameters>> _mesh_generator_params; 265 : 266 : /// Owning storage for mesh generators, map of name -> MeshGenerator 267 : std::map<std::string, std::shared_ptr<MeshGenerator>> _mesh_generators; 268 : 269 : /// Holds the ordered mesh generators from createMeshGeneratorOrder() until they are executed in executeMeshGenerators() 270 : std::vector<std::vector<MeshGenerator *>> _ordered_mesh_generators; 271 : 272 : /// Holds the output for each mesh generator - including duplicates needed downstream 273 : std::map<std::string, std::list<std::unique_ptr<libMesh::MeshBase>>> _mesh_generator_outputs; 274 : 275 : /// The final mesh generator name to use 276 : std::string _final_generator_name; 277 : 278 : /// Holds the map of save in mesh -> name 279 : std::map<std::string, std::unique_ptr<libMesh::MeshBase>> _save_in_meshes; 280 : 281 : /// The name of the data driven generator, if any 282 : std::optional<std::string> _data_driven_generator_name; 283 : 284 : /// Whether any of the mesh generators are a \p BreakMeshByBlockGenerator 285 : bool _has_bmbb; 286 : 287 : /// Whether to print the names of the mesh generators being executed or not 288 : bool _verbose; 289 : 290 : /// Whether mesh generator system is running in CSG-only mode 291 : bool _csg_only; 292 : 293 : /// Holds the output CSGBase object for each mesh generator 294 : std::map<std::string, std::unique_ptr<CSG::CSGBase>> _csg_base_output; 295 : };