dune-grid  2.2.0
level.hh
Go to the documentation of this file.
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