- Home
- About DUNE
- Download
- Documentation
- Community
- Development
00001 #ifndef DUNE_ALBERTA_COORDCACHE_HH 00002 #define DUNE_ALBERTA_COORDCACHE_HH 00003 00004 #include <dune/grid/albertagrid/meshpointer.hh> 00005 #include <dune/grid/albertagrid/dofadmin.hh> 00006 #include <dune/grid/albertagrid/dofvector.hh> 00007 00008 #if HAVE_ALBERTA 00009 00010 namespace Dune 00011 { 00012 00013 namespace Alberta 00014 { 00015 00016 // CoordCache 00017 // ---------- 00018 00019 template< int dim > 00020 class CoordCache 00021 { 00022 typedef DofVectorPointer< GlobalVector > CoordVectorPointer; 00023 typedef Alberta::DofAccess< dim, dim > DofAccess; 00024 00025 class LocalCaching; 00026 struct Interpolation; 00027 00028 public: 00029 static const int dimension = dim; 00030 00031 typedef Alberta::ElementInfo< dimension > ElementInfo; 00032 typedef Alberta::MeshPointer< dimension > MeshPointer; 00033 typedef HierarchyDofNumbering< dimension > DofNumbering; 00034 00035 GlobalVector &operator() ( const Element *element, int vertex ) const 00036 { 00037 assert( !(!coords_) ); 00038 GlobalVector *array = (GlobalVector *)coords_; 00039 return array[ dofAccess_( element, vertex ) ]; 00040 } 00041 00042 GlobalVector &operator() ( const ElementInfo &elementInfo, int vertex ) const 00043 { 00044 return (*this)( elementInfo.el(), vertex ); 00045 } 00046 00047 void create ( const DofNumbering &dofNumbering ) 00048 { 00049 MeshPointer mesh = dofNumbering.mesh(); 00050 const DofSpace *dofSpace = dofNumbering.dofSpace( dimension ); 00051 00052 coords_.create( dofSpace, "Coordinate Cache" ); 00053 LocalCaching localCaching( coords_ ); 00054 mesh.hierarchicTraverse( localCaching, FillFlags< dimension >::coords ); 00055 coords_.template setupInterpolation< Interpolation >(); 00056 00057 dofAccess_ = DofAccess( dofSpace ); 00058 } 00059 00060 void release () 00061 { 00062 coords_.release(); 00063 } 00064 00065 private: 00066 CoordVectorPointer coords_; 00067 DofAccess dofAccess_; 00068 }; 00069 00070 00071 00072 // CoordCache::LocalCaching 00073 // ------------------------ 00074 00075 template< int dim > 00076 class CoordCache< dim >::LocalCaching 00077 { 00078 CoordVectorPointer coords_; 00079 DofAccess dofAccess_; 00080 00081 public: 00082 explicit LocalCaching ( const CoordVectorPointer &coords ) 00083 : coords_( coords ), 00084 dofAccess_( coords.dofSpace() ) 00085 {} 00086 00087 void operator() ( const ElementInfo &elementInfo ) const 00088 { 00089 GlobalVector *array = (GlobalVector *)coords_; 00090 for( int i = 0; i < DofAccess::numSubEntities; ++i ) 00091 { 00092 const GlobalVector &x = elementInfo.coordinate( i ); 00093 GlobalVector &y = array[ dofAccess_( elementInfo.el(), i ) ]; 00094 for( int i = 0; i < dimWorld; ++i ) 00095 y[ i ] = x[ i ]; 00096 } 00097 } 00098 }; 00099 00100 00101 00102 // CoordCache::Interpolation 00103 // ------------------------- 00104 00105 template< int dim > 00106 struct CoordCache< dim >::Interpolation 00107 { 00108 static const int dimension = dim; 00109 00110 typedef Alberta::Patch< dimension > Patch; 00111 00112 static void 00113 interpolateVector ( const CoordVectorPointer &dofVector, const Patch &patch ) 00114 { 00115 DofAccess dofAccess( dofVector.dofSpace() ); 00116 GlobalVector *array = (GlobalVector *)dofVector; 00117 00118 const Element *element = patch[ 0 ]; 00119 00120 // new vertex is always the last one 00121 assert( element->child[ 0 ] != NULL ); 00122 GlobalVector &newCoord = array[ dofAccess( element->child[ 0 ], dimension ) ]; 00123 00124 if( element->new_coord != NULL ) 00125 { 00126 for( int j = 0; j < dimWorld; ++j ) 00127 newCoord[ j ] = element->new_coord[ j ]; 00128 } 00129 else 00130 { 00131 // new coordinate is the average of of old ones on the same edge 00132 // refinement edge is always between vertices 0 and 1 00133 const GlobalVector &coord0 = array[ dofAccess( element, 0 ) ]; 00134 const GlobalVector &coord1 = array[ dofAccess( element, 1 ) ]; 00135 for( int j = 0; j < dimWorld; ++j ) 00136 newCoord[ j ] = 0.5 * (coord0[ j ] + coord1[ j ]); 00137 } 00138 } 00139 }; 00140 00141 } 00142 00143 } 00144 00145 #endif // #if HAVE_ALBERTA 00146 00147 #endif // #ifndef DUNE_ALBERTA_COORDCACHE_HH
Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].