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 : // Local Includes
21 : #include "libmesh/elem.h"
22 : #include "libmesh/topology_map.h"
23 : #include "libmesh/mesh_base.h"
24 : #include "libmesh/node.h"
25 : #include "libmesh/parallel_only.h"
26 : #include "libmesh/remote_elem.h"
27 : #include "libmesh/libmesh_logging.h"
28 :
29 : // C++ Includes
30 : #include <limits>
31 : #include <utility>
32 :
33 : namespace libMesh
34 : {
35 :
36 54499 : void TopologyMap::init(MeshBase & mesh)
37 : {
38 : // This function must be run on all processors at once
39 : // for non-serial meshes
40 54499 : if (!mesh.is_serial())
41 46 : libmesh_parallel_only(mesh.comm());
42 :
43 3716 : LOG_SCOPE("init()", "TopologyMap");
44 :
45 : // Clear the old map
46 1858 : _map.clear();
47 :
48 54499 : this->fill(mesh);
49 54499 : }
50 :
51 :
52 :
53 73203423 : void TopologyMap::add_node(const Node & mid_node,
54 : const std::vector<std::pair<dof_id_type, dof_id_type>> & bracketing_nodes)
55 : {
56 73203423 : const dof_id_type mid_node_id = mid_node.id();
57 :
58 4250923 : libmesh_assert_not_equal_to(mid_node_id, DofObject::invalid_id);
59 :
60 149101381 : for (auto [id1, id2] : bracketing_nodes)
61 : {
62 4724111 : libmesh_assert_not_equal_to(id1, id2);
63 :
64 75897958 : const dof_id_type lower_id = std::min(id1, id2);
65 75897958 : const dof_id_type upper_id = std::max(id1, id2);
66 :
67 : // We should never be inserting inconsistent data
68 : #ifndef NDEBUG
69 4724111 : if (const auto it = _map.find(std::make_pair(lower_id, upper_id));
70 4724111 : it != _map.end())
71 2911290 : libmesh_assert_equal_to (it->second, mid_node_id);
72 : #endif
73 :
74 75897958 : this->_map.emplace(std::make_pair(lower_id, upper_id),
75 4724111 : mid_node_id);
76 :
77 : }
78 73203423 : }
79 :
80 :
81 31969963 : dof_id_type TopologyMap::find(const std::vector<std::pair<dof_id_type, dof_id_type>> & bracketing_nodes) const
82 : {
83 1860164 : dof_id_type new_node_id = DofObject::invalid_id;
84 :
85 44757166 : for (auto pair : bracketing_nodes)
86 : {
87 34485773 : const dof_id_type lower_id = std::min(pair.first, pair.second);
88 34485773 : const dof_id_type upper_id = std::max(pair.first, pair.second);
89 :
90 : const dof_id_type possible_new_node_id =
91 34485773 : this->find(lower_id, upper_id);
92 :
93 34485773 : if (possible_new_node_id != DofObject::invalid_id)
94 : {
95 : // If we found a node already, but we're still here, it's to
96 : // debug map consistency: we'd better always find the same
97 : // node
98 1730383 : if (new_node_id != DofObject::invalid_id)
99 378096 : libmesh_assert_equal_to (new_node_id, possible_new_node_id);
100 :
101 1730383 : new_node_id = possible_new_node_id;
102 : }
103 :
104 : // If we're not debugging map consistency then we can quit as
105 : // soon as we find a node
106 : #ifdef NDEBUG
107 1997240 : if (new_node_id != DofObject::invalid_id)
108 : break;
109 : #endif
110 : }
111 31969963 : return new_node_id;
112 : }
113 :
114 :
115 34485773 : dof_id_type TopologyMap::find(dof_id_type bracket_node1,
116 : dof_id_type bracket_node2) const
117 : {
118 34485773 : const dof_id_type lower_id = std::min(bracket_node1, bracket_node2);
119 34485773 : const dof_id_type upper_id = std::max(bracket_node1, bracket_node2);
120 :
121 34485773 : if (const auto it = _map.find(std::make_pair(lower_id, upper_id));
122 2377762 : it != _map.end())
123 : {
124 1730383 : libmesh_assert_not_equal_to (it->second, DofObject::invalid_id);
125 23428953 : return it->second;
126 : }
127 :
128 : // If not found, return invalid_id
129 647379 : return DofObject::invalid_id;
130 : }
131 :
132 :
133 :
134 : #ifdef LIBMESH_ENABLE_AMR
135 :
136 54499 : void TopologyMap::fill(const MeshBase & mesh)
137 : {
138 : // Populate the nodes map
139 30300932 : for (const auto & elem : mesh.element_ptr_range())
140 : {
141 : // We only need to add nodes which might be added during mesh
142 : // refinement; this means they need to be child nodes.
143 15925838 : if (!elem->has_children())
144 11366896 : continue;
145 :
146 23500923 : for (unsigned int c = 0, nc = elem->n_children(); c != nc; ++c)
147 : {
148 16040925 : const Elem * child = elem->child_ptr(c);
149 16040925 : if (child == remote_elem)
150 595317 : continue;
151 :
152 93579549 : for (unsigned int n = 0, nnic = elem->n_nodes_in_child(c); n != nnic; ++n)
153 : {
154 : const std::vector<std::pair<dof_id_type, dof_id_type>>
155 68027363 : bracketing_nodes = elem->bracketing_nodes(c,n);
156 :
157 64284317 : this->add_node(child->node_ref(n), bracketing_nodes);
158 : }
159 : }
160 50783 : }
161 54499 : }
162 :
163 : #else
164 :
165 : // no-op without AMR
166 : void TopologyMap::fill(const MeshBase &) {}
167 :
168 : #endif
169 :
170 :
171 :
172 : } // namespace libMesh
|