libMesh
Classes | Public Types | Public Member Functions | Static Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
libMesh::MeshTools::SidesToElemMap Class Reference

This class implements a generalization of the MeshTools::build_nodes_to_elem_map() function, but rather than being a standalone function taking a std::unordered_map argument, we define a class with APIs for both building the underlying map data structure and querying its contents. More...

#include <sides_to_elem_map.h>

Classes

struct  HashFunction
 

Public Types

typedef std::vector< const Elem * >::const_iterator ElemIter
 Typedef for the iterator type returned by the SidesToeElemMap::get_connected_elems() function. More...
 

Public Member Functions

 SidesToElemMap ()
 Default constructor/destructor. More...
 
 ~SidesToElemMap ()
 
std::pair< ElemIter, ElemIterget_connected_elems (const Elem *elem, unsigned int side) const
 Return an iterator pair defining the range of Elems connected to "side" of "elem". More...
 

Static Public Member Functions

static SidesToElemMap build (const MeshBase &mesh)
 Static build function. More...
 

Private Types

typedef std::vector< dof_id_typeKey
 Convenient typedefs for working with std::unordered_map. More...
 
typedef std::vector< const Elem * > Value
 

Private Member Functions

void get_sorted_vertex_ids (const Elem *elem, unsigned int side, std::vector< dof_id_type > &sorted_vertex_ids) const
 Construct a sorted list of vertex ids for the input (elem, side) pair. More...
 

Private Attributes

std::unordered_map< Key, Value, HashFunction, HashFunction_sides_to_elem_map
 Map from (sorted list of side vertex ids) -> (Elems touching that side) A "side" is uniquely defined by the sorted list of its vertex ids, so this is a good choice to use as a key. More...
 

Detailed Description

This class implements a generalization of the MeshTools::build_nodes_to_elem_map() function, but rather than being a standalone function taking a std::unordered_map argument, we define a class with APIs for both building the underlying map data structure and querying its contents.

This way, we avoid issues with hash collisions resulting from the Elem::low_order_key() function (which could occur with as few as 100k sides when using a 32-bit dof_id_type) in addition to being able to control exactly how the user will interact with the class.

Author
John W. Peterson
Date
2024

Definition at line 53 of file sides_to_elem_map.h.

Member Typedef Documentation

◆ ElemIter

typedef std::vector<const Elem *>::const_iterator libMesh::MeshTools::SidesToElemMap::ElemIter

Typedef for the iterator type returned by the SidesToeElemMap::get_connected_elems() function.

Definition at line 73 of file sides_to_elem_map.h.

◆ Key

Convenient typedefs for working with std::unordered_map.

Definition at line 90 of file sides_to_elem_map.h.

◆ Value

typedef std::vector<const Elem *> libMesh::MeshTools::SidesToElemMap::Value
private

Definition at line 91 of file sides_to_elem_map.h.

Constructor & Destructor Documentation

◆ SidesToElemMap()

libMesh::MeshTools::SidesToElemMap::SidesToElemMap ( )
default

Default constructor/destructor.

◆ ~SidesToElemMap()

libMesh::MeshTools::SidesToElemMap::~SidesToElemMap ( )
default

Member Function Documentation

◆ build()

SidesToElemMap libMesh::MeshTools::SidesToElemMap::build ( const MeshBase mesh)
static

Static build function.

Most users will simply call this function to construct the SidesToElemMap object for their Mesh.

Definition at line 37 of file sides_to_elem_map.C.

References _sides_to_elem_map, get_sorted_vertex_ids(), libMesh::invalid_uint, and mesh.

Referenced by NonManifoldTestPartitioner::_do_partition(), libMesh::NonManifoldGhostingFunctor::mesh_reinit(), and NonManifoldGhostingFunctorTest::verify_send_list_entries_helper().

38 {
39  LOG_SCOPE("build()", "SidesToElemMap");
40 
41  // Eventual return value
42  SidesToElemMap ret;
43 
44  // Temporary storage of sorted list of vertex ids on side "s" of
45  // "elem". We use only vertices since that is sufficient to
46  // uniquely identify an Elem side. We only create this once and then
47  // reuse it for each Side in the mesh to avoid repeated small memory
48  // allocations.
49  std::vector<dof_id_type> sorted_vertex_ids;
50 
51  // Flag which is used to check for hanging Nodes, a case not
52  // currently handled by the SidesToElemMap object.
53  unsigned int active_level_seen = libMesh::invalid_uint;
54 
55  for (const auto & elem : mesh.element_ptr_range())
56  {
57  // We currently don't handle meshes with hanging nodes. That is,
58  // if there is a refined element with a coarser neighbor, the
59  // SidesToElemMap won't contain any neighbor information (in
60  // either direction) about this. For now, we throw an error
61  // in this scenario.
62  if (elem->active())
63  {
64  if (active_level_seen == libMesh::invalid_uint)
65  active_level_seen = elem->level();
66  else
67  libmesh_error_msg_if(
68  active_level_seen != elem->level(),
69  "SidesToElemMap does not currently support hanging nodes.");
70  }
71 
72  for (auto s : elem->side_index_range())
73  {
74  ret.get_sorted_vertex_ids(elem, s, sorted_vertex_ids);
75 
76  // Get reference to (or create) the vector of Elem pointers
77  // associated with this list of vertex ids, and store "elem" in it.
78  ret._sides_to_elem_map[sorted_vertex_ids].push_back(elem);
79  }
80  }
81 
82  return ret;
83 }
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition: libmesh.h:310
MeshBase & mesh
SidesToElemMap()
Default constructor/destructor.

◆ get_connected_elems()

std::pair< SidesToElemMap::ElemIter, SidesToElemMap::ElemIter > libMesh::MeshTools::SidesToElemMap::get_connected_elems ( const Elem elem,
unsigned int  side 
) const

Return an iterator pair defining the range of Elems connected to "side" of "elem".

The returned list of Elems will also include "elem" itself. Throws an error if the requested (elem, side) combination is not found in the map (this should not happen because every side in the map should be attached to at least one Elem).

Definition at line 86 of file sides_to_elem_map.C.

References _sides_to_elem_map, and get_sorted_vertex_ids().

Referenced by NonManifoldTestPartitioner::_do_partition(), libMesh::NonManifoldGhostingFunctor::operator()(), and NonManifoldGhostingFunctorTest::verify_send_list_entries_helper().

87 {
88  std::vector<dof_id_type> sorted_vertex_ids;
89  this->get_sorted_vertex_ids(elem, side, sorted_vertex_ids);
90 
91  const auto & elem_vec = libmesh_map_find(_sides_to_elem_map, sorted_vertex_ids);
92  return std::make_pair(elem_vec.begin(), elem_vec.end());
93 }
std::unordered_map< Key, Value, HashFunction, HashFunction > _sides_to_elem_map
Map from (sorted list of side vertex ids) -> (Elems touching that side) A "side" is uniquely defined ...
void get_sorted_vertex_ids(const Elem *elem, unsigned int side, std::vector< dof_id_type > &sorted_vertex_ids) const
Construct a sorted list of vertex ids for the input (elem, side) pair.

◆ get_sorted_vertex_ids()

void libMesh::MeshTools::SidesToElemMap::get_sorted_vertex_ids ( const Elem elem,
unsigned int  side,
std::vector< dof_id_type > &  sorted_vertex_ids 
) const
private

Construct a sorted list of vertex ids for the input (elem, side) pair.

This is needed in a couple different places, so it makes sense to factor it out. The output array is passed as a reference to facilitate reuse over reallocation.

Definition at line 96 of file sides_to_elem_map.C.

References libMesh::Elem::is_vertex(), libMesh::Elem::node_id(), and libMesh::Elem::nodes_on_side().

Referenced by build(), and get_connected_elems().

100 {
101  // Clear any prior data
102  sorted_vertex_ids.clear();
103 
104  // Get all vertices for this side. Note: we can stop once we reach
105  // the first non-vertex node, since all vertices are numbered first.
106  for (const auto & n : elem->nodes_on_side(side))
107  {
108  if (elem->is_vertex(n))
109  sorted_vertex_ids.push_back(elem->node_id(n));
110  else
111  break;
112  }
113 
114  // Sort the vertex ids. The hash functions depend on the ordering
115  // of the ids, so we want to be sure they are the same for every
116  // Elem that touches this Side.
117  std::sort(sorted_vertex_ids.begin(), sorted_vertex_ids.end());
118 }

Member Data Documentation

◆ _sides_to_elem_map

std::unordered_map<Key, Value, HashFunction, HashFunction> libMesh::MeshTools::SidesToElemMap::_sides_to_elem_map
private

Map from (sorted list of side vertex ids) -> (Elems touching that side) A "side" is uniquely defined by the sorted list of its vertex ids, so this is a good choice to use as a key.

Definition at line 125 of file sides_to_elem_map.h.

Referenced by build(), and get_connected_elems().


The documentation for this class was generated from the following files: