foamVtkInternalMeshWriter.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2017-2021 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
29 #include "globalIndex.H"
30 #include "Time.H"
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
35 
36 
37 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
38 
39 void Foam::vtk::internalMeshWriter::beginPiece()
40 {
41  // Basic sizes
42 
43  numberOfPoints_ = vtuCells_.nFieldPoints(); // With addPointCellLabels
44  numberOfCells_ = vtuCells_.nFieldCells(); // With decomposed cells
45 
46  if (parallel_)
47  {
48  if (debug > 1)
49  {
51  << ": nPoints=" << numberOfPoints_
52  << " nCells=" << numberOfCells_ << nl;
53  }
54 
55  reduce(numberOfPoints_, sumOp<label>());
56  reduce(numberOfCells_, sumOp<label>());
57  }
58 
60  << "nPoints=" << numberOfPoints_
61  << " nCells=" << numberOfCells_ << nl;
62 
63  // Nothing else to do for legacy
64  if (legacy()) return;
65 
66  if (format_)
67  {
68  format()
69  .tag
70  (
74  );
75  }
76 }
77 
78 
79 void Foam::vtk::internalMeshWriter::writePoints()
80 {
81  this->beginPoints(numberOfPoints_);
82 
83  if (parallel_)
84  {
86  (
87  format_.ref(),
88  mesh_.points(),
89  mesh_.cellCentres(),
90  vtuCells_.addPointCellLabels()
91  );
92  }
93  else
94  {
96  (
97  format(),
98  mesh_.points(),
99  mesh_.cellCentres(),
100  vtuCells_.addPointCellLabels()
101  );
102  }
103 
104 
105  this->endPoints();
106 }
107 
108 
109 void Foam::vtk::internalMeshWriter::writeCellsLegacy(const label pointOffset)
110 {
111  const List<uint8_t>& cellTypes = vtuCells_.cellTypes();
112  const labelList& vertLabels = vtuCells_.vertLabels();
113 
114  label nCells = cellTypes.size();
115  label nVerts = vertLabels.size();
116 
117  if (parallel_)
118  {
119  reduce(nCells, sumOp<label>());
120  reduce(nVerts, sumOp<label>());
121  }
122 
123  if (nCells != numberOfCells_)
124  {
126  << "Expecting " << numberOfCells_
127  << " cells, but found " << nCells
128  << exit(FatalError);
129  }
130 
131 
132  // CELLS
133  {
134  if (format_)
135  {
136  os_ << nl
137  << "CELLS " << nCells << ' ' << nVerts << nl;
138  }
139 
140  if (parallel_)
141  {
143  (
144  format_.ref(),
146  (
147  vertLabels,
148  pointOffset
149  )
150  );
151  }
152  else
153  {
154  vtk::writeList(format(), vertLabels);
155  }
156 
157  if (format_)
158  {
159  format().flush();
160  }
161  }
162 
163 
164  // CELL_TYPES
165  {
166  if (format_)
167  {
168  os_ << nl
169  << "CELL_TYPES " << nCells << nl;
170  }
171 
172  if (parallel_)
173  {
174  vtk::writeListParallel(format_.ref(), cellTypes);
175  }
176  else
177  {
179  }
180 
181  if (format_)
182  {
183  format().flush();
184  }
185  }
186 }
187 
188 
189 void Foam::vtk::internalMeshWriter::writeCellsConnectivity
190 (
191  const label pointOffset
192 )
193 {
194  //
195  // 'connectivity'
196  //
197  {
198  const labelList& vertLabels = vtuCells_.vertLabels();
199  label nVerts = vertLabels.size();
200 
201  if (parallel_)
202  {
203  reduce(nVerts, sumOp<label>());
204  }
205 
206  if (format_)
207  {
208  const uint64_t payLoad = vtk::sizeofData<label>(nVerts);
209 
210  format().beginDataArray<label>(vtk::dataArrayAttr::CONNECTIVITY);
211  format().writeSize(payLoad);
212  }
213 
214  if (parallel_)
215  {
217  (
218  format_.ref(),
220  (
221  vertLabels,
222  pointOffset
223  )
224  );
225  }
226  else
227  {
228  vtk::writeList(format(), vertLabels);
229  }
230 
231  if (format_)
232  {
233  format().flush();
234  format().endDataArray();
235  }
236  }
237 
238 
239  //
240  // 'offsets' (connectivity offsets)
241  //
242  {
243  const labelList& vertOffsets = vtuCells_.vertOffsets();
244  label nOffs = vertOffsets.size();
245 
246  if (parallel_)
247  {
248  reduce(nOffs, sumOp<label>());
249  }
250 
251  if (format_)
252  {
253  const uint64_t payLoad =
254  vtk::sizeofData<label>(nOffs);
255 
256  format().beginDataArray<label>(vtk::dataArrayAttr::OFFSETS);
257  format().writeSize(payLoad);
258  }
259 
260  if (parallel_)
261  {
262  // processor-local connectivity offsets
263  const globalIndex procOffset
264  (
265  vertOffsets.empty() ? 0 : vertOffsets.last()
266  );
267 
268  vtk::writeListParallel(format_.ref(), vertOffsets, procOffset);
269  }
270  else
271  {
272  vtk::writeList(format(), vertOffsets);
273  }
274 
275  if (format_)
276  {
277  format().flush();
278  format().endDataArray();
279  }
280  }
281 
282 
283  //
284  // 'types' (cell types)
285  //
286  {
287  const List<uint8_t>& cellTypes = vtuCells_.cellTypes();
288  label nCells = cellTypes.size();
289 
290  if (parallel_)
291  {
292  reduce(nCells, sumOp<label>());
293  }
294 
295  if (nCells != numberOfCells_)
296  {
298  << "Expecting " << numberOfCells_
299  << " cells, but found " << nCells
300  << exit(FatalError);
301  }
302 
303  if (format_)
304  {
305  const uint64_t payLoad =
306  vtk::sizeofData<uint8_t>(nCells);
307 
308  format().beginDataArray<uint8_t>(vtk::dataArrayAttr::TYPES);
309  format().writeSize(payLoad);
310  }
311 
312  if (parallel_)
313  {
314  vtk::writeListParallel(format_.ref(), cellTypes);
315  }
316  else
317  {
318 // FIXME: clang-13 optimization jumps into incorrect branch
319  #ifdef __clang__
320  checkFormatterValidity();
321  #endif
322 
324  }
325 
326  if (format_)
327  {
328  format().flush();
329  format().endDataArray();
330  }
331  }
332 }
333 
334 
335 void Foam::vtk::internalMeshWriter::writeCellsFaces
336 (
337  const label pointOffset
338 )
339 {
340  label nFaceLabels = vtuCells_.faceLabels().size();
341 
342  if (parallel_)
343  {
344  reduce(nFaceLabels, sumOp<label>());
345  }
346 
347  // Can quit now if there are NO face streams
348  if (!nFaceLabels)
349  {
350  return;
351  }
352 
353  // --------------------------------------------------
354 
355  //
356  // 'faces' (face streams)
357  //
358  const labelList& faceLabels = vtuCells_.faceLabels();
359 
360  {
361  // Already have nFaceLabels (above)
362 
363  if (format_)
364  {
365  const uint64_t payLoad =
366  vtk::sizeofData<label>(nFaceLabels);
367 
368  format().beginDataArray<label>(vtk::dataArrayAttr::FACES);
369  format().writeSize(payLoad);
370  }
371 
372 
373  if (parallel_)
374  {
376  (
377  format_.ref(),
379  (
380  faceLabels,
381  pointOffset
382  )
383  );
384  }
385  else
386  {
387  vtk::writeList(format(), faceLabels);
388  }
389 
390 
391  if (format_)
392  {
393  format().flush();
394  format().endDataArray();
395  }
396  }
397 
398  // 'faceoffsets' (face stream offsets)
399  // -1 to indicate that the cell is a primitive type that does not
400  // have a face stream
401 
402  // If the processor-local mesh has any polyhedrals, we have a list with
403  // the faceoffsets and we just need to renumber.
404  // If the processor-local mesh has NO polyhedrals (but others do), we
405  // need to generate a list of -1 for that processor.
406  //
407  // Result: A face offset value for each cell.
408  {
409  const labelList& faceOffsets = vtuCells_.faceOffsets();
410  const label nLocalCells = vtuCells_.cellTypes().size();
411 
412  label nCells = nLocalCells;
413 
414  if (parallel_)
415  {
416  reduce(nCells, sumOp<label>());
417  }
418 
419  if (format_)
420  {
421  const uint64_t payLoad =
422  vtk::sizeofData<label>(nCells);
423 
424  format().beginDataArray<label>(vtk::dataArrayAttr::FACEOFFSETS);
425  format().writeSize(payLoad);
426  }
427 
428 
429  if (parallel_)
430  {
431  const List<uint8_t>& cellTypes = vtuCells_.cellTypes();
432  const label nLocalCells = cellTypes.size();
433 
434  const globalIndex procOffset(faceLabels.size());
435 
436  labelList faceOffsetsRenumber;
437 
438  if (faceOffsets.size()) // Or check procOffset.localSize()
439  {
440  faceOffsetsRenumber =
442  (
443  faceOffsets,
444  procOffset.localStart()
445  );
446  }
447  else
448  {
449  faceOffsetsRenumber.resize(nLocalCells, -1);
450  }
451 
452  vtk::writeListParallel(format_.ref(), faceOffsetsRenumber);
453  }
454  else
455  {
456  vtk::writeList(format(), faceOffsets);
457  }
458 
459 
460  if (format_)
461  {
462  format().flush();
463  format().endDataArray();
464  }
465  }
466 }
467 
468 
469 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
470 
471 Foam::vtk::internalMeshWriter::internalMeshWriter
472 (
473  const polyMesh& mesh,
474  const vtk::vtuCells& cells,
475  const vtk::outputOptions opts
476 )
477 :
479  numberOfPoints_(0),
480  numberOfCells_(0),
481 
482  mesh_(mesh),
483  vtuCells_(cells)
484 {
485  // We do not currently support append mode
486  opts_.append(false);
487 }
488 
489 
490 Foam::vtk::internalMeshWriter::internalMeshWriter
491 (
492  const polyMesh& mesh,
493  const vtk::vtuCells& cells,
494  const fileName& file,
495  bool parallel
496 )
497 :
499 {
500  open(file, parallel);
501 }
502 
503 
504 Foam::vtk::internalMeshWriter::internalMeshWriter
505 (
506  const polyMesh& mesh,
507  const vtk::vtuCells& cells,
508  const vtk::outputOptions opts,
509  const fileName& file,
510  bool parallel
511 )
512 :
514 {
515  open(file, parallel);
516 }
517 
518 
519 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
520 
522 {
523  if (title.size())
524  {
525  return vtk::fileWriter::beginFile(title);
526  }
527 
528  // Provide default title
529 
531  << "case=" << mesh_.time().caseName()
532  << " region=" << mesh_.name()
533  << " time=" << mesh_.time().timeName()
534  << " index=" << mesh_.time().timeIndex() << endl;
535 
536 
537  if (legacy())
538  {
540  (
541  mesh_.time().globalCaseName()
542  );
543  }
544 
545 
546  // XML (inline)
547 
549  (
550  "case='" + mesh_.time().globalCaseName()
551  + "' region='" + mesh_.name()
552  + "' time='" + mesh_.time().timeName()
553  + "' index='" + Foam::name(mesh_.time().timeIndex())
554  + "'"
555  );
556 }
557 
558 
560 {
561  enter_Piece();
562 
563  beginPiece();
564 
565  writePoints();
566 
567  // Include addPointCellLabels for the point offsets
568  const label pointOffset =
569  (
570  parallel_ ? globalIndex(vtuCells_.nFieldPoints()).localStart() : 0
571  );
572 
573  if (legacy())
574  {
575  writeCellsLegacy(pointOffset);
576  return true;
577  }
578 
579  if (format_)
580  {
582  }
583 
584  writeCellsConnectivity(pointOffset);
585  writeCellsFaces(pointOffset);
586 
587  if (format_)
588  {
589  format().endTag(vtk::fileTag::CELLS);
590  }
591 
592  return true;
593 }
594 
595 
597 {
598  return enter_CellData(numberOfCells_, nFields);
599 }
600 
601 
603 {
604  return enter_PointData(numberOfPoints_, nFields);
605 }
606 
607 
609 {
610  if (isState(outputState::CELL_DATA))
611  {
612  ++nCellData_;
613  }
614  else
615  {
617  << " for cellID field" << nl << endl
618  << exit(FatalError);
619  }
620 
621  const labelList& cellMap = vtuCells_.cellMap();
622 
623 
624  this->beginDataArray<label>("cellID", numberOfCells_);
625 
626  if (parallel_)
627  {
628  // With decomposed cells for the cell offsets
629  const globalIndex globalCellOffset(vtuCells_.nFieldCells());
630 
631  vtk::writeListParallel(format_.ref(), cellMap, globalCellOffset);
632  }
633  else
634  {
635  vtk::writeList(format(), cellMap);
636  }
637 
638  this->endDataArray();
639 }
640 
641 
643 {
644  if (!parallel_)
645  {
646  // Disabled in serial output (meaningless)
647  return false;
648  }
649 
650  return vtk::fileWriter::writeProcIDs(vtuCells_.nFieldCells());
651 }
652 
653 
655 {
656  if (isState(outputState::POINT_DATA))
657  {
658  ++nPointData_;
659  }
660  else
661  {
663  << " for pointID field" << nl << endl
664  << exit(FatalError);
665  }
666 
667 
668  this->beginDataArray<label>("pointID", numberOfPoints_);
669 
670  // Point offset for regular mesh points (without decomposed)
671  const label pointOffset =
672  (
673  parallel_ ? globalIndex(vtuCells_.nPoints()).localStart() : 0
674  );
675 
676  // Cell offset for *regular* mesh cells (without decomposed)
677  const label cellOffset =
678  (
679  parallel_ ? globalIndex(vtuCells_.nCells()).localStart() : 0
680  );
681 
682 
683  labelList pointIds = identity(vtuCells_.nFieldPoints(), pointOffset);
684 
685  // The pointID for added points is the cellID, tag as a negative number
686  label pointi = vtuCells_.nPoints();
687  for (const label celli : vtuCells_.addPointCellLabels())
688  {
689  pointIds[pointi] = (-1 - celli - cellOffset);
690  ++pointi;
691  }
692 
693  if (parallel_)
694  {
695  vtk::writeListParallel(format_.ref(), pointIds);
696  }
697  else
698  {
699  vtk::writeList(format(), pointIds);
700  }
701 
702  this->endDataArray();
703 }
704 
705 
706 // ************************************************************************* //
Foam::vtk::outputOptions
Encapsulated combinations of output format options. This is primarily useful when defining the output...
Definition: foamVtkOutputOptions.H:59
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::vtk::fileWriter
Base class for VTK output writers that handle geometry and fields (eg, vtp, vtu data)....
Definition: foamVtkFileWriter.H:66
Foam::vtk::fileWriter::legacy
bool legacy() const
Commonly used query.
Definition: foamVtkFileWriterI.H:74
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::List::resize
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:139
Foam::vtk::internalMeshWriter::writeCellIDs
void writeCellIDs()
Write cell ids as CellData.
Definition: foamVtkInternalMeshWriter.C:608
Foam::vtk::dataArrayAttr::OFFSETS
"offsets"
globalIndex.H
Foam::vtk::vtuSizing::nFieldPoints
label nFieldPoints() const noexcept
Number of field points = nPoints + nAddPoints.
Definition: foamVtuSizingI.H:105
Foam::vtk::fileWriter::beginFile
virtual bool beginFile(std::string title="")
Write file header (non-collective)
Definition: foamVtkFileWriter.C:393
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::vtk::writeListsParallel
void writeListsParallel(vtk::formatter &fmt, const UList< Type > &values1, const UList< Type > &values2)
Write a list of values and another list of values.
Definition: foamVtkOutputTemplates.C:353
Foam::vtk::dataArrayAttr::FACES
"faces"
Foam::vtk::fileWriter::format_
autoPtr< vtk::formatter > format_
The VTK formatter in use (only valid on master process)
Definition: foamVtkFileWriter.H:110
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
Foam::vtk::internalMeshWriter::writeProcIDs
bool writeProcIDs()
Write processor ids as CellData. This is no-op in serial.
Definition: foamVtkInternalMeshWriter.C:642
Foam::vtk::vtuSizing::copyVertLabelsLegacy
static labelList copyVertLabelsLegacy(const labelUList &connectivity, const label globalPointOffset)
Copy vertex labels with a global point offset - legacy format.
Definition: foamVtuSizing.C:768
Foam::vtk::fileTag::CELLS
"Cells"
format
word format(conversionProperties.get< word >("format"))
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:51
Foam::vtk::internalMeshWriter::beginPointData
virtual bool beginPointData(label nFields=0)
Begin PointData for specified number of fields.
Definition: foamVtkInternalMeshWriter.C:602
Foam::vtk::internalMeshWriter::vtuCells_
const vtuCells & vtuCells_
The volume cells (internalMesh)
Definition: foamVtkInternalMeshWriter.H:87
DebugInFunction
#define DebugInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:388
Foam::vtk::vtuSizing::nFieldCells
label nFieldCells() const noexcept
Number of field cells = nCells + nAddCells.
Definition: foamVtuSizingI.H:99
Foam::vtk::fileAttr::NUMBER_OF_POINTS
"NumberOfPoints"
Foam::vtk::writeList
void writeList(vtk::formatter &fmt, const UList< uint8_t > &values)
Write a list of uint8_t values.
Definition: foamVtkOutput.C:112
Foam::vtk::writeLists
void writeLists(vtk::formatter &fmt, const UList< Type > &values1, const UList< Type > &values2, const labelUList &addressing)
Write a list of values and a list of values via indirect addressing.
Definition: foamVtkOutputTemplates.C:114
Foam::vtk::legacy::beginPoints
void beginPoints(std::ostream &os, label nPoints)
Emit header for POINTS (with trailing newline).
Definition: foamVtkOutputI.H:113
Foam::vtk::fileAttr::NUMBER_OF_CELLS
"NumberOfCells"
Foam::vtk::fileWriter::parallel_
bool parallel_
Writing in parallel (via master)
Definition: foamVtkFileWriter.H:95
Foam::FatalError
error FatalError
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::globalIndex
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:68
Foam::vtk::fileTag::POINT_DATA
"PointData"
PoutInFunction
#define PoutInFunction
Report using Foam::Pout with FUNCTION_NAME prefix.
Definition: messageStream.H:357
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::vtk::dataArrayAttr::TYPES
"types"
Foam::vtk::fileTag::UNSTRUCTURED_GRID
"UnstructuredGrid"
Foam::vtk::internalMeshWriter::debug
static int debug
Debug information.
Definition: foamVtkInternalMeshWriter.H:123
Time.H
Foam::vtk::internalMeshWriter::beginFile
virtual bool beginFile(std::string title="")
Write file header (non-collective)
Definition: foamVtkInternalMeshWriter.C:521
Foam::vtk::vtuSizing::copyVertLabelsXml
static labelList copyVertLabelsXml(const labelUList &connectivity, const label globalPointOffset)
Copy vertex labels with a global point offset - XML format.
Definition: foamVtuSizing.C:851
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
cellTypes
const labelList & cellTypes
Definition: setCellMask.H:33
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::vtk::vtuSizing::copyFaceOffsetsXml
static labelList copyFaceOffsetsXml(const labelUList &faceOffsets, const label prevOffset)
Copy face offsets with an offset from previous - XML format.
Definition: foamVtuSizing.C:945
Foam::vtk::dataArrayAttr::FACEOFFSETS
"faceoffsets"
Foam::vtk::formatter::tag
formatter & tag(const word &t, Args &&... args)
Write XML tag without any attributes. Combines openTag/closeTag.
Foam::List< label >
Foam::vtk::vtuSizing::copyFaceLabelsXml
static labelList copyFaceLabelsXml(const labelUList &faceLabels, const label globalPointOffset)
Copy faces stream labels with a global point offset - XML format.
Definition: foamVtuSizing.C:890
Foam::vtk::vtuCells
A deep-copy description of an OpenFOAM volume mesh in data structures suitable for VTK UnstructuredGr...
Definition: foamVtuCells.H:70
Foam::identity
labelList identity(const label len, label start=0)
Create identity map of the given length with (map[i] == i)
Definition: labelList.C:38
Foam::vtk::internalMeshWriter::beginCellData
virtual bool beginCellData(label nFields=0)
Begin CellData output section for specified number of fields.
Definition: foamVtkInternalMeshWriter.C:596
Foam::vtk::internalMeshWriter::numberOfPoints_
label numberOfPoints_
The number of field points for the current Piece.
Definition: foamVtkInternalMeshWriter.H:78
Foam::vtk::fileWriter::writeProcIDs
bool writeProcIDs(const label nValues)
Write nValues of processor ids as CellData (no-op in serial)
Definition: foamVtkFileWriter.C:545
Foam::vtk::dataArrayAttr::CONNECTIVITY
"connectivity"
Foam::vtk::fileTag::CELL_DATA
"CellData"
foamVtkInternalMeshWriter.H
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::vtk::internalMeshWriter::numberOfCells_
label numberOfCells_
The number of field cells for the current Piece.
Definition: foamVtkInternalMeshWriter.H:81
Foam::vtk::fileTag::PIECE
"Piece"
Foam::vtk::fileWriter::format
vtk::formatter & format()
The VTK formatter in use.
Definition: foamVtkFileWriterI.H:36
cells
const cellShapeList & cells
Definition: gmvOutputHeader.H:3
Foam::vtk::internalMeshWriter::writePointIDs
void writePointIDs()
Write point ids as PointData.
Definition: foamVtkInternalMeshWriter.C:654
Foam::vtk::internalMeshWriter
Write an OpenFOAM volume (internal) geometry and internal fields as a vtu file or a legacy vtk file.
Definition: foamVtkInternalMeshWriter.H:69
Foam::vtk::writeListParallel
void writeListParallel(vtk::formatter &fmt, const UList< Type > &values)
Write a list of values.
Definition: foamVtkOutputTemplates.C:164
Foam::vtk::internalMeshWriter::writeGeometry
virtual bool writeGeometry()
Write mesh topology.
Definition: foamVtkInternalMeshWriter.C:559