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