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