LCOV - code coverage report
Current view: top level - include/mesh - mesh_communication.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_MESH_COMMUNICATION_H
      21             : #define LIBMESH_MESH_COMMUNICATION_H
      22             : 
      23             : // Local Includes
      24             : #include "libmesh/compare_elems_by_level.h"
      25             : #include "libmesh/libmesh_common.h"
      26             : #include "libmesh/mesh_base.h"
      27             : 
      28             : // C++ Includes
      29             : #include <set>
      30             : #include <utility>
      31             : #include <unordered_map>
      32             : #include <vector>
      33             : 
      34             : namespace libMesh
      35             : {
      36             : 
      37             : // Forward declarations
      38             : class MeshBase;
      39             : class DistributedMesh;
      40             : 
      41             : // This is for backwards compatibility, but if your code relies on
      42             : // forward declarations in our headers then fix it.
      43             : class ParallelMesh;
      44             : 
      45             : /**
      46             :  * This is the \p MeshCommunication class.  It handles all the details
      47             :  * of communicating mesh information from one processor to another.  All
      48             :  * parallelization of the \p Mesh data structures is done via this class.
      49             :  *
      50             :  * \author Benjamin S. Kirk
      51             :  * \date 2003
      52             :  */
      53             : class MeshCommunication
      54             : {
      55             : public:
      56             : 
      57             :   /**
      58             :    * Constructor.
      59             :    */
      60             :   MeshCommunication () = default;
      61             : 
      62             :   /**
      63             :    * Destructor.
      64             :    */
      65             :   ~MeshCommunication () = default;
      66             : 
      67             :   /**
      68             :    * Clears all data structures and resets to a pristine state.
      69             :    */
      70             :   void clear ();
      71             : 
      72             :   //   /**
      73             :   //    * Finds all the processors that may contain
      74             :   //    * elements that neighbor my elements.  This list
      75             :   //    * is guaranteed to include all processors that border
      76             :   //    * any of my elements, but may include additional ones as
      77             :   //    * well.  This method computes bounding boxes for the
      78             :   //    * elements on each processor and checks for overlaps.
      79             :   //    */
      80             :   //   void find_neighboring_processors(const MeshBase &);
      81             : 
      82             :   /**
      83             :    * This method takes a mesh (which is assumed to reside on
      84             :    * processor 0) and broadcasts it to all the other processors.
      85             :    * It also broadcasts any boundary information the mesh has
      86             :    * associated with it.
      87             :    */
      88             :   void broadcast (MeshBase &) const;
      89             : 
      90             :   /**
      91             :    * This method takes a parallel distributed mesh and redistributes
      92             :    * the elements.  Specifically, any elements stored on a given
      93             :    * processor are sent to the processor which "owns" them.  Similarly,
      94             :    * any elements assigned to the current processor but stored on
      95             :    * another are received. Once this step is completed any required ghost
      96             :    * elements are updated.  The final result is that each processor stores
      97             :    * only the elements it actually owns and any ghost elements required
      98             :    * to satisfy data dependencies. This method can be invoked after a
      99             :    * partitioning step to affect the new partitioning.
     100             :    *
     101             :    * Redistribution can also be done with newly coarsened elements'
     102             :    * neighbors only.
     103             :    */
     104             :   void redistribute (DistributedMesh & mesh,
     105             :                      bool newly_coarsened_only = false) const;
     106             : 
     107             :   /**
     108             :    *
     109             :    */
     110             :   void gather_neighboring_elements (DistributedMesh &) const;
     111             : 
     112             :   /**
     113             :    * Examine a just-coarsened mesh, and for any newly-coarsened elements,
     114             :    * send the associated ghosted elements to the processor which needs them.
     115             :    */
     116             :   void send_coarse_ghosts (MeshBase &) const;
     117             : 
     118             :   /**
     119             :    * This method takes an input \p DistributedMesh which may be
     120             :    * distributed among all the processors.  Each processor then
     121             :    * sends its local nodes and elements to processor \p root_id.
     122             :    * The end result is that a previously distributed \p DistributedMesh
     123             :    * will be serialized on processor \p root_id.  Since this method is
     124             :    * collective it must be called by all processors. For the special
     125             :    * case of \p root_id equal to \p DofObject::invalid_processor_id
     126             :    * this function performs an allgather.
     127             :    */
     128             :   void gather (const processor_id_type root_id, MeshBase &) const;
     129             : 
     130             :   /**
     131             :    * This method takes an input \p DistributedMesh which may be
     132             :    * distributed among all the processors.  Each processor then
     133             :    * sends its local nodes and elements to the other processors.
     134             :    * The end result is that a previously distributed \p DistributedMesh
     135             :    * will be serialized on each processor.  Since this method is
     136             :    * collective it must be called by all processors.
     137             :    */
     138          60 :   void allgather (MeshBase & mesh) const
     139       78246 :   { MeshCommunication::gather(DofObject::invalid_processor_id, mesh); }
     140             : 
     141             :   /**
     142             :    * This method takes an input \p DistributedMesh which may be
     143             :    * distributed among all the processors.  Each processor
     144             :    * deletes all elements which are neither local elements nor "ghost"
     145             :    * elements which touch local elements, and deletes all nodes which
     146             :    * are not contained in local or ghost elements.
     147             :    * The end result is that a previously serial \p DistributedMesh
     148             :    * will be distributed between processors.  Since this method is
     149             :    * collective it must be called by all processors.
     150             :    *
     151             :    * The std::set is a list of extra elements that you _don't_ want
     152             :    * to delete.  These will be left on the current processor along with
     153             :    * local elements and ghosted neighbors.
     154             :    */
     155             :   void delete_remote_elements (DistributedMesh &, const std::set<Elem *> &) const;
     156             : 
     157             :   /**
     158             :    * This method assigns globally unique, partition-agnostic
     159             :    * indices to the nodes and elements in the mesh.  The approach
     160             :    * is to compute the Hilbert space-filling curve key and use its
     161             :    * value to assign an index in [0,N_global). Since the Hilbert key
     162             :    * is unique for each spatial location, two objects occupying the
     163             :    * same location will be assigned the same global id.  Thus, this
     164             :    * method can also be useful for identifying duplicate nodes
     165             :    * which may occur during parallel refinement.
     166             :    */
     167             :   void assign_global_indices (MeshBase &) const;
     168             : 
     169             :   /**
     170             :    * Throw an error if we have any index clashes in the numbering used by
     171             :    * assign_global_indices.
     172             :    */
     173             :   void check_for_duplicate_global_indices (MeshBase & ) const;
     174             : 
     175             :   /**
     176             :    * This method determines a locally unique, contiguous
     177             :    * index for each object in the input range.
     178             :    */
     179             :   template <typename ForwardIterator>
     180             :   void find_local_indices (const libMesh::BoundingBox &,
     181             :                            const ForwardIterator &,
     182             :                            const ForwardIterator &,
     183             :                            std::unordered_map<dof_id_type, dof_id_type> &) const;
     184             : 
     185             :   /**
     186             :    * This method determines a globally unique, partition-agnostic
     187             :    * index for each object in the input range.
     188             :    */
     189             :   template <typename ForwardIterator>
     190             :   void find_global_indices (const Parallel::Communicator & communicator,
     191             :                             const libMesh::BoundingBox &,
     192             :                             const ForwardIterator &,
     193             :                             const ForwardIterator &,
     194             :                             std::vector<dof_id_type> &) const;
     195             : 
     196             :   /**
     197             :    * Copy ids of ghost elements from their local processors.
     198             :    */
     199             :   void make_elems_parallel_consistent (MeshBase &);
     200             : 
     201             : #ifdef LIBMESH_ENABLE_AMR
     202             :   /**
     203             :    * Copy p levels of ghost elements from their local processors.
     204             :    */
     205             :   void make_p_levels_parallel_consistent (MeshBase &);
     206             : #endif // LIBMESH_ENABLE_AMR
     207             : 
     208             :   /**
     209             :    * Assuming all ids on local nodes are globally unique, and
     210             :    * assuming all processor ids are parallel consistent, this function makes
     211             :    * all other ids parallel consistent.
     212             :    */
     213             :   void make_node_ids_parallel_consistent (MeshBase &);
     214             : 
     215             :   /**
     216             :    * Assuming all unique_ids on local nodes are globally unique, and
     217             :    * assuming all processor ids are parallel consistent, this function makes
     218             :    * all ghost unique_ids parallel consistent.
     219             :    */
     220             :   void make_node_unique_ids_parallel_consistent (MeshBase &);
     221             : 
     222             :   /**
     223             :    * Assuming all processor ids are parallel consistent, this function
     224             :    * makes all ghost boundary ids on nodes parallel consistent.
     225             :    */
     226             :   void make_node_bcids_parallel_consistent (MeshBase &);
     227             : 
     228             :   /**
     229             :    * Assuming all processor ids on nodes touching local elements
     230             :    * are parallel consistent, this function makes all other processor ids
     231             :    * parallel consistent as well.
     232             :    */
     233             :   void make_node_proc_ids_parallel_consistent (MeshBase &);
     234             : 
     235             :   /**
     236             :    * Assuming all processor ids on nodes touching local elements
     237             :    * are parallel consistent, this function makes processor ids
     238             :    * on new nodes on other processors parallel consistent as well.
     239             :    */
     240             :   void make_new_node_proc_ids_parallel_consistent (MeshBase &);
     241             : 
     242             :   /**
     243             :    * Copy processor_ids and ids on ghost nodes from their
     244             :    * local processors.  This is useful for code which wants to add
     245             :    * nodes to a distributed mesh.
     246             :    */
     247             :   void make_nodes_parallel_consistent (MeshBase &);
     248             : 
     249             :   /**
     250             :    * Copy processor_ids and ids on new nodes from their local
     251             :    * processors.
     252             :    */
     253             :   void make_new_nodes_parallel_consistent (MeshBase &);
     254             : };
     255             : 
     256             : 
     257             : // Related utilities
     258             : 
     259             : // What to use to fill sets of connected nodes and elements
     260             : typedef std::set<const Node *> connected_node_set_type;
     261             : typedef std::set<const Elem *, CompareElemIdsByLevel> connected_elem_set_type;
     262             : 
     263             : // Ask a mesh's ghosting functors to insert into a set all elements
     264             : // that are either on or connected to processor id \p pid.  Ask only
     265             : // for elements in the range from \p elem_it before \p elem_end;
     266             : // typically this may be mesh.active_pid_elements_*(pid)
     267             : void query_ghosting_functors(const MeshBase & mesh,
     268             :                              processor_id_type pid,
     269             :                              MeshBase::const_element_iterator elem_it,
     270             :                              MeshBase::const_element_iterator elem_end,
     271             :                              connected_elem_set_type & connected_elements);
     272             : 
     273             : // Take a set of elements and insert all immediate
     274             : // children of elements in the given range
     275             : void connect_children(const MeshBase & mesh,
     276             :                       MeshBase::const_element_iterator elem_it,
     277             :                       MeshBase::const_element_iterator elem_end,
     278             :                       connected_elem_set_type & connected_elements);
     279             : 
     280             : // Take a set of elements and insert all elements' ancestors and
     281             : // subactive descendants as well.  If a mesh is provided and has any
     282             : // constraint rows, insert elements with the constraining nodes for
     283             : // any constrained nodes in our set.
     284             : //
     285             : // \deprecated This method is now deprecated, because it does not
     286             : // handle recursive dependencies.  Use the new
     287             : // connect_element_dependencies method instead.
     288             : #ifdef LIBMESH_ENABLE_DEPRECATED
     289             : void connect_families(connected_elem_set_type & connected_elements,
     290             :                       const MeshBase * mesh = nullptr);
     291             : #endif // LIBMESH_ENABLE_DEPRECATED
     292             : 
     293             : // Take a set of elements and create a set of connected nodes.
     294             : void reconnect_nodes (connected_elem_set_type & connected_elements,
     295             :                       connected_node_set_type & connected_nodes);
     296             : 
     297             : // Take a set of elements and of nodes, and insert all
     298             : // libMesh-mandated element of them: ancestor elements,
     299             : // immediate children, subactive descendents of active elements,
     300             : // interior_parents, nodes of any of those elements, and elements used
     301             : // to constrain any of those nodes.  This must be done recursively
     302             : // (well, repeatedly; we unroll) in the general case, since a node
     303             : // constraint can require a new element that can require other new
     304             : // elements with new nodes with new constraints.
     305             : void connect_element_dependencies(const MeshBase & mesh,
     306             :                                   connected_elem_set_type & connected_elements,
     307             :                                   connected_node_set_type & connected_nodes);
     308             : 
     309             : // Takes already-examined sets and not-yet-examined sets, returns more sets
     310             : // in need of examination (or empty sets if done).
     311             : std::pair<connected_elem_set_type, connected_node_set_type>
     312             : connect_element_dependencies(const MeshBase & mesh,
     313             :                              const connected_elem_set_type & connected_elements,
     314             :                              const connected_node_set_type & connected_nodes,
     315             :                              const connected_elem_set_type & new_connected_elements,
     316             :                              const connected_node_set_type & new_connected_nodes);
     317             : 
     318             : //--------------------------------------------------------------
     319             : // MeshCommunication inline members
     320             : 
     321             : 
     322             : } // namespace libMesh
     323             : 
     324             : #endif // LIBMESH_MESH_COMMUNICATION_H

Generated by: LCOV version 1.14