foamVtkSurfaceWriter.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) 2018-2019 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 
28 #include "foamVtkSurfaceWriter.H"
29 #include "foamVtkOutput.H"
30 #include "globalIndex.H"
31 
32 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
33 
34 void Foam::vtk::surfaceWriter::beginPiece()
35 {
36  // Basic sizes
37  nLocalPoints_ = points_.get().size();
38  nLocalFaces_ = faces_.get().size();
39  nLocalVerts_ = 0;
40 
41  for (const face& f : faces_.get())
42  {
43  nLocalVerts_ += f.size();
44  }
45 
46  numberOfPoints_ = nLocalPoints_;
47  numberOfCells_ = nLocalFaces_;
48 
49  if (parallel_)
50  {
51  reduce(numberOfPoints_, sumOp<label>());
52  reduce(numberOfCells_, sumOp<label>());
53  }
54 
55 
56  // Nothing else to do for legacy
57  if (legacy()) return;
58 
59  if (format_)
60  {
61  format().tag
62  (
64  vtk::fileAttr::NUMBER_OF_POINTS, numberOfPoints_,
65  vtk::fileAttr::NUMBER_OF_POLYS, numberOfCells_
66  );
67  }
68 }
69 
70 
71 void Foam::vtk::surfaceWriter::writePoints()
72 {
73  if (format_)
74  {
75  if (legacy())
76  {
77  legacy::beginPoints(os_, numberOfPoints_);
78  }
79  else
80  {
81  const uint64_t payLoad = vtk::sizeofData<float, 3>(numberOfPoints_);
82 
83  format()
85  .beginDataArray<float,3>(vtk::dataArrayAttr::POINTS);
86 
87  format().writeSize(payLoad);
88  }
89  }
90 
91 
92  if (parallel_ ? Pstream::master() : true)
93  {
94  {
95  vtk::writeList(format(), points_.get());
96  }
97  }
98 
99 
100  if (parallel_)
101  {
102  if (Pstream::master())
103  {
104  pointField recv;
105 
106  // Receive each point field and write
107  for
108  (
109  int slave=Pstream::firstSlave();
110  slave<=Pstream::lastSlave();
111  ++slave
112  )
113  {
114  IPstream fromSlave(Pstream::commsTypes::blocking, slave);
115 
116  {
117  fromSlave >> recv;
118 
119  vtk::writeList(format(), recv);
120  }
121  }
122  }
123  else
124  {
125  // Send to master
126  OPstream toMaster
127  (
130  );
131 
132  {
133  toMaster << points_.get();
134  }
135  }
136  }
137 
138 
139  if (format_)
140  {
141  format().flush();
142  format().endDataArray();
143 
144  if (!legacy())
145  {
146  format()
147  .endTag(vtk::fileTag::POINTS);
148  }
149  }
150 }
151 
152 
153 void Foam::vtk::surfaceWriter::writePolysLegacy(const label pointOffset)
154 {
155  // Connectivity count without additional storage (done internally)
156 
157  label nFaces = nLocalFaces_;
158  label nVerts = nLocalVerts_;
159 
160  if (parallel_)
161  {
162  reduce(nFaces, sumOp<label>());
163  reduce(nVerts, sumOp<label>());
164  }
165 
166  if (nFaces != numberOfCells_)
167  {
169  << "Expecting " << numberOfCells_
170  << " faces, but found " << nFaces
171  << exit(FatalError);
172  }
173 
174  legacy::beginPolys(os_, nFaces, nVerts);
175 
176  labelList vertLabels(nLocalFaces_ + nLocalVerts_);
177 
178  {
179  // Legacy: size + connectivity together
180  // [nPts, id1, id2, ..., nPts, id1, id2, ...]
181 
182  auto iter = vertLabels.begin();
183 
184  label off = pointOffset;
185 
186  {
187  for (const face& f : faces_.get())
188  {
189  *iter = f.size(); // The size prefix
190  ++iter;
191 
192  for (const label pfi : f)
193  {
194  *iter = pfi + off; // Face vertex label
195  ++iter;
196  }
197  }
198  // off += points_.get().size();
199  }
200  }
201 
202 
203  if (parallel_)
204  {
205  vtk::writeListParallel(format_.ref(), vertLabels);
206  }
207  else
208  {
209  vtk::writeList(format(), vertLabels);
210  }
211 
212  if (format_)
213  {
214  format().flush();
215  }
216 }
217 
218 
219 void Foam::vtk::surfaceWriter::writePolys(const label pointOffset)
220 {
221  if (format_)
222  {
224  }
225 
226  //
227  // 'connectivity'
228  //
229  {
230  labelList vertLabels(nLocalVerts_);
231 
232  label nVerts = nLocalVerts_;
233 
234  if (parallel_)
235  {
236  reduce(nVerts, sumOp<label>());
237  }
238 
239  if (format_)
240  {
241  const uint64_t payLoad = vtk::sizeofData<label>(nVerts);
242 
243  format().beginDataArray<label>(vtk::dataArrayAttr::CONNECTIVITY);
244  format().writeSize(payLoad * sizeof(label));
245  }
246 
247  {
248  // XML: connectivity only
249  // [id1, id2, ..., id1, id2, ...]
250 
251  auto iter = vertLabels.begin();
252 
253  label off = pointOffset;
254 
255  {
256  for (const face& f : faces_.get())
257  {
258  for (const label pfi : f)
259  {
260  *iter = pfi + off; // Face vertex label
261  ++iter;
262  }
263  }
264  // off += points_.get().size();
265  }
266  }
267 
268 
269  if (parallel_)
270  {
271  vtk::writeListParallel(format_.ref(), vertLabels);
272  }
273  else
274  {
275  vtk::writeList(format(), vertLabels);
276  }
277 
278  if (format_)
279  {
280  format().flush();
281  format().endDataArray();
282  }
283  }
284 
285 
286  //
287  // 'offsets' (connectivity offsets)
288  //
289  {
290  labelList vertOffsets(nLocalFaces_);
291  label nOffs = vertOffsets.size();
292 
293  if (parallel_)
294  {
295  reduce(nOffs, sumOp<label>());
296  }
297 
298  if (format_)
299  {
300  const uint64_t payLoad = vtk::sizeofData<label>(nOffs);
301 
302  format().beginDataArray<label>(vtk::dataArrayAttr::OFFSETS);
303  format().writeSize(payLoad);
304  }
305 
306 
307  // processor-local connectivity offsets
308  label off =
309  (
310  parallel_ ? globalIndex(nLocalVerts_).localStart() : 0
311  );
312 
313 
314  auto iter = vertOffsets.begin();
315 
316  {
317  for (const face& f : faces_.get())
318  {
319  off += f.size(); // End offset
320  *iter = off;
321  ++iter;
322  }
323  }
324 
325 
326  if (parallel_)
327  {
328  vtk::writeListParallel(format_.ref(), vertOffsets);
329  }
330  else
331  {
332  vtk::writeList(format_.ref(), vertOffsets);
333  }
334 
335 
336  if (format_)
337  {
338  format().flush();
339  format().endDataArray();
340  }
341  }
342 
343  if (format_)
344  {
345  format().endTag(vtk::fileTag::POLYS);
346  }
347 }
348 
349 
350 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
351 
352 Foam::vtk::surfaceWriter::surfaceWriter
353 (
354  const pointField& points,
355  const faceList& faces,
356  const vtk::outputOptions opts
357 )
358 :
360  points_(std::cref<pointField>(points)),
361  faces_(std::cref<faceList>(faces)),
362  numberOfPoints_(0),
363  numberOfCells_(0),
364  nLocalPoints_(0),
365  nLocalFaces_(0),
366  nLocalVerts_(0),
367  instant_()
368 {
369  // We do not currently support append mode
370  opts_.append(false);
371 }
372 
373 
374 Foam::vtk::surfaceWriter::surfaceWriter
375 (
376  const pointField& points,
377  const faceList& faces,
378  const fileName& file,
379  bool parallel
380 )
381 :
382  surfaceWriter(points, faces)
383 {
384  open(file, parallel);
385 }
386 
387 
388 Foam::vtk::surfaceWriter::surfaceWriter
389 (
390  const pointField& points,
391  const faceList& faces,
392  const vtk::outputOptions opts,
393  const fileName& file,
394  bool parallel
395 )
396 :
397  surfaceWriter(points, faces, opts)
398 {
399  open(file, parallel);
400 }
401 
402 
403 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
404 
406 {
407  instant_ = inst;
408 }
409 
410 
411 bool Foam::vtk::surfaceWriter::beginFile(std::string title)
412 {
413  if (title.size())
414  {
415  return vtk::fileWriter::beginFile(title);
416  }
417 
418  if (instant_.name().size())
419  {
421  (
422  "time='" + instant_.name() + "'"
423  );
424  }
425 
426  // Provide default title
427  return vtk::fileWriter::beginFile("surface");
428 }
429 
430 
432 {
433  enter_Piece();
434 
435  beginPiece();
436 
437  writePoints();
438 
439  const label pointOffset =
440  (
441  parallel_ ? globalIndex(nLocalPoints_).localStart() : 0
442  );
443 
444  if (legacy())
445  {
446  writePolysLegacy(pointOffset);
447  }
448  else
449  {
450  writePolys(pointOffset);
451  }
452 
453  return true;
454 }
455 
456 
458 {
459  return enter_CellData(numberOfCells_, nFields);
460 }
461 
462 
464 {
465  return enter_PointData(numberOfPoints_, nFields);
466 }
467 
468 
470 {
471  if (instant_.name().size())
472  {
473  vtk::fileWriter::writeTimeValue(instant_.value());
474  }
475 }
476 
477 
479 (
480  const pointField& points,
481  const faceList& faces
482 )
483 {
484  endPiece();
485 
486  points_ = std::cref<pointField>(points);
487  faces_ = std::cref<faceList>(faces);
488 }
489 
490 
491 // ************************************************************************* //
Foam::vtk::outputOptions
Encapsulated combinations of output format options. This is primarily useful when defining the output...
Definition: foamVtkOutputOptions.H:59
Foam::vtk::surfaceWriter::beginFile
virtual bool beginFile(std::string title="")
Write file header (non-collective)
Definition: foamVtkSurfaceWriter.C:411
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:74
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
Foam::vtk::writeListParallel
void writeListParallel(vtk::formatter &fmt, const UList< uint8_t > &values)
Write a list of uint8_t values.
Definition: foamVtkOutput.C:126
Foam::vtk::surfaceWriter::piece
void piece(const pointField &points, const faceList &faces)
Reset point, face references to begin a new piece.
Definition: foamVtkSurfaceWriter.C:479
Foam::UPstream::commsTypes::blocking
foamVtkOutput.H
Foam::vtk::fileWriter
Base class for VTK output writers that handle geometry and fields (eg, vtp, vtu data)....
Definition: foamVtkFileWriter.H:66
Foam::UPstream::masterNo
static constexpr int masterNo() noexcept
Process index of the master.
Definition: UPstream.H:432
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:69
Foam::globalIndex::localStart
label localStart() const
My local start.
Definition: globalIndexI.H:112
Foam::vtk::surfaceWriter::writeTimeValue
void writeTimeValue()
Write the currently set time as "TimeValue" FieldData.
Definition: foamVtkSurfaceWriter.C:469
Foam::vtk::dataArrayAttr::OFFSETS
"offsets"
Foam::vtk::surfaceWriter::beginCellData
virtual bool beginCellData(label nFields=0)
Begin CellData output section for specified number of fields.
Definition: foamVtkSurfaceWriter.C:457
globalIndex.H
Foam::vtk::fileWriter::writeTimeValue
void writeTimeValue(scalar timeValue)
Write "TimeValue" FieldData (name as per Catalyst output)
Definition: foamVtkFileWriter.C:446
Foam::vtk::fileTag::POLY_DATA
"PolyData"
Foam::vtk::surfaceWriter::writeGeometry
virtual bool writeGeometry()
Write patch topology.
Definition: foamVtkSurfaceWriter.C:431
Foam::vtk::legacy::beginPolys
void beginPolys(std::ostream &os, label nPolys, label nConnectivity)
Emit header for POLYGONS (with trailing newline).
Definition: foamVtkOutputI.H:121
Foam::vtk::fileWriter::beginFile
virtual bool beginFile(std::string title="")
Write file header (non-collective)
Definition: foamVtkFileWriter.C:317
foamVtkSurfaceWriter.H
Foam::vtk::fileTag::POLYS
"Polys"
Foam::vtk::fileWriter::format_
autoPtr< vtk::formatter > format_
The VTK formatter in use (master process)
Definition: foamVtkFileWriter.H:110
Foam::vtk::surfaceWriter::setTime
virtual void setTime(const instant &inst)
Define a time name/value for the output.
Definition: foamVtkSurfaceWriter.C:405
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::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::Field< vector >
Foam::UPstream::lastSlave
static int lastSlave(const label communicator=0)
Process index of last slave.
Definition: UPstream.H:467
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::legacy::beginPoints
void beginPoints(std::ostream &os, label nPoints)
Emit header for POINTS (with trailing newline).
Definition: foamVtkOutputI.H:113
Foam::vtk::fileWriter::parallel_
bool parallel_
Writing in parallel (via master)
Definition: foamVtkFileWriter.H:95
Foam::FatalError
error FatalError
Foam::vtk::fileTag::POINTS
"Points"
Foam::globalIndex
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:68
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::UPstream::master
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:438
Foam::UPstream::firstSlave
static constexpr int firstSlave() noexcept
Process index of first slave.
Definition: UPstream.H:461
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
f
labelList f(nPoints)
Foam::vtk::surfaceWriter
Write faces/points (optionally with fields) as a vtp file or a legacy vtk file.
Definition: foamVtkSurfaceWriter.H:68
Foam::vtk::formatter::tag
formatter & tag(const word &t, Args &&... args)
Write XML tag without any attributes. Combines openTag/closeTag.
Foam::List< face >
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::vtk::dataArrayAttr::CONNECTIVITY
"connectivity"
Foam::vtk::fileTag::PIECE
"Piece"
Foam::vtk::fileWriter::format
vtk::formatter & format()
The VTK formatter in use.
Definition: foamVtkFileWriterI.H:36
Foam::instant
An instant of time. Contains the time value and name.
Definition: instant.H:52
Foam::vtk::surfaceWriter::beginPointData
virtual bool beginPointData(label nFields=0)
Begin PointData for specified number of fields.
Definition: foamVtkSurfaceWriter.C:463
Foam::vtk::fileAttr::NUMBER_OF_POLYS
"NumberOfPolys"