alugrid/3d/geometry.hh

Go to the documentation of this file.
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

Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].