LCOV - code coverage report
Current view: top level - include/meshgenerators - MeshGenerator.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 45 49 91.8 %
Date: 2025-07-17 01:28:37 Functions: 43 43 100.0 %
Legend: Lines: hit not hit

          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 "MooseObject.h"
      13             : #include "MeshMetaDataInterface.h"
      14             : #include "MooseApp.h"
      15             : 
      16             : // Included so mesh generators don't need to include this when constructing MeshBase objects
      17             : #include "MooseMesh.h"
      18             : 
      19             : #include "libmesh/mesh_base.h"
      20             : #include "libmesh/parameters.h"
      21             : 
      22             : class MooseMesh;
      23             : namespace libMesh
      24             : {
      25             : class ReplicatedMesh;
      26             : class DistributedMesh;
      27             : }
      28             : 
      29             : /**
      30             :  * MeshGenerators are objects that can modify or add to an existing mesh.
      31             :  */
      32             : class MeshGenerator : public MooseObject, public MeshMetaDataInterface
      33             : {
      34             : public:
      35             :   /**
      36             :    * Comparator for MeshGenerators that sorts by name
      37             :    */
      38             :   struct Comparator
      39             :   {
      40     2978783 :     bool operator()(const MeshGenerator * const & a, const MeshGenerator * const & b) const
      41             :     {
      42     2978783 :       return a->name() < b->name();
      43             :     }
      44             :   };
      45             : 
      46             :   static InputParameters validParams();
      47             : 
      48             :   /**
      49             :    * Sets that a mesh generator has a generateData() implementation.
      50             :    *
      51             :    * This must be called in the validParams() implementation for all
      52             :    * mesh generators that implement generateData().
      53             :    */
      54             :   static void setHasGenerateData(InputParameters & params);
      55             :   /**
      56             :    * @return Whether or not the mesh generator noted by the given parameters
      57             :    * has a generateData() implementation
      58             :    */
      59             :   static bool hasGenerateData(const InputParameters & params);
      60             : 
      61             :   /// The name of the private parameter for setting data only
      62             :   static const std::string data_only_param;
      63             : 
      64             :   MeshGenerator(const InputParameters & parameters);
      65             : 
      66             :   /**
      67             :    * Generate / modify the mesh
      68             :    */
      69             :   virtual std::unique_ptr<MeshBase> generate() = 0;
      70             : 
      71             :   /**
      72             :    * Internal generation method - this is what is actually called
      73             :    * within MooseApp to execute the MeshGenerator.
      74             :    */
      75             :   [[nodiscard]] std::unique_ptr<MeshBase> generateInternal();
      76             : 
      77             :   /**
      78             :    * @returns The names of the MeshGenerators that were requested in the getMesh methods
      79             :    */
      80       50659 :   const std::set<MeshGeneratorName> & getRequestedMeshGenerators() const
      81             :   {
      82       50659 :     return _requested_mesh_generators;
      83             :   }
      84             :   /**
      85             :    * @returns The names of the MeshGenerators that were requested in the declareMeshForSub
      86             :    * methods
      87             :    */
      88          36 :   const std::set<MeshGeneratorName> & getRequestedMeshGeneratorsForSub() const
      89             :   {
      90          36 :     return _requested_mesh_generators_for_sub;
      91             :   }
      92             : 
      93             :   /**
      94             :    * Class that is used as a parameter to add[Parent/Child]() that allows only
      95             :    * MeshGeneratorSystem methods to call said methods
      96             :    */
      97             :   class AddParentChildKey
      98             :   {
      99             :     friend class MeshGeneratorSystem;
     100       54610 :     AddParentChildKey() {}
     101             :     AddParentChildKey(const AddParentChildKey &) {}
     102             :   };
     103             : 
     104             :   /**
     105             :    * Adds the MeshGenerator \p mg as a parent.
     106             :    *
     107             :    * Protected by the AddParentChildKey so that parents can only be
     108             :    * added by the MooseApp.
     109             :    */
     110             :   void addParentMeshGenerator(const MeshGenerator & mg, const AddParentChildKey);
     111             :   /**
     112             :    * Adds the MeshGenerator \p mg as a child.
     113             :    *
     114             :    * Protected by the AddParentChildKey so that parents can only be
     115             :    * added by the MooseApp.
     116             :    */
     117             :   void addChildMeshGenerator(const MeshGenerator & mg, const AddParentChildKey);
     118             : 
     119             :   /**
     120             :    * Gets the MeshGenerators that are parents to this MeshGenerator.
     121             :    */
     122      129908 :   const std::set<const MeshGenerator *, Comparator> & getParentMeshGenerators() const
     123             :   {
     124      129908 :     return _parent_mesh_generators;
     125             :   }
     126             :   /**
     127             :    * Gets the MeshGenerators that are children to this MeshGenerator.
     128             :    */
     129       12291 :   const std::set<const MeshGenerator *, Comparator> & getChildMeshGenerators() const
     130             :   {
     131       12291 :     return _child_mesh_generators;
     132             :   }
     133             :   /**
     134             :    * Gets the MeshGenerators that are children to this MeshGenerator.
     135             :    */
     136         108 :   const std::set<const MeshGenerator *, Comparator> & getSubMeshGenerators() const
     137             :   {
     138         108 :     return _sub_mesh_generators;
     139             :   }
     140             : 
     141             :   /**
     142             :    * @returns Whether or not the MeshGenerator with the name \p name is a parent of this
     143             :    * MeshGenerator.
     144             :    *
     145             :    * If \p direct = true, check only immediate parents of this generator. Otherwise, check
     146             :    * all parents.
     147             :    */
     148             :   bool isParentMeshGenerator(const MeshGeneratorName & name, const bool direct = true) const;
     149             : 
     150             :   /**
     151             :    * @returns Whether or not the MeshGenerator with the name \p name is a child of this
     152             :    * MeshGenerator.
     153             :    *
     154             :    * If \p direct = true, check only immediate children of this generator. Otherwise, check
     155             :    * all children.
     156             :    */
     157             :   bool isChildMeshGenerator(const MeshGeneratorName & name, const bool direct = true) const;
     158             : 
     159             :   /**
     160             :    * @returns Whether or not the name \p name is registered as a "null" mesh, that is,
     161             :    * a MeshGenerator that will not represent an input mesh when requested via getMesh.
     162             :    *
     163             :    * See declareNullMeshName().
     164             :    */
     165       55004 :   bool isNullMeshName(const MeshGeneratorName & name) const { return _null_mesh_names.count(name); }
     166             : 
     167             :   /**
     168             :    * Return whether or not to save the current mesh
     169             :    */
     170             :   bool hasSaveMesh() const;
     171             : 
     172             :   /**
     173             :    * @return Whether or not to output this mesh generator separately (output parameter is set)
     174             :    */
     175             :   bool hasOutput() const;
     176             : 
     177             :   /**
     178             :    * Return the name of the saved mesh
     179             :    */
     180             :   const std::string & getSavedMeshName() const;
     181             : 
     182             :   /**
     183             :    * @return Whether or not this generator has a generateData() implementation
     184             :    */
     185       47937 :   bool hasGenerateData() const { return hasGenerateData(_pars); }
     186             : 
     187             :   /**
     188             :    * @return Whether or not this generator is to be generated in data-only mode
     189             :    */
     190      146549 :   bool isDataOnly() const { return _data_only; }
     191             : 
     192             : protected:
     193             :   /**
     194             :    * Generate the mesh data
     195             :    */
     196             :   virtual void generateData();
     197             : 
     198             :   /**
     199             :    * Methods for writing out attributes to the mesh meta-data store, which can be retrieved from
     200             :    * most other MOOSE systems and is recoverable.
     201             :    */
     202             :   ///@{
     203             :   template <typename T, typename... Args>
     204             :   T & declareMeshProperty(const std::string & data_name, Args &&... args);
     205             :   template <typename T>
     206      178976 :   T & declareMeshProperty(const std::string & data_name, const T & data_value)
     207             :   {
     208      178976 :     return declareMeshProperty<T, const T &>(data_name, data_value);
     209             :   }
     210             :   ///@}
     211             : 
     212             :   /**
     213             :    * Method for updating attributes to the mesh meta-data store, which can only be invoked in
     214             :    * the MeshGenerator generate routine only if the mesh generator property has already been
     215             :    * declared.
     216             :    */
     217             :   ///@{
     218             :   template <typename T, typename... Args>
     219             :   T & setMeshProperty(const std::string & data_name, Args &&... args);
     220             :   template <typename T>
     221             :   T & setMeshProperty(const std::string & data_name, const T & data_value)
     222             :   {
     223             :     return setMeshProperty<T, const T &>(data_name, data_value);
     224             :   }
     225             :   ///@}
     226             : 
     227             :   /**
     228             :    * Method for copying attribute from input mesh meta-data store to current mesh meta-data store.
     229             :    * This may often be avoided as getMeshProperty calls can traverse the tree of mesh generators to
     230             :    * find a metadata instance
     231             :    */
     232             :   template <typename T>
     233             :   T & copyMeshProperty(const std::string & target_data_name,
     234             :                        const std::string & source_data_name,
     235             :                        const std::string & source_mesh)
     236             :   {
     237             :     return declareMeshProperty(target_data_name, getMeshProperty<T>(source_data_name, source_mesh));
     238             :   }
     239             : 
     240             :   /**
     241             :    * Method for copying attribute from input mesh meta-data store to current mesh meta-data store,
     242             :    * keeping source and target data names the same. This may often be avoided as getMeshProperty
     243             :    * calls can traverse the tree of mesh generators to find a metadata instance
     244             :    */
     245             :   template <typename T>
     246             :   T & copyMeshProperty(const std::string & source_data_name, const std::string & source_mesh)
     247             :   {
     248             :     return copyMeshProperty<T>(source_data_name, source_data_name, source_mesh);
     249             :   }
     250             : 
     251             :   /**
     252             :    * Takes the name of a MeshGeneratorName parameter and then gets a pointer to the
     253             :    * Mesh that MeshGenerator is going to create.
     254             :    *
     255             :    * That MeshGenerator is made to be a dependency of this one, so
     256             :    * will generate() its mesh first.
     257             :    *
     258             :    * @param param_name The name of the parameter that contains the name of the MeshGenerator
     259             :    * @param allow_invalid If true, will allow for invalid parameters and will return a nullptr
     260             :    * mesh if said parameter does not exist
     261             :    * @return The Mesh generated by that MeshGenerator
     262             :    *
     263             :    * NOTE: You MUST catch this by reference!
     264             :    */
     265             :   [[nodiscard]] std::unique_ptr<MeshBase> & getMesh(const std::string & param_name,
     266             :                                                     const bool allow_invalid = false);
     267             :   /**
     268             :    * Like getMesh(), but for multiple generators.
     269             :    *
     270             :    * @returns The generated meshes
     271             :    */
     272             :   [[nodiscard]] std::vector<std::unique_ptr<MeshBase> *> getMeshes(const std::string & param_name);
     273             :   /**
     274             :    * Like \p getMesh(), but takes the name of another MeshGenerator directly.
     275             :    *
     276             :    * NOTE: You MUST catch this by reference!
     277             :    *
     278             :    * @return The Mesh generated by that MeshGenerator
     279             :    */
     280             :   [[nodiscard]] std::unique_ptr<MeshBase> &
     281             :   getMeshByName(const MeshGeneratorName & mesh_generator_name);
     282             :   /**
     283             :    * Like getMeshByName(), but for multiple generators.
     284             :    *
     285             :    * @returns The generated meshes
     286             :    */
     287             :   [[nodiscard]] std::vector<std::unique_ptr<MeshBase> *>
     288             :   getMeshesByName(const std::vector<MeshGeneratorName> & mesh_generator_names);
     289             : 
     290             :   /**
     291             :    * Declares that a MeshGenerator referenced in the InputParameters is to be
     292             :    * used as a dependency of a sub MeshGenerator created by this MeshGenerator
     293             :    * (see addSubMeshGenerator)
     294             :    *
     295             :    * You _must_ declare all such MeshGenerators that are passed by parameter to this
     296             :    * MeshGenerator but instead used in a sub MeshGenerator. This is in order to
     297             :    * declare the intention to use an input mesh as a dependency for a sub generator
     298             :    * instead of this one.
     299             :    */
     300             :   void declareMeshForSub(const std::string & param_name);
     301             :   /**
     302             :    * Like declareMeshForSub(), but for multiple generators.
     303             :    */
     304             :   void declareMeshesForSub(const std::string & param_name);
     305             :   /**
     306             :    * Like declareMeshForSub(), but takes the name of another MeshGenerator directly.
     307             :    */
     308             :   void declareMeshForSubByName(const MeshGeneratorName & mesh_generator_name);
     309             :   /**
     310             :    * Like declareMeshForSubByName(), but for multiple generators.
     311             :    */
     312             :   void declareMeshesForSubByName(const std::vector<MeshGeneratorName> & mesh_generator_names);
     313             : 
     314             :   /**
     315             :    * Build a \p MeshBase object whose underlying type will be determined by the Mesh input file
     316             :    * block
     317             :    * @param dim The logical dimension of the mesh, e.g. 3 for hexes/tets, 2 for quads/tris. If the
     318             :    * caller doesn't specify a value for \p dim, then the value in the \p Mesh input file block will
     319             :    * be used
     320             :    */
     321             :   [[nodiscard]] std::unique_ptr<MeshBase>
     322             :   buildMeshBaseObject(unsigned int dim = libMesh::invalid_uint);
     323             : 
     324             :   /**
     325             :    * Build a replicated mesh
     326             :    * @param dim The logical dimension of the mesh, e.g. 3 for hexes/tets, 2 for quads/tris. If the
     327             :    * caller doesn't specify a value for \p dim, then the value in the \p Mesh input file block will
     328             :    * be used
     329             :    */
     330             :   [[nodiscard]] std::unique_ptr<ReplicatedMesh>
     331             :   buildReplicatedMesh(unsigned int dim = libMesh::invalid_uint);
     332             : 
     333             :   /**
     334             :    * Build a distributed mesh that has correct remote element removal behavior and geometric
     335             :    * ghosting functors based on the simulation objects
     336             :    * @param dim The logical dimension of the mesh, e.g. 3 for hexes/tets, 2 for quads/tris. If the
     337             :    * caller doesn't specify a value for \p dim, then the value in the \p Mesh input file block will
     338             :    * be used
     339             :    */
     340             :   [[nodiscard]] std::unique_ptr<DistributedMesh>
     341             :   buildDistributedMesh(unsigned int dim = libMesh::invalid_uint);
     342             : 
     343             :   /**
     344             :    * Construct a "subgenerator", a different MeshGenerator subclass
     345             :    * that will be added to the same MooseApp on the fly.
     346             :    *
     347             :    * @param type The type of MeshGenerator
     348             :    * @param name The name of the MeshGenerator
     349             :    * @param extra_input_parameters ... Additional InputParameters to pass
     350             :    *
     351             :    * Sub generators must be added in the order that they are executed.
     352             :    *
     353             :    * Any input dependencies for a sub generator that come from inputs for
     354             :    * this generator must first be declared with the declareMesh(es)ForSub()
     355             :    * method.
     356             :    *
     357             :    * You can use the output of a sub generator as a mesh in this generator
     358             :    * by calling getMesh() with the sub generator's name _after_ adding
     359             :    * said sub generator.
     360             :    */
     361             :   template <typename... Ts>
     362             :   void addMeshSubgenerator(const std::string & type,
     363             :                            const std::string & name,
     364             :                            Ts... extra_input_parameters);
     365             : 
     366             :   /**
     367             :    * Construct a "subgenerator", as above.  User code is responsible
     368             :    * for constructing valid InputParameters.
     369             :    *
     370             :    * @param type The type of MeshGenerator
     371             :    * @param name The name of the MeshGenerator
     372             :    * @param params The parameters to use to construct the MeshGenerator
     373             :    */
     374             :   void
     375             :   addMeshSubgenerator(const std::string & type, const std::string & name, InputParameters params);
     376             : 
     377             :   /**
     378             :    * Registers the name \p name as a "null" mesh, which is a MeshGenerator used in
     379             :    * InputParameters that will not represent an input mesh when requested via getMesh.
     380             :    *
     381             :    * An example use case for this is when you as a developer want users to represent a hole
     382             :    * in a mesh pattern that is defined in input.
     383             :    *
     384             :    */
     385             :   void declareNullMeshName(const MeshGeneratorName & name);
     386             : 
     387             :   /// Pointer to the owning mesh
     388             :   MooseMesh * const _mesh;
     389             : 
     390             : private:
     391             :   /**
     392             :    * Override of the default prefix to use when getting mesh properties.
     393             :    *
     394             :    * Until we support getting mesh properties from other mesh generators (which is coming),
     395             :    * we will default to properties returned by this generator.
     396             :    */
     397      358632 :   virtual std::string meshPropertyPrefix(const std::string &) const override final
     398             :   {
     399      358632 :     return name();
     400             :   }
     401             : 
     402             :   /**
     403             :    * Helper for performing error checking in the getMesh methods.
     404             :    */
     405             :   void checkGetMesh(const MeshGeneratorName & mesh_generator_name,
     406             :                     const std::string & param_name) const;
     407             : 
     408             :   /**
     409             :    * Helper for getting a MeshGeneratorName parameter
     410             :    */
     411             :   const MeshGeneratorName * getMeshGeneratorNameFromParam(const std::string & param_name,
     412             :                                                           const bool allow_invalid) const;
     413             :   /**
     414             :    * Helper for getting a std::vector<MeshGeneratorName> parameter
     415             :    */
     416             :   const std::vector<MeshGeneratorName> &
     417             :   getMeshGeneratorNamesFromParam(const std::string & param_name) const;
     418             : 
     419             :   /**
     420             :    * Helper for getting a writable reference to a mesh property, used in
     421             :    * declareMeshProperty and setMeshProperty.
     422             :    */
     423             :   RestartableDataValue & setMeshPropertyHelper(const std::string & data_name);
     424             : 
     425             :   /// The names of the MeshGenerators that were requested in the getMesh methods
     426             :   std::set<MeshGeneratorName> _requested_mesh_generators;
     427             :   /// The names of the MeshGenerators that were requested in the declareMeshForSub methods
     428             :   std::set<MeshGeneratorName> _requested_mesh_generators_for_sub;
     429             :   /// The meshes that were requested by this MeshGenerator; used to verify that
     430             :   /// any input meshes that are requested are properly released after generation
     431             :   std::vector<std::pair<std::string, std::unique_ptr<MeshBase> *>> _requested_meshes;
     432             : 
     433             :   /// A nullptr to use for when inputs aren't specified
     434             :   std::unique_ptr<MeshBase> _null_mesh = nullptr;
     435             : 
     436             :   /// The MeshGenerators that are parents to this MeshGenerator
     437             :   std::set<const MeshGenerator *, Comparator> _parent_mesh_generators;
     438             :   /// The MeshGenerators that are children to this MeshGenerator
     439             :   std::set<const MeshGenerator *, Comparator> _child_mesh_generators;
     440             :   /// The sub MeshGenerators constructed by this MeshGenerator
     441             :   std::set<const MeshGenerator *, Comparator> _sub_mesh_generators;
     442             : 
     443             :   /// The declared "null" mesh names that will not represent a mesh in input; see declareNullMeshName()
     444             :   std::set<std::string> _null_mesh_names;
     445             : 
     446             :   /// A user-defined name to save the mesh
     447             :   const std::string & _save_with_name;
     448             : 
     449             :   /// Whether or not this mesh generator will run in data only mode
     450             :   const bool _data_only;
     451             : };
     452             : 
     453             : template <typename T, typename... Args>
     454             : T &
     455      179300 : MeshGenerator::declareMeshProperty(const std::string & data_name, Args &&... args)
     456             : {
     457      179300 :   if (!_app.constructingMeshGenerators())
     458           4 :     mooseError("Can only call declareMeshProperty() during MeshGenerator construction");
     459             : 
     460             :   // We sort construction ordering so that we _must_ declare before retrieving
     461      179296 :   if (hasMeshProperty(data_name))
     462           4 :     mooseError("While declaring mesh property '",
     463             :                data_name,
     464             :                "' with type '",
     465             :                MooseUtils::prettyCppType<T>(),
     466             :                "',\nsaid property has already been declared with type '",
     467           4 :                setMeshPropertyHelper(data_name).type(),
     468             :                "'");
     469             : 
     470      179292 :   const auto full_name = meshPropertyName(data_name);
     471      179292 :   auto new_T_value =
     472      179292 :       std::make_unique<RestartableData<T>>(full_name, nullptr, std::forward<Args>(args)...);
     473             :   auto value =
     474      179292 :       &_app.registerRestartableData(std::move(new_T_value), 0, false, MooseApp::MESH_META_DATA);
     475             :   mooseAssert(value->declared(), "Should be declared");
     476             : 
     477      179292 :   RestartableData<T> * T_value = dynamic_cast<RestartableData<T> *>(value);
     478             :   mooseAssert(T_value, "Bad cast");
     479             : 
     480      358584 :   return T_value->set();
     481      179292 : }
     482             : 
     483             : template <typename T, typename... Args>
     484             : T &
     485          20 : MeshGenerator::setMeshProperty(const std::string & data_name, Args &&... args)
     486             : {
     487          20 :   if (_app.actionWarehouse().getCurrentTaskName() != "execute_mesh_generators")
     488           0 :     mooseError("Updating mesh meta data with setMeshProperty() can only be called during "
     489             :                "MeshGenerator::generate()");
     490             : 
     491          20 :   if (!hasMeshProperty(data_name))
     492           0 :     mooseError("Failed to get the mesh property '", data_name, "'");
     493          20 :   RestartableDataValue * value = &setMeshPropertyHelper(data_name);
     494          20 :   RestartableData<T> * T_value = dynamic_cast<RestartableData<T> *>(value);
     495          20 :   if (!T_value)
     496           0 :     mooseError("While retrieving mesh property '",
     497             :                data_name,
     498             :                "' with type '",
     499             :                MooseUtils::prettyCppType<T>(),
     500             :                "',\nthe property was found with type '",
     501           0 :                value->type(),
     502             :                "'");
     503             : 
     504             :   // Set the value if someone provided arguments to set it to
     505             :   if constexpr (sizeof...(args) > 0)
     506             :     T_value->set() = T(std::forward<Args>(args)...);
     507             : 
     508          20 :   return T_value->set();
     509             : }
     510             : 
     511             : template <typename... Ts>
     512             : void
     513           8 : MeshGenerator::addMeshSubgenerator(const std::string & type,
     514             :                                    const std::string & name,
     515             :                                    Ts... extra_input_parameters)
     516             : {
     517           8 :   InputParameters subgenerator_params = _app.getFactory().getValidParams(type);
     518             : 
     519           8 :   subgenerator_params.setParameters(extra_input_parameters...);
     520             : 
     521           8 :   addMeshSubgenerator(type, name, subgenerator_params);
     522           8 : }

Generated by: LCOV version 1.14