4 #ifndef DUNE_ALU3DGRID_FACTORY_HH
5 #define DUNE_ALU3DGRID_FACTORY_HH
12 #include <dune/common/array.hh>
13 #include <dune/common/mpihelper.hh>
15 #include <dune/geometry/referenceelements.hh>
28 template<
class ALUGr
id >
29 class ALU3dGridFactory
30 :
public GridFactoryInterface< ALUGrid >
32 typedef ALU3dGridFactory< ALUGrid > ThisType;
33 typedef GridFactoryInterface< ALUGrid > BaseType;
45 typedef typename Grid::MPICommunicatorType MPICommunicatorType;
48 typedef DuneBoundaryProjection< 3 > DuneBoundaryProjectionType;
53 typedef typename Grid::template Codim< codim >::Entity Entity;
56 typedef unsigned int VertexId;
58 typedef ALUGridTransformation< ctype, dimensionworld > Transformation;
61 typedef typename Transformation::WorldVector WorldVector;
63 typedef typename Transformation::WorldMatrix WorldMatrix;
66 dune_static_assert( (elementType ==
tetra || elementType ==
hexa),
67 "ALU3dGridFactory supports only grids containing "
68 "tetrahedrons or hexahedrons exclusively." );
72 static const unsigned int numCorners = EntityCount< elementType >::numVertices;
73 static const unsigned int numFaces = EntityCount< elementType >::numFaces;
74 static const unsigned int numFaceCorners = EntityCount< elementType >::numVerticesPerFace;
76 typedef ElementTopologyMapping< elementType > ElementTopologyMappingType;
77 typedef FaceTopologyMapping< elementType > FaceTopologyMappingType;
79 typedef FieldVector< ctype, dimensionworld > VertexType;
81 typedef array< unsigned int, numFaceCorners > FaceType;
85 typedef std::vector< std::pair< VertexType, size_t > > VertexVector;
86 typedef std::vector< ElementType > ElementVector;
87 typedef std::pair< FaceType, int > BndPair ;
88 typedef std::map< FaceType, int > BoundaryIdMap;
89 typedef std::vector< std::pair< BndPair, BndPair > > PeriodicBoundaryVector;
90 typedef std::pair< unsigned int, int > SubEntity;
91 typedef std::map< FaceType, SubEntity, FaceLess > FaceMap;
93 typedef std::map< FaceType, const DuneBoundaryProjectionType* > BoundaryProjectionMap;
94 typedef std::vector< const DuneBoundaryProjectionType* > BoundaryProjectionVector;
96 typedef std::vector< Transformation > FaceTransformationVector;
99 void copyAndSort (
const std::vector< unsigned int > &vertices, FaceType &faceId )
const
101 std::vector<unsigned int> tmp( vertices );
102 std::sort( tmp.begin(), tmp.end() );
105 for(
size_t i = 0; i < faceId.size(); ++i ) faceId[ i ] = tmp[ i ];
110 virtual Grid* createGridObj( BoundaryProjectionVector* bndProjections,
const std::string& name )
const
112 return ( allowGridGeneration_ ) ?
113 new Grid( communicator_, globalProjection_, bndProjections , name, realGrid_ ) :
114 new Grid( communicator_ );
119 explicit ALU3dGridFactory (
const MPICommunicatorType &communicator = Grid::defaultCommunicator(),
120 bool removeGeneratedFile =
true );
123 explicit ALU3dGridFactory (
const std::string &filename,
124 const MPICommunicatorType &communicator = Grid::defaultCommunicator() );
127 explicit ALU3dGridFactory (
const bool verbose,
const MPICommunicatorType &communicator );
130 virtual ~ALU3dGridFactory ();
136 virtual void insertVertex (
const VertexType &pos );
139 VertexId insertVertex (
const VertexType &pos,
const size_t globalId );
151 const std::vector< VertexId > &vertices );
165 const std::vector< VertexId > &faceVertices,
174 virtual void insertBoundary (
const int element,
const int face,
const int id );
177 void insertProcessBorder (
const int element,
const int face )
192 const std::vector< VertexId > &vertices,
193 const DuneBoundaryProjectionType *projection );
200 insertBoundarySegment (
const std::vector< VertexId >& vertices ) ;
208 insertBoundarySegment (
const std::vector< VertexId >& vertices,
209 const shared_ptr<BoundarySegment<3,3> >& boundarySegment ) ;
215 virtual void insertBoundaryProjection (
const DuneBoundaryProjectionType& bndProjection );
226 void insertFaceTransformation (
const WorldMatrix &matrix,
const WorldVector &shift );
234 Grid *createGrid (
const bool addMissingBoundaries,
const std::string dgfName =
"" );
236 Grid *createGrid (
const bool addMissingBoundaries,
bool temporary,
const std::string dgfName =
"" );
239 insertionIndex (
const typename Codim< 0 >::Entity &entity )
const
241 return Grid::getRealImplementation( entity ).getIndex();
244 insertionIndex (
const typename Codim< dimension >::Entity &entity )
const
246 return Grid::getRealImplementation( entity ).getIndex();
251 return intersection.boundarySegmentIndex();
256 return intersection.boundary() &&
257 ( insertionIndex(intersection) < numFacesInserted_ );
261 size_t globalId (
const VertexId &
id )
const
263 assert(
id < vertices_.size() );
264 return vertices_[ id ].second;
267 const VertexType &position (
const VertexId &
id )
const
269 assert(
id < vertices_.size() );
270 return vertices_[ id ].first;
273 void assertGeometryType(
const GeometryType &geometry );
274 static void generateFace (
const ElementType &element,
const int f, FaceType &face );
275 void generateFace (
const SubEntity &subEntity, FaceType &face )
const;
276 void correctElementOrientation ();
277 bool identifyFaces (
const Transformation &transformation,
const FaceType &key1,
const FaceType &key2,
const int defaultId );
278 void searchPeriodicNeighbor ( FaceMap &faceMap,
const typename FaceMap::iterator &pos,
const int defaultId );
279 void reinsertBoundary (
const FaceMap &faceMap,
const typename FaceMap::const_iterator &pos,
const int id );
280 void recreateBoundaryIds (
const int defaultId = 1 );
284 VertexVector vertices_;
285 ElementVector elements_;
286 BoundaryIdMap boundaryIds_;
287 PeriodicBoundaryVector periodicBoundaries_;
288 const DuneBoundaryProjectionType* globalProjection_ ;
289 BoundaryProjectionMap boundaryProjections_;
290 FaceTransformationVector faceTransformations_;
291 unsigned int numFacesInserted_;
293 const bool allowGridGeneration_;
295 MPICommunicatorType communicator_;
300 template<
class ALUGr
id >
301 struct ALU3dGridFactory< ALUGrid >::FaceLess
302 :
public std::binary_function< FaceType, FaceType, bool >
304 bool operator() (
const FaceType &a,
const FaceType &b )
const
306 for(
unsigned int i = 0; i < numFaceCorners; ++i )
308 if( a[ i ] != b[ i ] )
309 return (a[ i ] < b[ i ]);
316 template<
class ALUGr
id >
317 inline void ALU3dGridFactory< ALUGrid >
320 if( elementType ==
tetra )
322 if( !geometry.isSimplex() )
323 DUNE_THROW( GridError,
"Only simplex geometries can be inserted into "
324 "ALUSimplexGrid< 3, 3 >." );
328 if( !geometry.isCube() )
329 DUNE_THROW( GridError,
"Only cube geometries can be inserted into "
330 "ALUCubeGrid< 3, 3 >." );
339 class GridFactory< ALUSimplexGrid< 3, 3 > >
340 :
public ALU3dGridFactory< ALUSimplexGrid< 3, 3 > >
342 typedef GridFactory< ALUSimplexGrid< 3, 3 > > ThisType;
343 typedef ALU3dGridFactory< ALUSimplexGrid< 3, 3 > > BaseType;
346 typedef BaseType::Grid Grid;
348 typedef BaseType::MPICommunicatorType MPICommunicatorType;
351 explicit GridFactory (
const MPICommunicatorType &communicator = Grid::defaultCommunicator() )
352 : BaseType( communicator )
357 const MPICommunicatorType &communicator = Grid::defaultCommunicator() )
358 : BaseType( filename, communicator )
362 template<
class,
class,
int >
friend class ALULocalGeometryStorage;
365 const MPICommunicatorType &communicator = Grid::defaultCommunicator() )
366 : BaseType( realGrid, communicator )
376 class GridFactory< ALUCubeGrid< 3, 3 > >
377 :
public ALU3dGridFactory< ALUCubeGrid< 3, 3 > >
379 typedef GridFactory< ALUCubeGrid< 3, 3 > > ThisType;
380 typedef ALU3dGridFactory< ALUCubeGrid< 3, 3 > > BaseType;
383 typedef BaseType::Grid Grid;
385 typedef BaseType::MPICommunicatorType MPICommunicatorType;
388 explicit GridFactory (
const MPICommunicatorType &communicator = Grid::defaultCommunicator() )
389 : BaseType( communicator )
394 const MPICommunicatorType &communicator = Grid::defaultCommunicator() )
395 : BaseType( filename, communicator )
399 template<
class,
class,
int >
friend class ALULocalGeometryStorage;
402 const MPICommunicatorType &communicator = Grid::defaultCommunicator() )
403 : BaseType( realGrid, communicator )
411 template<ALUGr
idElementType eltype, ALUGr
idRefinementType refinementtype ,
class Comm >
412 class GridFactory< ALUGrid< 3, 3, eltype, refinementtype, Comm > >
413 :
public ALU3dGridFactory< ALUGrid< 3, 3, eltype, refinementtype, Comm > >
415 typedef GridFactory< ALUGrid< 3, 3, eltype, refinementtype, Comm > > ThisType;
416 typedef ALU3dGridFactory< ALUGrid< 3, 3, eltype, refinementtype, Comm > > BaseType;
419 typedef typename BaseType::Grid Grid;
421 typedef typename BaseType::MPICommunicatorType MPICommunicatorType;
424 explicit GridFactory (
const MPICommunicatorType &communicator = Grid::defaultCommunicator() )
425 : BaseType( communicator )
430 const MPICommunicatorType &communicator = Grid::defaultCommunicator() )
431 : BaseType( filename, communicator )
435 template<
class,
class,
int >
friend class ALULocalGeometryStorage;
438 const MPICommunicatorType &communicator = Grid::defaultCommunicator() )
439 : BaseType( realGrid, communicator )
448 template<
class ALUGr
id >
450 ALU3dGridFactory< ALUGrid >
451 :: ALU3dGridFactory (
const MPICommunicatorType &communicator,
452 bool removeGeneratedFile )
453 : rank_( ALU3dGridCommunications< elementType, MPICommunicatorType >::getRank( communicator ) ),
454 globalProjection_ ( 0 ),
455 numFacesInserted_ ( 0 ),
457 allowGridGeneration_( rank_ == 0 ),
458 communicator_( communicator )
461 template<
class ALUGr
id >
463 ALU3dGridFactory< ALUGrid >
464 :: ALU3dGridFactory (
const std::string &filename,
465 const MPICommunicatorType &communicator )
466 : rank_( ALU3dGridCommunications< elementType, MPICommunicatorType >::getRank( communicator ) ),
467 globalProjection_ ( 0 ),
468 numFacesInserted_ ( 0 ),
470 allowGridGeneration_( rank_ == 0 ),
471 communicator_( communicator )
474 template<
class ALUGr
id >
476 ALU3dGridFactory< ALUGrid >
477 :: ALU3dGridFactory (
const bool realGrid,
478 const MPICommunicatorType &communicator )
479 : rank_( ALU3dGridCommunications< elementType, MPICommunicatorType >::getRank( communicator ) ),
480 globalProjection_ ( 0 ),
481 numFacesInserted_ ( 0 ),
482 realGrid_( realGrid ),
483 allowGridGeneration_( true ),
484 communicator_( communicator )
487 template<
class ALUGr
id >
488 inline void ALU3dGridFactory< ALUGrid > ::
489 insertBoundarySegment (
const std::vector< unsigned int >& vertices )
492 copyAndSort( vertices, faceId );
494 if( vertices.size() != numFaceCorners )
495 DUNE_THROW( GridError,
"Wrong number of face vertices passed: " << vertices.size() <<
"." );
497 if( boundaryProjections_.find( faceId ) != boundaryProjections_.end() )
498 DUNE_THROW( GridError,
"Only one boundary projection can be attached to a face." );
501 boundaryProjections_[ faceId ] = 0;
504 for(
unsigned int i = 0; i < numFaceCorners; ++i )
506 const unsigned int j = FaceTopologyMappingType::dune2aluVertex( i );
507 boundaryId.first[ j ] = vertices[ i ];
509 boundaryId.second = 1;
510 boundaryIds_.insert( boundaryId );
513 template<
class ALUGr
id >
514 inline void ALU3dGridFactory< ALUGrid > ::
515 insertBoundarySegment (
const std::vector< unsigned int >& vertices,
516 const shared_ptr<BoundarySegment<3,3> >& boundarySegment )
519 copyAndSort( vertices, faceId );
521 if( vertices.size() != numFaceCorners )
522 DUNE_THROW( GridError,
"Wrong number of face vertices passed: " << vertices.size() <<
"." );
524 if( boundaryProjections_.find( faceId ) != boundaryProjections_.end() )
525 DUNE_THROW( GridError,
"Only one boundary projection can be attached to a face." );
527 const size_t numVx = vertices.size();
530 type.makeSimplex( dimension-1 );
532 type.makeCube( dimension-1 );
536 typedef FieldVector< double, dimensionworld > CoordType;
537 std::vector< CoordType > coords( numVx );
538 for(
size_t i = 0; i < numVx; ++i )
541 assert( vertices_.size() > vertices[ i ] );
544 const VertexType &x = position( vertices[ i ] );
545 for(
unsigned int j = 0; j < dimensionworld; ++j )
546 coords[ i ][ j ] = x[ j ];
549 BoundarySegmentWrapperType* prj
550 =
new BoundarySegmentWrapperType( type, coords, boundarySegment );
551 boundaryProjections_[ faceId ] = prj;
554 for(
size_t i = 0; i < numVx; ++i )
556 CoordType global = (*prj)( coords [ i ] );
557 if( (global - coords[ i ]).two_norm() > 1e-6 )
558 DUNE_THROW(GridError,
"BoundarySegment does not map face vertices to face vertices.");
563 for(
unsigned int i = 0; i < numFaceCorners; ++i )
565 const unsigned int j = FaceTopologyMappingType::dune2aluVertex( i );
566 boundaryId.first[ j ] = vertices[ i ];
568 boundaryId.second = 1;
569 boundaryIds_.insert( boundaryId );
573 template<
class ALUGr
id >
574 inline void ALU3dGridFactory< ALUGrid >
575 ::generateFace (
const SubEntity &subEntity, FaceType &face )
const
577 generateFace( elements_[ subEntity.first ], subEntity.second, face );
582 #endif // #if HAVE_ALUGRID
584 #if COMPILE_ALUGRID_INLINE