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