level.hh
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
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
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
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
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
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