DUNE-FEM (unstable)

alugridwriter.hh
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
12
13#if HAVE_DUNE_ALUGRID
14#include <dune/alugrid/3d/topology.hh>
15
16namespace Dune
17{
18
19 namespace Fem
20 {
21
22 template <class GridPartType>
23 class GlobalConsecutiveIndexSet
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 = 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,
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 >
257 class ALUGridWriter
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 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 auto &refElem = Dune::ReferenceElements< coordType, dimension >::general( entity.type() );
396
397 const IntersectionIteratorType endnit = gridPart_.iend( entity );
398 for( IntersectionIteratorType nit = gridPart_.ibegin( entity );
399 nit != endnit ; ++nit )
400 {
401 typedef typename IntersectionIteratorType :: Intersection Intersection;
402 const Intersection& inter = *nit;
403 int bndId = 0;
404 if( inter.boundary() )
405 {
406 bndId = inter.boundaryId();
407 }
408 else if( inter.neighbor() &&
409 inter.outside().partitionType() != InteriorEntity )
410 {
411 bndId = 111;
412 }
413
414 if( bndId != 0 )
415 {
416 out << -bndId << " ";
417 const int duneFace = inter.indexInInside();
418 const int vxNr = refElem.size( duneFace, 1, dimension );
419 out << vxNr;
420
421 std::vector< int > vertices( vxNr );
422 const int aluFace = ElementTopo :: generic2aluFace( duneFace );
423 for( int i=0; i<vxNr; ++i)
424 {
425 const int j = ElementTopo :: faceVertex( aluFace, i );
426 const int k = ElementTopo :: alu2genericVertex( j );
427 out << " " << indexSet_.subIndex( entity, k, dimension );
428 }
429 out << std::endl;
430 }
431 }
432 }
433 }
434
435 public:
436 static void dumpMacroGrid(const GridPartType& gridPart,
437 const IndexSetType& indexSet,
438 const std::string& filename,
439 const int p = -1 )
440 {
441 const int rank = ( p < 0 ? gridPart.comm().rank() : p);
442 ALUGridWriter< GridPartType, IndexSetType > writer ( gridPart, indexSet );
443 writer.write( filename, rank );
444 }
445 };
446
447
448 } // namespace Fem
449
450} // namespace Dune
451
452#endif // #if HAVE_DUNE_ALUGRID
453#endif // #ifndef DUNE_FEM_ALUGRIDWRITER_HH
static constexpr int codimension
Know your own codimension.
Definition: entity.hh:106
Different resources needed by all grid implementations.
Describes the parallel communication interface class for MessageBuffers and DataHandles.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
@ InteriorEntity
all interior entities
Definition: gridenums.hh:31
@ ForwardCommunication
communicate as given in InterfaceType
Definition: gridenums.hh:171
@ InteriorBorder_InteriorBorder_Interface
send/receive interior and border entities
Definition: gridenums.hh:87
constexpr GeometryType vertex
GeometryType representing a vertex.
Definition: type.hh:492
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
constexpr std::bool_constant<((II==value)||...)> contains(std::integer_sequence< T, II... >, std::integral_constant< T, value >)
Checks whether or not a given sequence contains a value.
Definition: integersequence.hh:137
static const ReferenceElement & general(const GeometryType &type)
get general reference elements
Definition: referenceelements.hh:156
std::size_t fixedSize
The number of data items per index if it is fixed, 0 otherwise.
Definition: variablesizecommunicator.hh:264
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 21, 23:30, 2024)