LCOV - code coverage report
Current view: top level - include/mesh - distributed_mesh.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 26 68 38.2 %
Date: 2025-08-19 19:27:09 Functions: 25 102 24.5 %
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_DISTRIBUTED_MESH_H
      21             : #define LIBMESH_DISTRIBUTED_MESH_H
      22             : 
      23             : // Local Includes
      24             : #include "libmesh_config.h"
      25             : 
      26             : #if LIBMESH_MAPVECTOR_CHUNK_SIZE == 1
      27             : #  include "libmesh/mapvector.h"
      28             : #else
      29             : #  include "libmesh/chunked_mapvector.h"
      30             : #endif
      31             : 
      32             : #include "libmesh/unstructured_mesh.h"
      33             : 
      34             : // C++ Includes
      35             : #include <cstddef>
      36             : #include <memory>
      37             : #include <set>
      38             : 
      39             : namespace libMesh
      40             : {
      41             : 
      42             : // Forward declarations
      43             : class Elem;
      44             : class Node;
      45             : 
      46             : 
      47             : /**
      48             :  * The \p DistributedMesh class is derived from the \p MeshBase class,
      49             :  * and is intended to provide identical functionality to the user
      50             :  * but be distributed rather than replicated across distributed-memory
      51             :  * systems.
      52             :  *
      53             :  * \author Roy Stogner
      54             :  * \date 2007
      55             :  * \brief Mesh data structure which is distributed across all processors.
      56             :  */
      57             : class DistributedMesh : public UnstructuredMesh
      58             : {
      59             : public:
      60             : 
      61             :   template <typename Obj>
      62             : #if LIBMESH_MAPVECTOR_CHUNK_SIZE == 1
      63             :   using dofobject_container = mapvector<Obj *, dof_id_type>;
      64             : #else
      65             :   using dofobject_container = chunked_mapvector<Obj *, dof_id_type, LIBMESH_MAPVECTOR_CHUNK_SIZE>;
      66             : #endif
      67             : 
      68             :   /**
      69             :    * Constructor.  Takes \p dim, the dimension of the mesh.
      70             :    * The mesh dimension can be changed (and may automatically be
      71             :    * changed by mesh generation/loading) later.
      72             :    */
      73             :   explicit
      74             :   DistributedMesh (const Parallel::Communicator & comm_in,
      75             :                    unsigned char dim=1);
      76             : 
      77             :   /**
      78             :    * Copy-constructor.  This should be able to take a
      79             :    * replicated or distributed mesh.
      80             :    */
      81             :   DistributedMesh (const MeshBase & other_mesh);
      82             : 
      83             :   /**
      84             :    * Copy-constructor, possibly specialized for a
      85             :    * distributed mesh.
      86             :    */
      87             :   DistributedMesh (const DistributedMesh & other_mesh);
      88             : 
      89             :   /**
      90             :    * Move-constructor deleted in MeshBase.
      91             :    */
      92             :   DistributedMesh(DistributedMesh &&) = delete;
      93             : 
      94             :   /**
      95             :    * Copy assignment is not allowed.
      96             :    */
      97             :   DistributedMesh & operator= (const DistributedMesh &) = delete;
      98             : 
      99             :   /**
     100             :    * Overloaded operator= will move contents of other_mesh to calling
     101             :    * DistributedMesh object.
     102             :    */
     103             :   DistributedMesh & operator= (DistributedMesh && other_mesh);
     104             : 
     105             :   /**
     106             :    * Shim to call the move assignment operator for this class
     107             :   */
     108             :   virtual MeshBase & assign(MeshBase && other_mesh) override;
     109             : 
     110             :   /**
     111             :    * Shim to allow operator == (&) to behave like a virtual function
     112             :    * without having to be one.
     113             :    */
     114             :   virtual bool subclass_locally_equals (const MeshBase & other_mesh) const override;
     115             : 
     116             :   /**
     117             :    * Virtual copy-constructor, creates a copy of this mesh
     118             :    */
     119         476 :   virtual std::unique_ptr<MeshBase> clone () const override
     120             :   {
     121         484 :     auto returnval = std::make_unique<DistributedMesh>(*this);
     122             : #ifdef DEBUG
     123           8 :     libmesh_assert(*returnval == *this);
     124             : #endif
     125         484 :     return returnval;
     126         460 :   }
     127             : 
     128             :   /**
     129             :    * Destructor.
     130             :    */
     131             :   virtual ~DistributedMesh();
     132             : 
     133             :   /**
     134             :    * Clear all internal data.
     135             :    */
     136             :   virtual void clear() override;
     137             : 
     138             :   /**
     139             :    * Clear internal Elem data.
     140             :    */
     141             :   virtual void clear_elems() override;
     142             : 
     143             :   /**
     144             :    * Redistribute elements between processors.  This gets called
     145             :    * automatically by the Partitioner, and is a no-op in the case of a
     146             :    * serialized mesh.
     147             :    */
     148             :   virtual void redistribute () override;
     149             : 
     150             :   /**
     151             :    * Recalculate cached data after elements and nodes have been
     152             :    * repartitioned.
     153             :    */
     154             :   virtual void update_post_partitioning () override;
     155             : 
     156             :   /**
     157             :    * \returns \p true if all elements and nodes of the mesh
     158             :    * exist on the current processor, \p false otherwise
     159             :    */
     160       13500 :   virtual bool is_serial () const override final
     161      506108 :   { return _is_serial; }
     162             : 
     163             :   /**
     164             :    * \returns \p true if all elements and nodes of the mesh
     165             :    * exist on the processor 0, \p false otherwise
     166             :    */
     167          57 :   virtual bool is_serial_on_zero () const override final
     168         323 :   { return _is_serial || _is_serial_on_proc_0; }
     169             : 
     170             :   /**
     171             :    * Asserts that not all elements and nodes of the mesh necessarily
     172             :    * exist on the current processor.
     173             :    */
     174         402 :   virtual void set_distributed () override final
     175         402 :   { _is_serial = false;
     176         402 :     _is_serial_on_proc_0 = false; }
     177             : 
     178             :   /**
     179             :    * \returns \p true if new elements and nodes can and should be
     180             :    * created in synchronization on all processors, \p false otherwise
     181             :    */
     182       81536 :   virtual bool is_replicated () const override final
     183       81536 :   { return false; }
     184             : 
     185             :   /**
     186             :    * Verify id, processor_id, and if applicable unique_id consistency
     187             :    * of a parallel objects container.
     188             :    * Calls libmesh_assert() on each possible failure in that container.
     189             :    */
     190             :   template <typename T>
     191             :   void libmesh_assert_valid_parallel_object_ids(const dofobject_container<T> &) const;
     192             : 
     193             :   /**
     194             :    * Verify id and processor_id consistency of our elements and
     195             :    * nodes containers.
     196             :    * Calls libmesh_assert() on each possible failure.
     197             :    */
     198             :   virtual void libmesh_assert_valid_parallel_ids() const override;
     199             : 
     200             :   /**
     201             :    * Verify p_level consistency of our elements containers.
     202             :    * Calls libmesh_assert() on each possible failure.
     203             :    */
     204             :   void libmesh_assert_valid_parallel_p_levels() const;
     205             : 
     206             :   /**
     207             :    * Verify refinement_flag and p_refinement_flag consistency of our
     208             :    * elements containers.
     209             :    * Calls libmesh_assert() on each possible failure.
     210             :    */
     211             :   void libmesh_assert_valid_parallel_flags() const;
     212             : 
     213             :   /**
     214             :    * Renumber a parallel objects container.
     215             :    *
     216             :    * \returns The smallest globally unused id for that container.
     217             :    */
     218             :   template <typename T>
     219             :   dof_id_type renumber_dof_objects (dofobject_container<T> &);
     220             : 
     221             :   /**
     222             :    * Remove nullptr elements from arrays.
     223             :    */
     224             :   virtual void renumber_nodes_and_elements () override;
     225             : 
     226             :   /**
     227             :    * Gathers all elements and nodes of the mesh onto
     228             :    * every processor
     229             :    */
     230             :   virtual void allgather() override;
     231             : 
     232             :   /**
     233             :    * Gathers all elements and nodes of the mesh onto
     234             :    * processor zero
     235             :    */
     236             :   virtual void gather_to_zero() override;
     237             : 
     238             :   /**
     239             :    * Deletes all nonlocal elements of the mesh
     240             :    * except for "ghosts" which touch a local element, and deletes
     241             :    * all nodes which are not part of a local or ghost element
     242             :    */
     243             :   virtual void delete_remote_elements() override;
     244             : 
     245             :   /**
     246             :    * Inserts the element _and_ adds it to a list of elements that
     247             :    * should not get deleted or have their descendants deleted by
     248             :    * delete_remote_elements.  This is handy for inserting otherwise
     249             :    * off-processor elements that you want to keep track of on this
     250             :    * processor.
     251             :    */
     252             :   virtual void add_extra_ghost_elem(Elem * e);
     253             : 
     254             :   /**
     255             :    * Clears extra ghost elements.
     256             :    */
     257           0 :   virtual void clear_extra_ghost_elems() { _extra_ghost_elems.clear(); }
     258             : 
     259             :   /**
     260             :    * Clears specified extra ghost elements
     261             :    */
     262             :   virtual void clear_extra_ghost_elems(const std::set<Elem *> & extra_ghost_elems);
     263             : 
     264             :   /**
     265             :    * Const accessor to the ghosted elements
     266             :    */
     267             :   const std::set<Elem *> & extra_ghost_elems() const { return _extra_ghost_elems; }
     268             : 
     269             :   // Cached methods that can be called in serial
     270       76932 :   virtual dof_id_type n_nodes () const override final { return _n_nodes; }
     271       17188 :   virtual dof_id_type max_node_id () const override final { return _max_node_id; }
     272        2270 :   virtual void reserve_nodes (const dof_id_type) override final {}
     273       61532 :   virtual dof_id_type n_elem () const override final { return _n_elem; }
     274             :   virtual dof_id_type n_active_elem () const override final;
     275       19358 :   virtual dof_id_type max_elem_id () const override final { return _max_elem_id; }
     276        2151 :   virtual void reserve_elem (const dof_id_type) override final {}
     277             : 
     278             :   // Parallel only method to update the caches
     279             :   virtual void update_parallel_id_counts () override;
     280             : 
     281             :   // And more parallel only methods to test non-cached values
     282             :   virtual dof_id_type parallel_n_nodes () const override;
     283             :   dof_id_type parallel_max_node_id () const;
     284             :   virtual dof_id_type parallel_n_elem () const override;
     285             :   dof_id_type parallel_max_elem_id () const;
     286             : 
     287             : #ifdef LIBMESH_ENABLE_UNIQUE_ID
     288             :   virtual unique_id_type parallel_max_unique_id () const override;
     289             :   virtual void set_next_unique_id(unique_id_type id) override;
     290             : #endif
     291             : 
     292             :   virtual const Point & point (const dof_id_type i) const override final;
     293             : 
     294             :   virtual const Node * node_ptr (const dof_id_type i) const override final;
     295             :   virtual Node * node_ptr (const dof_id_type i) override final;
     296             : 
     297             :   virtual const Node * query_node_ptr (const dof_id_type i) const override final;
     298             :   virtual Node * query_node_ptr (const dof_id_type i) override final;
     299             : 
     300             :   virtual const Elem * elem_ptr (const dof_id_type i) const override final;
     301             :   virtual Elem * elem_ptr (const dof_id_type i) override final;
     302             : 
     303             :   virtual const Elem * query_elem_ptr (const dof_id_type i) const override final;
     304             :   virtual Elem * query_elem_ptr (const dof_id_type i) override final;
     305             : 
     306             :   /**
     307             :    * functions for adding /deleting nodes elements.
     308             :    */
     309             :   virtual Node * add_point (const Point & p,
     310             :                             const dof_id_type id = DofObject::invalid_id,
     311             :                             const processor_id_type proc_id = DofObject::invalid_processor_id) override final;
     312             :   virtual Node * add_node (Node * n) override final;
     313             :   virtual Node * add_node (std::unique_ptr<Node> n) override final;
     314             : 
     315             : #ifdef LIBMESH_ENABLE_DEPRECATED
     316             :   /**
     317             :    * These methods are deprecated. Please use \p add_node instead
     318             :    * Calls add_node().
     319             :    */
     320             :   virtual Node * insert_node(Node * n) override final;
     321             :   virtual Node * insert_node(std::unique_ptr<Node> n) override final;
     322             : #endif
     323             : 
     324             :   /**
     325             :    * Takes ownership of node \p n on this partition of a distributed
     326             :    * mesh, by setting n.processor_id() to this->processor_id(), as
     327             :    * well as changing n.id() and moving it in the mesh's internal
     328             :    * container to give it a new authoritative id.
     329             :    */
     330             :   virtual void own_node (Node & n) override final;
     331             : 
     332             :   virtual void delete_node (Node * n) override final;
     333             :   virtual void renumber_node (dof_id_type old_id, dof_id_type new_id) override final;
     334             :   virtual Elem * add_elem (Elem * e) override final;
     335             :   virtual Elem * add_elem (std::unique_ptr<Elem> e) override final;
     336             :   virtual Elem * insert_elem (Elem * e) override final;
     337             :   virtual Elem * insert_elem (std::unique_ptr<Elem> e) override final;
     338             :   virtual void delete_elem (Elem * e) override final;
     339             :   virtual void renumber_elem (dof_id_type old_id, dof_id_type new_id) override final;
     340             : 
     341             :   /**
     342             :    * There is no reason for a user to ever call this function.
     343             :    *
     344             :    * This function restores a previously broken element/node numbering such that
     345             :    * \p mesh.node_ref(n).id() == n.
     346             :    */
     347             :   virtual void fix_broken_node_and_element_numbering () override;
     348             : 
     349             : public:
     350             :   /**
     351             :    * Elem and Node iterator accessor functions.  See MeshBase for
     352             :    * documentation.
     353             :    */
     354       16238 :   DECLARE_ELEM_ITERATORS(,,);
     355       28696 :   DECLARE_ELEM_ITERATORS(active_,,);
     356           0 :   DECLARE_ELEM_ITERATORS(ancestor_,,)
     357           0 :   DECLARE_ELEM_ITERATORS(subactive_,,)
     358           0 :   DECLARE_ELEM_ITERATORS(local_,,)
     359           0 :   DECLARE_ELEM_ITERATORS(unpartitioned_,,)
     360           0 :   DECLARE_ELEM_ITERATORS(facelocal_,,)
     361           0 :   DECLARE_ELEM_ITERATORS(level_, unsigned int level, level)
     362           0 :   DECLARE_ELEM_ITERATORS(pid_, processor_id_type pid, pid)
     363           0 :   DECLARE_ELEM_ITERATORS(type_, ElemType type, type)
     364             : 
     365           0 :   DECLARE_ELEM_ITERATORS(active_subdomain_, subdomain_id_type sid, sid)
     366           0 :   DECLARE_ELEM_ITERATORS(active_subdomain_set_, std::set<subdomain_id_type> ss, ss)
     367             : 
     368             :   // Backwards compatibility
     369           0 :   virtual SimpleRange<element_iterator> active_subdomain_elements_ptr_range(subdomain_id_type sid) override final { return active_subdomain_element_ptr_range(sid); }
     370           0 :   virtual SimpleRange<const_element_iterator> active_subdomain_elements_ptr_range(subdomain_id_type sid) const override final { return active_subdomain_element_ptr_range(sid); }
     371           0 :   virtual SimpleRange<element_iterator> active_local_subdomain_elements_ptr_range(subdomain_id_type sid) override final { return active_local_subdomain_element_ptr_range(sid); }
     372           0 :   virtual SimpleRange<const_element_iterator> active_local_subdomain_elements_ptr_range(subdomain_id_type sid) const override final { return active_local_subdomain_element_ptr_range(sid); }
     373           0 :   virtual SimpleRange<element_iterator> active_subdomain_set_elements_ptr_range(std::set<subdomain_id_type> ss) override final { return active_subdomain_set_element_ptr_range(ss); }
     374           0 :   virtual SimpleRange<const_element_iterator> active_subdomain_set_elements_ptr_range(std::set<subdomain_id_type> ss) const override final { return active_subdomain_set_element_ptr_range(ss); }
     375             : 
     376           0 :   DECLARE_ELEM_ITERATORS(not_active_,,);
     377           0 :   DECLARE_ELEM_ITERATORS(not_ancestor_,,);
     378           0 :   DECLARE_ELEM_ITERATORS(not_subactive_,,);
     379           0 :   DECLARE_ELEM_ITERATORS(not_local_,,);
     380           0 :   DECLARE_ELEM_ITERATORS(not_level_, unsigned int level, level)
     381             : 
     382        9727 :   DECLARE_ELEM_ITERATORS(active_local_,,)
     383           0 :   DECLARE_ELEM_ITERATORS(active_not_local_,,)
     384         190 :   DECLARE_ELEM_ITERATORS(active_unpartitioned_,,)
     385           0 :   DECLARE_ELEM_ITERATORS(active_type_, ElemType type, type)
     386           0 :   DECLARE_ELEM_ITERATORS(active_pid_, processor_id_type pid, pid)
     387           0 :   DECLARE_ELEM_ITERATORS(local_level_, unsigned int level, level)
     388           0 :   DECLARE_ELEM_ITERATORS(local_not_level_, unsigned int level, level)
     389           0 :   DECLARE_ELEM_ITERATORS(active_local_subdomain_, subdomain_id_type sid, sid)
     390           0 :   DECLARE_ELEM_ITERATORS(active_local_subdomain_set_, std::set<subdomain_id_type> ss, ss)
     391             : 
     392           0 :   DECLARE_ELEM_ITERATORS(semilocal_,,)
     393           0 :   DECLARE_ELEM_ITERATORS(ghost_,,)
     394           0 :   DECLARE_ELEM_ITERATORS(active_semilocal_,,)
     395             : 
     396           0 :   DECLARE_ELEM_ITERATORS(evaluable_, const DofMap & dof_map LIBMESH_COMMA unsigned int var_num = libMesh::invalid_uint, dof_map LIBMESH_COMMA var_num)
     397           0 :   DECLARE_ELEM_ITERATORS(multi_evaluable_, std::vector<const DofMap *> dof_maps, dof_maps)
     398             : 
     399             : #ifdef LIBMESH_ENABLE_AMR
     400           0 :   DECLARE_ELEM_ITERATORS(flagged_, unsigned char rflag, rflag)
     401             : 
     402             :   // Elem::refinement_flag() == rflag && Elem::processor_id() == pid
     403           0 :   DECLARE_ELEM_ITERATORS(flagged_pid_, unsigned char rflag LIBMESH_COMMA processor_id_type pid, rflag LIBMESH_COMMA pid)
     404             : #endif
     405             : 
     406       11272 :   DECLARE_NODE_ITERATORS(,,)
     407           0 :   DECLARE_NODE_ITERATORS(active_,,)
     408        9532 :   DECLARE_NODE_ITERATORS(local_,,)
     409           0 :   DECLARE_NODE_ITERATORS(bnd_,,)
     410           0 :   DECLARE_NODE_ITERATORS(pid_, processor_id_type pid, pid)
     411           0 :   DECLARE_NODE_ITERATORS(bid_, boundary_id_type bid, bid)
     412             : 
     413           0 :   DECLARE_NODE_ITERATORS(evaluable_, const DofMap & dof_map LIBMESH_COMMA unsigned int var_num = libMesh::invalid_uint, dof_map LIBMESH_COMMA var_num)
     414             : 
     415           0 :   DECLARE_NODE_ITERATORS(multi_evaluable_, std::vector<const DofMap *> dof_maps, dof_maps)
     416             : 
     417             : 
     418             : protected:
     419             : 
     420             :   /**
     421             :    * Move node and elements from a DistributedMesh.
     422             :    */
     423             :   virtual void move_nodes_and_elements(MeshBase && other_mesh) override;
     424             : 
     425             :   /**
     426             :    * The vertices (spatial coordinates) of the mesh.
     427             :    */
     428             :   dofobject_container<Node> _nodes;
     429             : 
     430             :   /**
     431             :    * The elements in the mesh.
     432             :    */
     433             :   dofobject_container<Elem> _elements;
     434             : 
     435             :   /**
     436             :    * A boolean remembering whether we're serialized or not
     437             :    */
     438             :   bool _is_serial;
     439             : 
     440             :   /**
     441             :    * A boolean remembering whether we're serialized to proc 0 or not
     442             :    */
     443             :   bool _is_serial_on_proc_0;
     444             : 
     445             :   /**
     446             :    * A boolean remembering whether we've recently deleted top-level elements or
     447             :    * not.  If so, we'll need to be extra careful when deleting "unused" nodes
     448             :    * they used to have, because those nodes might still be used by ghost elements.
     449             :    */
     450             :   bool _deleted_coarse_elements;
     451             : 
     452             :   /**
     453             :    * Cached data from the last renumber_nodes_and_elements call
     454             :    */
     455             :   dof_id_type _n_nodes, _n_elem, _max_node_id, _max_elem_id;
     456             : 
     457             :   /**
     458             :    * Guaranteed globally unused IDs for use when adding new
     459             :    * nodes or elements.
     460             :    */
     461             :   dof_id_type _next_free_local_node_id,
     462             :     _next_free_local_elem_id;
     463             :   dof_id_type _next_free_unpartitioned_node_id,
     464             :     _next_free_unpartitioned_elem_id;
     465             : 
     466             : #ifdef LIBMESH_ENABLE_UNIQUE_ID
     467             :   /**
     468             :    * The next available unique id for assigning ids to unpartitioned DOF objects
     469             :    */
     470             :   unique_id_type _next_unpartitioned_unique_id;
     471             : #endif
     472             : 
     473             :   /**
     474             :    * These are extra ghost elements that we want to make sure
     475             :    * not to delete when we call delete_remote_elements()
     476             :    */
     477             :   std::set<Elem *> _extra_ghost_elems;
     478             : 
     479             : private:
     480             : 
     481             :   /**
     482             :    * Typedefs for the container implementation.
     483             :    */
     484             :   typedef dofobject_container<Elem>::veclike_iterator             elem_iterator_imp;
     485             :   typedef dofobject_container<Elem>::const_veclike_iterator const_elem_iterator_imp;
     486             : 
     487             :   /**
     488             :    * Typedefs for the container implementation.
     489             :    */
     490             :   typedef dofobject_container<Node>::veclike_iterator             node_iterator_imp;
     491             :   typedef dofobject_container<Node>::const_veclike_iterator const_node_iterator_imp;
     492             : };
     493             : 
     494             : 
     495             : } // namespace libMesh
     496             : 
     497             : #endif // LIBMESH_DISTRIBUTED_MESH_H

Generated by: LCOV version 1.14