dune-grid
2.2.0
|
00001 #ifndef DUNE_ALBERTA_LEVEL_HH 00002 #define DUNE_ALBERTA_LEVEL_HH 00003 00004 #include <cassert> 00005 #include <cstdlib> 00006 00007 #include <dune/grid/albertagrid/meshpointer.hh> 00008 #include <dune/grid/albertagrid/dofadmin.hh> 00009 #include <dune/grid/albertagrid/dofvector.hh> 00010 00011 #if HAVE_ALBERTA 00012 00013 namespace Dune 00014 { 00015 00016 // AlbertaGridLevelProvider 00017 // ------------------------ 00018 00019 template< int dim > 00020 class AlbertaGridLevelProvider 00021 { 00022 typedef AlbertaGridLevelProvider< dim > This; 00023 00024 typedef unsigned char Level; 00025 00026 typedef Alberta::DofVectorPointer< Level > DofVectorPointer; 00027 typedef Alberta::DofAccess< dim, 0 > DofAccess; 00028 00029 typedef Alberta::FillFlags< dim > FillFlags; 00030 00031 static const Level isNewFlag = (1 << 7); 00032 static const Level levelMask = (1 << 7) - 1; 00033 00034 struct SetLocal; 00035 struct CalcMaxLevel; 00036 00037 template< Level flags > 00038 struct ClearFlags; 00039 00040 struct Interpolation; 00041 00042 public: 00043 typedef Alberta::ElementInfo< dim > ElementInfo; 00044 typedef Alberta::MeshPointer< dim > MeshPointer; 00045 typedef Alberta::HierarchyDofNumbering< dim > DofNumbering; 00046 00047 Level operator() ( const Alberta::Element *element ) const 00048 { 00049 const Level *array = (Level *)level_; 00050 return array[ dofAccess_( element, 0 ) ] & levelMask; 00051 } 00052 00053 Level operator() ( const ElementInfo &elementInfo ) const 00054 { 00055 return (*this)( elementInfo.el() ); 00056 } 00057 00058 bool isNew ( const Alberta::Element *element ) const 00059 { 00060 const Level *array = (Level *)level_; 00061 return ((array[ dofAccess_( element, 0 ) ] & isNewFlag) != 0); 00062 } 00063 00064 bool isNew ( const ElementInfo &elementInfo ) const 00065 { 00066 return isNew( elementInfo.el() ); 00067 } 00068 00069 Level maxLevel () const 00070 { 00071 CalcMaxLevel calcFromCache; 00072 level_.forEach( calcFromCache ); 00073 #ifndef NDEBUG 00074 CalcMaxLevel calcFromGrid; 00075 mesh().leafTraverse( calcFromGrid, FillFlags::nothing ); 00076 assert( calcFromCache.maxLevel() == calcFromGrid.maxLevel() ); 00077 #endif 00078 return calcFromCache.maxLevel();; 00079 } 00080 00081 MeshPointer mesh () const 00082 { 00083 return MeshPointer( level_.dofSpace()->mesh ); 00084 } 00085 00086 void markAllOld () 00087 { 00088 ClearFlags< isNewFlag > clearIsNew; 00089 level_.forEach( clearIsNew ); 00090 } 00091 00092 void create ( const DofNumbering &dofNumbering ) 00093 { 00094 const Alberta::DofSpace *const dofSpace = dofNumbering.dofSpace( 0 ); 00095 dofAccess_ = DofAccess( dofSpace ); 00096 00097 level_.create( dofSpace, "Element level" ); 00098 assert( level_ ); 00099 level_.template setupInterpolation< Interpolation >(); 00100 00101 SetLocal setLocal( level_ ); 00102 mesh().hierarchicTraverse( setLocal, FillFlags::nothing ); 00103 } 00104 00105 void release () 00106 { 00107 level_.release(); 00108 dofAccess_ = DofAccess(); 00109 } 00110 00111 private: 00112 DofVectorPointer level_; 00113 DofAccess dofAccess_; 00114 }; 00115 00116 00117 00118 // AlbertaGridLevelProvider::SetLocal 00119 // ---------------------------------- 00120 00121 template< int dim > 00122 class AlbertaGridLevelProvider< dim >::SetLocal 00123 { 00124 DofVectorPointer level_; 00125 DofAccess dofAccess_; 00126 00127 public: 00128 explicit SetLocal ( const DofVectorPointer &level ) 00129 : level_( level ), 00130 dofAccess_( level.dofSpace() ) 00131 {} 00132 00133 void operator() ( const Alberta::ElementInfo< dim > &elementInfo ) const 00134 { 00135 Level *const array = (Level *)level_; 00136 array[ dofAccess_( elementInfo, 0 ) ] = elementInfo.level(); 00137 } 00138 }; 00139 00140 00141 00142 // AlbertaGridLevelProvider::CalcMaxLevel 00143 // -------------------------------------- 00144 00145 template< int dim > 00146 class AlbertaGridLevelProvider< dim >::CalcMaxLevel 00147 { 00148 Level maxLevel_; 00149 00150 public: 00151 CalcMaxLevel () 00152 : maxLevel_( 0 ) 00153 {} 00154 00155 void operator() ( const Level &dof ) 00156 { 00157 maxLevel_ = std::max( maxLevel_, Level( dof & levelMask ) ); 00158 } 00159 00160 void operator() ( const Alberta::ElementInfo< dim > &elementInfo ) 00161 { 00162 maxLevel_ = std::max( maxLevel_, Level( elementInfo.level() ) ); 00163 } 00164 00165 Level maxLevel () const 00166 { 00167 return maxLevel_; 00168 } 00169 }; 00170 00171 00172 00173 // AlbertaGridLevelProvider::ClearFlags 00174 // ------------------------------------ 00175 00176 template< int dim > 00177 template< typename AlbertaGridLevelProvider< dim >::Level flags > 00178 struct AlbertaGridLevelProvider< dim >::ClearFlags 00179 { 00180 void operator() ( Level &dof ) const 00181 { 00182 dof &= ~flags; 00183 } 00184 }; 00185 00186 00187 00188 // AlbertaGridLevelProvider::Interpolation 00189 // --------------------------------------- 00190 00191 template< int dim > 00192 struct AlbertaGridLevelProvider< dim >::Interpolation 00193 { 00194 static const int dimension = dim; 00195 00196 typedef Alberta::Patch< dimension > Patch; 00197 00198 static void interpolateVector ( const DofVectorPointer &dofVector, 00199 const Patch &patch ) 00200 { 00201 const DofAccess dofAccess( dofVector.dofSpace() ); 00202 Level *array = (Level *)dofVector; 00203 00204 for( int i = 0; i < patch.count(); ++i ) 00205 { 00206 const Alberta::Element *const father = patch[ i ]; 00207 assert( (array[ dofAccess( father, 0 ) ] & levelMask) < levelMask ); 00208 const Level childLevel = (array[ dofAccess( father, 0 ) ] + 1) | isNewFlag; 00209 for( int i = 0; i < 2; ++i ) 00210 { 00211 const Alberta::Element *child = father->child[ i ]; 00212 array[ dofAccess( child, 0 ) ] = childLevel; 00213 } 00214 } 00215 } 00216 }; 00217 00218 } 00219 00220 #endif // #if HAVE_ALBERTA 00221 00222 #endif