topology_map.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 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.h"
26 #include "libmesh/remote_elem.h"
27 
28 // C++ Includes
29 #include <limits>
30 #include <utility>
31 
32 namespace libMesh
33 {
34 
36 {
37  // This function must be run on all processors at once
38  // for non-serial meshes
39  if (!mesh.is_serial())
40  libmesh_parallel_only(mesh.comm());
41 
42  LOG_SCOPE("init()", "TopologyMap");
43 
44  // Clear the old map
45  _map.clear();
46 
47  this->fill(mesh);
48 }
49 
50 
51 
52 void TopologyMap::add_node(const Node & mid_node,
53  const std::vector<std::pair<dof_id_type, dof_id_type>> & bracketing_nodes)
54 {
55  const dof_id_type mid_node_id = mid_node.id();
56 
57  libmesh_assert_not_equal_to(mid_node_id, DofObject::invalid_id);
58 
59  for (std::size_t i=0; i != bracketing_nodes.size(); ++i)
60  {
61  const dof_id_type id1 = bracketing_nodes[i].first;
62  const dof_id_type id2 = bracketing_nodes[i].second;
63  const dof_id_type lower_id = std::min(id1, id2);
64  const dof_id_type upper_id = std::max(id1, id2);
65 
66  // We should never be inserting inconsistent data
67 #ifndef NDEBUG
68  map_type::iterator it =
69  _map.find(std::make_pair(lower_id, upper_id));
70 
71  if (it != _map.end())
72  libmesh_assert_equal_to (it->second, mid_node_id);
73 #endif
74 
75  this->_map.insert(std::make_pair(std::make_pair(lower_id, upper_id),
76  mid_node_id));
77 
78  }
79 }
80 
81 
82 dof_id_type TopologyMap::find(const std::vector<std::pair<dof_id_type, dof_id_type>> & bracketing_nodes) const
83 {
84  dof_id_type new_node_id = DofObject::invalid_id;
85 
86  for (std::size_t i = 0; i != bracketing_nodes.size(); ++i)
87  {
88  const dof_id_type lower_id = std::min(bracketing_nodes[i].first,
89  bracketing_nodes[i].second);
90  const dof_id_type upper_id = std::max(bracketing_nodes[i].first,
91  bracketing_nodes[i].second);
92 
93  const dof_id_type possible_new_node_id =
94  this->find(lower_id, upper_id);
95 
96  if (possible_new_node_id != DofObject::invalid_id)
97  {
98  // If we found a node already, but we're still here, it's to
99  // debug map consistency: we'd better always find the same
100  // node
101  if (new_node_id != DofObject::invalid_id)
102  libmesh_assert_equal_to (new_node_id, possible_new_node_id);
103 
104  new_node_id = possible_new_node_id;
105  }
106 
107  // If we're not debugging map consistency then we can quit as
108  // soon as we find a node
109 #ifdef NDEBUG
110  if (new_node_id != DofObject::invalid_id)
111  break;
112 #endif
113  }
114  return new_node_id;
115 }
116 
117 
119  dof_id_type bracket_node2) const
120 {
121  const dof_id_type lower_id = std::min(bracket_node1, bracket_node2);
122  const dof_id_type upper_id = std::max(bracket_node1, bracket_node2);
123 
124  map_type::const_iterator it =
125  _map.find(std::make_pair(lower_id, upper_id));
126 
127  if (it == _map.end())
128  return DofObject::invalid_id;
129 
130  libmesh_assert_not_equal_to (it->second, DofObject::invalid_id);
131 
132  return it->second;
133 }
134 
135 
136 
137 #ifdef LIBMESH_ENABLE_AMR
138 
140 {
141  // Populate the nodes map
142  for (const auto & elem : mesh.element_ptr_range())
143  {
144  // We only need to add nodes which might be added during mesh
145  // refinement; this means they need to be child nodes.
146  if (!elem->has_children())
147  continue;
148 
149  for (unsigned int c = 0, nc = elem->n_children(); c != nc; ++c)
150  {
151  const Elem * child = elem->child_ptr(c);
152  if (child == remote_elem)
153  continue;
154 
155  for (unsigned int n = 0; n != elem->n_nodes_in_child(c); ++n)
156  {
157  const std::vector<std::pair<dof_id_type, dof_id_type>>
158  bracketing_nodes = elem->bracketing_nodes(c,n);
159 
160  this->add_node(child->node_ref(n), bracketing_nodes);
161  }
162  }
163  }
164 }
165 
166 #else
167 
168 // no-op without AMR
169 void TopologyMap::fill(const MeshBase &) {}
170 
171 #endif
172 
173 
174 
175 } // namespace libMesh
virtual const std::vector< std::pair< dof_id_type, dof_id_type > > bracketing_nodes(unsigned int c, unsigned int n) const
Definition: elem.C:2206
A geometric point in (x,y,z) space associated with a DOF.
Definition: node.h:52
dof_id_type find(dof_id_type bracket_node1, dof_id_type bracket_node2) const
Definition: topology_map.C:118
void add_node(const Node &mid_node, const std::vector< std::pair< dof_id_type, dof_id_type >> &bracketing_nodes)
Definition: topology_map.C:52
The base class for all geometric element types.
Definition: elem.h:100
MeshBase & mesh
void init(MeshBase &)
Definition: topology_map.C:35
void fill(const MeshBase &)
Definition: topology_map.C:139
long double max(long double a, double b)
Base class for Mesh.
Definition: mesh_base.h:77
const Node & node_ref(const unsigned int i) const
Definition: elem.h:1979
dof_id_type id() const
Definition: dof_object.h:655
static const dof_id_type invalid_id
Definition: dof_object.h:347
long double min(long double a, double b)
const Elem * child_ptr(unsigned int i) const
Definition: elem.h:2578
uint8_t dof_id_type
Definition: id_types.h:64
const RemoteElem * remote_elem
Definition: remote_elem.C:57