Dune Core Modules (unstable)

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