- Home
- About DUNE
- Download
- Documentation
- Community
- Development
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
Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].