dune-grid  2.4.1-rc2
alu3dgridfactory.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 
4 #ifndef DUNE_ALU3DGRID_FACTORY_HH
5 #define DUNE_ALU3DGRID_FACTORY_HH
6 
7 #include <map>
8 #include <vector>
9 
10 #if HAVE_ALUGRID
11 
12 #include <dune/common/array.hh>
13 #include <dune/common/parallel/mpihelper.hh>
14 
15 #include <dune/geometry/referenceelements.hh>
16 
19 
22 
23 namespace Dune
24 {
25 
27  template< class ALUGrid >
28  class ALU3dGridFactory
29  : public GridFactoryInterface< ALUGrid >
30  {
31  typedef ALU3dGridFactory< ALUGrid > ThisType;
32  typedef GridFactoryInterface< ALUGrid > BaseType;
33 
34  public:
35  typedef ALUGrid Grid;
36 
37  typedef typename Grid::ctype ctype;
38 
39  static const ALU3dGridElementType elementType = Grid::elementType;
40 
41  static const unsigned int dimension = Grid::dimension;
42  static const unsigned int dimensionworld = Grid::dimensionworld;
43 
44  typedef typename Grid::MPICommunicatorType MPICommunicatorType;
45 
47  typedef DuneBoundaryProjection< 3 > DuneBoundaryProjectionType;
48 
49  template< int codim >
50  struct Codim
51  {
52  typedef typename Grid::template Codim< codim >::Entity Entity;
53  };
54 
55  typedef unsigned int VertexId;
56 
57  typedef ALUGridTransformation< ctype, dimensionworld > Transformation;
58 
60  typedef typename Transformation::WorldVector WorldVector;
62  typedef typename Transformation::WorldMatrix WorldMatrix;
63 
64  private:
65  static_assert((elementType == tetra || elementType == hexa),
66  "ALU3dGridFactory supports only grids containing "
67  "tetrahedrons or hexahedrons exclusively.");
68 
69  typedef Dune::BoundarySegmentWrapper< dimension, dimensionworld > BoundarySegmentWrapperType;
70 
71  static const unsigned int numCorners = EntityCount< elementType >::numVertices;
72  static const unsigned int numFaces = EntityCount< elementType >::numFaces;
73  static const unsigned int numFaceCorners = EntityCount< elementType >::numVerticesPerFace;
74 
75  typedef ElementTopologyMapping< elementType > ElementTopologyMappingType;
76  typedef FaceTopologyMapping< elementType > FaceTopologyMappingType;
77 
78  typedef FieldVector< ctype, dimensionworld > VertexType;
79  typedef std::vector< unsigned int > ElementType;
80  typedef array< unsigned int, numFaceCorners > FaceType;
81 
82  struct FaceLess;
83 
84  typedef std::vector< std::pair< VertexType, size_t > > VertexVector;
85  typedef std::vector< ElementType > ElementVector;
86  typedef std::pair< FaceType, int > BndPair ;
87  typedef std::map< FaceType, int > BoundaryIdMap;
88  typedef std::vector< std::pair< BndPair, BndPair > > PeriodicBoundaryVector;
89  typedef std::pair< unsigned int, int > SubEntity;
90  typedef std::map< FaceType, SubEntity, FaceLess > FaceMap;
91 
92  typedef std::map< FaceType, const DuneBoundaryProjectionType* > BoundaryProjectionMap;
93  typedef std::vector< const DuneBoundaryProjectionType* > BoundaryProjectionVector;
94 
95  typedef std::vector< Transformation > FaceTransformationVector;
96 
97  // copy vertex numbers and store smalled #dimension ones
98  void copyAndSort ( const std::vector< unsigned int > &vertices, FaceType &faceId ) const
99  {
100  std::vector<unsigned int> tmp( vertices );
101  std::sort( tmp.begin(), tmp.end() );
102 
103  // copy only the first dimension vertices (enough for key)
104  for( size_t i = 0; i < faceId.size(); ++i ) faceId[ i ] = tmp[ i ];
105  }
106 
107  private:
108  // return grid object
109  virtual Grid* createGridObj( BoundaryProjectionVector* bndProjections, const std::string& name ) const
110  {
111  return ( allowGridGeneration_ ) ?
112  new Grid( communicator_, globalProjection_, bndProjections , name, realGrid_ ) :
113  new Grid( communicator_ );
114  }
115 
116  public:
118  explicit ALU3dGridFactory ( const MPICommunicatorType &communicator = Grid::defaultCommunicator(),
119  bool removeGeneratedFile = true );
120 
122  explicit ALU3dGridFactory ( const std::string &filename,
123  const MPICommunicatorType &communicator = Grid::defaultCommunicator() );
124 
126  explicit ALU3dGridFactory ( const bool verbose, const MPICommunicatorType &communicator );
127 
129  virtual ~ALU3dGridFactory ();
130 
135  virtual void insertVertex ( const VertexType &pos );
136 
137  // for testing parallel GridFactory
138  VertexId insertVertex ( const VertexType &pos, const size_t globalId );
139 
148  virtual void
149  insertElement ( const GeometryType &geometry,
150  const std::vector< VertexId > &vertices );
151 
162  virtual void
163  insertBoundary ( const GeometryType &geometry,
164  const std::vector< VertexId > &faceVertices,
165  const int id );
166 
173  virtual void insertBoundary ( const int element, const int face, const int id );
174 
175  // for testing parallel GridFactory
176  void insertProcessBorder ( const int element, const int face )
177  {
178  insertBoundary( element, face, ALU3DSPACE ProcessorBoundary_t );
179  }
180 
189  virtual void
190  insertBoundaryProjection ( const GeometryType &type,
191  const std::vector< VertexId > &vertices,
192  const DuneBoundaryProjectionType *projection );
193 
198  virtual void
199  insertBoundarySegment ( const std::vector< VertexId >& vertices ) ;
200 
206  virtual void
207  insertBoundarySegment ( const std::vector< VertexId >& vertices,
208  const shared_ptr<BoundarySegment<3,3> >& boundarySegment ) ;
209 
214  virtual void insertBoundaryProjection ( const DuneBoundaryProjectionType& bndProjection );
215 
225  void insertFaceTransformation ( const WorldMatrix &matrix, const WorldVector &shift );
226 
231  Grid *createGrid ();
232 
233  Grid *createGrid ( const bool addMissingBoundaries, const std::string dgfName = "" );
234 
235  Grid *createGrid ( const bool addMissingBoundaries, bool temporary, const std::string dgfName = "" );
236 
237  virtual unsigned int
238  insertionIndex ( const typename Codim< 0 >::Entity &entity ) const
239  {
240  return Grid::getRealImplementation( entity ).getIndex();
241  }
242  virtual unsigned int
243  insertionIndex ( const typename Codim< dimension >::Entity &entity ) const
244  {
245  return Grid::getRealImplementation( entity ).getIndex();
246  }
247  virtual unsigned int
248  insertionIndex ( const typename Grid::LeafIntersection &intersection ) const
249  {
250  return intersection.boundarySegmentIndex();
251  }
252  virtual bool
253  wasInserted ( const typename Grid::LeafIntersection &intersection ) const
254  {
255  return intersection.boundary() &&
256  ( insertionIndex(intersection) < numFacesInserted_ );
257  }
258 
259  private:
260  size_t globalId ( const VertexId &id ) const
261  {
262  assert( id < vertices_.size() );
263  return vertices_[ id ].second;
264  }
265 
266  const VertexType &position ( const VertexId &id ) const
267  {
268  assert( id < vertices_.size() );
269  return vertices_[ id ].first;
270  }
271 
272  void assertGeometryType( const GeometryType &geometry );
273  static void generateFace ( const ElementType &element, const int f, FaceType &face );
274  void generateFace ( const SubEntity &subEntity, FaceType &face ) const;
275  void correctElementOrientation ();
276  bool identifyFaces ( const Transformation &transformation, const FaceType &key1, const FaceType &key2, const int defaultId );
277  void searchPeriodicNeighbor ( FaceMap &faceMap, const typename FaceMap::iterator &pos, const int defaultId );
278  void reinsertBoundary ( const FaceMap &faceMap, const typename FaceMap::const_iterator &pos, const int id );
279  void recreateBoundaryIds ( const int defaultId = 1 );
280 
281  int rank_;
282 
283  VertexVector vertices_;
284  ElementVector elements_;
285  BoundaryIdMap boundaryIds_;
286  PeriodicBoundaryVector periodicBoundaries_;
287  const DuneBoundaryProjectionType* globalProjection_ ;
288  BoundaryProjectionMap boundaryProjections_;
289  FaceTransformationVector faceTransformations_;
290  unsigned int numFacesInserted_;
291  bool realGrid_;
292  const bool allowGridGeneration_;
293 
294  MPICommunicatorType communicator_;
295  };
296 
297 
298 
299  template< class ALUGrid >
300  struct ALU3dGridFactory< ALUGrid >::FaceLess
301  : public std::binary_function< FaceType, FaceType, bool >
302  {
303  bool operator() ( const FaceType &a, const FaceType &b ) const
304  {
305  for( unsigned int i = 0; i < numFaceCorners; ++i )
306  {
307  if( a[ i ] != b[ i ] )
308  return (a[ i ] < b[ i ]);
309  }
310  return false;
311  }
312  };
313 
314 
315  template< class ALUGrid >
316  inline void ALU3dGridFactory< ALUGrid >
317  ::assertGeometryType( const GeometryType &geometry )
318  {
319  if( elementType == tetra )
320  {
321  if( !geometry.isSimplex() )
322  DUNE_THROW( GridError, "Only simplex geometries can be inserted into "
323  "ALUGrid< 3, 3 , simplex, (non)conforming>." );
324  }
325  else
326  {
327  if( !geometry.isCube() )
328  DUNE_THROW( GridError, "Only cube geometries can be inserted into "
329  "ALUGrid< 3, 3, cube, nonconforming >." );
330  }
331  }
332 
333 
338  template<ALUGridElementType eltype, ALUGridRefinementType refinementtype , class Comm >
339  class GridFactory< ALUGrid< 3, 3, eltype, refinementtype, Comm > >
340  : public ALU3dGridFactory< ALUGrid< 3, 3, eltype, refinementtype, Comm > >
341  {
342  typedef GridFactory< ALUGrid< 3, 3, eltype, refinementtype, Comm > > ThisType;
343  typedef ALU3dGridFactory< ALUGrid< 3, 3, eltype, refinementtype, Comm > > BaseType;
344 
345  public:
346  typedef typename BaseType::Grid Grid;
347 
348  typedef typename BaseType::MPICommunicatorType MPICommunicatorType;
349 
351  explicit GridFactory ( const MPICommunicatorType &communicator = Grid::defaultCommunicator() )
352  : BaseType( communicator )
353  {}
354 
356  GridFactory ( const std::string &filename,
357  const MPICommunicatorType &communicator = Grid::defaultCommunicator() )
358  : BaseType( filename, communicator )
359  {}
360 
361  protected:
362  template< class, class, int > friend class ALULocalGeometryStorage;
364  GridFactory ( const bool realGrid,
365  const MPICommunicatorType &communicator = Grid::defaultCommunicator() )
366  : BaseType( realGrid, communicator )
367  {}
368  };
369 
370 
371 
372  // Implementation of ALU3dGridFactory
373  // ----------------------------------
374 
375  template< class ALUGrid >
376  inline
377  ALU3dGridFactory< ALUGrid >
378  :: ALU3dGridFactory ( const MPICommunicatorType &communicator,
379  bool removeGeneratedFile )
380  : rank_( ALU3dGridCommunications< elementType, MPICommunicatorType >::getRank( communicator ) ),
381  globalProjection_ ( 0 ),
382  numFacesInserted_ ( 0 ),
383  realGrid_( true ),
384  allowGridGeneration_( rank_ == 0 ),
385  communicator_( communicator )
386  {}
387 
388  template< class ALUGrid >
389  inline
390  ALU3dGridFactory< ALUGrid >
391  :: ALU3dGridFactory ( const std::string &filename,
392  const MPICommunicatorType &communicator )
393  : rank_( ALU3dGridCommunications< elementType, MPICommunicatorType >::getRank( communicator ) ),
394  globalProjection_ ( 0 ),
395  numFacesInserted_ ( 0 ),
396  realGrid_( true ),
397  allowGridGeneration_( rank_ == 0 ),
398  communicator_( communicator )
399  {}
400 
401  template< class ALUGrid >
402  inline
403  ALU3dGridFactory< ALUGrid >
404  :: ALU3dGridFactory ( const bool realGrid,
405  const MPICommunicatorType &communicator )
406  : rank_( ALU3dGridCommunications< elementType, MPICommunicatorType >::getRank( communicator ) ),
407  globalProjection_ ( 0 ),
408  numFacesInserted_ ( 0 ),
409  realGrid_( realGrid ),
410  allowGridGeneration_( true ),
411  communicator_( communicator )
412  {}
413 
414  template< class ALUGrid >
415  inline void ALU3dGridFactory< ALUGrid > ::
416  insertBoundarySegment ( const std::vector< unsigned int >& vertices )
417  {
418  FaceType faceId;
419  copyAndSort( vertices, faceId );
420 
421  if( vertices.size() != numFaceCorners )
422  DUNE_THROW( GridError, "Wrong number of face vertices passed: " << vertices.size() << "." );
423 
424  if( boundaryProjections_.find( faceId ) != boundaryProjections_.end() )
425  DUNE_THROW( GridError, "Only one boundary projection can be attached to a face." );
426  // DUNE_THROW( NotImplemented, "insertBoundarySegment with a single argument" );
427 
428  boundaryProjections_[ faceId ] = 0;
429 
430  BndPair boundaryId;
431  for( unsigned int i = 0; i < numFaceCorners; ++i )
432  {
433  const unsigned int j = FaceTopologyMappingType::dune2aluVertex( i );
434  boundaryId.first[ j ] = vertices[ i ];
435  }
436  boundaryId.second = 1;
437  boundaryIds_.insert( boundaryId );
438  }
439 
440  template< class ALUGrid >
441  inline void ALU3dGridFactory< ALUGrid > ::
442  insertBoundarySegment ( const std::vector< unsigned int >& vertices,
443  const shared_ptr<BoundarySegment<3,3> >& boundarySegment )
444  {
445  FaceType faceId;
446  copyAndSort( vertices, faceId );
447 
448  if( vertices.size() != numFaceCorners )
449  DUNE_THROW( GridError, "Wrong number of face vertices passed: " << vertices.size() << "." );
450 
451  if( boundaryProjections_.find( faceId ) != boundaryProjections_.end() )
452  DUNE_THROW( GridError, "Only one boundary projection can be attached to a face." );
453 
454  const size_t numVx = vertices.size();
455  GeometryType type;
456  if( numVx == 3 )
457  type.makeSimplex( dimension-1 );
458  else
459  type.makeCube( dimension-1 );
460 
461  // we need double here because of the structure of BoundarySegment
462  // and BoundarySegmentWrapper which have double as coordinate type
463  typedef FieldVector< double, dimensionworld > CoordType;
464  std::vector< CoordType > coords( numVx );
465  for( size_t i = 0; i < numVx; ++i )
466  {
467  // if this assertions is thrown vertices were not inserted at first
468  assert( vertices_.size() > vertices[ i ] );
469 
470  // get global coordinate and copy it
471  const VertexType &x = position( vertices[ i ] );
472  for( unsigned int j = 0; j < dimensionworld; ++j )
473  coords[ i ][ j ] = x[ j ];
474  }
475 
476  BoundarySegmentWrapperType* prj
477  = new BoundarySegmentWrapperType( type, coords, boundarySegment );
478  boundaryProjections_[ faceId ] = prj;
479 #ifndef NDEBUG
480  // consistency check
481  for( size_t i = 0; i < numVx; ++i )
482  {
483  CoordType global = (*prj)( coords [ i ] );
484  if( (global - coords[ i ]).two_norm() > 1e-6 )
485  DUNE_THROW(GridError,"BoundarySegment does not map face vertices to face vertices.");
486  }
487 #endif
488 
489  BndPair boundaryId;
490  for( unsigned int i = 0; i < numFaceCorners; ++i )
491  {
492  const unsigned int j = FaceTopologyMappingType::dune2aluVertex( i );
493  boundaryId.first[ j ] = vertices[ i ];
494  }
495  boundaryId.second = 1;
496  boundaryIds_.insert( boundaryId );
497  }
498 
499 
500  template< class ALUGrid >
501  inline void ALU3dGridFactory< ALUGrid >
502  ::generateFace ( const SubEntity &subEntity, FaceType &face ) const
503  {
504  generateFace( elements_[ subEntity.first ], subEntity.second, face );
505  }
506 
507 } // end namespace Dune
508 
509 #endif // #if HAVE_ALUGRID
510 
511 #if COMPILE_ALUGRID_INLINE
512  #include "alu3dgridfactory.cc"
513 #endif
514 #endif
static const int ProcessorBoundary_t
Definition: alu3dinclude.hh:46
ElementType
Definition: alu2dinclude.hh:55
GeometryType
Type representing VTK&#39;s entity geometry types.
Definition: common.hh:178
Provides base classes for ALUGrid.
Definition: topology.hh:13
The dimension of the world the grid lives in.
Definition: common/grid.hh:408
Definition: boundaryprojection.hh:65
Provide a generic factory class for unstructured grids.
Definition: topology.hh:13
ct ctype
Define type used for coordinates in grid module.
Definition: common/grid.hh:548
Include standard header files.
Definition: agrid.hh:59
#define ALU3DSPACE
Definition: alu3dinclude.hh:26
ALU3dGridElementType
Definition: topology.hh:13
The dimension of the grid.
Definition: common/grid.hh:402
GridFamily::Traits::LeafIntersection LeafIntersection
A type that is a model of Dune::Intersection, an intersections of two codimension 1 of two codimensio...
Definition: common/grid.hh:486