Dune Core Modules (2.8.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
28#include <dune/grid/common/rangegenerators.hh>
29
30namespace Dune
31{
32
42 template< class GV >
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 -> std::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 -> std::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:123
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. The workhorse for C++11 SFINAE-techniques.
Definition: typetraits.hh:38
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
Traits::Grid Grid
type of the grid
Definition: gridview.hh:80
Traits::IndexSet IndexSet
type of the index set
Definition: gridview.hh:83
Traits::Intersection Intersection
type of the intersection
Definition: gridview.hh:86
@ dimension
The dimension of the grid.
Definition: gridview.hh:130
constexpr GeometryType cube(unsigned int dim)
Returns a GeometryType representing a hypercube of dimension dim.
Definition: type.hh:470
constexpr GeometryType simplex(unsigned int dim)
Returns a GeometryType representing a simplex of dimension dim.
Definition: type.hh:461
auto max(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::max()
Definition: defaults.hh:79
Dune namespace.
Definition: alignedallocator.hh:11
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.111.3 (Nov 13, 23:29, 2024)