1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2020 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_TOPOLOGY_MAP_H
21 #define LIBMESH_TOPOLOGY_MAP_H
22 
23 // Local Includes
24 #include "libmesh/libmesh_config.h"
25 #include "libmesh/libmesh_common.h"
26 
27 // C++ Includes
28 #include <unordered_map>
29 #include <functional> // std::hash
30 #include <vector>
31 
32 namespace libMesh
33 {
34 
35 // Forward Declarations
36 class Elem;
37 class MeshBase;
38 class Node;
39 
40 // Fix for STL laziness
41 struct myhash {
42 public:
43   template <typename T1, typename T2>
operatormyhash44   std::size_t operator()(const std::pair<T1, T2> & x) const
45   {
46     // recommendation from
47     // http://stackoverflow.com/questions/5889238/why-is-xor-the-default-way-to-combine-hashes
48     return 3 * std::hash<T1>()(x.first) + std::hash<T2>()(x.second);
49   }
50 };
51 
52 /**
53  * Data structures that enable topology-based lookups of nodes created
54  * by mesh refinement.
55  *
56  * The key is a pair of node ids for two nodes bracketing the new
57  * node, sorted lowest id first.
58  *
59  * A node created in the middle of a cell's quad face will be the
60  * value of two keys, one for each node pair bracketing it.
61  *
62  * For efficiency we will use a hashed map if it is available,
63  * otherwise a regular map.
64  *
65  * \author Roy Stogner
66  * \date 2015
67  * \brief Enables topology-based lookups of nodes.
68  */
69 class TopologyMap
70 {
71   // We need to supply our own hash function.
72   typedef std::unordered_map<std::pair<dof_id_type, dof_id_type>, dof_id_type, myhash> map_type;
73 public:
74   void init(MeshBase &);
75 
clear()76   void clear() { _map.clear(); }
77 
78   /**
79    * Add a node to the map, between each pair of specified bracketing
80    * nodes.
81    */
82   void add_node(const Node & mid_node,
83                 const std::vector<
84                 std::pair<dof_id_type, dof_id_type>> &
85                 bracketing_nodes);
86 
empty()87   bool empty() const { return _map.empty(); }
88 
89   dof_id_type find(dof_id_type bracket_node1,
90                    dof_id_type bracket_node2) const;
91 
92   dof_id_type find(const std::vector<
93                    std::pair<dof_id_type, dof_id_type>> &
94                    bracketing_nodes) const;
95 
96 protected:
97   void fill(const MeshBase &);
98 
99 private:
100   map_type          _map;
101 };
102 
103 } // namespace libMesh
104 
105 
106 #endif // LIBMESH_TOPOLOGY_MAP_H
107