foamVtkCoordSetWriter.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) 2022 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 "foamVtkCoordSetWriter.H"
29 #include "foamVtkOutput.H"
30 #include "globalIndex.H"
31 
32 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
33 
34 void Foam::vtk::coordSetWriter::beginPiece()
35 {
36  // Basic sizes
37  nLocalPoints_ = 0;
38  nLocalVerts_ = 0;
39  nLocalLines_ = 0;
40  nLocalPolys_ = 0;
41 
42  for (const pointField& pts : points_)
43  {
44  const label npts = pts.size();
45  nLocalPoints_ += npts;
46 
47  if (npts)
48  {
49  ++nLocalLines_;
50  }
51  }
52 
53  switch (elemOutput_)
54  {
55  case elemOutputType::NO_ELEMENTS:
56  {
58  break;
59  }
60  case elemOutputType::DEFAULT_ELEMENTS:
61  {
62  if (points_.size() < 2)
63  {
64  //OR nLocalVerts_ = nLocalPoints_;
65  nLocalVerts_ = 0;
66  nLocalLines_ = 0;
67  }
68  break;
69  }
70  case elemOutputType::POINT_ELEMENTS:
71  {
73  nLocalLines_ = 0;
74  break;
75  }
76  case elemOutputType::LINE_ELEMENTS:
77  {
78  // Already determined
79  break;
80  }
81  }
82 
83  // Update sizes, similar to
84  // vtk::polyWriter::beginPiece(const pointField&, const edgeList&)
85 
88 
89  // if (parallel_)
90  // {
91  // reduce(numberOfPoints_, sumOp<label>());
92  // reduce(numberOfCells_, sumOp<label>());
93  // }
94 
95 
96  // Nothing else to do for legacy
97  if (legacy()) return;
98 
99  if (format_)
100  {
101  format().openTag
102  (
105  );
106  if (nLocalVerts_)
107  {
109  }
110  if (nLocalLines_)
111  {
113  }
114  format().closeTag();
115  }
116 }
117 
118 
119 void Foam::vtk::coordSetWriter::writePoints()
120 {
121  this->beginPoints(numberOfPoints_); //<- same as nLocalPoints_
122 
123  {
124  for (const pointField& pts : points_)
125  {
127  }
128  }
129 
130  this->endPoints();
131 }
132 
133 
134 void Foam::vtk::coordSetWriter::writeVertsLegacy()
135 {
136  if (!nLocalVerts_)
137  {
138  return; // Nothing to do
139  }
140 
141  // connectivity = 1 per vertex
142  const label nLocalConns = nLocalVerts_;
143 
144  legacy::beginVerts(os_, nLocalVerts_, nLocalConns);
145 
146  labelList vertLabels(nLocalVerts_ + nLocalConns);
147 
148  auto iter = vertLabels.begin();
149 
150  for (label pointi = 0; pointi < nLocalVerts_; ++pointi)
151  {
152  *iter++ = 1;
153  *iter++ = pointi;
154  }
155 
156  vtk::writeList(format(), vertLabels);
157 
158  if (format_)
159  {
160  format().flush();
161  }
162 }
163 
164 
165 void Foam::vtk::coordSetWriter::writeLinesLegacy()
166 {
167  if (!nLocalLines_)
168  {
169  return; // Nothing to do
170  }
171 
172  // connectivity = use each point
173  label nLocalConns = nLocalPoints_;
174 
175  legacy::beginLines(os_, nLocalLines_, nLocalConns);
176 
177  labelList vertLabels(nLocalLines_ + nLocalConns);
178 
179  auto iter = vertLabels.begin();
180 
181  label localPointi = 0;
182  for (const pointField& pts : points_)
183  {
184  label npts = pts.size();
185 
186  if (npts)
187  {
188  *iter++ = npts;
189  while (npts--)
190  {
191  *iter++ = localPointi;
192  ++localPointi;
193  }
194  }
195  }
196 
197  vtk::writeList(format(), vertLabels);
198 
199  if (format_)
200  {
201  format().flush();
202  }
203 }
204 
205 
206 void Foam::vtk::coordSetWriter::writeVerts()
207 {
208  if (!nLocalVerts_)
209  {
210  return; // Nothing to do
211  }
212 
213  // connectivity = 1 per vertex
214  const label nLocalConns = nLocalVerts_;
215 
216  if (format_)
217  {
219  }
220 
221  //
222  // 'offsets' (connectivity offsets)
223  //
224  {
225  labelList vertOffsets(nLocalVerts_);
226  label nOffs = vertOffsets.size();
227 
228  // if (parallel_)
229  // {
230  // reduce(nOffs, sumOp<label>());
231  // }
232 
233  if (format_)
234  {
235  const uint64_t payLoad = vtk::sizeofData<label>(nOffs);
236 
237  format().beginDataArray<label>(vtk::dataArrayAttr::OFFSETS);
238  format().writeSize(payLoad);
239  }
240 
241  // processor-local connectivity offsets
242 
243  label off = 0;
244 
249 
250  auto iter = vertOffsets.begin();
251 
252  for (label pointi = 0; pointi < nLocalVerts_; ++pointi)
253  {
254  off += 1; // End offset
255  *iter = off;
256  ++iter;
257  }
258 
259  vtk::writeList(format_.ref(), vertOffsets);
260 
261  if (format_)
262  {
263  format().flush();
264  format().endDataArray();
265  }
266  }
267 
268  //
269  // 'connectivity'
270  //
271  {
272  labelList vertLabels(nLocalConns);
273 
274  label nConns = nLocalConns;
275 
276  // if (parallel_)
277  // {
278  // reduce(nConns, sumOp<label>());
279  // }
280 
281  if (format_)
282  {
283  const uint64_t payLoad = vtk::sizeofData<label>(nConns);
284 
285  format().beginDataArray<label>(vtk::dataArrayAttr::CONNECTIVITY);
286  format().writeSize(payLoad * sizeof(label));
287  }
288 
289  {
290  // XML: connectivity only
291  // [id1, id2, ..., id1, id2, ...]
292 
293  auto iter = vertLabels.begin();
294 
295  for (label pointi = 0; pointi < nLocalVerts_; ++pointi)
296  {
297  *iter++ = pointi;
298  }
299  }
300 
301  vtk::writeList(format(), vertLabels);
302 
303  if (format_)
304  {
305  format().flush();
306  format().endDataArray();
307  }
308  }
309 
310 
311  if (format_)
312  {
313  format().endTag(vtk::fileTag::VERTS);
314  }
315 }
316 
317 
318 void Foam::vtk::coordSetWriter::writeLines()
319 {
320  if (!nLocalLines_)
321  {
322  return; // Nothing to do
323  }
324 
325  // connectivity = use each point
326  label nLocalConns = nLocalPoints_;
327 
328  if (format_)
329  {
331  }
332 
333  //
334  // 'offsets' (connectivity offsets)
335  //
336  {
337  labelList vertOffsets(nLocalLines_);
338  label nOffs = vertOffsets.size();
339 
340  // if (parallel_)
341  // {
342  // reduce(nOffs, sumOp<label>());
343  // }
344 
345  if (format_)
346  {
347  const uint64_t payLoad = vtk::sizeofData<label>(nOffs);
348 
349  format().beginDataArray<label>(vtk::dataArrayAttr::OFFSETS);
350  format().writeSize(payLoad);
351  }
352 
353  // processor-local connectivity offsets
354 
355  label off = 0;
356 
361 
362  auto iter = vertOffsets.begin();
363 
364  for (const pointField& pts : points_)
365  {
366  const label npts = pts.size();
367 
368  if (npts)
369  {
370  off += npts; // End offset
371  *iter = off;
372  ++iter;
373  }
374  }
375 
376  vtk::writeList(format_.ref(), vertOffsets);
377 
378  if (format_)
379  {
380  format().flush();
381  format().endDataArray();
382  }
383  }
384 
385  //
386  // 'connectivity'
387  //
388  {
389  labelList vertLabels(nLocalConns);
390 
391  label nConns = nLocalConns;
392 
393  // if (parallel_)
394  // {
395  // reduce(nConns, sumOp<label>());
396  // }
397 
398  if (format_)
399  {
400  const uint64_t payLoad = vtk::sizeofData<label>(nConns);
401 
402  format().beginDataArray<label>(vtk::dataArrayAttr::CONNECTIVITY);
403  format().writeSize(payLoad * sizeof(label));
404  }
405 
406  {
407  // XML: connectivity only
408  // [id1, id2, ..., id1, id2, ...]
409 
410  auto iter = vertLabels.begin();
411 
412  label localPointi = 0;
413  for (const pointField& pts : points_)
414  {
415  label npts = pts.size();
416 
417  while (npts--)
418  {
419  *iter++ = localPointi;
420  ++localPointi;
421  }
422  }
423  }
424 
425 
426  vtk::writeList(format(), vertLabels);
427 
428  if (format_)
429  {
430  format().flush();
431  format().endDataArray();
432  }
433  }
434 
435  if (format_)
436  {
437  format().endTag(vtk::fileTag::LINES);
438  }
439 }
440 
441 
442 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
443 
444 Foam::vtk::coordSetWriter::coordSetWriter
445 (
447  const vtk::outputOptions opts
448 )
449 :
450  vtk::polyWriter(opts),
451 
452  points_(points),
453  instant_(),
454  elemOutput_(DEFAULT_ELEMENTS)
455 {}
456 
457 
458 Foam::vtk::coordSetWriter::coordSetWriter
459 (
461  const fileName& file,
462  bool parallel
463 )
464 :
466 {
467  open(file, parallel);
468 }
469 
470 
471 Foam::vtk::coordSetWriter::coordSetWriter
472 (
474  const vtk::outputOptions opts,
475  const fileName& file,
476  bool parallel
477 )
478 :
479  coordSetWriter(points, opts)
480 {
481  open(file, parallel);
482 }
483 
484 
485 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
486 
488 (
489  const elemOutputType elemOutput
490 )
491 {
492  elemOutput_ = elemOutput;
493 }
494 
495 
497 (
498  const fileName& file,
499  bool parallel
500 )
501 {
502  return vtk::polyWriter::open(file, false); // non-parallel only
503 }
504 
507 {
508  instant_ = inst;
509 }
510 
511 
512 bool Foam::vtk::coordSetWriter::beginFile(std::string title)
513 {
514  if (title.size())
515  {
516  return vtk::fileWriter::beginFile(title);
517  }
518 
519  if (!instant_.name().empty())
520  {
522  (
523  "time='" + instant_.name() + "'"
524  );
525  }
526 
527  // Provide default title
528  return vtk::fileWriter::beginFile("coord-set");
529 }
530 
531 
533 {
534  enter_Piece();
535 
536  beginPiece();
537 
538  writePoints();
539 
540  //const label pointOffset =
541  //(
542  // parallel_ ? globalIndex(nLocalPoints_).localStart() : 0
543  //);
544 
545  if (legacy())
546  {
547  writeVertsLegacy();
548  writeLinesLegacy();
549  }
550  else
551  {
552  writeVerts();
553  writeLines();
554  }
555 
556  return true;
557 }
558 
559 
561 {
562  if (!instant_.name().empty())
563  {
564  vtk::fileWriter::writeTimeValue(instant_.value());
565  }
566 }
567 
568 
570 (
572 )
573 {
574  endPiece();
575 
576  points_ = points;
577 }
578 
579 
581 {
582  // Ignore
583  return false;
584 }
585 
586 
587 // ************************************************************************* //
bool parallel() const noexcept
Parallel output requested?
virtual void setTime(const instant &inst)
Define a time name/value for the output.
autoPtr< vtk::formatter > format_
The VTK formatter in use (only valid on master process)
void setElementType(const elemOutputType elemOutput)
Define preferred element type.
A class for handling file names.
Definition: fileName.H:72
label nLocalVerts_
Local number of vertices (points)
vtk::formatter & format()
The VTK formatter in use. FatalError for off-processor.
bool writeProcIDs()
Write processor ids for each line as CellData or for each point as PointData, depending on isPointDat...
formatter & closeTag(const bool isEmpty=false)
Finish an XML tag, optional as an empty container.
Write as points/lines, optionally with fields, as a vtp file or a legacy vtk file.
void writeTimeValue()
Write the currently set time as "TimeValue" FieldData.
void writeTimeValue(scalar timeValue)
Write "TimeValue" FieldData (name as per Catalyst output)
label numberOfPoints_
The number of field points for the current Piece.
bool legacy() const noexcept
Commonly used query.
Encapsulated combinations of output format options. This is primarily useful when defining the output...
void beginPoints(std::ostream &os, label nPoints)
Emit header for POINTS (with trailing newline).
label nLocalLines_
Local number of lines (edges)
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
const pointField & points
virtual bool open(const fileName &file, bool parallel=false)
Open file for writing. Non-parallel only.
label nLocalPoints_
Local number of points.
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition: HashTable.H:106
void beginLines(std::ostream &os, label nLines, label nConnectivity=0)
Emit header for LINES (with trailing newline).
void writeList(vtk::formatter &fmt, const UList< uint8_t > &values)
Write a list of uint8_t values.
virtual bool open(const fileName &file, bool parallel=UPstream::parRun())
Open file for writing (creates parent directory).
virtual bool writeGeometry()
Write patch topology.
word format(conversionProperties.get< word >("format"))
An instant of time. Contains the time value and name. Uses Foam::Time when formatting the name...
Definition: instant.H:53
virtual bool beginFile(std::string title="")
Write file header (non-collective)
void piece(const UPtrList< const pointField > &points)
Reset point references to begin a new piece.
label nLocalPolys_
Local number of polys (faces)
virtual bool beginFile(std::string title="")
Write file header (non-collective)
formatter & openTag(const word &tagName, Args &&... args)
Start an XML tag, optionally with attributes.
List< label > labelList
A List of labels.
Definition: List.H:62
void beginVerts(std::ostream &os, label nVerts, label nConnectivity=0)
Emit header for VERTICES (with trailing newline).
formatter & xmlAttr()
No-op write XML attribute (for templating code).
label numberOfCells_
The number of field cells (edges or faces) for the current Piece.
const pointField & pts