dune-grid
2.1.1
|
00001 #ifndef DUNE_ALU3DGRIDGEOMETRY_HH 00002 #define DUNE_ALU3DGRIDGEOMETRY_HH 00003 00004 // System includes 00005 00006 // Dune includes 00007 #include <dune/common/misc.hh> 00008 #include <dune/grid/common/grid.hh> 00009 00010 // Local includes 00011 #include "alu3dinclude.hh" 00012 #include "topology.hh" 00013 #include "mappings.hh" 00014 00015 namespace Dune 00016 { 00017 00018 // Forward declarations 00019 template<int cd, int dim, class GridImp> 00020 class ALU3dGridEntity; 00021 template<int cd, class GridImp > 00022 class ALU3dGridEntityPointer; 00023 template<int mydim, int coorddim, class GridImp> 00024 class ALU3dGridGeometry; 00025 template< ALU3dGridElementType, class > 00026 class ALU3dGrid; 00027 class BilinearSurfaceMapping; 00028 class TrilinearMapping; 00029 00030 template< class GridImp > 00031 class ALU3dGridIntersectionIterator; 00032 00033 template <int cdim> 00034 class MyALUGridGeometryImplementation 00035 { 00036 public: 00037 typedef FieldVector<alu3d_ctype, cdim> CoordinateVectorType; 00038 00039 struct CoordVecCopy 00040 { 00041 // copy coordinate vector from field vector or alu3d_ctype[cdim] 00042 template <class CoordPtrType> 00043 static inline void copy(const CoordPtrType& p, 00044 CoordinateVectorType& c) 00045 { 00046 assert( cdim == 3 ); 00047 c[0] = p[0]; 00048 c[1] = p[1]; 00049 c[2] = p[2]; 00050 } 00051 00052 template <class CoordPtrType> 00053 void update(const CoordPtrType&, 00054 const CoordPtrType&, 00055 const CoordPtrType&, 00056 const CoordPtrType&, 00057 const CoordPtrType&, 00058 const CoordPtrType&, 00059 const CoordPtrType&, 00060 const CoordPtrType& ) const 00061 { 00062 DUNE_THROW(InvalidStateException,"This method should not be called!"); 00063 } 00064 00065 template <class CoordPtrType> 00066 void update(const CoordPtrType&, 00067 const CoordPtrType&, 00068 const CoordPtrType&, 00069 const CoordPtrType& ) const 00070 { 00071 DUNE_THROW(InvalidStateException,"This method should not be called!"); 00072 } 00073 00074 template <class CoordPtrType> 00075 void update(const CoordPtrType&, 00076 const CoordPtrType&, 00077 const CoordPtrType& ) const 00078 { 00079 DUNE_THROW(InvalidStateException,"This method should not be called!"); 00080 } 00081 }; 00082 00084 template <int dummy, int dim, 00085 ALU3dGridElementType eltype> class GeometryImpl; 00086 public: 00087 // geometry implementation for edges and vertices 00088 template <int dummy, int dim, ALU3dGridElementType eltype> 00089 class GeometryImpl : public CoordVecCopy 00090 { 00091 using CoordVecCopy :: copy ; 00092 00093 enum { corners_ = dim+1 }; 00095 typedef FieldMatrix<alu3d_ctype, corners_ , cdim> CoordinateMatrixType; 00096 00097 typedef LinearMapping<cdim, dim> MappingType; 00098 00099 CoordinateMatrixType coord_; 00100 MappingType liMap_; 00101 bool builtMapping_; 00102 00103 public: 00104 using CoordVecCopy :: update ; 00105 00106 GeometryImpl() : coord_() , liMap_() , builtMapping_(false) {} 00107 GeometryImpl(const GeometryImpl& other) 00108 : coord_(other.coord_), 00109 liMap_(other.liMap_), 00110 builtMapping_(other.builtMapping_) 00111 {} 00112 00113 // return coordinate vector 00114 inline const CoordinateVectorType& operator [] (const int i) const 00115 { 00116 assert( i>=0 && i<corners_ ); 00117 return coord_[i]; 00118 } 00119 00120 inline MappingType& mapping() 00121 { 00122 if( builtMapping_ ) return liMap_; 00123 00124 liMap_.buildMapping( coord_[0] ); 00125 builtMapping_ = true ; 00126 return liMap_; 00127 } 00128 00129 // update vertex 00130 template <class CoordPtrType> 00131 inline void update(const CoordPtrType& p0) 00132 { 00133 assert( corners_ == 1 ); 00134 copy( p0, coord_[0] ); 00135 // we need to update the mapping 00136 builtMapping_ = false ; 00137 } 00138 }; 00139 00140 // geometry implementation for edges and vertices 00141 template <int dummy, ALU3dGridElementType eltype> 00142 class GeometryImpl<dummy,1,eltype> : public CoordVecCopy 00143 { 00144 using CoordVecCopy :: copy ; 00145 00146 enum { dim = 1 }; 00147 enum { corners_ = dim+1 }; 00149 typedef FieldMatrix<alu3d_ctype, corners_ , cdim> CoordinateMatrixType; 00150 00151 typedef LinearMapping<cdim, dim> MappingType; 00152 00153 // for edges use LinearMapping<cdim, 1> here that has all features 00154 // implemented 00155 00156 CoordinateMatrixType coord_; 00157 MappingType liMap_; 00158 bool builtMapping_; 00159 00160 public: 00161 using CoordVecCopy :: update ; 00162 00163 GeometryImpl() : coord_() , liMap_() , builtMapping_(false) {} 00164 GeometryImpl(const GeometryImpl& other) 00165 : coord_(other.coord_), 00166 liMap_(other.liMap_), 00167 builtMapping_(other.builtMapping_) 00168 {} 00169 00170 // return coordinate vector 00171 inline const CoordinateVectorType& operator [] (const int i) const 00172 { 00173 assert( i>=0 && i<corners_ ); 00174 return coord_[i]; 00175 } 00176 00177 inline MappingType& mapping() 00178 { 00179 if( builtMapping_ ) return liMap_; 00180 00181 liMap_.buildMapping( coord_[0], coord_[1] ); 00182 builtMapping_ = true ; 00183 return liMap_; 00184 } 00185 00186 // update edge 00187 template <class CoordPtrType> 00188 inline void update(const CoordPtrType& p0, 00189 const CoordPtrType& p1) 00190 { 00191 assert( corners_ == 2 ); 00192 copy( p0, coord_[0] ); 00193 copy( p1, coord_[1] ); 00194 builtMapping_ = false; 00195 } 00196 00197 }; 00198 00199 // geom impl for simplex faces (triangles) 00200 template <int dummy> 00201 class GeometryImpl<dummy,2, tetra> : public CoordVecCopy 00202 { 00203 using CoordVecCopy :: copy ; 00204 00205 enum { corners_ = 3 }; 00206 00208 typedef FieldMatrix<alu3d_ctype, corners_ , cdim> CoordinateMatrixType; 00209 typedef LinearMapping<cdim, 2> MappingType; 00210 00212 CoordinateMatrixType coord_; 00213 00214 MappingType liMap_; 00215 bool builtMapping_; 00216 00217 public: 00218 using CoordVecCopy :: update ; 00219 00220 // constructor 00221 GeometryImpl() : coord_(), liMap_(), builtMapping_(false) {} 00222 // copy constructor 00223 GeometryImpl(const GeometryImpl& other) : 00224 coord_(other.coord_), 00225 liMap_(other.liMap_), 00226 builtMapping_(other.builtMapping_) 00227 {} 00228 00229 // return coordinate vector 00230 inline const CoordinateVectorType& operator [] (const int i) const 00231 { 00232 assert( i>=0 && i<corners_ ); 00233 return coord_[i]; 00234 } 00235 00236 // update geometry coordinates 00237 template <class CoordPtrType> 00238 inline void update(const CoordPtrType& p0, 00239 const CoordPtrType& p1, 00240 const CoordPtrType& p2) 00241 { 00242 copy(p0, coord_[0] ); 00243 copy(p1, coord_[1] ); 00244 copy(p2, coord_[2] ); 00245 builtMapping_ = false; 00246 } 00247 00248 // return mapping (always up2date) 00249 inline MappingType& mapping() 00250 { 00251 if( builtMapping_ ) return liMap_; 00252 00253 liMap_.buildMapping( coord_[0], coord_[1], coord_[2] ); 00254 builtMapping_ = true ; 00255 return liMap_; 00256 } 00257 }; 00258 00260 // 00261 // hexa specializations 00262 // 00264 00265 // geom impl for cube faces (quadrilaterals) 00266 template <int dummy> 00267 class GeometryImpl<dummy,2, hexa> : public CoordVecCopy 00268 { 00269 using CoordVecCopy :: copy ; 00270 00271 enum { corners_ = 4 }; 00272 00274 typedef FieldMatrix<alu3d_ctype, corners_ , cdim> CoordinateMatrixType; 00275 typedef BilinearSurfaceMapping MappingType; 00276 00278 CoordinateMatrixType coord_; 00279 00280 MappingType biMap_; 00281 bool builtMapping_; 00282 00283 public: 00284 using CoordVecCopy :: update ; 00285 00286 // constructor 00287 GeometryImpl() : coord_(), biMap_(), builtMapping_(false) {} 00288 // copy constructor 00289 GeometryImpl(const GeometryImpl& other) : 00290 coord_(other.coord_), 00291 biMap_(other.biMap_), 00292 builtMapping_(other.builtMapping_) 00293 {} 00294 00295 // return coordinate vector 00296 inline const CoordinateVectorType& operator [] (const int i) const 00297 { 00298 assert( i>=0 && i<corners_ ); 00299 return coord_[i]; 00300 } 00301 00302 // update geometry coordinates 00303 template <class CoordPtrType> 00304 inline void update(const CoordPtrType& p0, 00305 const CoordPtrType& p1, 00306 const CoordPtrType& p2, 00307 const CoordPtrType& p3) 00308 { 00309 copy(p0, coord_[0] ); 00310 copy(p1, coord_[1] ); 00311 copy(p2, coord_[2] ); 00312 copy(p3, coord_[3] ); 00313 builtMapping_ = false; 00314 } 00315 00316 // return mapping (always up2date) 00317 inline MappingType& mapping() 00318 { 00319 if( builtMapping_ ) return biMap_; 00320 00321 biMap_.buildMapping( coord_[0], coord_[1], coord_[2], coord_[3] ); 00322 builtMapping_ = true ; 00323 return biMap_; 00324 } 00325 }; 00326 00327 // geometry impl for hexahedrons 00328 template <int dummy> 00329 class GeometryImpl<dummy,3, hexa> : public CoordVecCopy 00330 { 00331 enum { corners_ = 8 }; 00332 00334 typedef alu3d_ctype CoordPtrType[cdim]; 00335 00337 typedef FieldMatrix<alu3d_ctype, corners_ , cdim> CoordinateMatrixType; 00338 00339 typedef TrilinearMapping MappingType; 00340 00341 // coordinate pointer vector 00342 FieldVector<const CoordPtrType*, corners_ > coordPtr_; 00343 MappingType triMap_; 00344 CoordinateMatrixType* fatherCoord_; 00345 bool builtMapping_; 00346 00347 public: 00348 using CoordVecCopy :: update ; 00349 00351 GeometryImpl() : coordPtr_((CoordPtrType*)0), triMap_(), 00352 fatherCoord_(0), 00353 builtMapping_(false) 00354 {} 00355 00356 00358 GeometryImpl(const GeometryImpl& other) : 00359 coordPtr_(other.coordPtr_), 00360 triMap_(other.triMap_), 00361 fatherCoord_(0), 00362 builtMapping_(other.builtMapping_) 00363 { 00364 // if father coords are set, then reset coordPtr 00365 if( other.fatherCoord_ ) 00366 { 00367 fatherCoord_ = new CoordinateMatrixType(*other.fatherCoord_); 00368 CoordinateMatrixType& coord = *fatherCoord_; 00369 for(int i=0; i<corners_; ++i) 00370 { 00371 coordPtr_[i] = reinterpret_cast<const CoordPtrType*> (&(coord[i][0])); 00372 } 00373 } 00374 } 00375 00376 // desctructor 00377 ~GeometryImpl() 00378 { 00379 if( fatherCoord_ ) delete fatherCoord_; 00380 } 00381 00382 // return coordinates 00383 inline const CoordinateVectorType& operator [] (const int i) const 00384 { 00385 assert( i>=0 && i<corners_ ); 00386 return reinterpret_cast<const CoordinateVectorType&> (*(coordPtr_[i])); 00387 } 00388 00389 // update geometry coordinates 00390 inline void update(const CoordPtrType& p0, 00391 const CoordPtrType& p1, 00392 const CoordPtrType& p2, 00393 const CoordPtrType& p3, 00394 const CoordPtrType& p4, 00395 const CoordPtrType& p5, 00396 const CoordPtrType& p6, 00397 const CoordPtrType& p7) 00398 { 00399 coordPtr_[0] = &p0; 00400 coordPtr_[1] = &p1; 00401 coordPtr_[2] = &p2; 00402 coordPtr_[3] = &p3; 00403 coordPtr_[4] = &p4; 00404 coordPtr_[5] = &p5; 00405 coordPtr_[6] = &p6; 00406 coordPtr_[7] = &p7; 00407 builtMapping_ = false; 00408 } 00409 00410 // update geometry in father coordinates 00411 template <class GeometryImp> 00412 inline void updateInFather(const GeometryImp &fatherGeom , 00413 const GeometryImp & myGeom) 00414 { 00415 if( fatherCoord_ == 0 ) 00416 { 00417 fatherCoord_ = new CoordinateMatrixType(); 00418 } 00419 00420 CoordinateMatrixType& coord = *fatherCoord_; 00421 // compute the local coordinates in father refelem 00422 for(int i=0; i < myGeom.corners() ; ++i) 00423 { 00424 // calculate coordinate 00425 coord[i] = fatherGeom.local( myGeom.corner( i ) ); 00426 00427 // set pointer 00428 coordPtr_[i] = reinterpret_cast<const CoordPtrType*> (&(coord[i][0])); 00429 00430 // to avoid rounding errors 00431 for(int j=0; j<cdim; ++j) 00432 { 00433 if ( coord[i][j] < 1e-16) coord[i][j] = 0.0; 00434 } 00435 } 00436 00437 builtMapping_ = false ; 00438 } 00439 00440 // return mapping (always up2date) 00441 inline MappingType& mapping() 00442 { 00443 if( builtMapping_ ) return triMap_; 00444 00445 triMap_.buildMapping( (*this)[0], (*this)[1], (*this)[2], (*this)[3], 00446 (*this)[4], (*this)[5], (*this)[6], (*this)[7] ); 00447 00448 builtMapping_ = true; 00449 return triMap_; 00450 } 00451 }; 00452 00453 00454 // geometry impl for hexahedrons 00455 template <int dummy> 00456 class GeometryImpl<dummy,3, tetra> : public CoordVecCopy 00457 { 00458 enum { corners_ = 4 }; 00459 00461 typedef alu3d_ctype CoordPtrType[cdim]; 00462 00464 typedef FieldMatrix<alu3d_ctype, corners_ , cdim> CoordinateMatrixType; 00465 00466 typedef LinearMapping<cdim, cdim> MappingType; 00467 00468 // coordinate pointer vector 00469 FieldVector<const CoordPtrType*, corners_ > coordPtr_; 00470 MappingType liMap_; 00471 CoordinateMatrixType* fatherCoord_; 00472 bool builtMapping_; 00473 00474 public: 00475 using CoordVecCopy :: update ; 00476 00477 // default constructor 00478 GeometryImpl() : coordPtr_((CoordPtrType*)0), liMap_(), 00479 fatherCoord_(0), 00480 builtMapping_(false) 00481 {} 00482 00483 // copy constructor 00484 GeometryImpl(const GeometryImpl& other) : 00485 coordPtr_(other.coordPtr_), 00486 liMap_(other.liMap_), 00487 fatherCoord_(0), 00488 builtMapping_(other.builtMapping_) 00489 { 00490 // if father coords are set, then reset coordPtr 00491 if( other.fatherCoord_ ) 00492 { 00493 fatherCoord_ = new CoordinateMatrixType(*other.fatherCoord_); 00494 CoordinateMatrixType& coord = *fatherCoord_; 00495 for(int i=0; i<corners_; ++i) 00496 { 00497 coordPtr_[i] = reinterpret_cast<const CoordPtrType*> (&(coord[i][0])); 00498 } 00499 } 00500 } 00501 00502 // destructor 00503 ~GeometryImpl() 00504 { 00505 if( fatherCoord_ ) delete fatherCoord_; 00506 } 00507 00508 // return coordinate vector 00509 inline const CoordinateVectorType& operator [] (const int i) const 00510 { 00511 assert( i>=0 && i<corners_ ); 00512 return reinterpret_cast<const CoordinateVectorType&> (*(coordPtr_[i])); 00513 } 00514 00515 // update geometry coordinates 00516 inline void update(const CoordPtrType& p0, 00517 const CoordPtrType& p1, 00518 const CoordPtrType& p2, 00519 const CoordPtrType& p3) 00520 { 00521 coordPtr_[0] = &p0; 00522 coordPtr_[1] = &p1; 00523 coordPtr_[2] = &p2; 00524 coordPtr_[3] = &p3; 00525 builtMapping_ = false; 00526 } 00527 00528 // update geometry in father coordinates 00529 template <class GeometryImp> 00530 inline void updateInFather(const GeometryImp &fatherGeom , 00531 const GeometryImp & myGeom) 00532 { 00533 if( fatherCoord_ == 0 ) 00534 { 00535 fatherCoord_ = new CoordinateMatrixType(); 00536 } 00537 00538 CoordinateMatrixType& coord = *fatherCoord_; 00539 // compute the local coordinates in father refelem 00540 for(int i=0; i < myGeom.corners() ; ++i) 00541 { 00542 // calculate coordinate 00543 coord[i] = fatherGeom.local( myGeom.corner( i ) ); 00544 00545 // set pointer 00546 coordPtr_[i] = reinterpret_cast<const CoordPtrType*> (&(coord[i][0])); 00547 00548 // to avoid rounding errors 00549 for(int j=0; j<cdim; ++j) 00550 { 00551 if ( coord[i][j] < 1e-16) coord[i][j] = 0.0; 00552 } 00553 } 00554 00555 builtMapping_ = false ; 00556 } 00557 00558 // return mapping (always up2date) 00559 inline MappingType& mapping() 00560 { 00561 if( builtMapping_ ) return liMap_; 00562 00563 liMap_.buildMapping( (*this)[0], (*this)[1], (*this)[2], (*this)[3] ); 00564 00565 builtMapping_ = true; 00566 return liMap_; 00567 } 00568 }; 00569 }; // end of class ALUGridGeometryImplementation 00570 00571 template <int mydim, int cdim, class GridImp> 00572 class ALU3dGridGeometry : 00573 public GeometryDefaultImplementation<mydim, cdim, GridImp, ALU3dGridGeometry> 00574 { 00575 static const ALU3dGridElementType elementType = GridImp::elementType; 00576 00577 typedef typename GridImp::MPICommunicatorType Comm; 00578 00579 friend class ALU3dGridIntersectionIterator<GridImp>; 00580 00581 typedef typename ALU3dImplTraits< elementType, Comm >::IMPLElementType IMPLElementType; 00582 typedef typename ALU3dImplTraits< elementType, Comm >::GEOFaceType GEOFaceType; 00583 typedef typename ALU3dImplTraits< elementType, Comm >::GEOEdgeType GEOEdgeType; 00584 typedef typename ALU3dImplTraits< elementType, Comm >::GEOVertexType GEOVertexType; 00585 00586 // interface types 00587 typedef typename ALU3dImplTraits< elementType, Comm >::HFaceType HFaceType; 00588 typedef typename ALU3dImplTraits< elementType, Comm >::HEdgeType HEdgeType; 00589 typedef typename ALU3dImplTraits< elementType, Comm >::VertexType VertexType; 00590 00591 typedef ElementTopologyMapping<elementType> ElementTopo; 00592 typedef FaceTopologyMapping<elementType> FaceTopo; 00593 00594 enum { corners_ = (elementType == hexa) ? Power_m_p<2,mydim>::power : mydim+1 }; 00595 00596 // type of specialized geometry implementation 00597 typedef typename MyALUGridGeometryImplementation<cdim> :: 00598 template GeometryImpl<0, mydim, elementType > GeometryImplType; 00599 00600 public: 00601 typedef typename GridImp :: ctype ctype; 00602 00604 typedef FieldVector<ctype, mydim> LocalCoordinate; 00605 00607 typedef FieldVector<ctype, cdim > GlobalCoordinate; 00608 00610 typedef FieldMatrix<ctype,cdim,mydim> Jacobian; 00611 00613 typedef FieldMatrix< ctype, mydim, cdim > JacobianTransposed; 00614 00615 // type of coordinate matrix for faces 00616 typedef FieldMatrix<ctype, 00617 EntityCount< elementType > :: numVerticesPerFace , 3> FaceCoordinatesType; 00618 00621 ALU3dGridGeometry(); 00622 00625 GeometryType type () const; 00626 00628 int corners () const; 00629 00631 const GlobalCoordinate& operator[] (int i) const; 00632 00634 GlobalCoordinate corner (int i) const; 00635 00638 GlobalCoordinate global (const LocalCoordinate& local) const; 00639 00642 LocalCoordinate local (const GlobalCoordinate& global) const; 00643 00645 ctype integrationElement (const LocalCoordinate& local) const; 00646 00649 const Jacobian& jacobianInverseTransposed (const LocalCoordinate& local) const; 00650 00652 const JacobianTransposed& jacobianTransposed (const LocalCoordinate& local) const; 00653 00655 inline bool affine () const; 00656 00658 ctype volume () const; 00659 00660 //*********************************************************************** 00662 //*********************************************************************** 00664 bool buildGeom(const IMPLElementType & item); 00665 bool buildGeom(const HFaceType & item, int twist, int faceNum); 00666 bool buildGeom(const HEdgeType & item, int twist, int); 00667 bool buildGeom(const VertexType & item, int twist, int); 00668 00669 // this method is used by the intersection iterator 00670 bool buildGeom(const FaceCoordinatesType& coords); 00671 00672 // this method is used by the intersection iterator 00673 template <class coord_t> 00674 bool buildGeom(const coord_t& p0, 00675 const coord_t& p1, 00676 const coord_t& p2, 00677 const coord_t& p3); 00678 00679 // this method is used by the intersection iterator 00680 template <class coord_t> 00681 bool buildGeom(const coord_t& p0, 00682 const coord_t& p1, 00683 const coord_t& p2); 00684 00686 template <class GeometryType> 00687 bool buildGeomInFather(const GeometryType &fatherGeom , const GeometryType & myGeom); 00688 00691 void print (std::ostream& ss) const; 00692 00693 private: 00694 // implementation of coord and mapping 00695 mutable GeometryImplType geoImpl_; 00696 // volume 00697 mutable ctype volume_; 00698 }; 00699 00700 } // end namespace Dune 00701 00702 #include "geometry_imp.cc" 00703 00704 #endif