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