foamVtuSizingImpl.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) 2016-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 
28 #include "foamVtuSizing.H"
29 #include "foamVtkCore.H"
30 #include "polyMesh.H"
31 #include "cellShape.H"
32 
33 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
34 
35 template<class LabelType>
36 void Foam::vtk::vtuSizing::adjustOffsets
37 (
38  UList<LabelType>& vertOffset,
39  UList<LabelType>& faceOffset,
40  const enum contentType output,
41  const bool hasFaceStream
42 )
43 {
44  // ===========================================
45  // Adjust vertOffset for all cells
46  // A second pass is needed for several reasons.
47  // - Additional (decomposed) cells are placed out of sequence
48  // - INTERNAL1 connectivity has size prefixed
49  //
50  // Cell offsets:
51  // - XML format expects end-offsets,
52  // - INTERNAL1 expects begin-offsets
53  // - INTERNAL2 expects begin/end-offsets
54 
55  switch (output)
56  {
57  case contentType::LEGACY: // Nothing to do
58  break;
59 
60  case contentType::XML:
61  {
62  // Transform cell sizes (vertOffset) into begin offsets
63 
64  // vertOffset[0] already contains its size, leave untouched
65  for (label i = 1; i < vertOffset.size(); ++i)
66  {
67  vertOffset[i] += vertOffset[i-1];
68  }
69 
70  // The end face offsets, leaving -1 untouched
71  if (hasFaceStream)
72  {
73  LabelType prev(0);
74 
75  for (LabelType& off : faceOffset)
76  {
77  const LabelType sz(off);
78  if (sz > 0)
79  {
80  prev += sz;
81  off = prev;
82  }
83  }
84  }
85  break;
86  }
87 
88  case contentType::INTERNAL1:
89  {
90  // Transform cell sizes (vertOffset) into begin offsets
91  {
92  LabelType beg(0);
93 
94  for (LabelType& off : vertOffset)
95  {
96  const LabelType sz(off);
97  off = beg;
98  beg += 1 + sz; // Additional 1 to skip embedded prefix
99  }
100  }
101 
102  // The begin face offsets, leaving -1 untouched
103  if (hasFaceStream)
104  {
105  LabelType beg(0);
106 
107  for (LabelType& off : faceOffset)
108  {
109  const LabelType sz(off);
110  if (sz > 0)
111  {
112  off = beg;
113  beg += sz;
114  }
115  }
116  }
117  break;
118  }
119 
120  case contentType::INTERNAL2:
121  {
122  // Transform cell sizes (vertOffset) into begin/end offsets
123  // input [n1, n2, n3, ..., 0]
124  // becomes [0, n1, n1+n2, n1+n2+n3, ..., nTotal]
125 
126  // The last entry of vertOffset was initialized as zero and
127  // never revisited, so the following loop is OK
128  {
129  LabelType total(0);
130 
131  for (LabelType& off : vertOffset)
132  {
133  const LabelType sz(off);
134  off = total;
135  total += sz;
136  }
137  }
138 
139  // The begin face offsets, leaving -1 untouched
140  if (hasFaceStream)
141  {
142  LabelType beg(0);
143 
144  for (LabelType& off : faceOffset)
145  {
146  const LabelType sz(off);
147  if (sz > 0)
148  {
149  off = beg;
150  beg += sz;
151  }
152  }
153  }
154  break;
155  }
156  }
157 }
158 
159 
160 template<class LabelType>
161 void Foam::vtk::vtuSizing::populateArrays
162 (
163  const polyMesh& mesh,
164  const vtk::vtuSizing& sizing,
165 
166  UList<uint8_t>& cellTypes,
167  UList<LabelType>& vertLabels,
168  UList<LabelType>& vertOffset,
169  UList<LabelType>& faceLabels,
170  UList<LabelType>& faceOffset,
171  const enum contentType output,
172  labelUList& cellMap,
173  labelUList& addPointsIds
174 )
175 {
176  if (sizing.selectionMode() == selectionModeType::SHAPE_MESH)
177  {
179  << "Programming error ... attempting to populate a VTU mesh"
180  << " but it was originally sized using independent cell shapes"
181  << exit(FatalError);
182  }
183 
184  // Verify storage sizes
185  checkSizes
186  (
187  sizing,
188 
189  cellTypes.size(),
190  vertLabels.size(), vertOffset.size(),
191  faceLabels.size(), faceOffset.size(),
192 
193  output,
194 
195  cellMap.size(),
196  addPointsIds.size()
197  );
198 
199  // Characteristics
200 
201  // Are vertLabels prefixed with the size?
202  // Also use as the size of the prefixed information
203  const int prefix =
204  (
205  output == contentType::LEGACY
206  || output == contentType::INTERNAL1
207  ) ? 1 : 0;
208 
209 
210  // Initialization
211 
212  faceOffset = -1;
213 
214  // For INTERNAL2, the vertOffset is (nFieldCells+1), which means that
215  // the last entry is never visited. Set as zero now.
216 
217  if (vertOffset.size())
218  {
219  vertOffset.first() = 0;
220  vertOffset.last() = 0;
221  }
222 
223 
224  const cellModel& tet = cellModel::ref(cellModel::TET);
225  const cellModel& pyr = cellModel::ref(cellModel::PYR);
226  const cellModel& prism = cellModel::ref(cellModel::PRISM);
227  const cellModel& hex = cellModel::ref(cellModel::HEX);
228  const cellModel& wedge = cellModel::ref(cellModel::WEDGE);
229  const cellModel& tetWedge = cellModel::ref(cellModel::TETWEDGE);
230 
231  const cellShapeList& shapes = mesh.cellShapes();
232 
233  // The face owner is needed to determine the face orientation
234  const labelList& owner = mesh.faceOwner();
235 
236  // Unique vertex labels per polyhedral
237  labelHashSet hashUniqId(512);
238 
239  // Index into vertLabels, faceLabels for normal cells
240  label nVertLabels = 0;
241  label nFaceLabels = 0;
242 
243  // Index into vertLabels for decomposed polys
244  label nVertDecomp = sizing.nVertLabels() + prefix*sizing.nCells();
245 
246  // Placement of additional decomposed cells
247  label nCellDecomp = mesh.nCells();
248 
249  // Placement of additional point labels
250  label nPointDecomp = mesh.nPoints();
251 
252  // Non-decomposed polyhedral are represented as a face-stream.
253  // For legacy format, this stream replaces the normal connectivity
254  // information. Use references to alias where the face output should land.
255 
256  UList<LabelType>& faceOutput =
257  (
258  output == contentType::LEGACY
259  ? vertLabels
260  : faceLabels
261  );
262 
263  label& faceIndexer =
264  (
265  output == contentType::LEGACY
266  ? nVertLabels
267  : nFaceLabels
268  );
269 
270  // ===========================================
271  // STAGE 2: Rewrite in VTK form
272  // During this stage, the vertOffset contains the *size* associated with
273  // the per-cell vertLabels entries, and the faceOffset contains the *size*
274  // associated with the per-cell faceLabels.
275 
276 
277  // Special treatment for mesh subsets
278  // Here the cellMap is the list of input cells!
279 
280  const bool isSubsetMesh
281  (
282  sizing.selectionMode() == selectionModeType::SUBSET_MESH
283  );
284 
285  const label nInputCells =
286  (
287  isSubsetMesh
288  ? cellMap.size()
289  : shapes.size()
290  );
291 
292 
293  for
294  (
295  label inputi = 0, cellIndex = 0; // cellIndex: the ouput location
296  inputi < nInputCells;
297  ++inputi, ++cellIndex
298  )
299  {
300  const label celli(isSubsetMesh ? cellMap[inputi] : inputi);
301 
302  const cellShape& shape = shapes[celli];
303  const cellModel& model = shape.model();
304 
305  if (!isSubsetMesh)
306  {
307  cellMap[cellIndex] = celli;
308  }
309 
310  if (model == tet)
311  {
312  cellTypes[cellIndex] = vtk::cellType::VTK_TETRA;
313  constexpr label nShapePoints = 4; // OR shape.size();
314 
315  if (vertOffset.size())
316  {
317  vertOffset[cellIndex] = nShapePoints;
318  }
319  if (prefix)
320  {
321  vertLabels[nVertLabels++] = nShapePoints;
322  }
323 
324  for (const label cpi : shape)
325  {
326  vertLabels[nVertLabels++] = cpi;
327  }
328  }
329  else if (model == pyr)
330  {
332  constexpr label nShapePoints = 5; // OR shape.size();
333 
334  if (vertOffset.size())
335  {
336  vertOffset[cellIndex] = nShapePoints;
337  }
338  if (prefix)
339  {
340  vertLabels[nVertLabels++] = nShapePoints;
341  }
342 
343  for (const label cpi : shape)
344  {
345  vertLabels[nVertLabels++] = cpi;
346  }
347  }
348  else if (model == hex)
349  {
351  constexpr label nShapePoints = 8; // OR shape.size();
352 
353  if (vertOffset.size())
354  {
355  vertOffset[cellIndex] = nShapePoints;
356  }
357  if (prefix)
358  {
359  vertLabels[nVertLabels++] = nShapePoints;
360  }
361 
362  for (const label cpi : shape)
363  {
364  vertLabels[nVertLabels++] = cpi;
365  }
366  }
367  else if (model == prism)
368  {
369  cellTypes[cellIndex] = vtk::cellType::VTK_WEDGE;
370  constexpr label nShapePoints = 6; // OR shape.size();
371 
372  if (vertOffset.size())
373  {
374  vertOffset[cellIndex] = nShapePoints;
375  }
376  if (prefix)
377  {
378  vertLabels[nVertLabels++] = nShapePoints;
379  }
380 
381  // VTK_WEDGE triangles point outwards (swap 1<->2, 4<->5)
382  vertLabels[nVertLabels++] = shape[0];
383  vertLabels[nVertLabels++] = shape[2];
384  vertLabels[nVertLabels++] = shape[1];
385  vertLabels[nVertLabels++] = shape[3];
386  vertLabels[nVertLabels++] = shape[5];
387  vertLabels[nVertLabels++] = shape[4];
388  }
389  else if (model == tetWedge && sizing.decompose())
390  {
391  // Treat as squeezed prism
392  cellTypes[cellIndex] = vtk::cellType::VTK_WEDGE;
393  constexpr label nShapePoints = 6;
394 
395  if (vertOffset.size())
396  {
397  vertOffset[cellIndex] = nShapePoints;
398  }
399  if (prefix)
400  {
401  vertLabels[nVertLabels++] = nShapePoints;
402  }
403 
404  vertLabels[nVertLabels++] = shape[0];
405  vertLabels[nVertLabels++] = shape[2];
406  vertLabels[nVertLabels++] = shape[1];
407  vertLabels[nVertLabels++] = shape[3];
408  vertLabels[nVertLabels++] = shape[4];
409  vertLabels[nVertLabels++] = shape[3];
410  }
411  else if (model == wedge && sizing.decompose())
412  {
413  // Treat as squeezed hex
415  constexpr label nShapePoints = 8;
416 
417  if (vertOffset.size())
418  {
419  vertOffset[cellIndex] = nShapePoints;
420  }
421  if (prefix)
422  {
423  vertLabels[nVertLabels++] = nShapePoints;
424  }
425 
426  vertLabels[nVertLabels++] = shape[0];
427  vertLabels[nVertLabels++] = shape[1];
428  vertLabels[nVertLabels++] = shape[2];
429  vertLabels[nVertLabels++] = shape[2];
430  vertLabels[nVertLabels++] = shape[3];
431  vertLabels[nVertLabels++] = shape[4];
432  vertLabels[nVertLabels++] = shape[5];
433  vertLabels[nVertLabels++] = shape[6];
434  }
435  else if (sizing.decompose())
436  {
437  // Polyhedral cell - decompose into tet/pyr.
438 
439  // Ensure we have the correct orientation for the base of the
440  // primitive cell shape.
441  // If the cell is face owner, the orientation needs to be flipped
442  // to avoid defining negative cells.
443  // VTK may not care, but we'll do it anyhow for safety.
444 
445  // Mapping from additional point to cell, and the new vertex from
446  // the cell-centre
447  const label newVertexLabel = nPointDecomp;
448 
449  addPointsIds[nPointDecomp++] = celli;
450 
451  // Whether to insert cell in place of original or not.
452  bool firstCell = true;
453 
454  const labelList& cFaces = mesh.cells()[celli];
455 
456  for (const label facei : cFaces)
457  {
458  const face& f = mesh.faces()[facei];
459  const bool isOwner = (owner[facei] == celli);
460 
461  // Count triangles/quads in decomposition
462  label nTria = 0, nQuad = 0;
463  f.nTrianglesQuads(mesh.points(), nTria, nQuad);
464 
465  // Do actual decomposition
466  faceList faces3(nTria);
467  faceList faces4(nQuad);
468  nTria = 0, nQuad = 0;
469  f.trianglesQuads(mesh.points(), nTria, nQuad, faces3, faces4);
470 
471  for (const face& quad : faces4)
472  {
473  // Quad becomes a pyramid
474 
475  constexpr label nShapePoints = 5; // pyr (5 vertices)
476 
477  label celLoc, vrtLoc;
478  if (firstCell)
479  {
480  firstCell = false;
481  celLoc = cellIndex;
482  vrtLoc = nVertLabels;
483  nVertLabels += prefix + nShapePoints;
484  }
485  else
486  {
487  celLoc = nCellDecomp++;
488  vrtLoc = nVertDecomp;
489  nVertDecomp += prefix + nShapePoints;
490  }
491  cellMap[celLoc] = celli;
492 
494  if (vertOffset.size())
495  {
496  vertOffset[celLoc] = nShapePoints;
497  }
498  if (prefix)
499  {
500  vertLabels[vrtLoc++] = nShapePoints;
501  }
502 
503  // See note above about the orientation.
504  if (isOwner)
505  {
506  vertLabels[vrtLoc++] = quad[0];
507  vertLabels[vrtLoc++] = quad[3];
508  vertLabels[vrtLoc++] = quad[2];
509  vertLabels[vrtLoc++] = quad[1];
510  }
511  else
512  {
513  vertLabels[vrtLoc++] = quad[0];
514  vertLabels[vrtLoc++] = quad[1];
515  vertLabels[vrtLoc++] = quad[2];
516  vertLabels[vrtLoc++] = quad[3];
517  }
518 
519  // The apex
520  vertLabels[vrtLoc++] = newVertexLabel;
521  }
522 
523  for (const face& tria : faces3)
524  {
525  // Triangle becomes a tetrahedral
526 
527  constexpr label nShapePoints = 4; // tet (4 vertices)
528 
529  label celLoc, vrtLoc;
530  if (firstCell)
531  {
532  firstCell = false;
533  celLoc = cellIndex;
534  vrtLoc = nVertLabels;
535  nVertLabels += prefix + nShapePoints;
536  }
537  else
538  {
539  celLoc = nCellDecomp++;
540  vrtLoc = nVertDecomp;
541  nVertDecomp += prefix + nShapePoints;
542  }
543  cellMap[celLoc] = celli;
544 
546  if (vertOffset.size())
547  {
548  vertOffset[celLoc] = nShapePoints;
549  }
550  if (prefix)
551  {
552  vertLabels[vrtLoc++] = nShapePoints;
553  }
554 
555  // See note above about the orientation.
556  if (isOwner)
557  {
558  vertLabels[vrtLoc++] = tria[0];
559  vertLabels[vrtLoc++] = tria[2];
560  vertLabels[vrtLoc++] = tria[1];
561  }
562  else
563  {
564  vertLabels[vrtLoc++] = tria[0];
565  vertLabels[vrtLoc++] = tria[1];
566  vertLabels[vrtLoc++] = tria[2];
567  }
568 
569  // The apex
570  vertLabels[vrtLoc++] = newVertexLabel;
571  }
572  }
573  }
574  else
575  {
576  // Polyhedral cell - not decomposed
577  hashUniqId.clear(); // unique node ids used (XML, INTERNAL)
578 
579  // face-stream
580  // [nFaces, nFace0Pts, id1, id2, ..., nFace1Pts, id1, id2, ...]
582  const labelList& cFaces = mesh.cells()[celli];
583 
584  const label startLabel = faceIndexer;
585 
586  if (output == contentType::LEGACY)
587  {
588  faceOutput[startLabel] = 0; // placeholder for total size
589  ++faceIndexer;
590  }
591 
592  faceOutput[faceIndexer++] = cFaces.size();
593 
594  for (const label facei : cFaces)
595  {
596  const face& f = mesh.faces()[facei];
597  const bool isOwner = (owner[facei] == celli);
598  const label nFacePoints = f.size();
599 
600  hashUniqId.insert(f);
601 
602  // The number of labels for this face
603  faceOutput[faceIndexer++] = nFacePoints;
604 
605  faceOutput[faceIndexer++] = f[0];
606  if (isOwner)
607  {
608  for (label fp = 1; fp < nFacePoints; ++fp)
609  {
610  faceOutput[faceIndexer++] = f[fp];
611  }
612  }
613  else
614  {
615  for (label fp = nFacePoints - 1; fp > 0; --fp)
616  {
617  faceOutput[faceIndexer++] = f[fp];
618  }
619  }
620  }
621 
622  if (output == contentType::LEGACY)
623  {
624  // Update size for legacy face stream
625  // (subtract 1 to avoid counting the storage location)
626  faceOutput[startLabel] = (faceIndexer - 1 - startLabel);
627  }
628  else
629  {
630  // Size for face stream
631  faceOffset[cellIndex] = (faceIndexer - startLabel);
632 
633  vertOffset[cellIndex] = hashUniqId.size();
634  if (prefix)
635  {
636  vertLabels[nVertLabels++] = hashUniqId.size();
637  }
638 
639  for (const label pointi : hashUniqId.sortedToc())
640  {
641  vertLabels[nVertLabels++] = pointi;
642  }
643  }
644  }
645  }
646 
647  // ===========================================
648  // STAGE 3: Adjust vertOffset for all cells
649  // A second pass is needed for several reasons.
650  // - Additional (decomposed) cells are placed out of sequence
651  // - INTERNAL1 connectivity has size prefixed
652  //
653  // Cell offsets:
654  // - XML format expects end-offsets,
655  // - INTERNAL1 expects begin-offsets
656  // - INTERNAL2 expects begin/end-offsets
657 
658  adjustOffsets<LabelType>
659  (
660  vertOffset,
661  faceOffset,
662  output,
663  sizing.nFaceLabels() // hasFaceStream
664  );
665 }
666 
667 
668 
669 // Synchronize changes here with the following:
670 // - vtuSizing::resetShapes
671 // - vtuSizing::populateArrays
672 
673 template<class LabelType>
674 void Foam::vtk::vtuSizing::populateArrays
675 (
676  const UList<cellShape>& shapes,
677  const vtk::vtuSizing& sizing,
678 
679  UList<uint8_t>& cellTypes,
680  UList<LabelType>& vertLabels,
681  UList<LabelType>& vertOffset,
682  UList<LabelType>& faceLabels,
683  UList<LabelType>& faceOffset,
684  const enum contentType output,
685  labelUList& cellMap,
686  labelUList& addPointsIds
687 )
688 {
689  if (sizing.selectionMode() != selectionModeType::SHAPE_MESH)
690  {
692  << "Programming error ... attempting to populate a VTU mesh"
693  << " from cell shapes, but sizing originated from a different"
694  << " representation" << nl
695  << exit(FatalError);
696  }
697 
698  // Verify storage sizes
699  checkSizes
700  (
701  sizing,
702 
703  cellTypes.size(),
704  vertLabels.size(), vertOffset.size(),
705  faceLabels.size(), faceOffset.size(),
706 
707  output,
708 
709  cellMap.size(),
710  addPointsIds.size()
711  );
712 
713  // Characteristics
714 
715  // Are vertLabels prefixed with the size?
716  // Also use as the size of the prefixed information
717  const int prefix =
718  (
719  output == contentType::LEGACY
720  || output == contentType::INTERNAL1
721  ) ? 1 : 0;
722 
723 
724  // Initialization
725 
726  faceOffset = -1;
727 
728  // For INTERNAL2, the vertOffset is (nFieldCells+1), which means that
729  // the last entry is never visited. Set as zero now.
730 
731  if (vertOffset.size())
732  {
733  vertOffset.first() = 0;
734  vertOffset.last() = 0;
735  }
736 
737 
738  const cellModel& tet = cellModel::ref(cellModel::TET);
739  const cellModel& pyr = cellModel::ref(cellModel::PYR);
740  const cellModel& prism = cellModel::ref(cellModel::PRISM);
741  const cellModel& hex = cellModel::ref(cellModel::HEX);
742 
743  // Index into vertLabels for normal cells
744  label nVertLabels = 0;
745 
746  // ===========================================
747  // STAGE 2: Rewrite in VTK form
748  // During this stage, the vertOffset contains the *size* associated with
749  // the per-cell vertLabels entries, and the faceOffset contains the *size*
750  // associated with the per-cell faceLabels.
751 
752  const label nInputCells = shapes.size();
753 
754  label nIgnored = 0;
755 
756  for
757  (
758  label inputi = 0, cellIndex = 0; // cellIndex: the ouput location
759  inputi < nInputCells;
760  ++inputi, ++cellIndex
761  )
762  {
763  const cellShape& shape = shapes[inputi];
764  const cellModel& model = shape.model();
765 
766  if (model == tet)
767  {
768  cellTypes[cellIndex] = vtk::cellType::VTK_TETRA;
769  constexpr label nShapePoints = 4; // OR shape.size();
770 
771  if (vertOffset.size())
772  {
773  vertOffset[cellIndex] = nShapePoints;
774  }
775  if (prefix)
776  {
777  vertLabels[nVertLabels++] = nShapePoints;
778  }
779 
780  for (const label cpi : shape)
781  {
782  vertLabels[nVertLabels++] = cpi;
783  }
784  }
785  else if (model == pyr)
786  {
788  constexpr label nShapePoints = 5; // OR shape.size();
789 
790  if (vertOffset.size())
791  {
792  vertOffset[cellIndex] = nShapePoints;
793  }
794  if (prefix)
795  {
796  vertLabels[nVertLabels++] = nShapePoints;
797  }
798 
799  for (const label cpi : shape)
800  {
801  vertLabels[nVertLabels++] = cpi;
802  }
803  }
804  else if (model == hex)
805  {
807  constexpr label nShapePoints = 8; // OR shape.size();
808 
809  if (vertOffset.size())
810  {
811  vertOffset[cellIndex] = nShapePoints;
812  }
813  if (prefix)
814  {
815  vertLabels[nVertLabels++] = nShapePoints;
816  }
817 
818  for (const label cpi : shape)
819  {
820  vertLabels[nVertLabels++] = cpi;
821  }
822  }
823  else if (model == prism)
824  {
825  cellTypes[cellIndex] = vtk::cellType::VTK_WEDGE;
826  constexpr label nShapePoints = 6; // OR shape.size();
827 
828  if (vertOffset.size())
829  {
830  vertOffset[cellIndex] = nShapePoints;
831  }
832  if (prefix)
833  {
834  vertLabels[nVertLabels++] = nShapePoints;
835  }
836 
837  // VTK_WEDGE triangles point outwards (swap 1<->2, 4<->5)
838  vertLabels[nVertLabels++] = shape[0];
839  vertLabels[nVertLabels++] = shape[2];
840  vertLabels[nVertLabels++] = shape[1];
841  vertLabels[nVertLabels++] = shape[3];
842  vertLabels[nVertLabels++] = shape[5];
843  vertLabels[nVertLabels++] = shape[4];
844  }
845  else
846  {
847  // Silent here.
848  // - already complained (and skipped) during initial sizing
849  --cellIndex;
850  ++nIgnored;
851  }
852  }
853 
854  // May have been done by caller,
855  // but for additional safety set an identity mapping
856  ListOps::identity(cellMap);
857 
858  // ===========================================
859  // Adjust vertOffset for all cells
860  // A second pass is needed for several reasons.
861  // - Additional (decomposed) cells are placed out of sequence
862  // - INTERNAL1 connectivity has size prefixed
863  //
864  // Cell offsets:
865  // - XML format expects end-offsets,
866  // - INTERNAL1 expects begin-offsets
867  // - INTERNAL2 expects begin/end-offsets
868 
869  adjustOffsets<LabelType>
870  (
871  vertOffset,
872  faceOffset,
873  output,
874  sizing.nFaceLabels() // hasFaceStream
875  );
876 }
877 
878 
879 //unused template<class LabelType, class LabelType2>
880 //unused void Foam::vtk::vtuSizing::renumberVertLabelsInternalImpl
881 //unused (
882 //unused UList<uint8_t>& cellTypes,
883 //unused UList<LabelType>& vertLabels,
884 //unused const LabelType2 globalPointOffset
885 //unused )
886 //unused {
887 //unused // INTERNAL vertLabels = "connectivity" contain
888 //unused // [nLabels, vertex labels...]
889 //unused
890 //unused auto iter = vertLabels.begin();
891 //unused const auto last = vertLabels.end();
892 //unused
893 //unused while (iter < last)
894 //unused {
895 //unused LabelType nLabels = *iter;
896 //unused ++iter;
897 //unused
898 //unused while (nLabels--)
899 //unused {
900 //unused *iter += globalPointOffset;
901 //unused ++iter;
902 //unused }
903 //unused }
904 //unused }
905 
906 
907 // ************************************************************************* //
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::output
static Ostream & output(Ostream &os, const IntRange< T > &range)
Definition: IntRanges.C:66
Foam::cellModel::HEX
hex
Definition: cellModel.H:81
Foam::vtk::VTK_HEXAHEDRON
Definition: foamVtkCore.H:103
Foam::cellShapeList
List< cellShape > cellShapeList
List of cellShapes and PtrList of List of cellShape.
Definition: cellShapeList.H:45
Foam::vtk::VTK_PYRAMID
Definition: foamVtkCore.H:105
Foam::vtk::VTK_POLYHEDRON
Definition: foamVtkCore.H:108
polyMesh.H
Foam::cellModel::TET
tet
Definition: cellModel.H:85
foamVtuSizing.H
Foam::vtk::VTK_WEDGE
Definition: foamVtkCore.H:104
Foam::cellModel::PRISM
prism
Definition: cellModel.H:83
Foam::cellModel::ref
static const cellModel & ref(const modelType model)
Look up reference to cellModel by enumeration. Fatal on failure.
Definition: cellModels.C:157
Foam::FatalError
error FatalError
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::hex
IOstream & hex(IOstream &io)
Definition: IOstream.H:446
Foam::cellModel::WEDGE
wedge
Definition: cellModel.H:82
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::cellModel::PYR
pyr
Definition: cellModel.H:84
cellTypes
const labelList & cellTypes
Definition: setCellMask.H:33
Foam::nl
constexpr char nl
Definition: Ostream.H:404
f
labelList f(nPoints)
Foam::faceList
List< face > faceList
A List of faces.
Definition: faceListFwd.H:47
Foam::ListOps::identity
void identity(labelUList &map, label start=0)
Set identity map with (map[i] == i)
Definition: ListOps.C:203
foamVtkCore.H
Foam::vtk::VTK_TETRA
Definition: foamVtkCore.H:101
cellShape.H
Foam::cellModel::TETWEDGE
tetWedge
Definition: cellModel.H:87
Foam::labelUList
UList< label > labelUList
A UList of labels.
Definition: UList.H:85
Foam::labelHashSet
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition: HashSet.H:85