Dune Core Modules (2.6.0)

dgfwriter.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 #ifndef DUNE_GRID_IO_FILE_DGFPARSER_DGFWRITER_HH
4 #define DUNE_GRID_IO_FILE_DGFPARSER_DGFWRITER_HH
5 
11 #include <cassert>
12 #include <cstddef>
13 
14 #include <algorithm>
15 #include <fstream>
16 #include <string>
17 #include <type_traits>
18 #include <utility>
19 #include <vector>
20 
23 
24 #include <dune/geometry/referenceelements.hh>
25 #include <dune/geometry/type.hh>
26 
27 #include <dune/grid/common/grid.hh>
28 #include <dune/grid/common/rangegenerators.hh>
29 
30 namespace Dune
31 {
32 
42  template< class GV >
43  class DGFWriter
44  {
45  typedef DGFWriter< GV > This;
46 
47  public:
49  typedef GV GridView;
51  typedef typename GridView::Grid Grid;
52 
54  static const int dimGrid = GridView::dimension;
55 
56  private:
57  typedef typename GridView::IndexSet IndexSet;
58  typedef typename GridView::template Codim< 0 >::Entity Element;
59  typedef typename GridView::Intersection Intersection;
60 
61  typedef typename Element::EntitySeed ElementSeed;
62 
63  typedef typename IndexSet::IndexType Index;
64 
65  public:
70  DGFWriter ( const GridView &gridView )
71  : gridView_( gridView )
72  {}
73 
83  template< class BoundaryData >
84  void write ( std::ostream &gridout, const std::vector< Index > &newElemOrder, BoundaryData &&boundaryData, const std::stringstream &addParams = std::stringstream() ) const;
85 
94  template< class BoundaryData >
95  void write ( std::ostream &gridout, BoundaryData &&boundaryData, const std::stringstream &addParams = std::stringstream() ) const;
96 
105  void write ( std::ostream &gridout, const std::vector< Index > &newElemOrder, const std::stringstream &addParams = std::stringstream() ) const
106  {
107  write( gridout, newElemOrder, [] ( const Intersection &i ) -> int { return boundaryId( i ); }, addParams );
108  }
109 
117  void write ( std::ostream &gridout, const std::stringstream &addParams = std::stringstream() ) const
118  {
119  write( gridout, [] ( const Intersection &i ) -> int { return boundaryId( i ); }, addParams );
120  }
121 
128  template< class... Args >
129  auto write ( const std::string &fileName, Args &&... args ) const
130  -> void_t< decltype( this->write( std::declval< std::ostream & >(), std::declval< Args >()... ) ) >
131  {
132  std::ofstream gridout( fileName );
133  if( gridout )
134  write( gridout, std::forward< Args >( args )... );
135  else
136  std::cerr << "Couldn't open file `"<< fileName << "'!"<< std::endl;
137  }
138 
139  protected:
140  auto elementsSeeds ( const std::vector< Index > &newElemOrder ) const
141  -> std::vector< ElementSeed >;
142 
143  void writeHeader ( std::ostream &gridout ) const;
144  void writeFooter ( std::ostream &gridout ) const;
145 
146  auto writeVertices ( std::ostream &gridout ) const
147  -> std::vector< Index >;
148 
149  void writeElement ( std::ostream &gridout, const std::vector< Index > &dgfIndices, const Element &element, const GeometryType &elementType ) const;
150 
151  void writeSimplices ( std::ostream &gridout, const std::vector< Index > &dgfIndices ) const;
152  void writeSimplices ( std::ostream &gridout, const std::vector< Index > &dgfIndices, const std::vector< ElementSeed > &elementSeeds ) const;
153 
154  void writeCubes ( std::ostream &gridout, const std::vector< Index > &dgfIndices ) const;
155  void writeCubes ( std::ostream &gridout, const std::vector< Index > &dgfIndices, const std::vector< ElementSeed > &elementSeeds ) const;
156 
157  template< class... Args >
158  void writeElements ( std::ostream &gridout, const std::vector< Index > &dgfIndices, const Args &... args ) const;
159 
160  private:
161  template< class I >
162  static auto boundaryId ( const I &i, PriorityTag< 1 > )
163  -> std::enable_if_t< std::is_convertible< std::decay_t< decltype( i.impl().boundaryId() ) >, int >::value, int >
164  {
165  return i.impl().boundaryId();
166  }
167 
168  template< class I >
169  static int boundaryId ( const I &i, PriorityTag< 0 > )
170  {
171  return 1;
172  }
173 
174  protected:
175  static int boundaryId ( const Intersection &i ) { return boundaryId( i, PriorityTag< 42 >() ); }
176 
177  private:
178  static int boundaryId ( const Intersection &, int bndId ) { return bndId; }
179  static int boundaryId ( const Intersection &i, const std::string & ) { return boundaryId( i ); }
180  static int boundaryId ( const Intersection &i, const std::pair< int, std::string > &data ) { return boundrayId( i, data.first ); }
181 
182  static void appendBoundaryData ( std::ostream &gridout, int ) { gridout << std::endl; }
183  static void appendBoundaryData ( std::ostream &gridout, std::pair< int, std::string > &data ) { appendBoundaryData( gridout, data.second ); }
184  static void appendBoundaryData ( std::ostream &gridout, const std::string &s ) { gridout << " : " << s << std::endl; }
185 
186  protected:
187  template< class BoundaryData >
188  void writeBoundaries ( std::ostream &gridout, const std::vector< Index > &dgfIndices, BoundaryData &&boundaryData ) const;
189 
190  void writeBoundaries ( std::ostream &gridout, const std::vector< Index > &dgfIndices ) const
191  {
192  writeBoundaries( gridout, dgfIndices, [] ( const Intersection &i ) -> int { return boundaryId( i ); } );
193  }
194 
195  protected:
196  GridView gridView_;
197  };
198 
199 
200  template< class GV >
201  inline auto DGFWriter< GV >::elementsSeeds ( const std::vector< Index > &newElemOrder ) const
202  -> std::vector< ElementSeed >
203  {
204  const IndexSet &indexSet = gridView_.indexSet();
205 
206  const std::size_t orderSize = newElemOrder.size() ;
207  std::vector< ElementSeed > elementSeeds( orderSize );
208 
209  for( const Element &element : elements( gridView_ ) )
210  {
211  assert( newElemOrder[ indexSet.index( element ) ] < orderSize );
212  elementSeeds[ newElemOrder[ indexSet.index( element ) ] ] = element.seed();
213  }
214 
215  return elementSeeds;
216  }
217 
218 
219  template< class GV >
220  inline void DGFWriter< GV >::writeHeader ( std::ostream &gridout ) const
221  {
222  // set the stream to full double precision
223  gridout.setf( std::ios_base::scientific, std::ios_base::floatfield );
224  gridout.precision( 16 );
225 
226  const IndexSet &indexSet = gridView_.indexSet();
227 
228  // write DGF header
229  gridout << "DGF" << std::endl;
230  gridout << "%" << " Elements = " << indexSet.size( 0 ) << " | Vertices = " << indexSet.size( dimGrid ) << std::endl;
231  }
232 
233 
234  template< class GV >
235  inline void DGFWriter< GV >::writeFooter ( std::ostream &gridout ) const
236  {
237  gridout << std::endl << "#" << std::endl;
238  }
239 
240 
241  template< class GV >
242  inline auto DGFWriter< GV >::writeVertices ( std::ostream &gridout ) const
243  -> std::vector< Index >
244  {
245  const IndexSet &indexSet = gridView_.indexSet();
246 
247  const Index vxSize = indexSet.size( dimGrid );
248  std::vector< Index > dgfIndices( vxSize, vxSize );
249 
250  // write all vertices into the "vertex" block
251  gridout << std::endl << "VERTEX" << std::endl;
252  Index vertexCount = 0;
253  for( const Element &element : elements( gridView_ ) )
254  {
255  for( auto i : range( element.subEntities( dimGrid ) ) )
256  {
257  const Index vxIndex = indexSet.subIndex( element, i, dimGrid );
258  assert( vxIndex < vxSize );
259  if( dgfIndices[ vxIndex ] == vxSize )
260  {
261  dgfIndices[ vxIndex ] = vertexCount++;
262  gridout << element.geometry().corner( i ) << std::endl;
263  }
264  }
265  }
266  gridout << "#" << std::endl;
267 
268  if( vertexCount != vxSize )
269  DUNE_THROW( GridError, "IndexSet reports wrong number of vertices." );
270  return dgfIndices;
271  }
272 
273 
274  template< class GV >
275  inline void DGFWriter< GV >::writeElement ( std::ostream &gridout, const std::vector< Index > &dgfIndices, const Element &element, const GeometryType &elementType ) const
276  {
277  // if element's type is not the same as the type to write the return
278  if( element.type() != elementType )
279  return;
280 
281  // write vertex numbers of the element
282  const IndexSet &indexSet = gridView_.indexSet();
283  for( auto i : range( element.subEntities( Element::dimension ) ) )
284  gridout << (i > 0 ? " " : "") << dgfIndices[ indexSet.subIndex( element, i, dimGrid ) ];
285  gridout << std::endl;
286  }
287 
288 
289  template< class GV >
290  inline void DGFWriter< GV >::writeSimplices ( std::ostream &gridout, const std::vector< Index > &dgfIndices ) const
291  {
292  // write all simplices to the "simplex" block
293  gridout << std::endl << "SIMPLEX" << std::endl;
294 
295  // write all simplex elements
296  for( const Element &element : elements( gridView_ ) )
297  writeElement( gridout, dgfIndices, element, GeometryTypes::simplex( dimGrid ) );
298 
299  // write end marker for block
300  gridout << "#" << std::endl;
301  }
302 
303 
304  template< class GV >
305  inline void DGFWriter< GV >::writeSimplices ( std::ostream &gridout, const std::vector< Index > &dgfIndices, const std::vector< ElementSeed > &elementSeeds ) const
306  {
307  // write all simplices to the "simplex" block
308  gridout << std::endl << "SIMPLEX" << std::endl;
309 
310  // write all simplex elements
311  for( const ElementSeed &seed : elementSeeds )
312  writeElement( gridout, dgfIndices, gridView_.grid().entity( seed ), GeometryTypes::simplex( dimGrid ) );
313 
314  // write end marker for block
315  gridout << "#" << std::endl;
316  }
317 
318 
319  template< class GV >
320  inline void DGFWriter< GV >::writeCubes ( std::ostream &gridout, const std::vector< Index > &dgfIndices ) const
321  {
322  // write all cubes to the "cube" block
323  gridout << std::endl << "CUBE" << std::endl;
324 
325  // write all cube elements
326  for( const Element &element : elements( gridView_ ) )
327  writeElement( gridout, dgfIndices, element, GeometryTypes::cube( dimGrid ) );
328 
329  // write end marker for block
330  gridout << "#" << std::endl;
331  }
332 
333 
334  template< class GV >
335  inline void DGFWriter< GV >::writeCubes ( std::ostream &gridout, const std::vector< Index > &dgfIndices, const std::vector< ElementSeed > &elementSeeds ) const
336  {
337  const IndexSet &indexSet = gridView_.indexSet();
338 
339  // write all cubes to the "cube" block
340  gridout << std::endl << "CUBE" << std::endl;
341 
342  // write all cube elements
343  for( const ElementSeed &seed : elementSeeds )
344  writeElement( gridout, dgfIndices, gridView_.grid().entity( seed ), GeometryTypes::cube( dimGrid ) );
345 
346  // write end marker for block
347  gridout << "#" << std::endl;
348  }
349 
350 
351  template< class GV >
352  template< class... Args >
353  inline void DGFWriter< GV >::writeElements ( std::ostream &gridout, const std::vector< Index > &dgfIndices, const Args &... args ) const
354  {
355  const IndexSet &indexSet = gridView_.indexSet();
356 
357  if( (dimGrid > 1) && (indexSet.size( GeometryTypes::simplex( dimGrid ) ) > 0) )
358  writeSimplices( gridout, dgfIndices, args... );
359 
360  if( indexSet.size( GeometryTypes::cube( dimGrid ) ) > 0 )
361  writeCubes( gridout, dgfIndices, args... );
362  }
363 
364 
365  template< class GV >
366  template< class BoundaryData >
367  inline void DGFWriter< GV >::writeBoundaries ( std::ostream &gridout, const std::vector< Index > &dgfIndices, BoundaryData &&boundaryData ) const
368  {
369  using std::max;
370 
371  const IndexSet &indexSet = gridView_.indexSet();
372 
373  // write all boundaries to the "boundarysegments" block
374  gridout << std::endl << "BOUNDARYSEGMENTS" << std::endl;
375 
376  for( const Element &element : elements( gridView_ ) )
377  {
378  if( !element.hasBoundaryIntersections() )
379  continue;
380 
381  const auto &refElement = ReferenceElements< typename Grid::ctype, dimGrid >::general( element.type() );
382  for( const Intersection &intersection : intersections( gridView_, element ) )
383  {
384  if( !intersection.boundary() )
385  continue;
386 
387  const auto data = boundaryData( intersection );
388  const int bndId = max( boundaryId( intersection, data ), 1 );
389 
390  const int faceNumber = intersection.indexInInside();
391  const unsigned int faceSize = refElement.size( faceNumber, 1, dimGrid );
392  gridout << bndId << " ";
393  for( auto i : range( faceSize ) )
394  {
395  const int j = refElement.subEntity( faceNumber, 1, i, dimGrid );
396  gridout << " " << dgfIndices[ indexSet.subIndex( element, j, dimGrid ) ];
397  }
398  appendBoundaryData( gridout, data );
399  }
400  }
401  gridout << "#" << std::endl;
402  }
403 
404 
405  template< class GV >
406  template< class BoundaryData >
407  inline void DGFWriter< GV >::write ( std::ostream &gridout, const std::vector< Index > &newElemOrder, BoundaryData &&boundaryData, const std::stringstream &addParams ) const
408  {
409  writeHeader( gridout );
410  auto dgfIndices = writeVertices( gridout );
411  writeElements( gridout, dgfIndices, elementSeeds( newElemOrder ) );
412  writeBoundaries( gridout, dgfIndices, std::forward< BoundaryData >( boundaryData ) );
413  gridout << addParams.str();
414  writeFooter( gridout );
415  }
416 
417 
418  template< class GV >
419  template< class BoundaryData >
420  inline void DGFWriter< GV >::write ( std::ostream &gridout, BoundaryData &&boundaryData, const std::stringstream &addParams ) const
421  {
422  writeHeader( gridout );
423  auto dgfIndices = writeVertices( gridout );
424  writeElements( gridout, dgfIndices );
425  writeBoundaries( gridout, dgfIndices, std::forward< BoundaryData >( boundaryData ) );
426  gridout << addParams.str();
427  writeFooter( gridout );
428  }
429 
430 } // namespace Dune
431 
432 #endif // #ifndef DUNE_GRID_IO_FILE_DGFPARSER_DGFWRITER_HH
write a GridView to a DGF file
Definition: dgfwriter.hh:44
static const int dimGrid
dimension of the grid
Definition: dgfwriter.hh:54
DGFWriter(const GridView &gridView)
constructor
Definition: dgfwriter.hh:70
void write(std::ostream &gridout, const std::stringstream &addParams=std::stringstream()) const
write the GridView into a std::ostream
Definition: dgfwriter.hh:117
auto write(const std::string &fileName, Args &&... args) const -> void_t< decltype(this->write(std::declval< std::ostream & >(), std::declval< Args >()...)) >
write the GridView to a file
Definition: dgfwriter.hh:129
void write(std::ostream &gridout, const std::vector< Index > &newElemOrder, const std::stringstream &addParams=std::stringstream()) const
write the GridView into a std::ostream
Definition: dgfwriter.hh:105
void write(std::ostream &gridout, const std::vector< Index > &newElemOrder, BoundaryData &&boundaryData, const std::stringstream &addParams=std::stringstream()) const
write the GridView into a std::ostream
Definition: dgfwriter.hh:407
GV GridView
type of grid view
Definition: dgfwriter.hh:49
GridView::Grid Grid
type of underlying hierarchical grid
Definition: dgfwriter.hh:51
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:277
IndexTypeImp IndexType
The type used for the indices.
Definition: indexidset.hh:90
Different resources needed by all grid implementations.
typename Impl::voider< Types... >::type void_t
Is void for all valid input types (see N3911). The workhorse for C++11 SFINAE-techniques.
Definition: typetraits.hh:39
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
Traits ::IndexSet IndexSet
type of the index set
Definition: gridview.hh:80
Traits ::Intersection Intersection
type of the intersection
Definition: gridview.hh:83
Traits ::Grid Grid
type of the grid
Definition: gridview.hh:77
@ dimension
The dimension of the grid.
Definition: gridview.hh:127
constexpr GeometryType cube(unsigned int dim)
Returns a GeometryType representing a hypercube of dimension dim.
Definition: type.hh:705
constexpr GeometryType simplex(unsigned int dim)
Returns a GeometryType representing a simplex of dimension dim.
Definition: type.hh:696
Dune namespace.
Definition: alignedallocator.hh:10
Utilities for reduction like operations on ranges.
Static tag representing a codimension.
Definition: dimension.hh:22
static const ReferenceElement & general(const GeometryType &type)
get general reference elements
Definition: referenceelements.hh:196
Helper class for tagging priorities.
Definition: typeutilities.hh:71
A unique label for each type of element that can occur in a grid.
Utilities for type computations, constraining overloads, ...
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 1, 22:29, 2024)