LCOV - code coverage report
Current view: top level - include/mesh - unstructured_mesh.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 2 2 100.0 %
Date: 2025-08-19 19:27:09 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
       3             : 
       4             : // This library is free software; you can redistribute it and/or
       5             : // modify it under the terms of the GNU Lesser General Public
       6             : // License as published by the Free Software Foundation; either
       7             : // version 2.1 of the License, or (at your option) any later version.
       8             : 
       9             : // This library is distributed in the hope that it will be useful,
      10             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             : // Lesser General Public License for more details.
      13             : 
      14             : // You should have received a copy of the GNU Lesser General Public
      15             : // License along with this library; if not, write to the Free Software
      16             : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      17             : 
      18             : 
      19             : 
      20             : #ifndef LIBMESH_UNSTRUCTURED_MESH_H
      21             : #define LIBMESH_UNSTRUCTURED_MESH_H
      22             : 
      23             : // Local Includes
      24             : #include "libmesh/mesh_base.h"
      25             : 
      26             : // C++ Includes
      27             : #include <cstddef>
      28             : 
      29             : namespace libMesh
      30             : {
      31             : 
      32             : /**
      33             :  * The \p UnstructuredMesh class is derived from the \p MeshBase class.  The
      34             :  * user will typically want to instantiate and use the
      35             :  * Mesh class in her applications, which is currently a simple
      36             :  * derived class of UnstructuredMesh.
      37             :  * In order to use the adaptive mesh refinement capabilities
      38             :  * of the library, first instantiate a MeshRefinement object
      39             :  * with a reference to this class.  Then call the appropriate
      40             :  * refinement functions from that object.  To interact with the
      41             :  * boundary, instantiate a BoundaryMesh with a reference to
      42             :  * this class, and then use that object's functionality.
      43             :  *
      44             :  * \author Roy Stogner
      45             :  * \date 2007
      46             :  * \brief Base class for Replicated and Distributed meshes.
      47             :  */
      48          24 : class UnstructuredMesh : public MeshBase
      49             : {
      50             : public:
      51             : 
      52             :   /**
      53             :    * Constructor.  Takes \p dim, the dimension of the mesh.
      54             :    * The mesh dimension can be changed (and may automatically be
      55             :    * changed by mesh generation/loading) later.
      56             :    */
      57             :   explicit
      58             :   UnstructuredMesh (const Parallel::Communicator & comm_in,
      59             :                     unsigned char dim=1);
      60             : 
      61             :   /**
      62             :    * UnstructuredMesh uses a defaulted copy constructor.
      63             :    */
      64             :   UnstructuredMesh(const UnstructuredMesh &) = default;
      65             : 
      66             :   /**
      67             :    * UnstructuredMesh constructor from arbitrary (e.g. Cartesian
      68             :    * someday?) meshes
      69             :    */
      70             :   UnstructuredMesh(const MeshBase &);
      71             : 
      72             :   /**
      73             :    * Move-constructor deleted in MeshBase.
      74             :    */
      75             :   UnstructuredMesh(UnstructuredMesh &&) = delete;
      76             : 
      77             :   /**
      78             :    * Copy assignment is not allowed.
      79             :    */
      80             :   UnstructuredMesh & operator= (const UnstructuredMesh &) = delete;
      81             : 
      82             :   /**
      83             :    * Move assignment is allowed, by subclasses who handle
      84             :    * post_dofobject_moves()
      85             :    */
      86         402 :   UnstructuredMesh & operator= (UnstructuredMesh && other_mesh) = default;
      87             : 
      88             :   virtual MeshBase & assign(MeshBase && other_mesh) override = 0;
      89             : 
      90             :   /**
      91             :    * Destructor.
      92             :    */
      93             :   virtual ~UnstructuredMesh();
      94             : 
      95             :   /**
      96             :    * Reads the file specified by \p name.  Attempts to figure out the
      97             :    * proper method by the file extension.  This is now the only
      98             :    * way to read a mesh.  The \p UnstructuredMesh then initializes its data
      99             :    * structures and is ready for use.
     100             :    *
     101             :    * The skip_renumber_nodes_and_elements argument is now deprecated -
     102             :    * to disallow renumbering, set \p MeshBase::allow_renumbering(false).
     103             :    *
     104             :    * Set skip_find_neighbors=true to skip the find-neighbors operation
     105             :    * during prepare_for_use. This operation isn't always necessary
     106             :    * and it can be time-consuming, which is why we provide an option to
     107             :    * skip it.
     108             :    */
     109             :   virtual void read (const std::string & name,
     110             :                      void * mesh_data=nullptr,
     111             :                      bool skip_renumber_nodes_and_elements=false,
     112             :                      bool skip_find_neighbors=false) override;
     113             :   /**
     114             :    * Write the file specified by \p name.  Attempts to figure out the
     115             :    * proper method by the file extension.
     116             :    */
     117             :   virtual void write (const std::string & name) const override;
     118             : 
     119             :   /**
     120             :    * Write to the file specified by \p name.  Attempts to figure out the
     121             :    * proper method by the file extension. Also writes data.
     122             :    */
     123             :   void write (const std::string & name,
     124             :               const std::vector<Number> & values,
     125             :               const std::vector<std::string> & variable_names) const;
     126             : 
     127             :   /**
     128             :    * Converts a mesh with higher-order
     129             :    * elements into a mesh with linear elements.  For
     130             :    * example, a mesh consisting of \p Tet10 will be converted
     131             :    * to a mesh with \p Tet4 etc.
     132             :    */
     133             :   virtual void all_first_order () override;
     134             : 
     135             :   /**
     136             :    * Converts a (conforming, non-refined) mesh with linear elements
     137             :    * into a mesh with second-order elements.  For example, a mesh
     138             :    * consisting of \p Tet4 will be converted to a mesh with \p Tet10
     139             :    * etc.
     140             :    *
     141             :    * \note For some elements like \p Hex8 there exist two higher order
     142             :    * equivalents, \p Hex20 and \p Hex27.  When \p full_ordered is \p
     143             :    * true (default), then \p Hex27 is built.  Otherwise, \p Hex20 is
     144             :    * built.  The same holds obviously for \p Quad4, \p Prism6, etc.
     145             :    */
     146             :   virtual void all_second_order_range (const SimpleRange<element_iterator> & range,
     147             :                                        const bool full_ordered=true) override;
     148             : 
     149             :   /**
     150             :    * Converts a (conforming, non-refined) mesh with linear elements
     151             :    * into a mesh with "complete" order elements, i.e. elements which
     152             :    * can store degrees of freedom on any vertex, edge, or face.  For
     153             :    * example, a mesh consisting of \p Tet4 or \p Tet10 will be
     154             :    * converted to a mesh with \p Tet14 etc.
     155             :    */
     156             :   virtual void all_complete_order_range (const SimpleRange<element_iterator> & range) override;
     157             : 
     158             :   /**
     159             :    * Generates a new mesh containing all the elements which
     160             :    * are assigned to processor \p pid.  This mesh is written
     161             :    * to the pid_mesh reference which you must create and pass
     162             :    * to the function.
     163             :    */
     164             :   void create_pid_mesh (UnstructuredMesh & pid_mesh,
     165             :                         const processor_id_type pid) const;
     166             : 
     167             :   /**
     168             :    * Constructs a mesh called "new_mesh" from the current mesh by
     169             :    * iterating over the elements between it and it_end and adding
     170             :    * them to the new mesh.
     171             :    */
     172             :   void create_submesh (UnstructuredMesh & new_mesh,
     173             :                        const const_element_iterator & it,
     174             :                        const const_element_iterator & it_end) const;
     175             : 
     176             :   /**
     177             :    * Stitch \p other_mesh to this mesh so that this mesh is the union of the two meshes.
     178             :    * \p this_mesh_boundary and \p other_mesh_boundary are used to specify a dim-1 dimensional
     179             :    * surface on which we seek to merge any "overlapping" nodes, where we use the parameter
     180             :    * \p tol as a relative tolerance (relative to the smallest edge length on the surfaces
     181             :    * being stitched) to determine whether or not nodes are overlapping.
     182             :    * If \p clear_stitched_boundary_ids==true, this function clears boundary_info IDs in this
     183             :    * mesh associated \p this_mesh_boundary and \p other_mesh_boundary.
     184             :    * If \p use_binary_search is true, we use an optimized "sort then binary search" algorithm
     185             :    * for finding matching nodes. Otherwise we use a N^2 algorithm (which can be more reliable
     186             :    * at dealing with slightly misaligned meshes).
     187             :    * If \p enforce_all_nodes_match_on_boundaries is true, we throw an error if the number of
     188             :    * nodes on the specified boundaries don't match the number of nodes that were merged.
     189             :    * This is a helpful error check in some cases. If this is true, it overrides the value of
     190             :    * \p merge_boundary_nodes_all_or_nothing.
     191             :    * If \p skip_find_neighbors is true, a faster stitching method is used, where the lists of
     192             :    * neighbors for each elements are copied as well and patched, without calling the time-consuming
     193             :    * find_neighbors() function. This option is now hard-coded to true.
     194             :    * If \p merge_boundary_nodes_all_or_nothing is true, instead of throwing an error
     195             :    * like \p enforce_all_nodes_match_on_boundaries, the meshes are combined anyway but coincident
     196             :    * nodes are not merged into single nodes. This is useful in cases where you are not sure if the
     197             :    * boundaries are fully conforming beforehand and you want to handle the non-conforming cases
     198             :    * differently.
     199             :    *
     200             :    * Note that the element IDs for elements in the stitched mesh corresponding to "this" mesh
     201             :    * will be unchanged. The IDs for elements corresponding to \p other_mesh will be incremented
     202             :    * by this->max_elem_id().
     203             :    *
     204             :    * There is no simple a priori relationship between node IDs in "this" mesh
     205             :    * and other_mesh and node IDs in the stitched mesh because the number of nodes (and hence
     206             :    * the node IDs) in the stitched mesh depend on how many nodes are stitched.
     207             :    *
     208             :    * If \p remap_subdomain_ids is true then we assume that some
     209             :    * subdomain ids might have been autogenerated, so we remap them as
     210             :    * necessary, treating subdomain names as the important thing for
     211             :    * consistency; if we have missing names and cannot infer a
     212             :    * consistent resolution to an id conflict then we exit with an
     213             :    * error.  If \p remap_subdomain_ids is false then we revert to the
     214             :    * older libMesh behavior: leave all subdomain ids alone and woe
     215             :    * unto you if you weren't keeping track of them.
     216             :    *
     217             :    * \returns the count of how many nodes were merged between the two meshes.
     218             :    * This can be zero in the case of no matching nodes or if
     219             :    * \p merge_boundary_nodes_all_or_nothing was active and relevant.
     220             :    */
     221             :   std::size_t stitch_meshes (const MeshBase & other_mesh,
     222             :                              boundary_id_type this_mesh_boundary,
     223             :                              boundary_id_type other_mesh_boundary,
     224             :                              Real tol=TOLERANCE,
     225             :                              bool clear_stitched_boundary_ids=false,
     226             :                              bool verbose=true,
     227             :                              bool use_binary_search=true,
     228             :                              bool enforce_all_nodes_match_on_boundaries=false,
     229             :                              bool merge_boundary_nodes_all_or_nothing=false,
     230             :                              bool remap_subdomain_ids=false);
     231             : 
     232             :   /**
     233             :    * Similar to stitch_meshes, except that we stitch two adjacent surfaces within this mesh.
     234             :    */
     235             :   std::size_t stitch_surfaces (boundary_id_type boundary_id_1,
     236             :                                boundary_id_type boundary_id_2,
     237             :                                Real tol=TOLERANCE,
     238             :                                bool clear_stitched_boundary_ids=false,
     239             :                                bool verbose=true,
     240             :                                bool use_binary_search=true,
     241             :                                bool enforce_all_nodes_match_on_boundaries=false,
     242             :                                bool merge_boundary_nodes_all_or_nothing=false);
     243             : 
     244             :   /**
     245             :    * Deep copy of nodes and elements from another mesh object (used by
     246             :    * subclass copy constructors and by mesh merging operations)
     247             :    *
     248             :    * This will not copy most "high level" data in the mesh; that is
     249             :    * done separately by constructors.  An exception is that, if the
     250             :    * \p other_mesh has element or node extra_integer data, any names
     251             :    * for that data which do not already exist on \p this mesh are
     252             :    * added so that all such data can be copied.
     253             :    *
     254             :    * If an \p id_remapping map is provided, then element subdomain ids
     255             :    * in \p other_mesh will be converted using it before adding them to
     256             :    * \p this mesh.
     257             :    */
     258             :   virtual void copy_nodes_and_elements (const MeshBase & other_mesh,
     259             :                                         const bool skip_find_neighbors = false,
     260             :                                         dof_id_type element_id_offset = 0,
     261             :                                         dof_id_type node_id_offset = 0,
     262             :                                         unique_id_type unique_id_offset = 0,
     263             :                                         std::unordered_map<subdomain_id_type, subdomain_id_type> *
     264             :                                           id_remapping = nullptr);
     265             : 
     266             :   /**
     267             :    * Move node and elements from other_mesh to this mesh.
     268             :    */
     269             :   virtual void move_nodes_and_elements(MeshBase && other_mesh) = 0;
     270             : 
     271             : 
     272             :   /**
     273             :    * Other functions from MeshBase requiring re-definition.
     274             :    */
     275             :   virtual void find_neighbors (const bool reset_remote_elements = false,
     276             :                                const bool reset_current_list    = true) override;
     277             : 
     278             : #ifdef LIBMESH_ENABLE_AMR
     279             :   /**
     280             :    * Delete subactive (i.e. children of coarsened) elements.
     281             :    * This removes all elements descended from currently active
     282             :    * elements in the mesh.
     283             :    */
     284             :   virtual bool contract () override;
     285             : #endif // #ifdef LIBMESH_ENABLE_AMR
     286             : 
     287             : private:
     288             : 
     289             :   /**
     290             :    * Helper function for stitch_meshes and stitch_surfaces
     291             :    * that does the mesh stitching.
     292             :    */
     293             :   std::size_t stitching_helper (const MeshBase * other_mesh,
     294             :                                 boundary_id_type boundary_id_1,
     295             :                                 boundary_id_type boundary_id_2,
     296             :                                 Real tol,
     297             :                                 bool clear_stitched_boundary_ids,
     298             :                                 bool verbose,
     299             :                                 bool use_binary_search,
     300             :                                 bool enforce_all_nodes_match_on_boundaries,
     301             :                                 bool skip_find_neighbors,
     302             :                                 bool merge_boundary_nodes_all_or_nothing,
     303             :                                 bool remap_subdomain_ids);
     304             : };
     305             : 
     306             : 
     307             : } // namespace libMesh
     308             : 
     309             : #endif // LIBMESH_UNSTRUCTURED_MESH_H

Generated by: LCOV version 1.14