- Home
- About DUNE
- Download
- Documentation
- Community
- Development
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 private: 00048 DofVectorPointer level_; 00049 DofAccess dofAccess_; 00050 00051 public: 00052 Level operator() ( const Alberta::Element *element ) const 00053 { 00054 const Level *array = (Level *)level_; 00055 return array[ dofAccess_( element, 0 ) ] & levelMask; 00056 } 00057 00058 Level operator() ( const ElementInfo &elementInfo ) const 00059 { 00060 return (*this)( elementInfo.el() ); 00061 } 00062 00063 bool isNew ( const Alberta::Element *element ) const 00064 { 00065 const Level *array = (Level *)level_; 00066 return ((array[ dofAccess_( element, 0 ) ] & isNewFlag) != 0); 00067 } 00068 00069 bool isNew ( const ElementInfo &elementInfo ) const 00070 { 00071 return isNew( elementInfo.el() ); 00072 } 00073 00074 Level maxLevel () const 00075 { 00076 CalcMaxLevel calcFromCache; 00077 level_.forEach( calcFromCache ); 00078 #ifndef NDEBUG 00079 CalcMaxLevel calcFromGrid; 00080 mesh().leafTraverse( calcFromGrid, FillFlags::nothing ); 00081 assert( calcFromCache.maxLevel() == calcFromGrid.maxLevel() ); 00082 #endif 00083 return calcFromCache.maxLevel();; 00084 } 00085 00086 MeshPointer mesh () const 00087 { 00088 return MeshPointer( level_.dofSpace()->mesh ); 00089 } 00090 00091 void markAllOld () 00092 { 00093 ClearFlags< isNewFlag > clearIsNew; 00094 level_.forEach( clearIsNew ); 00095 } 00096 00097 void create ( const DofNumbering &dofNumbering ) 00098 { 00099 const Alberta::DofSpace *const dofSpace = dofNumbering.dofSpace( 0 ); 00100 dofAccess_ = DofAccess( dofSpace ); 00101 00102 level_.create( dofSpace, "Element level" ); 00103 assert( !(!level_) ); 00104 level_.template setupInterpolation< Interpolation >(); 00105 00106 SetLocal setLocal( level_ ); 00107 mesh().hierarchicTraverse( setLocal, FillFlags::nothing ); 00108 } 00109 00110 void release () 00111 { 00112 level_.release(); 00113 dofAccess_ = DofAccess(); 00114 } 00115 }; 00116 00117 00118 00119 // AlbertaGridLevelProvider::SetLocal 00120 // ---------------------------------- 00121 00122 template< int dim > 00123 class AlbertaGridLevelProvider< dim >::SetLocal 00124 { 00125 DofVectorPointer level_; 00126 DofAccess dofAccess_; 00127 00128 public: 00129 explicit SetLocal ( const DofVectorPointer &level ) 00130 : level_( level ), 00131 dofAccess_( level.dofSpace() ) 00132 {} 00133 00134 void operator() ( const Alberta::ElementInfo< dim > &elementInfo ) const 00135 { 00136 Level *const array = (Level *)level_; 00137 array[ dofAccess_( elementInfo, 0 ) ] = elementInfo.level(); 00138 } 00139 }; 00140 00141 00142 00143 // AlbertaGridLevelProvider::CalcMaxLevel 00144 // -------------------------------------- 00145 00146 template< int dim > 00147 class AlbertaGridLevelProvider< dim >::CalcMaxLevel 00148 { 00149 Level maxLevel_; 00150 00151 public: 00152 CalcMaxLevel () 00153 : maxLevel_( 0 ) 00154 {} 00155 00156 void operator() ( const Level &dof ) 00157 { 00158 maxLevel_ = std::max( maxLevel_, Level( dof & levelMask ) ); 00159 } 00160 00161 void operator() ( const Alberta::ElementInfo< dim > &elementInfo ) 00162 { 00163 maxLevel_ = std::max( maxLevel_, Level( elementInfo.level() ) ); 00164 } 00165 00166 Level maxLevel () const 00167 { 00168 return maxLevel_; 00169 } 00170 }; 00171 00172 00173 00174 // AlbertaGridLevelProvider::ClearFlags 00175 // ------------------------------------ 00176 00177 template< int dim > 00178 template< typename AlbertaGridLevelProvider< dim >::Level flags > 00179 struct AlbertaGridLevelProvider< dim >::ClearFlags 00180 { 00181 void operator() ( Level &dof ) const 00182 { 00183 dof &= ~flags; 00184 } 00185 }; 00186 00187 00188 00189 // AlbertaGridLevelProvider::Interpolation 00190 // --------------------------------------- 00191 00192 template< int dim > 00193 struct AlbertaGridLevelProvider< dim >::Interpolation 00194 { 00195 static const int dimension = dim; 00196 00197 typedef Alberta::Patch< dimension > Patch; 00198 00199 static void interpolateVector ( const DofVectorPointer &dofVector, 00200 const Patch &patch ) 00201 { 00202 const DofAccess dofAccess( dofVector.dofSpace() ); 00203 Level *array = (Level *)dofVector; 00204 00205 for( int i = 0; i < patch.count(); ++i ) 00206 { 00207 const Alberta::Element *const father = patch[ i ]; 00208 assert( (array[ dofAccess( father, 0 ) ] & levelMask) < levelMask ); 00209 const Level childLevel = (array[ dofAccess( father, 0 ) ] + 1) | isNewFlag; 00210 for( int i = 0; i < 2; ++i ) 00211 { 00212 const Alberta::Element *child = father->child[ i ]; 00213 array[ dofAccess( child, 0 ) ] = childLevel; 00214 } 00215 } 00216 } 00217 }; 00218 00219 } 00220 00221 #endif // #if HAVE_ALBERTA 00222 00223 #endif
Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].