phdMesh Version of the Day
OctTree.hpp
00001 /*------------------------------------------------------------------------*/
00002 /*      phdMesh : Parallel Heterogneous Dynamic unstructured Mesh         */
00003 /*                Copyright (2007) Sandia Corporation                     */
00004 /*                                                                        */
00005 /*  Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive   */
00006 /*  license for use of this work by or on behalf of the U.S. Government.  */
00007 /*                                                                        */
00008 /*  This library is free software; you can redistribute it and/or modify  */
00009 /*  it under the terms of the GNU Lesser General Public License as        */
00010 /*  published by the Free Software Foundation; either version 2.1 of the  */
00011 /*  License, or (at your option) any later version.                       */
00012 /*                                                                        */
00013 /*  This library is distributed in the hope that it will be useful,       */
00014 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of        */
00015 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     */
00016 /*  Lesser General Public License for more details.                       */
00017 /*                                                                        */
00018 /*  You should have received a copy of the GNU Lesser General Public      */
00019 /*  License along with this library; if not, write to the Free Software   */
00020 /*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307   */
00021 /*  USA                                                                   */
00022 /*------------------------------------------------------------------------*/
00028 #ifndef pddgeom_OctTree_hpp
00029 #define pddgeom_OctTree_hpp
00030 
00031 #include <limits>
00032 #include <iosfwd>
00033 #include <util/Basics.hpp>
00034 #include <util/SimpleArrayOps.hpp>
00035 
00036 namespace phdmesh {
00037 
00038 class OctTreeKey ;
00039 
00040 }
00041 
00042 namespace std {
00043 
00044 ostream & operator << ( ostream & , const phdmesh::OctTreeKey & );
00045 
00046 }
00047 
00048 namespace phdmesh {
00049 
00050 class OctTreeKey {
00051 public:
00052   typedef unsigned value_type ;
00053   enum { MaxDepth     = 16 };
00054   enum { MaskIndex    = 0x0f };
00055   enum { BitsPerIndex = 4 };
00056   enum { BitsPerWord  = std::numeric_limits<value_type>::digits };
00057   enum { IndexPerWord = BitsPerWord / BitsPerIndex };
00058   enum { NWord        = MaxDepth / IndexPerWord };
00059   enum { OKBits = StaticAssert< 0 == BitsPerWord % BitsPerIndex >::OK };
00060   enum { OKWord = StaticAssert< 0 == MaxDepth    % IndexPerWord >::OK };
00061 private:
00062   value_type m_value[ NWord ];
00063 public:
00064 
00065   OctTreeKey()
00066     { Copy<NWord>( m_value , 0u ); }
00067 
00068   OctTreeKey( const OctTreeKey & k )
00069     { Copy<NWord>( m_value , k.m_value ); }
00070 
00071   OctTreeKey & operator = ( const OctTreeKey & k )
00072     { Copy<NWord>( m_value , k.m_value ); return *this ; }
00073 
00074   bool operator == ( const OctTreeKey & k ) const
00075     { return Equal<NWord>( m_value , k.m_value ); }
00076 
00077   bool operator != ( const OctTreeKey & k ) const
00078     { return Equal<NWord>( m_value , k.m_value ); }
00079 
00080   bool operator < ( const OctTreeKey & k ) const
00081     { return Less<NWord>( m_value , k.m_value ); }
00082 
00084   unsigned depth() const ;
00085 
00089   template<unsigned Depth> unsigned index() const ;
00090 
00092   unsigned index( const unsigned Depth ) const ;
00093 
00095   template<unsigned D> OctTreeKey & clear_index() ;
00096 
00098   OctTreeKey & clear_index( const unsigned Depth );
00099 
00101   template<unsigned D> OctTreeKey & set_index( const unsigned );
00102 
00104   OctTreeKey & set_index( const unsigned Depth , const unsigned );
00105 
00107   OctTreeKey & clear();
00108 
00110   OctTreeKey & set_maximum();
00111 
00113   const value_type * value() const { return m_value ; }
00114 
00116   OctTreeKey & set_value( const value_type * );
00117 
00119   bool intersect( const OctTreeKey & k ) const ;
00120 
00121 private:
00122   void throw_depth( const unsigned ) const ;
00123   void throw_index( const unsigned , const unsigned ) const ;
00124 };
00125 
00126 //----------------------------------------------------------------------
00127 
00130 OctTreeKey hsfc3d( const unsigned Depth , const unsigned * const coord );
00131 
00132 //----------------------------------------------------------------------
00133 //----------------------------------------------------------------------
00134 
00135 template<unsigned Depth> struct OctTreeSize ;
00136 
00137 template<>
00138 struct OctTreeSize<0>
00139 { enum { value = 1 }; };
00140 
00141 template<unsigned Depth>
00142 struct OctTreeSize
00143 {
00144   enum { MaxDepth = 10 , N = Depth }; // Size representable by an unsigned int
00145 
00146   enum { OK = StaticAssert< N <= MaxDepth >::OK };
00147 
00148   enum { value = 1 + 8 * OctTreeSize<Depth-1>::value };
00149 };
00150 
00151 unsigned oct_tree_size( const unsigned Depth );
00152 
00154 unsigned oct_tree_offset( const unsigned Depth , const OctTreeKey & );
00155 
00156 template<unsigned Depth>
00157 inline
00158 unsigned oct_tree_offset( const OctTreeKey & k )
00159 { return oct_tree_offset( Depth , k ); }
00160 
00161 }
00162 
00163 //----------------------------------------------------------------------
00164 //----------------------------------------------------------------------
00165 
00166 namespace phdmesh {
00167 
00168 template<unsigned Depth>
00169 inline
00170 unsigned OctTreeKey::index() const
00171 {
00172   enum { OK = StaticAssert< 0 < Depth && Depth <= MaxDepth >::OK };
00173   enum { which = ( Depth - 1 ) / IndexPerWord };
00174   enum { shift = BitsPerWord - BitsPerIndex * ( Depth % IndexPerWord ) };
00175 
00176   return ( m_value[ which ] >> shift ) & MaskIndex ;
00177 }
00178 
00179 template<unsigned Depth>
00180 inline
00181 OctTreeKey & OctTreeKey::clear_index()
00182 {
00183   enum { OK = StaticAssert< 0 < Depth && Depth <= MaxDepth >::OK };
00184   enum { which = ( Depth - 1 ) / IndexPerWord };
00185   enum { shift = BitsPerWord - BitsPerIndex * ( Depth % IndexPerWord ) };
00186 
00187   const value_type m = MaskIndex ;
00188 
00189   m_value[ which ] &= ~( m << shift );
00190 
00191   return *this ;
00192 }
00193 
00194 template<unsigned Depth>
00195 inline
00196 OctTreeKey & OctTreeKey::set_index( const unsigned Index )
00197 {
00198   enum { OK = StaticAssert< 0 < Depth && Depth <= MaxDepth >::OK };
00199   enum { which = ( Depth - 1 ) / IndexPerWord };
00200   enum { shift = BitsPerWord - BitsPerIndex * ( Depth % IndexPerWord ) };
00201 
00202   if ( 8 < Index ) { throw_index( Depth , Index ); }
00203 
00204   const value_type m = MaskIndex ;
00205 
00206   ( m_value[which] &= ~( m << shift ) ) |= Index << shift ;
00207 
00208   return *this ;
00209 }
00210 
00211 }
00212 
00213 #endif
00214 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator