dune-grid  2.1.1
cachedcoordfunction.hh
Go to the documentation of this file.
00001 #ifndef DUNE_GEOGRID_CACHEDCOORDFUNCTION_HH
00002 #define DUNE_GEOGRID_CACHEDCOORDFUNCTION_HH
00003 
00004 #include <cassert>
00005 
00006 #include <dune/common/typetraits.hh>
00007 
00008 #include <dune/grid/common/gridenums.hh>
00009 
00010 #include <dune/grid/geometrygrid/capabilities.hh>
00011 #include <dune/grid/geometrygrid/coordfunction.hh>
00012 #include <dune/grid/utility/persistentcontainer.hh>
00013 
00014 namespace Dune
00015 {
00016 
00017   // Internal Forward Declarations
00018   // -----------------------------
00019 
00020   template< class HostGrid, class CoordFunction >
00021   class CachedCoordFunction;
00022 
00023 
00024 
00025   // GeoGrid::CoordCache
00026   // -------------------
00027 
00028   namespace GeoGrid
00029   {
00030 
00031     template< class HostGrid, class Coordinate >
00032     class CoordCache
00033     {
00034       typedef CoordCache< HostGrid, Coordinate > This;
00035 
00036       static const unsigned int dimension = HostGrid::dimension;
00037 
00038       typedef typename HostGrid::template Codim< dimension >::Entity Vertex;
00039 
00040       typedef PersistentContainer< HostGrid, Coordinate > DataCache;
00041 
00042     public:
00043       explicit CoordCache ( const HostGrid &hostGrid )
00044         : data_(hostGrid,dimension)
00045       {}
00046 
00047       template< class Entity >
00048       const Coordinate &operator() ( const Entity &entity, unsigned int corner ) const
00049       {
00050         return data_(entity,corner);
00051       }
00052 
00053       const Coordinate &operator() ( const Vertex &vertex, unsigned int corner ) const
00054       {
00055         assert( corner == 0 );
00056         return data_[ vertex ];
00057       }
00058  
00059       template< class Entity >
00060       Coordinate &operator() ( const Entity &entity, unsigned int corner )
00061       {
00062         return data_( entity,corner) ;
00063       }
00064 
00065       Coordinate &operator() ( const Vertex &vertex, unsigned int corner )
00066       {
00067         assert( corner == 0 );
00068         return data_[ vertex ];
00069       }
00070 
00071       void adapt ()
00072       {
00073         data_.update();
00074       }
00075 
00076     private:
00077       CoordCache ( const This & );
00078       This &operator= ( const This & );
00079 
00080       mutable DataCache data_;
00081     };
00082 
00083   }
00084 
00085 
00086 
00087   // CachedCoordFunction
00088   // -------------------
00089 
00090   template< class HostGrid, class CoordFunction >
00091   class CachedCoordFunction
00092   : public DiscreteCoordFunction
00093     < typename CoordFunction::ctype, CoordFunction::dimRange,
00094       CachedCoordFunction< HostGrid, CoordFunction > >
00095   {
00096     typedef CachedCoordFunction< HostGrid, CoordFunction > This;
00097     typedef DiscreteCoordFunction< typename CoordFunction::ctype, CoordFunction::dimRange, This >
00098       Base;
00099 
00100   public:
00101     typedef typename Base::RangeVector RangeVector;
00102 
00103   private:
00104     typedef GeoGrid::CoordCache< HostGrid, RangeVector > Cache;
00105 
00106     const HostGrid &hostGrid_;
00107     const CoordFunction &coordFunction_;
00108     Cache cache_;
00109 
00110   public:
00111     explicit
00112     CachedCoordFunction ( const HostGrid &hostGrid,
00113                           const CoordFunction &coordFunction = CoordFunction() )
00114     : hostGrid_( hostGrid ),
00115       coordFunction_( coordFunction ),
00116       cache_( hostGrid )
00117     {
00118       buildCache();
00119     }
00120 
00121     void adapt ()
00122     {
00123       cache_.adapt();
00124       buildCache();
00125     }
00126 
00127     inline void buildCache ();
00128 
00129     template< class HostEntity >
00130     inline void insertEntity ( const HostEntity &hostEntity );
00131 
00132     template< class HostEntity >
00133     void evaluate ( const HostEntity &hostEntity, unsigned int corner,
00134                     RangeVector &y ) const
00135     {
00136       y = cache_( hostEntity, corner );
00137 #ifndef NDEBUG
00138       RangeVector z;
00139       calculate( hostEntity.geometry(), corner, z );
00140       assert( ((y - z).two_norm() < 1e-6) );
00141 #endif
00142     }
00143 
00144     template< class HostGeometry >
00145     void calculate ( const HostGeometry &hostGeometry, unsigned int corner,
00146                      RangeVector &y ) const
00147     {
00148       coordFunction_.evaluate( hostGeometry.corner( corner ), y );
00149     }
00150   };
00151 
00152 
00153 
00154   template< class HostGrid, class CoordFunction >
00155   inline void CachedCoordFunction< HostGrid, CoordFunction >::buildCache ()
00156   {
00157     typedef typename HostGrid::template Codim< 0 >::Entity Element;
00158     typedef typename HostGrid::template Codim< 0 >::template Partition< All_Partition >::LevelIterator
00159       LevelIterator;
00160     typedef typename HostGrid::Traits::HierarchicIterator HierarchicIterator;
00161 
00162     const int maxLevel = hostGrid_.maxLevel();
00163     const LevelIterator macroEnd = hostGrid_.template lend< 0, All_Partition >( 0 );
00164     for( LevelIterator macroIt = hostGrid_.template lbegin< 0, All_Partition >( 0 );
00165          macroIt != macroEnd; ++macroIt )
00166     {
00167       const Element &macroElement = *macroIt;
00168       insertEntity( macroElement );
00169 
00170       const HierarchicIterator hEnd = macroElement.hend( maxLevel );
00171       for( HierarchicIterator hIt = macroElement.hbegin( maxLevel ); hIt != hEnd; ++hIt )
00172         insertEntity( *hIt );
00173     }
00174   }
00175 
00176 
00177   template< class HostGrid, class CoordFunction >
00178   template< class HostEntity >
00179   inline void CachedCoordFunction< HostGrid, CoordFunction >
00180     ::insertEntity ( const HostEntity &hostEntity )
00181   {
00182     typedef typename HostEntity::Geometry HostGeometry;
00183 
00184     const HostGeometry &hostGeo = hostEntity.geometry();
00185     const unsigned int numCorners = hostGeo.corners();
00186     for( unsigned int i = 0; i < numCorners; ++i )
00187       calculate( hostGeo, i, cache_( hostEntity, i ) );
00188   }
00189 
00190 }
00191 
00192 #endif // #ifndef DUNE_GEOGRID_CACHEDCOORDFUNCTION_HH