phdMesh  Version of the Day
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Groups
OctTree.hpp
1 /*------------------------------------------------------------------------*/
2 /* phdMesh : Parallel Heterogneous Dynamic unstructured Mesh */
3 /* Copyright (2007) Sandia Corporation */
4 /* */
5 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */
6 /* license for use of this work by or on behalf of the U.S. Government. */
7 /* */
8 /* This library is free software; you can redistribute it and/or modify */
9 /* it under the terms of the GNU Lesser General Public License as */
10 /* published by the Free Software Foundation; either version 2.1 of the */
11 /* License, or (at your option) any later version. */
12 /* */
13 /* This library is distributed in the hope that it will be useful, */
14 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
15 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
16 /* Lesser General Public License for more details. */
17 /* */
18 /* You should have received a copy of the GNU Lesser General Public */
19 /* License along with this library; if not, write to the Free Software */
20 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 */
21 /* USA */
22 /*------------------------------------------------------------------------*/
28 #ifndef pddgeom_OctTree_hpp
29 #define pddgeom_OctTree_hpp
30 
31 #include <limits>
32 #include <iosfwd>
33 #include <util/Basics.hpp>
34 #include <util/SimpleArrayOps.hpp>
35 
36 namespace phdmesh {
37 
38 class OctTreeKey ;
39 
40 }
41 
42 namespace std {
43 
44 ostream & operator << ( ostream & , const phdmesh::OctTreeKey & );
45 
46 }
47 
48 namespace phdmesh {
49 
50 class OctTreeKey {
51 public:
52  typedef unsigned value_type ;
53  enum { MaxDepth = 16 };
54  enum { MaskIndex = 0x0f };
55  enum { BitsPerIndex = 4 };
56  enum { BitsPerWord = std::numeric_limits<value_type>::digits };
57  enum { IndexPerWord = BitsPerWord / BitsPerIndex };
58  enum { NWord = MaxDepth / IndexPerWord };
59  enum { OKBits = StaticAssert< 0 == BitsPerWord % BitsPerIndex >::OK };
60  enum { OKWord = StaticAssert< 0 == MaxDepth % IndexPerWord >::OK };
61 private:
62  value_type m_value[ NWord ];
63 public:
64 
65  OctTreeKey()
66  { Copy<NWord>( m_value , 0u ); }
67 
68  OctTreeKey( const OctTreeKey & k )
69  { Copy<NWord>( m_value , k.m_value ); }
70 
71  OctTreeKey & operator = ( const OctTreeKey & k )
72  { Copy<NWord>( m_value , k.m_value ); return *this ; }
73 
74  bool operator == ( const OctTreeKey & k ) const
75  { return Equal<NWord>( m_value , k.m_value ); }
76 
77  bool operator != ( const OctTreeKey & k ) const
78  { return Equal<NWord>( m_value , k.m_value ); }
79 
80  bool operator < ( const OctTreeKey & k ) const
81  { return Less<NWord>( m_value , k.m_value ); }
82 
84  unsigned depth() const ;
85 
89  template<unsigned Depth> unsigned index() const ;
90 
92  unsigned index( const unsigned Depth ) const ;
93 
95  template<unsigned D> OctTreeKey & clear_index() ;
96 
98  OctTreeKey & clear_index( const unsigned Depth );
99 
101  template<unsigned D> OctTreeKey & set_index( const unsigned );
102 
104  OctTreeKey & set_index( const unsigned Depth , const unsigned );
105 
107  OctTreeKey & clear();
108 
110  OctTreeKey & set_maximum();
111 
113  const value_type * value() const { return m_value ; }
114 
116  OctTreeKey & set_value( const value_type * );
117 
119  bool intersect( const OctTreeKey & k ) const ;
120 
121 private:
122  void throw_depth( const unsigned ) const ;
123  void throw_index( const unsigned , const unsigned ) const ;
124 };
125 
126 //----------------------------------------------------------------------
127 
130 OctTreeKey hsfc3d( const unsigned Depth , const unsigned * const coord );
131 
132 //----------------------------------------------------------------------
133 //----------------------------------------------------------------------
134 
135 template<unsigned Depth> struct OctTreeSize ;
136 
137 template<>
138 struct OctTreeSize<0>
139 { enum { value = 1 }; };
140 
141 template<unsigned Depth>
142 struct OctTreeSize
143 {
144  enum { MaxDepth = 10 , N = Depth }; // Size representable by an unsigned int
145 
146  enum { OK = StaticAssert< N <= MaxDepth >::OK };
147 
148  enum { value = 1 + 8 * OctTreeSize<Depth-1>::value };
149 };
150 
151 unsigned oct_tree_size( const unsigned Depth );
152 
154 unsigned oct_tree_offset( const unsigned Depth , const OctTreeKey & );
155 
156 template<unsigned Depth>
157 inline
158 unsigned oct_tree_offset( const OctTreeKey & k )
159 { return oct_tree_offset( Depth , k ); }
160 
161 }
162 
163 //----------------------------------------------------------------------
164 //----------------------------------------------------------------------
165 
166 namespace phdmesh {
167 
168 template<unsigned Depth>
169 inline
170 unsigned OctTreeKey::index() const
171 {
172  enum { OK = StaticAssert< 0 < Depth && Depth <= MaxDepth >::OK };
173  enum { which = ( Depth - 1 ) / IndexPerWord };
174  enum { shift = BitsPerWord - BitsPerIndex * ( Depth % IndexPerWord ) };
175 
176  return ( m_value[ which ] >> shift ) & MaskIndex ;
177 }
178 
179 template<unsigned Depth>
180 inline
181 OctTreeKey & OctTreeKey::clear_index()
182 {
183  enum { OK = StaticAssert< 0 < Depth && Depth <= MaxDepth >::OK };
184  enum { which = ( Depth - 1 ) / IndexPerWord };
185  enum { shift = BitsPerWord - BitsPerIndex * ( Depth % IndexPerWord ) };
186 
187  const value_type m = MaskIndex ;
188 
189  m_value[ which ] &= ~( m << shift );
190 
191  return *this ;
192 }
193 
194 template<unsigned Depth>
195 inline
196 OctTreeKey & OctTreeKey::set_index( const unsigned Index )
197 {
198  enum { OK = StaticAssert< 0 < Depth && Depth <= MaxDepth >::OK };
199  enum { which = ( Depth - 1 ) / IndexPerWord };
200  enum { shift = BitsPerWord - BitsPerIndex * ( Depth % IndexPerWord ) };
201 
202  if ( 8 < Index ) { throw_index( Depth , Index ); }
203 
204  const value_type m = MaskIndex ;
205 
206  ( m_value[which] &= ~( m << shift ) ) |= Index << shift ;
207 
208  return *this ;
209 }
210 
211 }
212 
213 #endif
214 
OctTreeKey hsfc3d(const unsigned Depth, const unsigned *const coord)
unsigned oct_tree_offset(const unsigned Depth, const OctTreeKey &)