foamVtkIndPatchWriter.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-2020 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 "foamVtkIndPatchWriter.H"
29 #include "foamVtkOutput.H"
30 #include "globalIndex.H"
31 
32 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
33 
34 void Foam::vtk::indirectPatchWriter::beginPiece()
35 {
36  // Basic sizes
37  nLocalPoints_ = pp_.nPoints();
38  nLocalFaces_ = pp_.size();
39  nLocalVerts_ = 0;
40 
41  for (const face& f : pp_)
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::indirectPatchWriter::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(), pp_.localPoints());
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 (const int slave : Pstream::subProcs())
108  {
109  IPstream fromSlave(Pstream::commsTypes::blocking, slave);
110 
111  {
112  fromSlave >> recv;
113 
114  vtk::writeList(format(), recv);
115  }
116  }
117  }
118  else
119  {
120  // Send to master
121  OPstream toMaster
122  (
125  );
126 
127  {
128  toMaster << pp_.localPoints();
129  }
130  }
131  }
132 
133 
134  if (format_)
135  {
136  format().flush();
137  format().endDataArray();
138 
139  if (!legacy())
140  {
141  format()
142  .endTag(vtk::fileTag::POINTS);
143  }
144  }
145 }
146 
147 
148 void Foam::vtk::indirectPatchWriter::writePolysLegacy(const label pointOffset)
149 {
150  // Connectivity count without additional storage (done internally)
151 
152  label nFaces = nLocalFaces_;
153  label nVerts = nLocalVerts_;
154 
155  if (parallel_)
156  {
157  reduce(nFaces, sumOp<label>());
158  reduce(nVerts, sumOp<label>());
159  }
160 
161  if (nFaces != numberOfCells_)
162  {
164  << "Expecting " << numberOfCells_
165  << " faces, but found " << nFaces
166  << exit(FatalError);
167  }
168 
169  legacy::beginPolys(os_, nFaces, nVerts);
170 
171  labelList vertLabels(nLocalFaces_ + nLocalVerts_);
172 
173  {
174  // Legacy: size + connectivity together
175  // [nPts, id1, id2, ..., nPts, id1, id2, ...]
176 
177  auto iter = vertLabels.begin();
178 
179  label off = pointOffset;
180 
181  {
182  for (const face& f : pp_.localFaces())
183  {
184  *iter = f.size(); // The size prefix
185  ++iter;
186 
187  for (const label pfi : f)
188  {
189  *iter = pfi + off; // Face vertex label
190  ++iter;
191  }
192  }
193  // off += pp_.nPoints();
194  }
195  }
196 
197 
198  if (parallel_)
199  {
200  vtk::writeListParallel(format_.ref(), vertLabels);
201  }
202  else
203  {
204  vtk::writeList(format(), vertLabels);
205  }
206 
207  if (format_)
208  {
209  format().flush();
210  }
211 }
212 
213 
214 void Foam::vtk::indirectPatchWriter::writePolys(const label pointOffset)
215 {
216  if (format_)
217  {
219  }
220 
221  //
222  // 'connectivity'
223  //
224  {
225  labelList vertLabels(nLocalVerts_);
226 
227  label nVerts = nLocalVerts_;
228 
229  if (parallel_)
230  {
231  reduce(nVerts, sumOp<label>());
232  }
233 
234  if (format_)
235  {
236  const uint64_t payLoad = vtk::sizeofData<label>(nVerts);
237 
238  format().beginDataArray<label>(vtk::dataArrayAttr::CONNECTIVITY);
239  format().writeSize(payLoad * sizeof(label));
240  }
241 
242  {
243  // XML: connectivity only
244  // [id1, id2, ..., id1, id2, ...]
245 
246  auto iter = vertLabels.begin();
247 
248  label off = pointOffset;
249 
250  {
251  for (const face& f : pp_.localFaces())
252  {
253  for (const label pfi : f)
254  {
255  *iter = pfi + off; // Face vertex label
256  ++iter;
257  }
258  }
259  // off += pp_.nPoints();
260  }
261  }
262 
263 
264  if (parallel_)
265  {
266  vtk::writeListParallel(format_.ref(), vertLabels);
267  }
268  else
269  {
270  vtk::writeList(format(), vertLabels);
271  }
272 
273  if (format_)
274  {
275  format().flush();
276  format().endDataArray();
277  }
278  }
279 
280 
281  //
282  // 'offsets' (connectivity offsets)
283  //
284  {
285  labelList vertOffsets(nLocalFaces_);
286  label nOffs = vertOffsets.size();
287 
288  if (parallel_)
289  {
290  reduce(nOffs, sumOp<label>());
291  }
292 
293  if (format_)
294  {
295  const uint64_t payLoad = vtk::sizeofData<label>(nOffs);
296 
297  format().beginDataArray<label>(vtk::dataArrayAttr::OFFSETS);
298  format().writeSize(payLoad);
299  }
300 
301 
302  // processor-local connectivity offsets
303  label off =
304  (
305  parallel_ ? globalIndex(nLocalVerts_).localStart() : 0
306  );
307 
308  auto iter = vertOffsets.begin();
309 
310  {
311  for (const face& f : pp_)
312  {
313  off += f.size(); // End offset
314  *iter = off;
315  ++iter;
316  }
317  }
318 
319 
320  if (parallel_)
321  {
322  vtk::writeListParallel(format_.ref(), vertOffsets);
323  }
324  else
325  {
326  vtk::writeList(format_.ref(), vertOffsets);
327  }
328 
329 
330  if (format_)
331  {
332  format().flush();
333  format().endDataArray();
334  }
335  }
336 
337  if (format_)
338  {
339  format().endTag(vtk::fileTag::POLYS);
340  }
341 }
342 
343 
344 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
345 
346 Foam::vtk::indirectPatchWriter::indirectPatchWriter
347 (
348  const indirectPrimitivePatch& pp,
349  const vtk::outputOptions opts
350 )
351 :
353  pp_(pp),
354  numberOfPoints_(0),
355  numberOfCells_(0),
356  nLocalPoints_(0),
357  nLocalFaces_(0),
358  nLocalVerts_(0)
359 {
360  // We do not currently support append mode
361  opts_.append(false);
362 }
363 
364 
365 Foam::vtk::indirectPatchWriter::indirectPatchWriter
366 (
367  const indirectPrimitivePatch& pp,
368  const fileName& file,
369  bool parallel
370 )
371 :
373 {
374  open(file, parallel);
375 }
376 
377 
378 Foam::vtk::indirectPatchWriter::indirectPatchWriter
379 (
380  const indirectPrimitivePatch& pp,
381  const vtk::outputOptions opts,
382  const fileName& file,
383  bool parallel
384 )
385 :
386  indirectPatchWriter(pp, opts)
387 {
388  open(file, parallel);
389 }
390 
391 
392 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
393 
395 {
396  if (title.size())
397  {
398  return vtk::fileWriter::beginFile(title);
399  }
400 
401  // Provide default title
402  return vtk::fileWriter::beginFile("surfaces");
403 }
404 
405 
407 {
408  enter_Piece();
409 
410  beginPiece();
411 
412  writePoints();
413 
414  const label pointOffset =
415  (
416  parallel_ ? globalIndex(nLocalPoints_).localStart() : 0
417  );
418 
419  if (legacy())
420  {
421  writePolysLegacy(pointOffset);
422  }
423  else
424  {
425  writePolys(pointOffset);
426  }
427 
428  return true;
429 }
430 
431 
433 {
434  return enter_CellData(numberOfCells_, nFields);
435 }
436 
437 
439 {
440  return enter_PointData(numberOfPoints_, nFields);
441 }
442 
443 
444 // ************************************************************************* //
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:71
Foam::vtk::indirectPatchWriter
Write indirectPrimitivePatch faces/points (optionally with fields) as a vtp file or a legacy vtk file...
Definition: foamVtkIndPatchWriter.H:65
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::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 (always 0)
Definition: UPstream.H:452
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::vtk::indirectPatchWriter::writeGeometry
virtual bool writeGeometry()
Write patch topology.
Definition: foamVtkIndPatchWriter.C:406
Foam::globalIndex::localStart
label localStart() const
My local start.
Definition: globalIndexI.H:112
Foam::vtk::dataArrayAttr::OFFSETS
"offsets"
foamVtkIndPatchWriter.H
globalIndex.H
Foam::vtk::fileTag::POLY_DATA
"PolyData"
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::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:458
Foam::vtk::fileWriter::beginFile
virtual bool beginFile(std::string title="")
Write file header (non-collective)
Definition: foamVtkFileWriter.C:317
Foam::vtk::fileTag::POLYS
"Polys"
Foam::vtk::fileWriter::format_
autoPtr< vtk::formatter > format_
The VTK formatter in use (master process)
Definition: foamVtkFileWriter.H:110
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::UPstream::subProcs
static rangeType subProcs(const label communicator=worldComm)
Range of process indices for sub-processes.
Definition: UPstream.H:516
Foam::vtk::indirectPatchWriter::beginCellData
virtual bool beginCellData(label nFields=0)
Begin CellData output section for specified number of fields.
Definition: foamVtkIndPatchWriter.C:432
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::PrimitivePatch::nPoints
label nPoints() const
Return number of points supporting patch faces.
Definition: PrimitivePatch.H:316
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
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
Foam::vtk::indirectPatchWriter::beginPointData
virtual bool beginPointData(label nFields=0)
Begin PointData for specified number of fields.
Definition: foamVtkIndPatchWriter.C:438
f
labelList f(nPoints)
Foam::vtk::formatter::tag
formatter & tag(const word &t, Args &&... args)
Write XML tag without any attributes. Combines openTag/closeTag.
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::vtk::dataArrayAttr::POINTS
"Points"
Foam::vtk::indirectPatchWriter::beginFile
virtual bool beginFile(std::string title="")
Write file header (non-collective)
Definition: foamVtkIndPatchWriter.C:394
Foam::vtk::fileAttr::NUMBER_OF_POLYS
"NumberOfPolys"
Foam::PrimitivePatch
A list of faces which address into the list of points.
Definition: PrimitivePatch.H:85