coordcache.hh

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     template< int dim >
00017     class CoordCache
00018     {
00019       typedef DofVectorPointer< GlobalVector > CoordVectorPointer;
00020       typedef Alberta::DofAccess< dim, dim > DofAccess;
00021 
00022       class LocalCaching;
00023       struct Interpolation;
00024 
00025     public:
00026       static const int dimension = dim;
00027 
00028       typedef Alberta::ElementInfo< dimension > ElementInfo;
00029       typedef Alberta::MeshPointer< dimension > MeshPointer;
00030       typedef HierarchyDofNumbering< dimension > DofNumbering;
00031 
00032     private:
00033       CoordVectorPointer coords_;
00034       DofAccess dofAccess_;
00035 
00036     public:
00037       GlobalVector &operator() ( const Element *element, int vertex ) const
00038       {
00039         assert( !(!coords_) );
00040         GlobalVector *array = (GlobalVector *)coords_;
00041         return array[ dofAccess_( element, vertex ) ];
00042       }
00043 
00044       GlobalVector &operator() ( const ElementInfo &elementInfo, int vertex ) const
00045       {
00046         return (*this)( elementInfo.el(), vertex );
00047       }
00048 
00049       void create ( const DofNumbering &dofNumbering )
00050       {
00051         MeshPointer mesh = dofNumbering.mesh();
00052         const DofSpace *dofSpace = dofNumbering.dofSpace( dimension );
00053         
00054         coords_.create( dofSpace, "Coordinate Cache" );
00055         LocalCaching localCaching( coords_ );
00056         mesh.hierarchicTraverse( localCaching, FillFlags< dimension >::coords );
00057         coords_.template setupInterpolation< Interpolation >();
00058         //((ALBERTA DOF_REAL_D_VEC *)coords_)->refine_interpol = &AlbertHelp::refineCoordsAndRefineCallBack< dimension  >;
00059 
00060         dofAccess_ = DofAccess( dofSpace );
00061       }
00062 
00063       void release ()
00064       {
00065         coords_.release();
00066       }
00067     };
00068 
00069 
00070 
00071     // CoordCache::LocalCaching
00072     // ------------------------
00073 
00074     template< int dim >
00075     class CoordCache< dim >::LocalCaching
00076     {
00077       CoordVectorPointer coords_;
00078       DofAccess dofAccess_;
00079 
00080     public:
00081       explicit LocalCaching ( const CoordVectorPointer &coords )
00082       : coords_( coords ),
00083         dofAccess_( coords.dofSpace() )
00084       {}
00085 
00086       void operator() ( const ElementInfo &elementInfo ) const
00087       {
00088         GlobalVector *array = (GlobalVector *)coords_;
00089         for( int i = 0; i < DofAccess::numSubEntities; ++i )
00090         {
00091           const GlobalVector &x = elementInfo.coordinate( i );
00092           GlobalVector &y = array[ dofAccess_( elementInfo.el(), i ) ];
00093           for( int i = 0; i < dimWorld; ++i )
00094             y[ i ] = x[ i ];
00095         }
00096       }
00097     };
00098 
00099 
00100 
00101     // CoordCache::Interpolation
00102     // -------------------------
00103 
00104     template< int dim >
00105     struct CoordCache< dim >::Interpolation
00106     {
00107       static const int dimension = dim;
00108 
00109       typedef Alberta::Patch< dimension > Patch;
00110 
00111       static void
00112       interpolateVector ( const CoordVectorPointer &dofVector, const Patch &patch )
00113       {
00114         DofAccess dofAccess( dofVector.dofSpace() );
00115         GlobalVector *array = (GlobalVector *)dofVector;
00116 
00117         // refinement edge is always between vertices 0 and 1
00118         const Element *element = patch[ 0 ];
00119         const GlobalVector &coord0 = array[ dofAccess( element, 0 ) ];
00120         const GlobalVector &coord1 = array[ dofAccess( element, 1 ) ];
00121 
00122         // new vertex is always the last one
00123         assert( element->child[ 0 ] != NULL );
00124         GlobalVector &newCoord = array[ dofAccess( element->child[ 0 ], dimension ) ];
00125 
00126         // new coordinate is the average of of old ones on the same edge
00127         for( int j = 0; j < dimWorld; ++j )
00128           newCoord[ j ] = 0.5 * (coord0[ j ] + coord1[ j ]);
00129       }
00130     };
00131 
00132   }
00133 
00134 }
00135 
00136 #endif // #if HAVE_ALBERTA
00137 
00138 #endif

Generated on Sun Nov 15 22:28:39 2009 for dune-grid by  doxygen 1.5.6