dune-grid
2.1.1
|
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 ¯oElement = *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