00001 #ifndef DUNE_ALBERTA_GEOMETRY
00002 #define DUNE_ALBERTA_GEOMETRY
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 #include <dune/grid/albertagrid/referencetopo.hh>
00011
00012
00013 #define USE_GENERICGEOMETRY 0
00014
00015 namespace Dune
00016 {
00017
00018
00019
00020
00021 template< int dim, int dimworld >
00022 class AlbertaGrid;
00023
00024
00025
00026
00027
00028
00029 template< int codim, class GridImp >
00030 struct AlbertaGridCoordinateReader
00031 {
00032 typedef typename remove_const< GridImp >::type Grid;
00033
00034 static const int dimension = Grid::dimension;
00035 static const int codimension = codim;
00036 static const int mydimension = dimension - codimension;
00037 static const int coorddimension = Grid::dimensionworld;
00038
00039 typedef Alberta::Real ctype;
00040
00041 typedef Alberta::ElementInfo< dimension > ElementInfo;
00042 typedef FieldVector< ctype, coorddimension > Coordinate;
00043
00044 private:
00045 const Grid &grid_;
00046 const ElementInfo &elementInfo_;
00047 const int subEntity_;
00048
00049 public:
00050 AlbertaGridCoordinateReader ( const GridImp &grid,
00051 const ElementInfo &elementInfo,
00052 int subEntity )
00053 : grid_( grid ),
00054 elementInfo_( elementInfo ),
00055 subEntity_( subEntity )
00056 {}
00057
00058 void coordinate ( int i, Coordinate &x ) const
00059 {
00060 assert( !elementInfo_ == false );
00061 assert( (i >= 0) && (i <= mydimension) );
00062
00063 const int k = mapVertices( subEntity_, i );
00064 const Alberta::GlobalVector &coord = grid_.getCoord( elementInfo_, k );
00065 for( int j = 0; j < coorddimension; ++j )
00066 x[ j ] = coord[ j ];
00067 }
00068
00069 bool hasDeterminant () const
00070 {
00071 return ((codimension == 0) && elementInfo_.isLeaf());
00072 }
00073
00074 ctype determinant () const
00075 {
00076 assert( hasDeterminant() );
00077
00078 const Alberta::Element *el = elementInfo_.el();
00079 typedef typename Grid::LeafDataType::Data LeafData;
00080 LeafData *leafdata = (LeafData *)el->child[ 1 ];
00081 assert( leafdata != NULL );
00082 return leafdata->determinant;
00083 }
00084
00085 private:
00086 static int mapVertices ( int subEntity, int i )
00087 {
00088 typedef AlbertHelp::MapVertices< mydimension, dimension > Mapper;
00089 return Mapper::mapVertices( subEntity, i );
00090 }
00091 };
00092
00093
00094
00095
00096
00097
00098 template< class CoordTraits, class Topology, unsigned int dimW >
00099 class AlbertaGridCornerStorage
00100 {
00101 typedef AlbertaGridCornerStorage< CoordTraits, Topology, dimW > This;
00102
00103 public:
00104 static const unsigned int size = Topology::numCorners;
00105
00106 static const unsigned int dimWorld = dimW;
00107
00108 typedef typename CoordTraits::template Vector< dimWorld >::type
00109 GlobalCoordinate;
00110
00111 template< class SubTopology >
00112 struct SubStorage
00113 {
00114 typedef AlbertaGridCornerStorage< CoordTraits, SubTopology, dimWorld > type;
00115 };
00116
00117 private:
00118 GlobalCoordinate coords_[ size ];
00119
00120 public:
00121 template< class CoordReader >
00122 explicit AlbertaGridCornerStorage ( const CoordReader &coordReader )
00123 {
00124 for( unsigned int i = 0; i < size; ++i )
00125 coordReader.coordinate( i, coords_[ i ] );
00126 }
00127
00128 template< class Mapping, unsigned int codim >
00129 explicit AlbertaGridCornerStorage ( const GenericGeometry::SubMappingCoords< Mapping, codim > &coords )
00130 {
00131 for( unsigned int i = 0; i < size; ++i )
00132 coords_[ i ] = coords[ i ];
00133 }
00134
00135 const GlobalCoordinate &operator[] ( unsigned int i ) const
00136 {
00137 return coords_[ i ];
00138 }
00139 };
00140
00141
00142
00143
00144 template <class GridImp,int cdim>
00145 struct AlbertaGridGeometryTraits
00146 {
00147
00148 typedef typename remove_const<GridImp>::type Grid;
00149
00150 typedef GenericGeometry::DuneCoordTraits< Alberta::Real > CoordTraits;
00151
00152 static const int dimGrid = Grid::dimension;
00153 static const int dimWorld = cdim;
00154
00155 static const bool hybrid = false;
00156 static const GeometryType::BasicType dunetype = GeometryType::simplex;
00157
00158 static const GeometryType::BasicType linetype = GeometryType::simplex;
00159
00160 template< class Topology >
00161 struct Mapping
00162 {
00163 typedef AlbertaGridCornerStorage< CoordTraits, Topology, dimWorld > CornerStorage;
00164 typedef GenericGeometry::CornerMapping< CoordTraits, Topology, dimWorld, CornerStorage > type;
00165 };
00166
00167 struct Caching
00168 {
00169 static const GenericGeometry::EvaluationType evaluateJacobianTransposed = GenericGeometry::ComputeOnDemand;
00170 static const GenericGeometry::EvaluationType evaluateJacobianInverseTransposed = GenericGeometry::ComputeOnDemand;
00171 static const GenericGeometry::EvaluationType evaluateIntegrationElement = GenericGeometry::ComputeOnDemand;
00172 static const GenericGeometry::EvaluationType evaluateNormal = GenericGeometry::ComputeOnDemand;
00173 };
00174 };
00175
00176
00177
00178
00179
00180
00181 #if USE_GENERICGEOMETRY
00182 template< int mydim, int cdim, class GridImp >
00183 class AlbertaGridGeometry
00184 : public GenericGeometry::BasicGeometry
00185 < mydim, AlbertaGridGeometryTraits< GridImp, cdim > >
00186 {
00187 typedef AlbertaGridGeometry< mydim, cdim, GridImp > This;
00188 typedef GenericGeometry::BasicGeometry
00189 < mydim, AlbertaGridGeometryTraits< GridImp, cdim > >
00190 Base;
00191
00192 public:
00194 AlbertaGridGeometry ()
00195 : Base ()
00196 {}
00197
00198 AlbertaGridGeometry ( const This &other )
00199 : Base ( other )
00200 {}
00201
00202 template< class CoordReader >
00203 AlbertaGridGeometry ( const CoordReader &coordReader )
00204 : Base( GeometryType( GeometryType::simplex, mydim ), coordReader )
00205 {}
00206
00207 template< class CoordReader >
00208 void build ( const CoordReader &coordReader )
00209 {
00210 (*this) = AlbertaGridGeometry( coordReader );
00211 }
00212 };
00213 #endif // #if USE_GENERICGEOMETRY
00214
00215 #if !USE_GENERICGEOMETRY
00216
00228 template< int mydim, int cdim, class GridImp >
00229 class AlbertaGridGeometry
00230 {
00231 typedef AlbertaGridGeometry< mydim, cdim, GridImp > This;
00232
00233
00234 typedef GridImp Grid;
00235
00236
00237 static const int dimbary = mydim + 1;
00238
00239 public:
00241 typedef Alberta::Real ctype;
00242
00243 static const int dimension = Grid :: dimension;
00244 static const int mydimension = mydim;
00245 static const int codimension = dimension - mydimension;
00246 static const int coorddimension = cdim;
00247
00248 typedef FieldVector< ctype, mydimension > LocalVector;
00249 typedef FieldVector< ctype, coorddimension > GlobalVector;
00250
00251 private:
00252 static const int numCorners = mydimension + 1;
00253
00254 typedef FieldMatrix< ctype, numCorners, coorddimension > CoordMatrix;
00255
00256 public:
00258 AlbertaGridGeometry ();
00259
00260 AlbertaGridGeometry ( const This &other );
00261
00262 template< class CoordReader >
00263 AlbertaGridGeometry ( const CoordReader &coordReader );
00264
00267 GeometryType type () const;
00268
00270 int corners () const;
00271
00273 const GlobalVector &operator[] (int i) const;
00274
00277 GlobalVector global ( const LocalVector &local ) const;
00278
00281 LocalVector local ( const GlobalVector &global ) const;
00282
00284 bool checkInside( const LocalVector &local ) const;
00285
00309
00310 ctype integrationElement ( const LocalVector &local ) const;
00311
00312
00313 ctype volume () const;
00314
00319 const FieldMatrix< ctype, cdim, mydim > &
00320 jacobianInverseTransposed ( const LocalVector &local ) const;
00321
00322
00323
00324
00325
00326 void invalidate ();
00327
00328 template< class CoordReader >
00329 void build ( const CoordReader &coordReader );
00330
00333 void print (std::ostream& ss) const;
00334
00335 private:
00336
00337 void calcElMatrix () const;
00338
00340 void buildJacobianInverseTransposed () const;
00341
00342
00343 ctype elDeterminant () const;
00344
00346 CoordMatrix coord_;
00347
00348 mutable FieldMatrix< ctype, cdim, mydim > Jinv_;
00349
00350 mutable FieldMatrix< ctype, cdim, mydim > elMat_;
00351
00353 mutable bool builtElMat_;
00355 mutable bool builtinverse_;
00356
00357 mutable bool calcedDet_;
00358 mutable ctype elDet_;
00359 };
00360 #endif // #if !USE_GENERICGEOMETRY
00361
00362
00363
00364
00365
00366
00367 template< class Grid >
00368 class AlbertaGridLocalGeometryProvider
00369 {
00370 typedef AlbertaGridLocalGeometryProvider< Grid > This;
00371
00372 public:
00373 typedef typename Grid::ctype ctype;
00374
00375 static const int dimension = Grid::dimension;
00376
00377 template< int codim >
00378 struct Codim
00379 {
00380 typedef Geometry< dimension-codim, dimension, Grid, AlbertaGridGeometry >
00381 LocalGeometry;
00382 };
00383
00384 typedef typename Codim< 0 >::LocalGeometry LocalElementGeometry;
00385 typedef typename Codim< 1 >::LocalGeometry LocalFaceGeometry;
00386
00387 static const int numChildren = 2;
00388 static const int numFaces = dimension + 1;
00389
00390 private:
00391 struct GeoInFatherCoordReader;
00392 struct FaceCoordReader;
00393
00394 const LocalElementGeometry *geometryInFather_[ numChildren ][ 2 ];
00395 const LocalFaceGeometry *faceGeometry_[ numFaces ];
00396
00397 AlbertaGridLocalGeometryProvider ()
00398 {
00399 buildGeometryInFather();
00400 buildFaceGeometry();
00401 }
00402
00403 ~AlbertaGridLocalGeometryProvider ()
00404 {
00405 for( int child = 0; child < numChildren; ++child )
00406 {
00407 delete geometryInFather_[ child ][ 0 ];
00408 delete geometryInFather_[ child ][ 1 ];
00409 }
00410
00411 for( int i = 0; i < numFaces; ++i )
00412 delete faceGeometry_[ i ];
00413 }
00414
00415 void buildGeometryInFather();
00416 void buildFaceGeometry();
00417
00418 public:
00419 const LocalElementGeometry &
00420 geometryInFather ( int child, const int orientation = 1 ) const
00421 {
00422 assert( (child >= 0) && (child < numChildren) );
00423 assert( (orientation == 1) || (orientation == -1) );
00424 return *geometryInFather_[ child ][ (orientation + 1) / 2 ];
00425 }
00426
00427 const LocalFaceGeometry &
00428 faceGeometry ( int face ) const
00429 {
00430 assert( (face >= 0) && (face < numFaces) );
00431 return *faceGeometry_[ face ];
00432 }
00433
00434 static const This &instance ()
00435 {
00436 static This theInstance;
00437 return theInstance;
00438 }
00439 };
00440
00441 }
00442
00443 #endif