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