dune-grid  2.1.1
albertagrid/geometry.hh
Go to the documentation of this file.
00001 #ifndef DUNE_ALBERTA_GEOMETRY_HH
00002 #define DUNE_ALBERTA_GEOMETRY_HH
00003 
00004 #include <dune/grid/common/geometry.hh>
00005 
00006 #include <dune/grid/genericgeometry/geometry.hh>
00007 
00008 #include <dune/grid/albertagrid/misc.hh>
00009 #include <dune/grid/albertagrid/elementinfo.hh>
00010 
00011 #if HAVE_ALBERTA
00012 
00013 namespace Dune
00014 {
00015 
00016   // Forward Declarations
00017   // --------------------
00018 
00019   template< int dim, int dimworld >
00020   class AlbertaGrid;
00021 
00022 
00023 
00024   // AlbertaGridCoordinateReader
00025   // ---------------------------
00026 
00027   template< int codim, class GridImp >
00028   struct AlbertaGridCoordinateReader
00029   {
00030     typedef typename remove_const< GridImp >::type Grid;
00031 
00032     static const int dimension = Grid::dimension;
00033     static const int codimension = codim;
00034     static const int mydimension = dimension - codimension;
00035     static const int coorddimension = Grid::dimensionworld;
00036 
00037     typedef Alberta::Real ctype;
00038 
00039     typedef Alberta::ElementInfo< dimension > ElementInfo;
00040     typedef FieldVector< ctype, coorddimension > Coordinate;
00041 
00042     AlbertaGridCoordinateReader ( const GridImp &grid,
00043                                   const ElementInfo &elementInfo,
00044                                   int subEntity )
00045     : grid_( grid ),
00046       elementInfo_( elementInfo ),
00047       subEntity_( subEntity )
00048     {}
00049 
00050     const ElementInfo &elementInfo () const
00051     {
00052       return elementInfo_;
00053     }
00054 
00055     void coordinate ( int i, Coordinate &x ) const
00056     {
00057       assert( !elementInfo_ == false );
00058       assert( (i >= 0) && (i <= mydimension) );
00059 
00060       const int k = mapVertices( subEntity_, i );
00061       const Alberta::GlobalVector &coord = grid_.getCoord( elementInfo_, k );
00062       for( int j = 0; j < coorddimension; ++j )
00063         x[ j ] = coord[ j ];
00064     }
00065 
00066     bool hasDeterminant () const
00067     {
00068       return false;
00069     }
00070 
00071     ctype determinant () const
00072     {
00073       assert( hasDeterminant() );
00074       return ctype( 0 );
00075     }
00076 
00077   private:
00078     static int mapVertices ( int subEntity, int i )
00079     {
00080       return Alberta::MapVertices< dimension, codimension >::apply( subEntity, i );
00081     }
00082 
00083     const Grid &grid_;
00084     const ElementInfo &elementInfo_;
00085     const int subEntity_;
00086   };
00087 
00088 
00089 
00090   // AlbertaGridCoordStorage
00091   // -----------------------
00092 
00093   template< class CoordTraits, class Topology, unsigned int dimW >
00094   class AlbertaGridCornerStorage
00095   {
00096     typedef AlbertaGridCornerStorage< CoordTraits, Topology, dimW > This;
00097 
00098   public:
00099     static const unsigned int size = Topology::numCorners;
00100 
00101     static const unsigned int dimWorld = dimW;
00102 
00103     typedef typename CoordTraits::template Vector< dimWorld >::type
00104       GlobalCoordinate;
00105 
00106     template< class SubTopology >
00107     struct SubStorage
00108     {
00109       typedef AlbertaGridCornerStorage< CoordTraits, SubTopology, dimWorld > type;
00110     };
00111 
00112   private:
00113     GlobalCoordinate coords_[ size ];
00114 
00115   public:
00116     template< class CoordReader >
00117     explicit AlbertaGridCornerStorage ( const CoordReader &coordReader )
00118     {
00119       for( unsigned int i = 0; i < size; ++i )
00120         coordReader.coordinate( i, coords_[ i ] );
00121     }
00122 
00123     template< class Mapping, unsigned int codim >
00124     explicit AlbertaGridCornerStorage ( const GenericGeometry::SubMappingCoords< Mapping, codim > &coords )
00125     {
00126       for( unsigned int i = 0; i < size; ++i )
00127         coords_[ i ] = coords[ i ];
00128     }
00129 
00130     const GlobalCoordinate &operator[] ( unsigned int i ) const
00131     {
00132       return coords_[ i ];
00133     }
00134   };
00135 
00136 
00137 
00138   // template< int dim, int dimworld, int cdim >
00139   template <class GridImp,int cdim>
00140   struct AlbertaGridGeometryTraits
00141   {
00142     // typedef AlbertaGrid< dim, dimworld > Grid;
00143     typedef typename remove_const<GridImp>::type Grid;
00144 
00145     typedef GenericGeometry::DuneCoordTraits< Alberta::Real > CoordTraits;
00146 
00147     static const int dimGrid = Grid::dimension;
00148     static const int dimWorld = cdim;
00149 
00150     static const bool hybrid = false;
00151     static const unsigned int topologyId = GenericGeometry::SimplexTopology< dimGrid >::type::id;
00152 
00153     template< class Topology >
00154     struct Mapping
00155     {
00156       typedef AlbertaGridCornerStorage< CoordTraits, Topology, dimWorld > CornerStorage;
00157       typedef GenericGeometry::CornerMapping< CoordTraits, Topology, dimWorld, CornerStorage > type;
00158     };
00159 
00160     struct Caching
00161     {
00162       static const GenericGeometry::EvaluationType evaluateJacobianTransposed = GenericGeometry::ComputeOnDemand;
00163       static const GenericGeometry::EvaluationType evaluateJacobianInverseTransposed = GenericGeometry::ComputeOnDemand;
00164       static const GenericGeometry::EvaluationType evaluateIntegrationElement = GenericGeometry::ComputeOnDemand;
00165       static const GenericGeometry::EvaluationType evaluateNormal = GenericGeometry::ComputeOnDemand;
00166     };
00167 
00168   };
00169 
00170 
00171 
00172   // AlbertaGridGeometry
00173   // -------------------
00174 
00175 #if DUNE_ALBERTA_USE_GENERICGEOMETRY
00176   template< int mydim, int cdim, class GridImp >
00177   class AlbertaGridGeometry
00178   : public GenericGeometry::BasicGeometry
00179     < mydim, AlbertaGridGeometryTraits< GridImp, cdim > >
00180   { 
00181     typedef AlbertaGridGeometry< mydim, cdim, GridImp > This;
00182     typedef GenericGeometry::BasicGeometry
00183       < mydim, AlbertaGridGeometryTraits< GridImp, cdim > >
00184       Base;
00185 
00186     public:
00188     AlbertaGridGeometry ()
00189     : Base ()
00190     {}
00191 
00192     AlbertaGridGeometry ( const This &other )
00193     : Base ( other )
00194     {}
00195 
00196     template< class CoordReader >
00197     AlbertaGridGeometry ( const CoordReader &coordReader )
00198     : Base( GeometryType( GenericGeometry::SimplexTopology< mydim >::type::id, mydim ), coordReader )
00199     {}
00200 
00201     template< class CoordReader >
00202     void build ( const CoordReader &coordReader )
00203     {
00204       (*this) = AlbertaGridGeometry( coordReader );
00205     }
00206   };
00207 #endif // #if DUNE_ALBERTA_USE_GENERICGEOMETRY
00208 
00209 #if !DUNE_ALBERTA_USE_GENERICGEOMETRY
00210 
00222   template< int mydim, int cdim, class GridImp >
00223   class AlbertaGridGeometry
00224   { 
00225     typedef AlbertaGridGeometry< mydim, cdim, GridImp > This;
00226 
00227     // remember type of the grid
00228     typedef GridImp Grid;
00229 
00230     // dimension of barycentric coordinates
00231     static const int dimbary = mydim + 1;
00232 
00233   public:
00235     typedef Alberta::Real ctype;
00236 
00237     static const int dimension = Grid :: dimension;
00238     static const int mydimension = mydim;
00239     static const int codimension = dimension - mydimension;
00240     static const int coorddimension = cdim;
00241 
00242     typedef FieldVector< ctype, mydimension > LocalVector;
00243     typedef FieldVector< ctype, coorddimension > GlobalVector;
00244 
00245     typedef FieldMatrix< ctype, mydimension, coorddimension >
00246       JacobianTransposed;
00247     typedef FieldMatrix< ctype, coorddimension, mydimension >
00248       JacobianInverseTransposed;
00249 
00250   private:
00251     static const int numCorners = mydimension + 1;
00252 
00253     typedef FieldMatrix< ctype, numCorners, coorddimension > CoordMatrix;
00254 
00255   public:
00256     AlbertaGridGeometry ()
00257     {
00258       invalidate();
00259     }
00260 
00261     template< class CoordReader >
00262     AlbertaGridGeometry ( const CoordReader &coordReader )
00263     {
00264       build( coordReader );
00265     }
00266 
00268     GeometryType type () const
00269     {
00270       typedef typename GenericGeometry::SimplexTopology< mydimension >::type Topology;
00271       return GeometryType( Topology() );
00272     }
00273 
00275     bool affine () const { return true; }
00276 
00278     int corners () const
00279     {
00280       return numCorners;
00281     }
00282 
00284     GlobalVector corner ( const int i ) const
00285     {
00286       assert( (i >= 0) && (i < corners()) );
00287       return coord_[ i ];
00288     }
00289 
00291     GlobalVector center () const
00292     {
00293       return centroid_;
00294     }
00295 
00297     const GlobalVector &operator[] ( const int i ) const
00298     {
00299       assert( (i >= 0) && (i < corners()) );
00300       return coord_[ i ];
00301     }
00302 
00304     GlobalVector global ( const LocalVector &local ) const;
00305   
00307     LocalVector local ( const GlobalVector &global ) const;
00308 
00314     ctype integrationElement () const
00315     {
00316       assert( calcedDet_ );
00317       return elDet_;
00318     }
00319 
00321     ctype integrationElement ( const LocalVector &local ) const
00322     {
00323       return integrationElement();
00324     }
00325 
00327     ctype volume () const
00328     {
00329       return integrationElement() / ctype( Factorial< mydimension >::factorial );
00330     }
00331 
00337     const JacobianTransposed &jacobianTransposed () const;
00338 
00340     const JacobianTransposed &
00341     jacobianTransposed ( const LocalVector &local ) const
00342     {
00343       return jacobianTransposed();
00344     }
00345  
00351     const JacobianInverseTransposed &jacobianInverseTransposed () const;
00352 
00354     const JacobianInverseTransposed &
00355     jacobianInverseTransposed ( const LocalVector &local ) const
00356     {
00357       return jacobianInverseTransposed();
00358     }
00359 
00360     //***********************************************************************
00361     //  Methods that not belong to the Interface, but have to be public
00362     //***********************************************************************
00363 
00365     void invalidate ()
00366     {
00367       builtJT_ = false;
00368       builtJTInv_ = false;
00369       calcedDet_ = false;
00370     }
00371 
00373     template< class CoordReader >
00374     void build ( const CoordReader &coordReader );
00375 
00376     void print ( std::ostream &out ) const;
00377 
00378   private:
00379     // calculates the volume of the element 
00380     ctype elDeterminant () const
00381     {
00382       return std::abs( Alberta::determinant( jacobianTransposed() ) );
00383     }
00384 
00386     CoordMatrix coord_;
00387 
00389     GlobalVector centroid_;
00390 
00391     // storage for the transposed of the jacobian
00392     mutable JacobianTransposed jT_;
00393 
00394     // storage for the transposed inverse of the jacboian
00395     mutable JacobianInverseTransposed jTInv_;
00396 
00397     // has jT_ been computed, yet?
00398     mutable bool builtJT_;
00399     // has jTInv_ been computed, yet?
00400     mutable bool builtJTInv_;
00401 
00402     mutable bool calcedDet_; 
00403     mutable ctype elDet_; 
00404   };
00405 #endif // #if !DUNE_ALBERTA_USE_GENERICGEOMETRY
00406 
00407 
00408 
00409   // AlbertaGridGlobalGeometry
00410   // -------------------------
00411 
00412   template< int mydim, int cdim, class GridImp >
00413   class AlbertaGridGlobalGeometry
00414   : public AlbertaGridGeometry< mydim, cdim, GridImp >
00415   {
00416     typedef AlbertaGridGlobalGeometry< mydim, cdim, GridImp > This;
00417     typedef AlbertaGridGeometry< mydim, cdim, GridImp > Base;
00418 
00419   public:
00420     AlbertaGridGlobalGeometry ()
00421     : Base()
00422     {}
00423 
00424     template< class CoordReader >
00425     AlbertaGridGlobalGeometry ( const CoordReader &coordReader )
00426     : Base( coordReader )
00427     {}
00428   };
00429 
00430 
00431 #if !DUNE_ALBERTA_USE_GENERICGEOMETRY
00432 #if !DUNE_ALBERTA_CACHE_COORDINATES
00433   template< int dim, int cdim >
00434   class AlbertaGridGlobalGeometry< dim, cdim, const AlbertaGrid< dim, cdim > >
00435   { 
00436     typedef AlbertaGridGlobalGeometry< dim, cdim, const AlbertaGrid< dim, cdim > > This;
00437 
00438     // remember type of the grid
00439     typedef AlbertaGrid< dim, cdim > Grid;
00440 
00441     // dimension of barycentric coordinates
00442     static const int dimbary = dim + 1;
00443 
00444     typedef Alberta::ElementInfo< dim > ElementInfo;
00445 
00446   public:
00448     typedef Alberta::Real ctype;
00449 
00450     static const int dimension = Grid::dimension;
00451     static const int mydimension = dimension;
00452     static const int codimension = dimension - mydimension;
00453     static const int coorddimension = cdim;
00454 
00455     typedef FieldVector< ctype, mydimension > LocalVector;
00456     typedef FieldVector< ctype, coorddimension > GlobalVector;
00457 
00458     typedef FieldMatrix< ctype, mydimension, coorddimension >
00459       JacobianTransposed;
00460     typedef FieldMatrix< ctype, coorddimension, mydimension >
00461       JacobianInverseTransposed;
00462 
00463   private:
00464     static const int numCorners = mydimension + 1;
00465 
00466     typedef FieldMatrix< ctype, numCorners, coorddimension > CoordMatrix;
00467 
00468   public:
00469     AlbertaGridGlobalGeometry ()
00470     {
00471       invalidate();
00472     }
00473 
00474     template< class CoordReader >
00475     AlbertaGridGlobalGeometry ( const CoordReader &coordReader )
00476     {
00477       build( coordReader );
00478     }
00479 
00481     GeometryType type () const
00482     {
00483       typedef typename GenericGeometry::SimplexTopology< mydimension >::type Topology;
00484       return GeometryType( Topology() );
00485     }
00486 
00488     int corners () const
00489     {
00490       return numCorners;
00491     }
00492 
00494     GlobalVector corner ( const int i ) const
00495     {
00496       assert( (i >= 0) && (i < corners()) );
00497       const Alberta::GlobalVector &x = elementInfo_.coordinate( i );
00498       GlobalVector y;
00499       for( int j = 0; j < coorddimension; ++j )
00500         y[ j ] = x[ j ];
00501       return y;
00502     }
00503 
00505     const GlobalVector &operator[] ( const int i ) const
00506     {
00507       return reinterpret_cast< const GlobalVector & >( elementInfo_.coordinate( i ) );
00508     }
00509 
00511     GlobalVector center () const
00512     {
00513       GlobalVector centroid_ = corner( 0 );
00514       for( int i = 1; i < numCorners; ++i )
00515         centroid_ += corner( i );
00516       centroid_ *= ctype( 1 ) / ctype( numCorners );
00517       return centroid_;
00518     }
00519 
00521     GlobalVector global ( const LocalVector &local ) const;
00522   
00524     LocalVector local ( const GlobalVector &global ) const;
00525 
00531     ctype integrationElement () const
00532     {
00533       return elementInfo_.geometryCache().integrationElement();
00534     }
00535 
00537     ctype integrationElement ( const LocalVector &local ) const
00538     {
00539       return integrationElement();
00540     }
00541 
00543     ctype volume () const
00544     {
00545       return integrationElement() / ctype( Factorial< mydimension >::factorial );
00546     }
00547 
00553     const JacobianTransposed &jacobianTransposed () const
00554     {
00555       return elementInfo_.geometryCache().jacobianTransposed();
00556     }
00557 
00559     const JacobianTransposed &
00560     jacobianTransposed ( const LocalVector &local ) const
00561     {
00562       return jacobianTransposed();
00563     }
00564  
00570     const JacobianInverseTransposed &jacobianInverseTransposed () const
00571     {
00572       return elementInfo_.geometryCache().jacobianInverseTransposed();
00573     }
00574 
00576     const JacobianInverseTransposed &
00577     jacobianInverseTransposed ( const LocalVector &local ) const
00578     {
00579       return jacobianInverseTransposed();
00580     }
00581 
00582     //***********************************************************************
00583     //  Methods that not belong to the Interface, but have to be public
00584     //***********************************************************************
00585 
00587     void invalidate ()
00588     {
00589       elementInfo_ = ElementInfo(); 
00590     }
00591 
00593     template< class CoordReader >
00594     void build ( const CoordReader &coordReader )
00595     {
00596       elementInfo_ = coordReader.elementInfo();
00597     }
00598 
00599   private:
00600     ElementInfo elementInfo_;
00601   };
00602 #endif // #if !DUNE_ALBERTA_CACHE_COORDINATES
00603 #endif // #if !DUNE_ALBERTA_USE_GENERICGEOMETRY
00604 
00605 
00606 
00607   // AlbertaGridLocalGeometryProvider
00608   // --------------------------------
00609 
00610   template< class Grid >
00611   class AlbertaGridLocalGeometryProvider
00612   {
00613     typedef AlbertaGridLocalGeometryProvider< Grid > This;
00614 
00615   public:
00616     typedef typename Grid::ctype ctype;
00617     
00618     static const int dimension = Grid::dimension;
00619 
00620     template< int codim >
00621     struct Codim
00622     {
00623       typedef Geometry< dimension-codim, dimension, Grid, AlbertaGridGeometry >
00624         LocalGeometry;
00625     };
00626 
00627     typedef typename Codim< 0 >::LocalGeometry LocalElementGeometry;
00628     typedef typename Codim< 1 >::LocalGeometry LocalFaceGeometry;
00629 
00630     static const int numChildren = 2;
00631     static const int numFaces = dimension + 1;
00632 
00633     static const int minFaceTwist = Alberta::Twist< dimension, dimension-1 >::minTwist;
00634     static const int maxFaceTwist = Alberta::Twist< dimension, dimension-1 >::maxTwist;
00635     static const int numFaceTwists = maxFaceTwist - minFaceTwist + 1;
00636 
00637   private:
00638     struct GeoInFatherCoordReader;
00639     struct FaceCoordReader;
00640 
00641     AlbertaGridLocalGeometryProvider ()
00642     {
00643       buildGeometryInFather();
00644       buildFaceGeometry();
00645     }
00646 
00647     ~AlbertaGridLocalGeometryProvider ()
00648     {
00649       for( int child = 0; child < numChildren; ++child )
00650       {
00651         delete geometryInFather_[ child ][ 0 ];
00652         delete geometryInFather_[ child ][ 1 ];
00653       }
00654 
00655       for( int i = 0; i < numFaces; ++i )
00656       {
00657         for( int j = 0; j < numFaceTwists; ++j )
00658           delete faceGeometry_[ i ][ j ];
00659       }
00660     }
00661 
00662     void buildGeometryInFather();
00663     void buildFaceGeometry();
00664 
00665   public:
00666     const LocalElementGeometry &
00667     geometryInFather ( int child, const int orientation = 1 ) const
00668     {
00669       assert( (child >= 0) && (child < numChildren) );
00670       assert( (orientation == 1) || (orientation == -1) );
00671       return *geometryInFather_[ child ][ (orientation + 1) / 2 ];
00672     }
00673 
00674     const LocalFaceGeometry &
00675     faceGeometry ( int face, int twist = 0 ) const
00676     {
00677       assert( (face >= 0) && (face < numFaces) );
00678       assert( (twist >= minFaceTwist) && (twist <= maxFaceTwist) );
00679       return *faceGeometry_[ face ][ twist - minFaceTwist ];
00680     }
00681 
00682     static const This &instance ()
00683     {
00684       static This theInstance;
00685       return theInstance;
00686     }
00687 
00688   private:
00689     template< int codim >
00690     static int mapVertices ( int subEntity, int i )
00691     {
00692       return Alberta::MapVertices< dimension, codim >::apply( subEntity, i );
00693     }
00694 
00695     const LocalElementGeometry *geometryInFather_[ numChildren ][ 2 ];
00696     const LocalFaceGeometry *faceGeometry_[ numFaces ][ numFaceTwists ];
00697   };
00698 
00699 }
00700 
00701 #endif // #if HAVE_ALBERTA
00702 
00703 #endif // #ifndef DUNE_ALBERTA_GEOMETRY_HH