libMesh
sides_to_elem_map.C
Go to the documentation of this file.
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 // libMesh includes
19 #include "libmesh/sides_to_elem_map.h"
20 #include "libmesh/elem.h"
21 #include "libmesh/libmesh_logging.h" // LOG_SCOPE
22 #include "libmesh/mesh_base.h"
23 #include "libmesh/utility.h" // libmesh_map_find()
24 
25 namespace libMesh
26 {
27 
28 namespace MeshTools
29 {
30 
33 
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 }
84 
85 std::pair<SidesToElemMap::ElemIter, SidesToElemMap::ElemIter>
86 SidesToElemMap::get_connected_elems(const Elem * elem, unsigned int side) const
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 }
94 
95 void
97  const Elem * elem,
98  unsigned int side,
99  std::vector<dof_id_type> & sorted_vertex_ids) const
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 }
119 
120 } // namespace MeshTools
121 
122 } // namespace libMesh
123 
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
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
std::pair< ElemIter, ElemIter > get_connected_elems(const Elem *elem, unsigned int side) const
Return an iterator pair defining the range of Elems connected to "side" of "elem".
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 ...
The libMesh namespace provides an interface to certain functionality in the library.
This is the MeshBase class.
Definition: mesh_base.h:75
static SidesToElemMap build(const MeshBase &mesh)
Static build function.
SidesToElemMap()
Default constructor/destructor.
virtual bool is_vertex(const unsigned int i) const =0
This class implements a generalization of the MeshTools::build_nodes_to_elem_map() function...
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:2475
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.
virtual std::vector< unsigned int > nodes_on_side(const unsigned int) const =0