Memosa-FVM  0.2
VTKWriter.h
Go to the documentation of this file.
1 // This file os part of FVM
2 // Copyright (c) 2012 FVM Authors
3 // See LICENSE file for terms.
4 
5 #ifndef _VTKWRITER_H_
6 #define _VTKWRITER_H_
7 
8 #include "atype.h"
9 
10 #include "Mesh.h"
11 #include "ArrayWriter.h"
12 #include "Field.h"
13 #include "GeomFields.h"
14 
15 // taken from VTK source
16 #define VTK_EMPTY_CELL 0
17 #define VTK_VERTEX 1
18 #define VTK_POLY_VERTEX 2
19 #define VTK_LINE 3
20 #define VTK_POLY_LINE 4
21 #define VTK_TRIANGLE 5
22 #define VTK_TRIANGLE_STRIP 6
23 #define VTK_POLYGON 7
24 #define VTK_PIXEL 8
25 #define VTK_QUAD 9
26 #define VTK_TETRA 10
27 #define VTK_VOXEL 11
28 #define VTK_HEXAHEDRON 12
29 #define VTK_WEDGE 13
30 #define VTK_PYRAMID 14
31 #define VTK_PENTAGONAL_PRISM 15
32 #define VTK_HEXAGONAL_PRISM 16
33 #define VTK_CONVEX_POINT_SET 41
34 
35 template<class T>
36 class VTKWriter
37 {
38 public:
39  typedef Array<T> TArray;
43 
44  VTKWriter(const GeomFields& geomFields,
45  const MeshList& meshes,
46  const string fileName,
47  const string& comment,
48  const bool binary,
49  const int atypeComponent,
50  const bool surfaceOnly=false) :
51  _geomFields(geomFields),
52  _meshes(meshes),
53  _fp(fopen(fileName.c_str(),"wb")),
54  _binary(binary),
55  _atypeComponent(atypeComponent),
56  _surfaceOnly(surfaceOnly)
57  {
58  if (!_fp)
59  throw CException("VTKWriter: cannot open file " + fileName +
60  "for writing");
61 
62  Field globalIndexField("gIndex");
63 
64  const int numMeshes = _meshes.size();
65  for (int n=0; n<numMeshes; n++)
66  {
67  const Mesh& mesh = *_meshes[n];
68  const StorageSite& nodes = mesh.getNodes();
69  const int numNodes = nodes.getCount();
70  shared_ptr<IntArray> gnPtr(new IntArray(numNodes));
71  globalIndexField.addArray(nodes,gnPtr);
72  *gnPtr = -1;
73  }
74 
75  _gNodeCount = 0;
76  _gCellCount = 0;
77  int gCellNodeCount =0;
78 
79  for (int n=0; n<numMeshes; n++)
80  {
81  const Mesh& mesh = *_meshes[n];
82  const StorageSite& nodes = mesh.getNodes();
83  IntArray& gNodeIndex = dynamic_cast<IntArray&>(globalIndexField[nodes]);
84 
85  if (_surfaceOnly)
86  {
87  foreach(const FaceGroupPtr fgPtr, mesh.getAllFaceGroups())
88  {
89  const FaceGroup& fg = *fgPtr;
90  if (fg.groupType!="interior")
91  {
92  const StorageSite& faces = fg.site;
93  const int faceCount = faces.getCount();
94  const CRConnectivity& faceNodes = mesh.getFaceNodes(faces);
95 
96  for(int f=0; f<faceCount; f++)
97  {
98  const int nFaceNodes = faceNodes.getCount(f);
99  for(int nn=0; nn<nFaceNodes; nn++)
100  {
101  const int node = faceNodes(f,nn);
102  if (gNodeIndex[node] == -1)
103  gNodeIndex[node] = _gNodeCount++;
104  }
105  _gCellCount++;
106  gCellNodeCount += nFaceNodes+1;
107 
108  }
109  }
110  }
111  }
112  else
113  {
114  const StorageSite& cells = mesh.getCells();
115  const int numCells = cells.getSelfCount();
116  const CRConnectivity& cellNodes = mesh.getCellNodes();
117  const IntArray& ibType = dynamic_cast<const IntArray&>(_geomFields.ibType[cells]);
118 
119  for(int c=0; c<numCells; c++)
120  if (ibType[c] == Mesh::IBTYPE_FLUID)
121  {
122  const int nCellNodes = cellNodes.getCount(c);
123  for(int nn=0; nn<nCellNodes; nn++)
124  {
125  const int node = cellNodes(c,nn);
126  if (gNodeIndex[node] == -1)
127  gNodeIndex[node] = _gNodeCount++;
128  }
129  _gCellCount++;
130  gCellNodeCount += nCellNodes+1;
131  }
132  }
133  }
134 
135  Array<Vector<double,3> > gNodeCoords(_gNodeCount);
136 
137  for (int n=0; n<numMeshes; n++)
138  {
139  const Mesh& mesh = *_meshes[n];
140  const StorageSite& nodes = mesh.getNodes();
141  const int numNodes = nodes.getCount();
142 
143  const IntArray& gNodeIndex =
144  dynamic_cast<const IntArray&>(globalIndexField[nodes]);
145 
146  const VectorT3Array& coords =
147  dynamic_cast<const VectorT3Array&>(geomFields.coordinate[nodes]);
148 
149  for(int node=0; node<numNodes; node++)
150  {
151  const int gn = gNodeIndex[node];
152  if (gn != -1)
153  {
154  for(int k=0; k<3; k++)
155  gNodeCoords[gn][k] = coords[node][k];
156  }
157  }
158  }
159 
160  fprintf(_fp,"# vtk DataFile Version 2.0\n");
161  fprintf(_fp,"%s\n",comment.c_str());
162  // if (_surfaceOnly)
163  // fprintf(_fp,"ASCII\nDATASET POLYDATA\n");
164  //else
165  fprintf(_fp,"ASCII\nDATASET UNSTRUCTURED_GRID\n");
166 
167  fprintf(_fp,"POINTS %d double\n", _gNodeCount);
168 
169  for(int node=0; node<_gNodeCount; node++)
170  fprintf(_fp,"%12.5le %12.5le %12.5le\n", gNodeCoords[node][0],
171  gNodeCoords[node][1],gNodeCoords[node][2]);
172 
173  //if (_surfaceOnly)
174  // fprintf(_fp,"LINES");
175  //else
176  fprintf(_fp,"CELLS");
177 
178  fprintf(_fp," %d %d\n", _gCellCount, gCellNodeCount);
179 
180  for (int n=0; n<numMeshes; n++)
181  {
182  const Mesh& mesh = *_meshes[n];
183  const StorageSite& nodes = mesh.getNodes();
184  const IntArray& gNodeIndex =
185  dynamic_cast<const IntArray&>(globalIndexField[nodes]);
186 
187  if (_surfaceOnly)
188  {
189  foreach(const FaceGroupPtr fgPtr, mesh.getAllFaceGroups())
190  {
191  const FaceGroup& fg = *fgPtr;
192  if (fg.groupType!="interior")
193  {
194  const StorageSite& faces = fg.site;
195  const int faceCount = faces.getCount();
196  const CRConnectivity& faceNodes = mesh.getFaceNodes(faces);
197 
198  for(int f=0; f<faceCount; f++)
199  {
200  const int nFaceNodes = faceNodes.getCount(f);
201  fprintf(_fp, "%d ", nFaceNodes);
202  for(int nn=0; nn<nFaceNodes; nn++)
203  {
204  const int node = faceNodes(f,nn);
205  fprintf(_fp, "%d ", gNodeIndex[node]);
206  }
207  fprintf(_fp,"\n");
208  }
209  }
210  }
211  }
212  else
213  {
214 
215  const StorageSite& cells = mesh.getCells();
216  const int numCells = cells.getSelfCount();
217  const IntArray& ibType =
218  dynamic_cast<const IntArray&>(_geomFields.ibType[cells]);
219 
220  const CRConnectivity& cellNodes = mesh.getCellNodes();
221 
222  for(int c=0; c<numCells; c++)
223  if (ibType[c] == Mesh::IBTYPE_FLUID)
224  {
225  const int nCellNodes = cellNodes.getCount(c);
226  fprintf(_fp, "%d ", nCellNodes);
227  for(int nn=0; nn<nCellNodes; nn++)
228  {
229  const int node = cellNodes(c,nn);
230  fprintf(_fp, "%d ", gNodeIndex[node]);
231  }
232  fprintf(_fp,"\n");
233  }
234  }
235  }
236 
237  fprintf(_fp,"CELL_TYPES %d\n", _gCellCount);
238  for (int n=0; n<numMeshes; n++)
239  {
240  const Mesh& mesh = *_meshes[n];
241  const int dim = mesh.getDimension();
242  if (_surfaceOnly)
243  {
244  foreach(const FaceGroupPtr fgPtr, mesh.getAllFaceGroups())
245  {
246  const FaceGroup& fg = *fgPtr;
247  if (fg.groupType!="interior")
248  {
249  const StorageSite& faces = fg.site;
250  const int faceCount = faces.getCount();
251  const CRConnectivity& faceNodes = mesh.getFaceNodes(faces);
252 
253  for(int f=0; f<faceCount; f++)
254  {
255  const int nFaceNodes = faceNodes.getCount(f);
256  int vtkCellType = VTK_POLYGON;
257  if (dim == 2)
258  vtkCellType = VTK_LINE;
259  else if (nFaceNodes == 3)
260  vtkCellType = VTK_TRIANGLE;
261  else if (nFaceNodes == 4)
262  vtkCellType = VTK_QUAD;
263  fprintf(_fp,"%d\n",vtkCellType);
264  }
265  }
266  }
267  }
268  else
269  {
270  const StorageSite& cells = mesh.getCells();
271  const int numCells = cells.getSelfCount();
272  const IntArray& ibType =
273  dynamic_cast<const IntArray&>(_geomFields.ibType[cells]);
274 
275  const CRConnectivity& cellNodes = mesh.getCellNodes();
276 
277  for(int c=0; c<numCells; c++)
278  if (ibType[c] == Mesh::IBTYPE_FLUID)
279  {
280  const int nCellNodes = cellNodes.getCount(c);
281  int vtkCellType = VTK_CONVEX_POINT_SET;
282  if (dim == 2)
283  {
284  if (nCellNodes == 4)
285  vtkCellType = VTK_QUAD;
286  else if (nCellNodes == 3)
287  vtkCellType = VTK_TRIANGLE;
288  else
289  vtkCellType = VTK_POLYGON;
290  }
291  else
292  {
293  if (nCellNodes == 4)
294  vtkCellType = VTK_TETRA;
295  else if (nCellNodes == 8)
296  vtkCellType = VTK_HEXAHEDRON;
297  else if (nCellNodes == 5)
298  vtkCellType = VTK_PYRAMID;
299  else if (nCellNodes == 6)
300  vtkCellType = VTK_WEDGE;
301  }
302  fprintf(_fp,"%d\n",vtkCellType);
303  }
304  }
305  }
306 
307  fprintf(_fp,"CELL_DATA %d\n", _gCellCount);
308 
309  }
310 
311  void init()
312  {}
313 
314 
315  void writeScalarField(const Field& field,
316  const string label)
317  {
318  const int numMeshes = _meshes.size();
319  fprintf(_fp,"SCALARS %s double\n", label.c_str());
320  fprintf(_fp,"LOOKUP_TABLE default\n");
321 
322  for (int n=0; n<numMeshes; n++)
323  {
324  const Mesh& mesh = *_meshes[n];
325  if (_surfaceOnly)
326  {
327  const StorageSite& allFaces = mesh.getFaces();
328  const TArray& a =
329  dynamic_cast<const TArray&>(field[allFaces]);
330 
331  foreach(const FaceGroupPtr fgPtr, mesh.getAllFaceGroups())
332  {
333  const FaceGroup& fg = *fgPtr;
334  if (fg.groupType!="interior")
335  {
336  const StorageSite& faces = fg.site;
337  const int numFaces = faces.getSelfCount();
338  const int offset = faces.getOffset();
339  for(int f=0; f<numFaces; f++)
340  {
341  const int gf = f + offset;
342  fprintf(_fp,"%12.5le\n", (a[gf]));
343  }
344  }
345  }
346  }
347  else
348  {
349  const StorageSite& cells = mesh.getCells();
350  const int numCells = cells.getSelfCount();
351  const IntArray& ibType =
352  dynamic_cast<const IntArray&>(_geomFields.ibType[cells]);
353 
354  const TArray& aCell = dynamic_cast<const TArray&>(field[cells]);
355  for(int c=0; c<numCells; c++)
356  if (ibType[c] == Mesh::IBTYPE_FLUID)
357  {
358  fprintf(_fp,"%12.5le\n", (aCell[c]));
359  }
360  }
361  }
362  }
363 
364  void writeVectorField(const Field& field,const string label)
365  {
366 
367 
368  fprintf(_fp,"VECTORS %s double\n", label.c_str());
369  const int numMeshes = _meshes.size();
370 
371  for (int n=0; n<numMeshes; n++)
372  {
373  const Mesh& mesh = *_meshes[n];
374 
375  if (_surfaceOnly)
376  {
377  const StorageSite& allFaces = mesh.getFaces();
378  const VectorT3Array& v =
379  dynamic_cast<const VectorT3Array&>(field[allFaces]);
380 
381  foreach(const FaceGroupPtr fgPtr, mesh.getAllFaceGroups())
382  {
383  const FaceGroup& fg = *fgPtr;
384  if (fg.groupType!="interior")
385  {
386  const StorageSite& faces = fg.site;
387  const int numFaces = faces.getSelfCount();
388  const int offset = faces.getOffset();
389  for(int f=0; f<numFaces; f++)
390  {
391  const int gf = f + offset;
392  fprintf(_fp,"%12.5le %12.5le %12.5le\n", (v[gf][0]),
393  (v[gf][1]),
394  (v[gf][2])
395  );
396  }
397  }
398  }
399  }
400  else
401  {
402  const StorageSite& cells = mesh.getCells();
403  const int numCells = cells.getSelfCount();
404  const IntArray& ibType =
405  dynamic_cast<const IntArray&>(_geomFields.ibType[cells]);
406 
407  const VectorT3Array& aCell =
408  dynamic_cast<const VectorT3Array&>(field[cells]);
409  for(int c=0; c<numCells; c++)
410  if (ibType[c] == Mesh::IBTYPE_FLUID)
411  {
412  fprintf(_fp,"%12.5le %12.5le %12.5le\n", (aCell[c][0]),
413  (aCell[c][1]),
414  (aCell[c][2])
415  );
416  }
417  }
418  }
419  }
420 
421  void finish()
422  {
423  fclose(_fp);
424  }
425 
426 private:
429  FILE *_fp;
430  const bool _binary;
431  const int _atypeComponent;
434  const bool _surfaceOnly;
435 };
436 #endif
int getCount(const int i) const
shared_ptr< FaceGroup > FaceGroupPtr
Definition: Mesh.h:46
int getSelfCount() const
Definition: StorageSite.h:40
Field coordinate
Definition: GeomFields.h:19
const MeshList _meshes
Definition: VTKWriter.h:428
void finish()
Definition: VTKWriter.h:421
Definition: Mesh.h:28
const FaceGroupList & getAllFaceGroups() const
Definition: Mesh.h:193
const StorageSite & getNodes() const
Definition: Mesh.h:110
Definition: Field.h:14
#define VTK_QUAD
Definition: VTKWriter.h:25
const int _atypeComponent
Definition: VTKWriter.h:431
#define VTK_TRIANGLE
Definition: VTKWriter.h:21
void init()
Definition: VTKWriter.h:311
Definition: Mesh.h:49
const CRConnectivity & getFaceNodes(const StorageSite &site) const
Definition: Mesh.cpp:402
FILE * _fp
Definition: VTKWriter.h:429
string groupType
Definition: Mesh.h:42
Field ibType
Definition: GeomFields.h:38
void writeScalarField(const Field &field, const string label)
Definition: VTKWriter.h:315
Array< T > TArray
Definition: VTKWriter.h:39
#define VTK_HEXAHEDRON
Definition: VTKWriter.h:28
#define VTK_TETRA
Definition: VTKWriter.h:26
const StorageSite & getFaces() const
Definition: Mesh.h:108
#define VTK_LINE
Definition: VTKWriter.h:19
const bool _surfaceOnly
Definition: VTKWriter.h:434
#define VTK_WEDGE
Definition: VTKWriter.h:29
const StorageSite & getCells() const
Definition: Mesh.h:109
Vector< T, 3 > VectorT3
Definition: VTKWriter.h:41
#define VTK_POLYGON
Definition: VTKWriter.h:23
void addArray(const StorageSite &, shared_ptr< ArrayBase > a)
Definition: Field.cpp:72
Definition: Array.h:14
int getOffset() const
Definition: StorageSite.h:87
int _gNodeCount
Definition: VTKWriter.h:432
const GeomFields & _geomFields
Definition: VTKWriter.h:427
#define VTK_CONVEX_POINT_SET
Definition: VTKWriter.h:33
VTKWriter(const GeomFields &geomFields, const MeshList &meshes, const string fileName, const string &comment, const bool binary, const int atypeComponent, const bool surfaceOnly=false)
Definition: VTKWriter.h:44
int getCount() const
Definition: StorageSite.h:39
Array< int > IntArray
Definition: VTKWriter.h:40
const bool _binary
Definition: VTKWriter.h:430
int _gCellCount
Definition: VTKWriter.h:433
int getDimension() const
Definition: Mesh.h:105
void writeVectorField(const Field &field, const string label)
Definition: VTKWriter.h:364
Array< Vector< T, 3 > > VectorT3Array
Definition: VTKWriter.h:42
const CRConnectivity & getCellNodes() const
Definition: Mesh.cpp:426
#define VTK_PYRAMID
Definition: VTKWriter.h:30
vector< Mesh * > MeshList
Definition: Mesh.h:439
StorageSite site
Definition: Mesh.h:40