dune-fem  2.4.1-rc
alugridwriter.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_ALUGRIDWRITER_HH
2 #define DUNE_FEM_ALUGRIDWRITER_HH
3 
4 #include <iostream>
5 #include <fstream>
6 #include <map>
7 #include <utility>
8 #include <string>
9 
10 #include <dune/grid/common/datahandleif.hh>
11 #include <dune/grid/common/grid.hh>
12 #include <dune/grid/alugrid/3d/topology.hh>
13 
15 
16 namespace Dune
17 {
18 
19  namespace Fem
20  {
21 
22  template <class GridPartType>
24  {
25  typedef typename GridPartType :: GridType GridType;
26  typedef typename GridType :: Traits :: LocalIdSet IdSetType;
27  typedef typename IdSetType :: IdType IdType;
28 
29  enum { dimension = GridType :: dimension };
30 
31  const GridPartType& gridPart_;
32  const GridType& grid_;
33  const IdSetType& idSet_;
34 
35  typedef typename GridType :: template Codim< 0 > :: Geometry :: GlobalCoordinate CoordinateType;
36  typedef typename GridType :: template Codim< 0 > :: Entity EntityType;
37 
38  class Vertex
39  {
40  CoordinateType vx_;
41  IdType id_;
42  int index_;
43  public:
44  Vertex() {}
45 
46  Vertex( const CoordinateType& vx,
47  const IdType& id,
48  const int index)
49  : vx_( vx ), id_( id ), index_( index )
50  {}
51  const CoordinateType& vx() const { return vx_ ; }
52  const IdType& id () const { return id_; }
53  const int index () const { assert(index_ >= 0); return index_; }
54  void setIndex(const int index) { index_ = index; }
55  };
56  typedef Vertex VertexType;
57 
58  typedef std::map< IdType, VertexType > IndexMapType;
59  typedef typename IndexMapType :: iterator IndexMapIteratorType;
60  mutable IndexMapType indices_;
61  const bool useIds_;
62 
63  class DataHandle :
64  public CommDataHandleIF<
65  DataHandle, int >
66  {
67  const IdSetType& idSet_;
68  const int myRank_;
69  IndexMapType& indices_;
70  public:
71  explicit DataHandle( const IdSetType& idSet,
72  const int rank,
73  IndexMapType& indices )
74  : idSet_( idSet ),
75  myRank_( rank ),
76  indices_( indices )
77  {}
78 
79 
81  bool contains ( int dim, int codim ) const
82  {
83  return dim == codim;
84  }
85 
87  bool fixedsize ( int dim, int codim ) const
88  {
89  return true;
90  }
91 
93  template< class Entity >
94  size_t size ( const Entity &entity ) const
95  {
96  return 2;
97  }
98 
100  template< class MessageBuffer, class Entity >
101  void gather ( MessageBuffer &buffer,
102  const Entity &entity ) const
103  {
104  assert( (int) Entity :: codimension == (int) dimension );
105  buffer.write( myRank_ );
106  IndexMapIteratorType it = indices_.find( idSet_.id( entity ) );
107  int index = ( it == indices_.end() ) ? -1 : (*it).second.index();
108  buffer.write( index );
109  }
110 
112  template< class MessageBuffer, class Entity >
113  void scatter ( MessageBuffer &buffer,
114  const Entity &entity,
115  const size_t dataSize )
116  {
117  assert( (int) Entity :: codimension == (int) dimension );
118  int rank;
119  buffer.read( rank );
120  int index ;
121  buffer.read( index );
122  if( myRank_ > rank && index > -1 )
123  {
124  const IdType id = idSet_.id( entity );
125  IndexMapIteratorType it = indices_.find( id );
126  if( it == indices_.end() )
127  {
128  VertexType vx( entity.geometry().corner(0), id, index );
129  indices_[ id ] = vx;
130  }
131  }
132  }
133  };
134  public:
135  explicit GlobalConsecutiveIndexSet( const GridPartType& gridPart,
136  const bool useIds = false )
137  : gridPart_( gridPart ),
138  grid_( gridPart.grid() ),
139  idSet_( grid_.localIdSet() ),
140  useIds_( useIds )
141  {
142  const int pSize = grid_.comm().size();
143  const int myRank = grid_.comm().rank();
144  int index = 0;
145  for( int p = 0; p<pSize; ++p )
146  {
147  if( p == myRank )
148  {
149  if( useIds_ )
150  {
151  typedef typename GridPartType :: template Codim< dimension > :: IteratorType
152  IteratorType;
153  const IteratorType endit = gridPart_.template end< dimension > ();
154  for( IteratorType it = gridPart_.template begin< dimension > ();
155  it != endit; ++it )
156  {
157  const typename IteratorType::Entity &entity = *it;
158  const IdType id = idSet_.id( entity );
159  if( indices_.find( id ) == indices_.end() )
160  {
161  VertexType vx( entity.geometry().corner(0), id, index );
162  indices_[ id ] = vx ;
163  ++index;
164  }
165  }
166  }
167  else
168  {
169  typedef typename GridPartType :: template Codim< 0 > :: IteratorType
170  IteratorType;
171  const IteratorType endit = gridPart_.template end< 0 > ();
172  for( IteratorType it = gridPart_.template begin< 0 > ();
173  it != endit; ++it )
174  {
175  const EntityType& entity = *it ;
176  const int count = entity.subEntities( dimension );
177  for( int i = 0; i<count; ++i)
178  {
179  auto vertex = make_entity( entity.template subEntity< dimension > ( i ) );
180  const int id = gridPart_.indexSet().index( vertex );
181  if( indices_.find( id ) == indices_.end() )
182  {
183  VertexType vx( vertex.geometry().corner(0), id, -1);
184  indices_[ id ] = vx ;
185  ++ index ;
186  }
187  }
188  }
189  {
190  // set index according to appearance in map
191  int myindex = 0;
192  IndexMapIteratorType end = indices_.end();
193  for( IndexMapIteratorType it = indices_.begin(); it != end; ++it, ++myindex)
194  {
195  (*it).second.setIndex( myindex );
196  }
197  }
198  }
199  }
200 
201  //std::cout << "P["<<myRank<< "] inddex = " << index << std::endl;
202  // send current index number
203  grid_.comm().broadcast(&index, 1, p );
204  //std::cout << "P["<<myRank<< "] inddex = " << index << std::endl;
205 
206  if( grid_.comm().size() > 1 )
207  {
208  DataHandle dataHandle( idSet_, myRank, indices_ );
209  gridPart_.communicate( dataHandle,
210  InteriorBorder_InteriorBorder_Interface,
211  ForwardCommunication );
212  }
213  }
214  }
215 
216  void writeCoordinates ( std::ostream& out ) const
217  {
218  out << indices_.size() << std::endl;
219  out.precision( 16 );
220  out << std::scientific;
221  IndexMapIteratorType end = indices_.end();
222  for( IndexMapIteratorType it = indices_.begin(); it != end; ++it)
223  {
224  out << (*it).second.vx() << std::endl;
225  }
226  }
227 
228  void writeIndices ( std::ostream& out ) const
229  {
230  IndexMapIteratorType end = indices_.end();
231  for( IndexMapIteratorType it = indices_.begin(); it != end; ++it)
232  {
233  out << (*it).second.id() << " -1" << std::endl;
234  }
235  }
236 
237  template <class EntityType>
238  int index ( const EntityType& entity ) const
239  {
240  //assert( (int) EntityType :: codimension == (int) dimension );
241  //assert( (int) EntityType :: dimension == 0 );
242  IndexMapIteratorType it = indices_.find(
243  ( useIds_ ) ?
244  idSet_.id( entity ) :
245  gridPart_.indexSet().index( entity ) );
246  assert( it != indices_.end() );
247  return (*it).second.index();
248  }
249 
250  int size() const
251  {
252  return indices_.size();
253  }
254  };
255 
256  template <class GridPartType, class IndexSetType >
258  {
259  const GridPartType& gridPart_;
260 
261  typedef typename GridPartType :: GridType GridType;
262 
263  const IndexSetType& indexSet_;
264 
265  enum { dimension = GridType :: dimension };
266 
267  typedef typename GridType :: template Codim< 0 > :: Entity Entity;
268  protected:
269  ALUGridWriter( const GridPartType& gridPart,
270  const IndexSetType& indexSet )
271  : gridPart_( gridPart ),
272  indexSet_( indexSet )
273  {
274  }
275 
276  void write(const std::string& filename, const int rank ) const
277  {
278  typedef typename GridPartType :: template Codim< 0 > :: IteratorType
279  IteratorType;
280  const IteratorType endit = gridPart_.template end< 0 > ();
281  IteratorType it = gridPart_.template begin< 0 > ();
282  if( it == endit ) return;
283 
284  const Entity &entity = *it;
285  bool hexahedra = entity.type().isHexahedron();
286  if( ! hexahedra && ! entity.type().isTetrahedron() )
287  {
288  DUNE_THROW(InvalidStateException,"Wrong geometry type");
289  }
290 
291  int noElements = 0;
292  for(; it != endit; ++it )
293  {
294  ++noElements;
295  }
296 
297  std::stringstream filestr;
298  filestr << filename << "." << rank;
299 
300  std::ofstream file ( filestr.str().c_str() );
301  if( ! file )
302  {
303  std::cerr << "ERROR: couldn't open file " << filestr.str() << std::endl;
304  assert( false );
305  abort();
306  }
307 
308  file.setf (std::ios::fixed, std::ios::floatfield) ;
309 
310  const char* header = ( hexahedra ) ? "!Hexahedra" : "!Tetrahedra";
311  // write header
312  file << header;
313  file << " ( noVertices = " << indexSet_.size();
314  file << " | noElements = " << noElements << " )" << std :: endl;
315 
316  // write vertex coordinates
317  indexSet_.writeCoordinates( file );
318 
319  file << noElements << std::endl;
320  if( hexahedra )
321  {
322  typedef ElementTopologyMapping< hexa > ElementTopo;
323  writeElements< ElementTopo >( file );
324  writeBoundaries< ElementTopo >( file );
325  }
326  else
327  {
328  typedef ElementTopologyMapping< tetra > ElementTopo;
329  writeElements< ElementTopo >( file );
330  writeBoundaries< ElementTopo >( file );
331  }
332 
333  // write global numbers of indices
334  indexSet_.writeIndices( file );
335  }
336 
337  int getIndex( const Entity& entity, const int i ) const
338  {
339  return indexSet_.subIndex( entity, i, dimension );
340  }
341 
342  template <class ElementTopo>
343  void writeElements( std::ostream& out ) const
344  {
345  typedef typename GridPartType :: template Codim< 0 > :: IteratorType IteratorType;
346  const IteratorType endit = gridPart_.template end< 0 > ();
347  for(IteratorType it = gridPart_.template begin< 0 > ();
348  it != endit; ++it )
349  {
350  const Entity& entity = *it ;
351  const int nVx = entity.subEntities( dimension );
352 
353  out << getIndex( entity, ElementTopo::dune2aluVertex( 0 ) );
354  for(int i=1; i<nVx; ++i)
355  {
356  out << " " << getIndex( entity, ElementTopo::dune2aluVertex( i ));
357  }
358  out << std::endl;
359  }
360  }
361 
362  template <class ElementTopo>
363  void writeBoundaries( std::ostream& out ) const
364  {
365  typedef typename GridPartType :: template Codim< 0 > :: IteratorType IteratorType;
366  typedef typename GridPartType :: IntersectionIteratorType IntersectionIteratorType;
367  typedef typename GridType :: template Codim< 0 > :: Entity Entity;
368  const IteratorType endit = gridPart_.template end< 0 > ();
369  int bndFaces = 0;
370  for(IteratorType it = gridPart_.template begin< 0 > ();
371  it != endit; ++it )
372  {
373  const Entity& entity = *it ;
374  const IntersectionIteratorType endnit = gridPart_.iend( entity );
375  for( IntersectionIteratorType nit = gridPart_.ibegin( entity );
376  nit != endnit ; ++nit )
377  {
378  typedef typename IntersectionIteratorType :: Intersection Intersection;
379  const Intersection& inter = *nit;
380  if( inter.boundary() )
381  ++bndFaces;
382  else if( inter.neighbor() &&
383  make_entity( inter.outside() ).partitionType() != InteriorEntity )
384  ++bndFaces;
385  }
386  }
387 
388  out << bndFaces << std::endl;
389 
390  for(IteratorType it = gridPart_.template begin< 0 > ();
391  it != endit; ++it )
392  {
393  const Entity& entity = *it ;
394  typedef typename GridType :: ctype coordType;
395  const Dune::ReferenceElement< coordType, dimension > &refElem
396  = Dune::ReferenceElements< coordType, dimension >::general( entity.type() );
397 
398  const IntersectionIteratorType endnit = gridPart_.iend( entity );
399  for( IntersectionIteratorType nit = gridPart_.ibegin( entity );
400  nit != endnit ; ++nit )
401  {
402  typedef typename IntersectionIteratorType :: Intersection Intersection;
403  const Intersection& inter = *nit;
404  int bndId = 0;
405  if( inter.boundary() )
406  {
407  bndId = inter.boundaryId();
408  }
409  else if( inter.neighbor() &&
410  make_entity( inter.outside() ).partitionType() != InteriorEntity )
411  {
412  bndId = 111;
413  }
414 
415  if( bndId != 0 )
416  {
417  out << -bndId << " ";
418  const int duneFace = inter.indexInInside();
419  const int vxNr = refElem.size( duneFace, 1, dimension );
420  out << vxNr;
421 
422  std::vector< int > vertices( vxNr );
423  const int aluFace = ElementTopo :: generic2aluFace( duneFace );
424  for( int i=0; i<vxNr; ++i)
425  {
426  const int j = ElementTopo :: faceVertex( aluFace, i );
427  const int k = ElementTopo :: alu2genericVertex( j );
428  out << " " << indexSet_.subIndex( entity, k, dimension );
429  }
430  out << std::endl;
431  }
432  }
433  }
434  }
435 
436  public:
437  static void dumpMacroGrid(const GridPartType& gridPart,
438  const IndexSetType& indexSet,
439  const std::string& filename,
440  const int p = -1 )
441  {
442  const int rank = ( p < 0 ? gridPart.comm().rank() : p);
443  ALUGridWriter< GridPartType, IndexSetType > writer ( gridPart, indexSet );
444  writer.write( filename, rank );
445  }
446  };
447 
448 
449  } // namespace Fem
450 
451 } // namespace Dune
452 
453 #endif // #ifndef DUNE_FEM_ALUGRIDWRITER_HH
int index(const EntityType &entity) const
Definition: alugridwriter.hh:238
static void dumpMacroGrid(const GridPartType &gridPart, const IndexSetType &indexSet, const std::string &filename, const int p=-1)
Definition: alugridwriter.hh:437
GlobalConsecutiveIndexSet(const GridPartType &gridPart, const bool useIds=false)
Definition: alugridwriter.hh:135
int size() const
Definition: alugridwriter.hh:250
void writeBoundaries(std::ostream &out) const
Definition: alugridwriter.hh:363
ALUGridWriter(const GridPartType &gridPart, const IndexSetType &indexSet)
Definition: alugridwriter.hh:269
Definition: alugridwriter.hh:257
Definition: alugridwriter.hh:23
Dune::EntityPointer< Grid, Implementation >::Entity make_entity(const Dune::EntityPointer< Grid, Implementation > &entityPointer)
Definition: compatibility.hh:23
Definition: coordinate.hh:4
void writeCoordinates(std::ostream &out) const
Definition: alugridwriter.hh:216
void write(const std::string &filename, const int rank) const
Definition: alugridwriter.hh:276
void writeElements(std::ostream &out) const
Definition: alugridwriter.hh:343
int getIndex(const Entity &entity, const int i) const
Definition: alugridwriter.hh:337
void writeIndices(std::ostream &out) const
Definition: alugridwriter.hh:228