1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_PDELAB_COMMON_GLOBALDOFINDEX_HH
4 #define DUNE_PDELAB_COMMON_GLOBALDOFINDEX_HH
5 
6 #include <dune/pdelab/common/multiindex.hh>
7 
8 namespace Dune {
9 
10   namespace PDELab {
11 
12 
13     template<typename T, std::size_t tree_n, typename ID>
14     class GlobalDOFIndex
15     {
16 
17     public:
18 
19       //! The maximum possible depth of the MultiIndex.
20       static const std::size_t max_depth = tree_n;
21 
22       typedef ID EntityID;
23       typedef MultiIndex<T,max_depth> TreeIndex;
24 
25       typedef typename TreeIndex::size_type size_type;
26       typedef T value_type;
27 
28       class View
29       {
30 
31         friend class GlobalDOFIndex;
32 
33       public:
34 
35         static const std::size_t max_depth = tree_n;
36 
37         typedef ID EntityID;
38         typedef typename MultiIndex<T,tree_n>::View TreeIndex;
39 
entityID() const40         const EntityID& entityID() const
41         {
42           return _entity_id;
43         }
44 
treeIndex() const45         const TreeIndex& treeIndex() const
46         {
47           return _tree_index_view;
48         }
49 
back_popped() const50         View back_popped() const
51         {
52           return View(_entity_id,_tree_index_view.back_popped());
53         }
54 
operator <<(std::ostream & s,const View & di)55         friend std::ostream& operator<< (std::ostream& s, const View& di)
56         {
57           s << "(";
58 
59           s << di._entity_id;
60 
61           s << " | "
62             << di._tree_index_view
63             << ")";
64           return s;
65         }
66 
size() const67         std::size_t size() const
68         {
69           return _tree_index_view.size();
70         };
71 
72       private:
73 
View(const GlobalDOFIndex & dof_index)74         explicit View(const GlobalDOFIndex& dof_index)
75           : _entity_id(dof_index._entity_id)
76           , _tree_index_view(dof_index._tree_index.view())
77         {}
78 
View(const GlobalDOFIndex & dof_index,std::size_t size)79         View(const GlobalDOFIndex& dof_index, std::size_t size)
80           : _entity_id(dof_index._entity_id)
81           , _tree_index_view(dof_index._tree_index.view(size))
82         {}
83 
View(const EntityID & entity_id,const TreeIndex & tree_index)84         View(const EntityID& entity_id, const TreeIndex& tree_index)
85           : _entity_id(entity_id)
86           , _tree_index_view(tree_index)
87         {}
88 
89         const EntityID& _entity_id;
90         TreeIndex _tree_index_view;
91 
92       };
93 
94       //! Default constructor.
GlobalDOFIndex()95       GlobalDOFIndex()
96       {}
97 
GlobalDOFIndex(const EntityID & entity_id,const TreeIndex & tree_index)98       GlobalDOFIndex(const EntityID& entity_id, const TreeIndex& tree_index)
99         : _entity_id(entity_id)
100         , _tree_index(tree_index)
101       {}
102 
view() const103       View view() const
104       {
105         return View(*this);
106       }
107 
view(std::size_t size) const108       View view(std::size_t size) const
109       {
110         return View(*this,size);
111       }
112 
clear()113       void clear()
114       {
115         _entity_id = EntityID();
116         _tree_index.clear();
117       }
118 
119       //! Returns the index of the grid entity associated with the DOF.
entityID()120       EntityID& entityID()
121       {
122         return _entity_id;
123       }
124 
entityID() const125       const EntityID& entityID() const
126       {
127         return _entity_id;
128       }
129 
treeIndex()130       TreeIndex& treeIndex()
131       {
132         return _tree_index;
133       }
134 
treeIndex() const135       const TreeIndex& treeIndex() const
136       {
137         return _tree_index;
138       }
139 
140       //! Writes a pretty representation of the MultiIndex to the given std::ostream.
operator <<(std::ostream & s,const GlobalDOFIndex & di)141       friend std::ostream& operator<< (std::ostream& s, const GlobalDOFIndex& di)
142       {
143         s << "(";
144 
145         s << di._entity_id;
146 
147         s << " | "
148           << di._tree_index
149           << ")";
150         return s;
151       }
152 
153       //! Tests whether two MultiIndices are equal.
154       /**
155        * \note Only MultiIndices of identical max_depth are comparable
156        */
operator ==(const GlobalDOFIndex & r) const157       bool operator== (const GlobalDOFIndex& r) const
158       {
159         return
160           _entity_id == r._entity_id && _tree_index == r._tree_index;
161       }
162 
163       //! Tests whether two MultiIndices are not equal.
operator !=(const GlobalDOFIndex & r) const164       bool operator!= (const GlobalDOFIndex& r) const
165       {
166         return !(*this == r);
167       }
168 
169 
size() const170       std::size_t size() const
171       {
172         return _tree_index.size();
173       }
174 
175     private:
176 
177       EntityID _entity_id;
178       TreeIndex _tree_index;
179 
180     };
181 
182     template<typename T, std::size_t n, typename ID>
hash_value(const GlobalDOFIndex<T,n,ID> & di)183     inline std::size_t hash_value(const GlobalDOFIndex<T,n,ID>& di)
184     {
185       std::size_t seed = 0;
186       std::hash<ID> id_hasher;
187       hash_combine(seed,id_hasher(di.entityID()));
188       hash_range(seed,di.treeIndex().begin(),di.treeIndex().end());
189       return seed;
190     }
191 
192 
193 
194   } // namespace PDELab
195 } // namespace Dune
196 
197 DUNE_DEFINE_HASH(DUNE_HASH_TEMPLATE_ARGS(typename T, std::size_t n, typename ID),DUNE_HASH_TYPE(Dune::PDELab::GlobalDOFIndex<T,n,ID>))
198 
199 #endif // DUNE_PDELAB_COMMON_GLOBALDOFINDEX_HH
200