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  // Nothing else to do for legacy
84  if (legacy()) return;
85 
86  if (format_)
87  {
88  format().openTag
89  (
92  );
93  if (nLocalVerts_)
94  {
96  }
97  if (nLocalLines_)
98  {
100  }
101  format().closeTag();
102  }
103 }
104 
105 
106 void Foam::vtk::coordSetWriter::writePoints()
107 {
108  this->beginPoints(nLocalPoints_);
109 
110  {
111  for (const pointField& pts : points_)
112  {
114  }
115  }
116 
117  this->endPoints();
118 }
119 
120 
121 void Foam::vtk::coordSetWriter::writeVertsLegacy()
122 {
123  if (!nLocalVerts_)
124  {
125  return; // Nothing to do
126  }
127 
128  // connectivity = 1 per vertex
129  const label nLocalConns = nLocalVerts_;
130 
131  legacy::beginVerts(os_, nLocalVerts_, nLocalConns);
132 
133  labelList vertLabels(nLocalVerts_ + nLocalConns);
134 
135  auto iter = vertLabels.begin();
136 
137  for (label pointi = 0; pointi < nLocalVerts_; ++pointi)
138  {
139  *iter++ = 1;
140  *iter++ = pointi;
141  }
142 
143  vtk::writeList(format(), vertLabels);
144 
145  if (format_)
146  {
147  format().flush();
148  }
149 }
150 
151 
152 void Foam::vtk::coordSetWriter::writeLinesLegacy()
153 {
154  if (!nLocalLines_)
155  {
156  return; // Nothing to do
157  }
158 
159  // connectivity = use each point
160  label nLocalConns = nLocalPoints_;
161 
162  legacy::beginLines(os_, nLocalLines_, nLocalConns);
163 
164  labelList vertLabels(nLocalLines_ + nLocalConns);
165 
166  auto iter = vertLabels.begin();
167 
168  label localPointi = 0;
169  for (const pointField& pts : points_)
170  {
171  label npts = pts.size();
172 
173  if (npts)
174  {
175  *iter++ = npts;
176  while (npts--)
177  {
178  *iter++ = localPointi;
179  ++localPointi;
180  }
181  }
182  }
183 
184  vtk::writeList(format(), vertLabels);
185 
186  if (format_)
187  {
188  format().flush();
189  }
190 }
191 
192 
193 void Foam::vtk::coordSetWriter::writeVerts()
194 {
195  if (!nLocalVerts_)
196  {
197  return; // Nothing to do
198  }
199 
200  // connectivity = 1 per vertex
201  const label nLocalConns = nLocalVerts_;
202 
203  if (format_)
204  {
206  }
207 
208  //
209  // 'offsets' (connectivity offsets)
210  //
211  {
212  labelList vertOffsets(nLocalVerts_);
213  label nOffs = vertOffsets.size();
214 
215  // if (parallel_)
216  // {
217  // reduce(nOffs, sumOp<label>());
218  // }
219 
220  if (format_)
221  {
222  const uint64_t payLoad = vtk::sizeofData<label>(nOffs);
223 
224  format().beginDataArray<label>(vtk::dataArrayAttr::OFFSETS);
225  format().writeSize(payLoad);
226  }
227 
228  // processor-local connectivity offsets
229 
230  label off = 0;
231 
236 
237  auto iter = vertOffsets.begin();
238 
239  for (label pointi = 0; pointi < nLocalVerts_; ++pointi)
240  {
241  off += 1; // End offset
242  *iter = off;
243  ++iter;
244  }
245 
246  vtk::writeList(format_.ref(), vertOffsets);
247 
248  if (format_)
249  {
250  format().flush();
251  format().endDataArray();
252  }
253  }
254 
255  //
256  // 'connectivity'
257  //
258  {
259  labelList vertLabels(nLocalConns);
260 
261  label nConns = nLocalConns;
262 
263  // if (parallel_)
264  // {
265  // reduce(nConns, sumOp<label>());
266  // }
267 
268  if (format_)
269  {
270  const uint64_t payLoad = vtk::sizeofData<label>(nConns);
271 
272  format().beginDataArray<label>(vtk::dataArrayAttr::CONNECTIVITY);
273  format().writeSize(payLoad * sizeof(label));
274  }
275 
276  {
277  // XML: connectivity only
278  // [id1, id2, ..., id1, id2, ...]
279 
280  auto iter = vertLabels.begin();
281 
282  for (label pointi = 0; pointi < nLocalVerts_; ++pointi)
283  {
284  *iter++ = pointi;
285  }
286  }
287 
288  vtk::writeList(format(), vertLabels);
289 
290  if (format_)
291  {
292  format().flush();
293  format().endDataArray();
294  }
295  }
296 
297 
298  if (format_)
299  {
300  format().endTag(vtk::fileTag::VERTS);
301  }
302 }
303 
304 
305 void Foam::vtk::coordSetWriter::writeLines()
306 {
307  if (!nLocalLines_)
308  {
309  return; // Nothing to do
310  }
311 
312  // connectivity = use each point
313  label nLocalConns = nLocalPoints_;
314 
315  if (format_)
316  {
318  }
319 
320  //
321  // 'offsets' (connectivity offsets)
322  //
323  {
324  labelList vertOffsets(nLocalLines_);
325  label nOffs = vertOffsets.size();
326 
327  // if (parallel_)
328  // {
329  // reduce(nOffs, sumOp<label>());
330  // }
331 
332  if (format_)
333  {
334  const uint64_t payLoad = vtk::sizeofData<label>(nOffs);
335 
336  format().beginDataArray<label>(vtk::dataArrayAttr::OFFSETS);
337  format().writeSize(payLoad);
338  }
339 
340  // processor-local connectivity offsets
341 
342  label off = 0;
343 
348 
349  auto iter = vertOffsets.begin();
350 
351  for (const pointField& pts : points_)
352  {
353  const label npts = pts.size();
354 
355  if (npts)
356  {
357  off += npts; // End offset
358  *iter = off;
359  ++iter;
360  }
361  }
362 
363  vtk::writeList(format_.ref(), vertOffsets);
364 
365  if (format_)
366  {
367  format().flush();
368  format().endDataArray();
369  }
370  }
371 
372  //
373  // 'connectivity'
374  //
375  {
376  labelList vertLabels(nLocalConns);
377 
378  label nConns = nLocalConns;
379 
380  // if (parallel_)
381  // {
382  // reduce(nConns, sumOp<label>());
383  // }
384 
385  if (format_)
386  {
387  const uint64_t payLoad = vtk::sizeofData<label>(nConns);
388 
389  format().beginDataArray<label>(vtk::dataArrayAttr::CONNECTIVITY);
390  format().writeSize(payLoad * sizeof(label));
391  }
392 
393  {
394  // XML: connectivity only
395  // [id1, id2, ..., id1, id2, ...]
396 
397  auto iter = vertLabels.begin();
398 
399  label localPointi = 0;
400  for (const pointField& pts : points_)
401  {
402  label npts = pts.size();
403 
404  while (npts--)
405  {
406  *iter++ = localPointi;
407  ++localPointi;
408  }
409  }
410  }
411 
412 
413  vtk::writeList(format(), vertLabels);
414 
415  if (format_)
416  {
417  format().flush();
418  format().endDataArray();
419  }
420  }
421 
422  if (format_)
423  {
424  format().endTag(vtk::fileTag::LINES);
425  }
426 }
427 
428 
429 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
430 
431 Foam::vtk::coordSetWriter::coordSetWriter
432 (
434  const vtk::outputOptions opts
435 )
436 :
437  vtk::polyWriter(opts),
438 
439  points_(points),
440  instant_(),
441  elemOutput_(DEFAULT_ELEMENTS)
442 {}
443 
444 
445 Foam::vtk::coordSetWriter::coordSetWriter
446 (
448  const fileName& file,
449  bool parallel
450 )
451 :
453 {
454  open(file, parallel);
455 }
456 
457 
458 Foam::vtk::coordSetWriter::coordSetWriter
459 (
461  const vtk::outputOptions opts,
462  const fileName& file,
463  bool parallel
464 )
465 :
466  coordSetWriter(points, opts)
467 {
468  open(file, parallel);
469 }
470 
471 
472 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
473 
475 (
476  const elemOutputType elemOutput
477 )
478 {
479  elemOutput_ = elemOutput;
480 }
481 
482 
484 (
485  const fileName& file,
486  bool parallel
487 )
488 {
489  return vtk::polyWriter::open(file, false); // non-parallel only
490 }
491 
494 {
495  instant_ = inst;
496 }
497 
498 
499 bool Foam::vtk::coordSetWriter::beginFile(std::string title)
500 {
501  if (title.size())
502  {
503  return vtk::fileWriter::beginFile(title);
504  }
505 
506  if (!instant_.name().empty())
507  {
509  (
510  "time='" + instant_.name() + "'"
511  );
512  }
513 
514  // Provide default title
515  return vtk::fileWriter::beginFile("coord-set");
516 }
517 
518 
520 {
521  enter_Piece();
522 
523  beginPiece();
524 
525  writePoints();
526 
527  //const label pointOffset =
528  //(
529  // parallel_ ? globalIndex(nLocalPoints_).localStart() : 0
530  //);
531 
532  if (legacy())
533  {
534  writeVertsLegacy();
535  writeLinesLegacy();
536  }
537  else
538  {
539  writeVerts();
540  writeLines();
541  }
542 
543  return true;
544 }
545 
546 
548 {
549  if (!instant_.name().empty())
550  {
551  vtk::fileWriter::writeTimeValue(instant_.value());
552  }
553 }
554 
555 
557 (
559 )
560 {
561  endPiece();
562 
563  points_ = points;
564 }
565 
566 
568 {
569  // Ignore
570  return false;
571 }
572 
573 
574 // ************************************************************************* //
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:71
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 (no-op in serial)
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)
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:100
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).
const pointField & pts