DUNE PDELab (git)

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
30#include <dune/grid/common/rangegenerators.hh>
31
32namespace Dune
33{
34
44 template< class GV >
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::Grid Grid
type of the grid
Definition: gridview.hh:83
Traits::IndexSet IndexSet
type of the index set
Definition: gridview.hh:86
static constexpr int dimension
The dimension of the grid.
Definition: gridview.hh:134
Traits::Intersection Intersection
type of the intersection
Definition: gridview.hh:89
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
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.111.3 (Nov 24, 23:30, 2024)