dune-grid
2.1.1
|
00001 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 00002 // vi: set et ts=8 sw=2 sts=2: 00003 00004 #ifndef DUNE_ALU3DGRID_FACTORY_HH 00005 #define DUNE_ALU3DGRID_FACTORY_HH 00006 00007 #include <map> 00008 #include <vector> 00009 00010 #ifdef ENABLE_ALUGRID 00011 00012 #include <dune/common/array.hh> 00013 #include <dune/common/mpihelper.hh> 00014 00015 #include <dune/grid/common/genericreferenceelements.hh> 00016 #include <dune/grid/common/gridfactory.hh> 00017 #include <dune/grid/common/boundaryprojection.hh> 00018 00019 #include <dune/grid/alugrid/common/transformation.hh> 00020 #include <dune/grid/alugrid/3d/alugrid.hh> 00021 00022 namespace Dune 00023 { 00024 00026 template< class ALUGrid > 00027 class ALU3dGridFactory 00028 : public GridFactoryInterface< ALUGrid > 00029 { 00030 typedef ALU3dGridFactory< ALUGrid > ThisType; 00031 typedef GridFactoryInterface< ALUGrid > BaseType; 00032 00033 public: 00034 typedef ALUGrid Grid; 00035 00036 typedef typename Grid::ctype ctype; 00037 00038 static const ALU3dGridElementType elementType = Grid::elementType; 00039 00040 static const unsigned int dimension = Grid::dimension; 00041 static const unsigned int dimensionworld = Grid::dimensionworld; 00042 00043 typedef typename Grid::MPICommunicatorType MPICommunicatorType; 00044 00046 typedef DuneBoundaryProjection< 3 > DuneBoundaryProjectionType; 00047 00048 template< int codim > 00049 struct Codim 00050 { 00051 typedef typename Grid::template Codim< codim >::Entity Entity; 00052 }; 00053 00054 typedef ALUGridTransformation< ctype, dimensionworld > Transformation; 00055 00057 typedef typename Transformation::WorldVector WorldVector; 00059 typedef typename Transformation::WorldMatrix WorldMatrix; 00060 00061 private: 00062 dune_static_assert( (elementType == tetra || elementType == hexa), 00063 "ALU3dGridFactory supports only grids containing " 00064 "tetrahedrons or hexahedrons exclusively." ); 00065 00066 typedef Dune::BoundarySegmentWrapper< dimension, dimensionworld > BoundarySegmentWrapperType; 00067 00068 static const unsigned int numCorners = EntityCount< elementType >::numVertices; 00069 static const unsigned int numFaces = EntityCount< elementType >::numFaces; 00070 static const unsigned int numFaceCorners = EntityCount< elementType >::numVerticesPerFace; 00071 00072 typedef ElementTopologyMapping< elementType > ElementTopologyMappingType; 00073 typedef FaceTopologyMapping< elementType > FaceTopologyMappingType; 00074 00075 typedef FieldVector< ctype, dimensionworld > VertexType; 00076 typedef std::vector< unsigned int > ElementType; 00077 typedef array< unsigned int, numFaceCorners > FaceType; 00078 00079 struct FaceLess; 00080 00081 typedef std::vector< VertexType > VertexVector; 00082 typedef std::vector< ElementType > ElementVector; 00083 typedef std::vector< std::pair< FaceType, int > > BoundaryIdVector; 00084 typedef std::vector< std::pair< FaceType, FaceType > > PeriodicBoundaryVector; 00085 typedef std::pair< unsigned int, int > SubEntity; 00086 typedef std::map< FaceType, SubEntity, FaceLess > FaceMap; 00087 00088 typedef std::map< FaceType, const DuneBoundaryProjectionType* > BoundaryProjectionMap; 00089 typedef std::vector< const DuneBoundaryProjectionType* > BoundaryProjectionVector; 00090 00091 typedef std::vector< Transformation > FaceTransformationVector; 00092 00093 // copy vertex numbers and store smalled #dimension ones 00094 void copyAndSort ( const std::vector< unsigned int > &vertices, FaceType &faceId ) const 00095 { 00096 std::vector<unsigned int> tmp( vertices ); 00097 std::sort( tmp.begin(), tmp.end() ); 00098 00099 // copy only the first dimension vertices (enough for key) 00100 for( size_t i = 0; i < faceId.size(); ++i ) faceId[ i ] = tmp[ i ]; 00101 } 00102 00103 private: 00104 // return grid object 00105 virtual Grid* createGridObj( BoundaryProjectionVector* bndProjections, const std::string& name ) const 00106 { 00107 return ( allowGridGeneration_ ) ? 00108 new Grid( communicator_, globalProjection_, bndProjections , name, realGrid_ ) : 00109 new Grid( communicator_ ); 00110 } 00111 00112 public: 00114 explicit ALU3dGridFactory ( const MPICommunicatorType &communicator = Grid::defaultCommunicator(), 00115 bool removeGeneratedFile = true ); 00116 00118 explicit ALU3dGridFactory ( const std::string &filename, 00119 const MPICommunicatorType &communicator = Grid::defaultCommunicator() ); 00120 00122 explicit ALU3dGridFactory ( const bool verbose, const MPICommunicatorType &communicator ); 00123 00125 virtual ~ALU3dGridFactory (); 00126 00131 virtual void insertVertex ( const VertexType &pos ); 00132 00141 virtual void 00142 insertElement ( const GeometryType &geometry, 00143 const std::vector< unsigned int > &vertices ); 00144 00155 virtual void 00156 insertBoundary ( const GeometryType &geometry, 00157 const std::vector< unsigned int > &faceVertices, 00158 const int id ); 00159 00166 virtual void insertBoundary ( const int element, const int face, const int id ); 00167 00176 virtual void 00177 insertBoundaryProjection ( const GeometryType &type, 00178 const std::vector< unsigned int > &vertices, 00179 const DuneBoundaryProjectionType *projection ); 00180 00185 virtual void 00186 insertBoundarySegment ( const std::vector< unsigned int >& vertices ) ; 00187 00193 virtual void 00194 insertBoundarySegment ( const std::vector< unsigned int >& vertices, 00195 const shared_ptr<BoundarySegment<3,3> >& boundarySegment ) ; 00196 00201 virtual void insertBoundaryProjection ( const DuneBoundaryProjectionType& bndProjection ); 00202 00212 void insertFaceTransformation ( const WorldMatrix &matrix, const WorldVector &shift ); 00213 00218 Grid *createGrid (); 00219 00220 Grid *createGrid ( const bool addMissingBoundaries, const std::string dgfName = "" ); 00221 00222 Grid *createGrid ( const bool addMissingBoundaries, bool temporary, const std::string dgfName = "" ); 00223 00224 virtual unsigned int 00225 insertionIndex ( const typename Codim< 0 >::Entity &entity ) const 00226 { 00227 return Grid::getRealImplementation( entity ).getIndex(); 00228 } 00229 virtual unsigned int 00230 insertionIndex ( const typename Codim< dimension >::Entity &entity ) const 00231 { 00232 return Grid::getRealImplementation( entity ).getIndex(); 00233 } 00234 virtual unsigned int 00235 insertionIndex ( const typename Grid::LeafIntersection &intersection ) const 00236 { 00237 return intersection.boundarySegmentIndex(); 00238 } 00239 virtual bool 00240 wasInserted ( const typename Grid::LeafIntersection &intersection ) const 00241 { 00242 return intersection.boundary() && 00243 ( insertionIndex(intersection) < numFacesInserted_ ); 00244 } 00245 00246 private: 00247 void assertGeometryType( const GeometryType &geometry ); 00248 static void generateFace ( const ElementType &element, const int f, FaceType &face ); 00249 void generateFace ( const SubEntity &subEntity, FaceType &face ) const; 00250 void correctElementOrientation (); 00251 bool identifyFaces ( const Transformation &transformation, const FaceType &key1, const FaceType &key2 ); 00252 void searchPeriodicNeighbor ( FaceMap &faceMap, const typename FaceMap::iterator &pos ); 00253 void reinsertBoundary ( const FaceMap &faceMap, const typename FaceMap::const_iterator &pos, const int id ); 00254 void recreateBoundaryIds ( const int defaultId = 1 ); 00255 00256 int rank_; 00257 00258 VertexVector vertices_; 00259 ElementVector elements_; 00260 BoundaryIdVector boundaryIds_; 00261 PeriodicBoundaryVector periodicBoundaries_; 00262 const DuneBoundaryProjectionType* globalProjection_ ; 00263 BoundaryProjectionMap boundaryProjections_; 00264 FaceTransformationVector faceTransformations_; 00265 unsigned int numFacesInserted_; 00266 bool realGrid_; 00267 const bool allowGridGeneration_; 00268 00269 MPICommunicatorType communicator_; 00270 }; 00271 00272 00273 00274 template< class ALUGrid > 00275 struct ALU3dGridFactory< ALUGrid >::FaceLess 00276 : public std::binary_function< FaceType, FaceType, bool > 00277 { 00278 bool operator() ( const FaceType &a, const FaceType &b ) const 00279 { 00280 for( unsigned int i = 0; i < numFaceCorners; ++i ) 00281 { 00282 if( a[ i ] != b[ i ] ) 00283 return (a[ i ] < b[ i ]); 00284 } 00285 return false; 00286 } 00287 }; 00288 00289 00290 template< class ALUGrid > 00291 inline void ALU3dGridFactory< ALUGrid > 00292 ::assertGeometryType( const GeometryType &geometry ) 00293 { 00294 if( elementType == tetra ) 00295 { 00296 if( !geometry.isSimplex() ) 00297 DUNE_THROW( GridError, "Only simplex geometries can be inserted into " 00298 "ALUSimplexGrid< 3, 3 >." ); 00299 } 00300 else 00301 { 00302 if( !geometry.isCube() ) 00303 DUNE_THROW( GridError, "Only cube geometries can be inserted into " 00304 "ALUCubeGrid< 3, 3 >." ); 00305 } 00306 } 00307 00308 00312 template<> 00313 class GridFactory< ALUSimplexGrid< 3, 3 > > 00314 : public ALU3dGridFactory< ALUSimplexGrid< 3, 3 > > 00315 { 00316 typedef GridFactory< ALUSimplexGrid< 3, 3 > > ThisType; 00317 typedef ALU3dGridFactory< ALUSimplexGrid< 3, 3 > > BaseType; 00318 00319 public: 00320 typedef BaseType::Grid Grid; 00321 00322 typedef BaseType::MPICommunicatorType MPICommunicatorType; 00323 00325 explicit GridFactory ( const MPICommunicatorType &communicator = Grid::defaultCommunicator() ) 00326 : BaseType( communicator ) 00327 {} 00328 00330 GridFactory ( const std::string &filename, 00331 const MPICommunicatorType &communicator = Grid::defaultCommunicator() ) 00332 : BaseType( filename, communicator ) 00333 {} 00334 00335 protected: 00336 template< class, class, int > friend class ALULocalGeometryStorage; 00338 GridFactory ( const bool realGrid, 00339 const MPICommunicatorType &communicator = Grid::defaultCommunicator() ) 00340 : BaseType( realGrid, communicator ) 00341 {} 00342 }; 00343 00344 00345 00349 template<> 00350 class GridFactory< ALUCubeGrid< 3, 3 > > 00351 : public ALU3dGridFactory< ALUCubeGrid< 3, 3 > > 00352 { 00353 typedef GridFactory< ALUCubeGrid< 3, 3 > > ThisType; 00354 typedef ALU3dGridFactory< ALUCubeGrid< 3, 3 > > BaseType; 00355 00356 public: 00357 typedef BaseType::Grid Grid; 00358 00359 typedef BaseType::MPICommunicatorType MPICommunicatorType; 00360 00362 explicit GridFactory ( const MPICommunicatorType &communicator = Grid::defaultCommunicator() ) 00363 : BaseType( communicator ) 00364 {} 00365 00367 GridFactory ( const std::string &filename, 00368 const MPICommunicatorType &communicator = Grid::defaultCommunicator() ) 00369 : BaseType( filename, communicator ) 00370 {} 00371 00372 protected: 00373 template< class, class, int > friend class ALULocalGeometryStorage; 00375 GridFactory ( const bool realGrid, 00376 const MPICommunicatorType &communicator = Grid::defaultCommunicator() ) 00377 : BaseType( realGrid, communicator ) 00378 {} 00379 }; 00380 00381 00382 00383 // Implementation of ALU3dGridFactory 00384 // ---------------------------------- 00385 00386 template< class ALUGrid > 00387 inline 00388 ALU3dGridFactory< ALUGrid > 00389 :: ALU3dGridFactory ( const MPICommunicatorType &communicator, 00390 bool removeGeneratedFile ) 00391 : rank_( ALU3dGridCommunications< elementType, MPICommunicatorType >::getRank( communicator ) ), 00392 globalProjection_ ( 0 ), 00393 numFacesInserted_ ( 0 ), 00394 realGrid_( true ), 00395 allowGridGeneration_( rank_ == 0 ), 00396 communicator_( communicator ) 00397 {} 00398 00399 template< class ALUGrid > 00400 inline 00401 ALU3dGridFactory< ALUGrid > 00402 :: ALU3dGridFactory ( const std::string &filename, 00403 const MPICommunicatorType &communicator ) 00404 : rank_( ALU3dGridCommunications< elementType, MPICommunicatorType >::getRank( communicator ) ), 00405 globalProjection_ ( 0 ), 00406 numFacesInserted_ ( 0 ), 00407 realGrid_( true ), 00408 allowGridGeneration_( rank_ == 0 ), 00409 communicator_( communicator ) 00410 {} 00411 00412 template< class ALUGrid > 00413 inline 00414 ALU3dGridFactory< ALUGrid > 00415 :: ALU3dGridFactory ( const bool realGrid, 00416 const MPICommunicatorType &communicator ) 00417 : rank_( ALU3dGridCommunications< elementType, MPICommunicatorType >::getRank( communicator ) ), 00418 globalProjection_ ( 0 ), 00419 numFacesInserted_ ( 0 ), 00420 realGrid_( realGrid ), 00421 allowGridGeneration_( true ), 00422 communicator_( communicator ) 00423 {} 00424 00425 template< class ALUGrid > 00426 inline void ALU3dGridFactory< ALUGrid > :: 00427 insertBoundarySegment ( const std::vector< unsigned int >& vertices ) 00428 { 00429 FaceType faceId; 00430 copyAndSort( vertices, faceId ); 00431 00432 if( vertices.size() != numFaceCorners ) 00433 DUNE_THROW( GridError, "Wrong number of face vertices passed: " << vertices.size() << "." ); 00434 00435 if( boundaryProjections_.find( faceId ) != boundaryProjections_.end() ) 00436 DUNE_THROW( GridError, "Only one boundary projection can be attached to a face." ); 00437 // DUNE_THROW( NotImplemented, "insertBoundarySegment with a single argument" ); 00438 00439 boundaryProjections_[ faceId ] = 0; 00440 00441 std::pair< FaceType, int > boundaryId; 00442 for( unsigned int i = 0; i < numFaceCorners; ++i ) 00443 { 00444 const unsigned int j = FaceTopologyMappingType::dune2aluVertex( i ); 00445 boundaryId.first[ j ] = vertices[ i ]; 00446 } 00447 boundaryId.second = 1; 00448 boundaryIds_.push_back( boundaryId ); 00449 } 00450 00451 template< class ALUGrid > 00452 inline void ALU3dGridFactory< ALUGrid > :: 00453 insertBoundarySegment ( const std::vector< unsigned int >& vertices, 00454 const shared_ptr<BoundarySegment<3,3> >& boundarySegment ) 00455 { 00456 FaceType faceId; 00457 copyAndSort( vertices, faceId ); 00458 00459 if( vertices.size() != numFaceCorners ) 00460 DUNE_THROW( GridError, "Wrong number of face vertices passed: " << vertices.size() << "." ); 00461 00462 if( boundaryProjections_.find( faceId ) != boundaryProjections_.end() ) 00463 DUNE_THROW( GridError, "Only one boundary projection can be attached to a face." ); 00464 00465 const size_t numVx = vertices.size(); 00466 GeometryType type; 00467 if( numVx == 3 ) 00468 type.makeSimplex( dimension-1 ); 00469 else 00470 type.makeCube( dimension-1 ); 00471 00472 // we need double here because of the structure of BoundarySegment 00473 // and BoundarySegmentWrapper which have double as coordinate type 00474 typedef FieldVector< double, dimensionworld > CoordType; 00475 std::vector< CoordType > coords( numVx ); 00476 for( size_t i = 0; i < numVx; ++i ) 00477 { 00478 // if this assertions is thrown vertices were not inserted at first 00479 assert( vertices_.size() > vertices[ i ] ); 00480 00481 // get global coordinate and copy it 00482 const VertexType &x = vertices_[ vertices[ i ] ]; 00483 for( unsigned int j = 0; j < dimensionworld; ++j ) 00484 coords[ i ][ j ] = x[ j ]; 00485 } 00486 00487 BoundarySegmentWrapperType* prj 00488 = new BoundarySegmentWrapperType( type, coords, boundarySegment ); 00489 boundaryProjections_[ faceId ] = prj; 00490 #ifndef NDEBUG 00491 // consistency check 00492 for( size_t i = 0; i < numVx; ++i ) 00493 { 00494 CoordType global = (*prj)( coords [ i ] ); 00495 if( (global - coords[ i ]).two_norm() > 1e-6 ) 00496 DUNE_THROW(GridError,"BoundarySegment does not map face vertices to face vertices."); 00497 } 00498 #endif 00499 00500 std::pair< FaceType, int > boundaryId; 00501 for( unsigned int i = 0; i < numFaceCorners; ++i ) 00502 { 00503 const unsigned int j = FaceTopologyMappingType::dune2aluVertex( i ); 00504 boundaryId.first[ j ] = vertices[ i ]; 00505 } 00506 boundaryId.second = 1; 00507 boundaryIds_.push_back( boundaryId ); 00508 } 00509 00510 00511 template< class ALUGrid > 00512 inline void ALU3dGridFactory< ALUGrid > 00513 ::generateFace ( const SubEntity &subEntity, FaceType &face ) const 00514 { 00515 generateFace( elements_[ subEntity.first ], subEntity.second, face ); 00516 } 00517 00518 } // end namespace Dune 00519 00520 #endif // #ifdef ENABLE_ALUGRID 00521 00522 #if COMPILE_ALUGRID_INLINE 00523 #include "alu3dgridfactory.cc" 00524 #endif 00525 #endif