STARCDMeshReader.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) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2016-2019 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "STARCDMeshReader.H"
30#include "oldCyclicPolyPatch.H"
31#include "emptyPolyPatch.H"
32#include "wallPolyPatch.H"
33#include "symmetryPolyPatch.H"
34#include "cellModel.H"
35#include "ListOps.H"
36#include "stringOps.H"
37#include "IFstream.H"
38#include "IOMap.H"
39
40// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
41
42namespace Foam
43{
44
45 // Read and discard to newline
46 static inline void readToNewline(ISstream& is)
47 {
48 char ch = '\n';
49 do
50 {
51 is.get(ch);
52 }
53 while ((is) && ch != '\n');
54 }
55
56} // End namespace Foam
57
58
59// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
60
62(
63 const objectRegistry& registry
64)
65{
66 boundaryRegion_.readDict(registry);
67 cellTable_.readDict(registry);
68}
69
70
71// Read points from <.vrt> file
72//
73/*---------------------------------------------------------------------------*\
74Line 1:
75 PROSTAR_VERTEX [newline]
76
77Line 2:
78 <version> 0 0 0 0 0 0 0 [newline]
79
80Body:
81 <vertexId> <x> <y> <z> [newline]
82
83\*---------------------------------------------------------------------------*/
85(
86 const fileName& inputName,
87 const scalar scaleFactor
88)
89{
90 label nPoints = 0, maxId = 0;
91 token tok;
92
93 // Pass 1:
94 // get # points and maximum vertex label
95 {
96 IFstream is(inputName);
97 readHeader(is, STARCDCore::HEADER_VRT);
98
99 scalar x, y, z;
100
101 while (is.read(tok).good() && tok.isLabel())
102 {
103 const label starVertexId = tok.labelToken();
104
105 is >> x >> y >> z;
106
107 maxId = max(maxId, starVertexId);
108 ++nPoints;
109 }
110 }
111
112 if (!nPoints)
113 {
115 << "No points in file " << inputName << nl
116 << abort(FatalError);
117 }
118
119 Info<< "Number of points = " << nPoints << endl;
120
121 // Set sizes and reset to invalid values
122
123 points_.setSize(nPoints);
124 mapToFoamPointId_.setSize(maxId+1);
125
126 //- Original Point number for a given vertex
127 // might need again in the future
130
131 mapToFoamPointId_ = -1;
132
133 // Pass 2:
134 // construct pointList and conversion table
135 // from Star vertex numbers to Foam point labels
136 {
137 IFstream is(inputName);
138 readHeader(is, STARCDCore::HEADER_VRT);
139
140 label pointi = 0;
141 while (is.read(tok).good() && tok.isLabel())
142 {
143 const label starVertexId = tok.labelToken();
144
145 is >> points_[pointi].x()
146 >> points_[pointi].y()
147 >> points_[pointi].z();
148
149 // might need again in the future
151 mapToFoamPointId_[starVertexId] = pointi;
152 ++pointi;
153 }
154
155 if (nPoints > pointi)
156 {
157 nPoints = pointi;
158 points_.setSize(nPoints);
159 // might need again in the future
161 }
162
163 if
164 (
165 scaleFactor > 0
166 && (scaleFactor > 1.0 + SMALL || scaleFactor < 1.0 - SMALL)
167 )
168 {
169 points_ *= scaleFactor;
170 }
171 }
172
173 return maxId;
174}
175
176
177// Read cells from <.cel> file
178//
179/*---------------------------------------------------------------------------*\
180Line 1:
181 PROSTAR_CELL [newline]
182
183Line 2:
184 <version> 0 0 0 0 0 0 0 [newline]
185
186Body:
187 <cellId> <shapeId> <nLabels> <cellTableId> <typeId> [newline]
188 <cellId> <int1> .. <int8>
189 <cellId> <int9> .. <int16>
190
191 with shapeId:
192 * 1 = point
193 * 2 = line
194 * 3 = shell
195 * 11 = hexa
196 * 12 = prism
197 * 13 = tetra
198 * 14 = pyramid
199 * 255 = polyhedron
200
201 with typeId
202 * 1 = fluid
203 * 2 = solid
204 * 3 = baffle
205 * 4 = shell
206 * 5 = line
207 * 6 = point
208
209For primitive cell shapes, the number of vertices will never exceed 8 (hexa)
210and corresponds to <nLabels>.
211For polyhedral, <nLabels> includes an index table comprising beg/end pairs
212for each cell face.
213
214Strictly speaking, we only need the cellModeller for adding boundaries.
215\*---------------------------------------------------------------------------*/
216
218{
219 label nFluids = 0, nSolids = 0, nBaffles = 0, nShells = 0;
220 label maxId = 0;
221 token tok;
222
223 bool unknownVertices = false;
224
225
226 // Pass 1:
227 // count nFluids, nSolids, nBaffle, nShell and maxId
228 // also see if polyhedral cells were used
229 {
230 IFstream is(inputName);
231 readHeader(is, STARCDCore::HEADER_CEL);
232
233 label shapeId, nLabels, cellTableId, typeId;
234
235 while (is.read(tok).good() && tok.isLabel())
236 {
237 const label starCellId = tok.labelToken();
238
239 is >> shapeId
240 >> nLabels
241 >> cellTableId
242 >> typeId;
243
244 // Skip the rest of the line
245 readToNewline(is);
246
247 // Max 8 indices per line
248 while (nLabels > 0)
249 {
250 readToNewline(is);
251 nLabels -= 8;
252 }
253
254 if (typeId == STARCDCore::starcdFluidType)
255 {
256 ++nFluids;
257 maxId = max(maxId, starCellId);
258
259 if (!cellTable_.found(cellTableId))
260 {
261 cellTable_.setName(cellTableId);
262 cellTable_.setMaterial(cellTableId, "fluid");
263 }
264 }
265 else if (typeId == STARCDCore::starcdSolidType)
266 {
267 ++nSolids;
268 if (keepSolids_)
269 {
270 maxId = max(maxId, starCellId);
271 }
272
273 if (!cellTable_.found(cellTableId))
274 {
275 cellTable_.setName(cellTableId);
276 cellTable_.setMaterial(cellTableId, "solid");
277 }
278 }
279 else if (typeId == STARCDCore::starcdBaffleType)
280 {
281 // baffles have no cellTable entry
282 ++nBaffles;
283 maxId = max(maxId, starCellId);
284 }
285 else if (typeId == STARCDCore::starcdShellType)
286 {
287 ++nShells;
288 if (!cellTable_.found(cellTableId))
289 {
290 cellTable_.setName(cellTableId);
291 cellTable_.setMaterial(cellTableId, "shell");
292 }
293 }
294 }
295 }
296
297 const label nCells = nFluids + (keepSolids_ ? nSolids : 0);
298
299 Info<< "Number of fluids = " << nFluids << nl
300 << "Number of baffles = " << nBaffles << nl
301 << "Number of solids = " << nSolids
302 << (keepSolids_ ? " (treat as fluid)" : " (ignored)") << nl
303 << "Number of shells = " << nShells << " (ignored)" << nl;
304
305 if (!nCells)
306 {
308
309 err << "No cells in file " << inputName << nl;
310
311 if (nShells)
312 {
313 err << "Consists of shells only (typeId=4)." << nl;
314 }
315
316 err << nl
317 << abort(FatalError);
318 }
319
320 cellFaces_.setSize(nCells);
321 cellShapes_.setSize(nCells);
322 cellTableId_.setSize(nCells);
323
324 // information for the interfaces
325 baffleFaces_.setSize(nBaffles);
326
327 // extra space for baffles
328 origCellId_.setSize(nCells + nBaffles);
329 mapToFoamCellId_.setSize(maxId+1);
330 mapToFoamCellId_ = -1;
331
332
333 // avoid undefined shapes for polyhedra
334 cellShape genericShape
335 (
337 );
338
339 // Pass 2:
340 // construct cellFaces_ and possibly cellShapes_
341 {
342 IFstream is(inputName);
343 readHeader(is, STARCDCore::HEADER_CEL);
344
345 labelList starLabels(64);
346 label ignoredLabel, shapeId, nLabels, cellTableId, typeId;
347
348 label celli = 0, bafflei = 0;
349
350 while (is.read(tok).good() && tok.isLabel())
351 {
352 const label starCellId = tok.labelToken();
353
354 is >> shapeId
355 >> nLabels
356 >> cellTableId
357 >> typeId;
358
359 if (nLabels > starLabels.size())
360 {
361 starLabels.setSize(nLabels);
362 }
363 starLabels = -1;
364
365 // Read indices - max 8 per line
366 for (label i = 0; i < nLabels; ++i)
367 {
368 if ((i % 8) == 0)
369 {
370 is >> ignoredLabel; // Skip cellId for continuation lines
371 }
372 is >> starLabels[i];
373 }
374
375 // Skip solid cells
376 if
377 (
379 && !keepSolids_
380 )
381 {
382 continue;
383 }
384
385 // Determine the OpenFOAM cell shape
386 const cellModel* curModelPtr = nullptr;
387
388 // fluid/solid cells
389 switch (shapeId)
390 {
392 curModelPtr = cellModel::ptr(cellModel::HEX);
393 break;
395 curModelPtr = cellModel::ptr(cellModel::PRISM);
396 break;
398 curModelPtr = cellModel::ptr(cellModel::TET);
399 break;
401 curModelPtr = cellModel::ptr(cellModel::PYR);
402 break;
403 }
404
405 if (curModelPtr)
406 {
407 // primitive cell - use shapes
408
409 // convert orig vertex Id to point label
410 bool isBad = false;
411 for (label i=0; i < nLabels; ++i)
412 {
413 label pointId = mapToFoamPointId_[starLabels[i]];
414 if (pointId < 0)
415 {
416 Info<< "Cells inconsistent with vertex file. "
417 << "Star vertex " << starLabels[i]
418 << " does not exist" << endl;
419 isBad = true;
420 unknownVertices = true;
421 }
422 starLabels[i] = pointId;
423 }
424
425 if (isBad)
426 {
427 continue;
428 }
429
430 // record original cell number and lookup
431 origCellId_[celli] = starCellId;
432 mapToFoamCellId_[starCellId] = celli;
433
434 cellTableId_[celli] = cellTableId;
435 cellShapes_[celli] = cellShape
436 (
437 *curModelPtr,
438 SubList<label>(starLabels, nLabels)
439 );
440
441 cellFaces_[celli] = cellShapes_[celli].faces();
442 ++celli;
443 }
444 else if (shapeId == STARCDCore::starcdPoly)
445 {
446 // polyhedral cell
447 label nFaces = starLabels[0] - 1;
448
449 // convert orig vertex id to point label
450 // start with offset (skip the index table)
451 bool isBad = false;
452 for (label i=starLabels[0]; i < nLabels; ++i)
453 {
454 label pointId = mapToFoamPointId_[starLabels[i]];
455 if (pointId < 0)
456 {
457 Info<< "Cells inconsistent with vertex file. "
458 << "Star vertex " << starLabels[i]
459 << " does not exist" << endl;
460 isBad = true;
461 unknownVertices = true;
462 }
463 starLabels[i] = pointId;
464 }
465
466 if (isBad)
467 {
468 continue;
469 }
470
471 // traverse beg/end indices
472 faceList faces(nFaces);
473 label facei = 0;
474 for (label i=0; i < nFaces; ++i)
475 {
476 label beg = starLabels[i];
477 label n = starLabels[i+1] - beg;
478
479 face f
480 (
481 SubList<label>(starLabels, n, beg)
482 );
483
484 f.collapse();
485
486 // valid faces only
487 if (f.size() >= 3)
488 {
489 faces[facei++] = f;
490 }
491 }
492
493 if (nFaces > facei)
494 {
495 Info<< "star cell " << starCellId << " has "
496 << (nFaces - facei)
497 << " empty faces - could cause boundary "
498 << "addressing problems"
499 << endl;
500
501 nFaces = facei;
502 faces.setSize(nFaces);
503 }
504
505 if (nFaces < 4)
506 {
508 << "star cell " << starCellId << " has " << nFaces
509 << abort(FatalError);
510 }
511
512 // record original cell number and lookup
513 origCellId_[celli] = starCellId;
514 mapToFoamCellId_[starCellId] = celli;
515
516 cellTableId_[celli] = cellTableId;
517 cellShapes_[celli] = genericShape;
518 cellFaces_[celli] = faces;
519 ++celli;
520 }
521 else if (typeId == STARCDCore::starcdBaffleType)
522 {
523 // baffles
524
525 // convert orig vertex id to point label
526 bool isBad = false;
527 for (label i=0; i < nLabels; ++i)
528 {
529 label pointId = mapToFoamPointId_[starLabels[i]];
530 if (pointId < 0)
531 {
532 Info<< "Baffles inconsistent with vertex file. "
533 << "Star vertex " << starLabels[i]
534 << " does not exist" << endl;
535 isBad = true;
536 unknownVertices = true;
537 }
538 starLabels[i] = pointId;
539 }
540
541 if (isBad)
542 {
543 continue;
544 }
545
546
547 face f
548 (
549 SubList<label>(starLabels, nLabels)
550 );
551
552 f.collapse();
553
554 // valid faces only
555 if (f.size() >= 3)
556 {
557 baffleFaces_[bafflei] = f;
558 // insert lookup addressing in normal list
559 mapToFoamCellId_[starCellId] = nCells + bafflei;
560 origCellId_[nCells + bafflei] = starCellId;
561 ++bafflei;
562 }
563 }
564 }
565
566 baffleFaces_.setSize(bafflei);
567 }
568
569 if (unknownVertices)
570 {
572 << "cells with unknown vertices"
573 << abort(FatalError);
574 }
575
576 // truncate lists
577
578#ifdef DEBUG_READING
579 Info<< "CELLS READ" << endl;
580#endif
581
582 // cleanup
583 mapToFoamPointId_.clear();
584}
585
586
587// Read boundaries from <.bnd> file
588//
589/*---------------------------------------------------------------------------*\
590Line 1:
591 PROSTAR_BOUNDARY [newline]
592
593Line 2:
594 <version> 0 0 0 0 0 0 0 [newline]
595
596Body:
597 <boundId> <cellId> <cellFace> <regionId> 0 <boundaryType> [newline]
598
599where boundaryType is truncated to 4 characters from one of the following:
600INLET
601PRESSSURE
602OUTLET
603BAFFLE
604etc,
605\*---------------------------------------------------------------------------*/
606
608(
609 const fileName& inputName
610)
611{
612 label nPatches = 0, nFaces = 0, nBafflePatches = 0, maxId = 0;
613 label starCellId, cellFaceId, starRegion, configNumber;
614 token tok;
615 word patchType;
616
617 labelList mapToFoamPatchId(1000, label(-1));
618 labelList nPatchFaces(1000, Zero);
619 labelList origRegion(1000, Zero);
620 patchTypes_.setSize(1000);
621
622 //
623 // Mapping between OpenFOAM and PROSTAR primitives
624 // - needed for face mapping
625 //
626 const Map<label> shapeLookup =
627 {
632 };
633
634 // Pass 1:
635 // collect
636 // no. of faces (nFaces), no. of patches (nPatches)
637 // and for each of these patches the number of faces
638 // (nPatchFaces[patchLabel])
639 //
640 // and a conversion table from Star regions to (Foam) patchLabels
641 //
642 // additionally note the no. of baffle patches (nBafflePatches)
643 // so that we sort these to the end of the patch list
644 // - this makes it easier to transfer them to an adjacent patch if reqd
645 {
646 IFstream is(inputName);
647
648 if (is.good())
649 {
650 readHeader(is, STARCDCore::HEADER_BND);
651
652 while (is.read(tok).good() && tok.isLabel())
653 {
654 // Ignore boundary id (not needed)
655
656 ++nFaces;
657
658 is >> starCellId
659 >> cellFaceId
660 >> starRegion
661 >> configNumber
662 >> patchType;
663
664 // Build translation table to convert star patch to foam patch
665 label patchLabel = mapToFoamPatchId[starRegion];
666 if (patchLabel == -1)
667 {
668 patchLabel = nPatches;
669 mapToFoamPatchId[starRegion] = patchLabel;
670 origRegion[patchLabel] = starRegion;
671 patchTypes_[patchLabel] = patchType;
672
673 maxId = max(maxId, starRegion);
674
675 // should actually be case-insensitive
676 if (patchType == "BAFF")
677 {
678 ++nBafflePatches;
679 }
680 ++nPatches;
681 }
682
683 ++nPatchFaces[patchLabel];
684 }
685
686 if (nPatches == 0)
687 {
688 Info<< "No boundary faces in file " << inputName << endl;
689 }
690 }
691 else
692 {
693 Info<< "Could not read boundary file " << inputName << endl;
694 }
695 }
696
697 // keep empty patch region in reserve
698 ++nPatches;
699 Info<< "Number of patches = " << nPatches
700 << " (including extra for missing)" << endl;
701
702 // resize
703 origRegion.setSize(nPatches);
704 patchTypes_.setSize(nPatches);
705 patchNames_.setSize(nPatches);
706 nPatchFaces.setSize(nPatches);
707
708 // add our empty patch
709 origRegion[nPatches-1] = 0;
710 nPatchFaces[nPatches-1] = 0;
711 patchTypes_[nPatches-1] = "none";
712
713 // create names
714 // - use 'Label' entry from "constant/boundaryRegion" dictionary
715 forAll(patchTypes_, patchi)
716 {
717 bool fndName = false, fndType = false;
718
719 auto iter = boundaryRegion_.cfind(origRegion[patchi]);
720
721 if (iter.found())
722 {
723 const dictionary& dict = *iter;
724
725 fndType = dict.readIfPresent("BoundaryType", patchTypes_[patchi]);
726 fndName = dict.readIfPresent("Label", patchNames_[patchi]);
727 }
728
729 // Consistent names. Long form and in lowercase
730 if (!fndType)
731 {
732 stringOps::inplaceLower(patchTypes_[patchi]);
733
734 if (patchTypes_[patchi] == "symp")
735 {
736 patchTypes_[patchi] = "symplane";
737 }
738 else if (patchTypes_[patchi] == "cycl")
739 {
740 patchTypes_[patchi] = "cyclic";
741 }
742 else if (patchTypes_[patchi] == "baff")
743 {
744 patchTypes_[patchi] = "baffle";
745 }
746 else if (patchTypes_[patchi] == "moni")
747 {
748 patchTypes_[patchi] = "monitoring";
749 }
750 }
751
752 // Create a name if needed
753 if (!fndName)
754 {
755 patchNames_[patchi] =
756 patchTypes_[patchi] + "_" + name(origRegion[patchi]);
757 }
758 }
759
760 // Enforce name "Default_Boundary_Region"
761 patchNames_[nPatches-1] = defaultBoundaryName;
762
763 // Sort according to ascending region numbers, but leave
764 // "Default_Boundary_Region" as the final patch
765 {
766 labelList sortedIndices
767 (
768 sortedOrder(SubList<label>(origRegion, nPatches-1))
769 );
770
771 labelList oldToNew = identity(nPatches);
772 forAll(sortedIndices, i)
773 {
774 oldToNew[sortedIndices[i]] = i;
775 }
776
777 inplaceReorder(oldToNew, origRegion);
778 inplaceReorder(oldToNew, patchTypes_);
779 inplaceReorder(oldToNew, patchNames_);
780 inplaceReorder(oldToNew, nPatchFaces);
781 }
782
783 // re-sort to have baffles near the end
784 nBafflePatches = 1;
785 if (nBafflePatches)
786 {
787 labelList oldToNew = identity(nPatches);
788 label newIndex = 0;
789 label baffleIndex = (nPatches-1 - nBafflePatches);
790
791 for (label i=0; i < oldToNew.size()-1; ++i)
792 {
793 if (patchTypes_[i] == "baffle")
794 {
795 oldToNew[i] = baffleIndex++;
796 }
797 else
798 {
799 oldToNew[i] = newIndex++;
800 }
801 }
802
803 inplaceReorder(oldToNew, origRegion);
804 inplaceReorder(oldToNew, patchTypes_);
805 inplaceReorder(oldToNew, patchNames_);
806 inplaceReorder(oldToNew, nPatchFaces);
807 }
808
809 mapToFoamPatchId.setSize(maxId+1, -1);
810 forAll(origRegion, patchi)
811 {
812 mapToFoamPatchId[origRegion[patchi]] = patchi;
813 }
814
815 boundaryIds_.setSize(nPatches);
816 forAll(boundaryIds_, patchi)
817 {
818 boundaryIds_[patchi].setSize(nPatchFaces[patchi]);
819 nPatchFaces[patchi] = 0;
820 }
821
822
823 // Pass 2:
824 //
825 if (nPatches > 1 && mapToFoamCellId_.size() > 1)
826 {
827 IFstream is(inputName);
828 readHeader(is, STARCDCore::HEADER_BND);
829
830 while (is.read(tok).good() && tok.isLabel())
831 {
832 // Ignore boundary id (not needed)
833
834 is
835 >> starCellId
836 >> cellFaceId
837 >> starRegion
838 >> configNumber
839 >> patchType;
840
841 label patchi = mapToFoamPatchId[starRegion];
842
843 // zero-based indexing
844 cellFaceId--;
845
846 label cellId = -1;
847
848 // convert to FOAM cell number
849 if (starCellId < mapToFoamCellId_.size())
850 {
851 cellId = mapToFoamCellId_[starCellId];
852 }
853
854 if (cellId < 0)
855 {
856 Info
857 << "Boundaries inconsistent with cell file. "
858 << "Star cell " << starCellId << " does not exist"
859 << endl;
860 }
861 else
862 {
863 // restrict lookup to volume cells (no baffles)
864 if (cellId < cellShapes_.size())
865 {
866 label mapIndex = cellShapes_[cellId].model().index();
867 if (shapeLookup.found(mapIndex))
868 {
869 mapIndex = shapeLookup[mapIndex];
870 cellFaceId =
872 [mapIndex][cellFaceId];
873 }
874 }
875 else
876 {
877 // we currently use cellId >= nCells to tag baffles,
878 // we can also use a negative face number
879 cellFaceId = -1;
880 }
881
882 boundaryIds_[patchi][nPatchFaces[patchi]] =
883 cellFaceIdentifier(cellId, cellFaceId);
884
885#ifdef DEBUG_BOUNDARY
886 Info<< "bnd " << cellId << " " << cellFaceId << endl;
887#endif
888 // Increment counter of faces in current patch
889 ++nPatchFaces[patchi];
890 }
891 }
892 }
893
894 // retain original information in patchPhysicalTypes_ - overwrite latter
895 patchPhysicalTypes_.setSize(patchTypes_.size());
896
897
898 forAll(boundaryIds_, patchi)
899 {
900 // resize - avoid invalid boundaries
901 if (nPatchFaces[patchi] < boundaryIds_[patchi].size())
902 {
903 boundaryIds_[patchi].setSize(nPatchFaces[patchi]);
904 }
905
906 word origType = patchTypes_[patchi];
907 patchPhysicalTypes_[patchi] = origType;
908
909 if (origType == "symplane")
910 {
911 patchTypes_[patchi] = symmetryPolyPatch::typeName;
912 patchPhysicalTypes_[patchi] = patchTypes_[patchi];
913 }
914 else if (origType == "wall")
915 {
916 patchTypes_[patchi] = wallPolyPatch::typeName;
917 patchPhysicalTypes_[patchi] = patchTypes_[patchi];
918 }
919 else if (origType == "cyclic")
920 {
921 // incorrect. should be cyclicPatch but this
922 // requires info on connected faces.
923 patchTypes_[patchi] = oldCyclicPolyPatch::typeName;
924 patchPhysicalTypes_[patchi] = patchTypes_[patchi];
925 }
926 else if (origType == "baffle")
927 {
928 // incorrect. tag the patch until we get proper support.
929 // set physical type to a canonical "baffle"
930 patchTypes_[patchi] = emptyPolyPatch::typeName;
931 patchPhysicalTypes_[patchi] = "baffle";
932 }
933 else
934 {
935 patchTypes_[patchi] = polyPatch::typeName;
936 }
937
938 Info<< "patch " << patchi
939 << " (region " << origRegion[patchi]
940 << ": " << origType << ") type: '" << patchTypes_[patchi]
941 << "' name: " << patchNames_[patchi] << endl;
942 }
943
944 // cleanup
945 mapToFoamCellId_.clear();
946 cellShapes_.clear();
947}
948
949
950//
951// remove unused points
952//
954{
955 label nPoints = points_.size();
956 labelList oldToNew(nPoints, -1);
957
958 // loop through cell faces and note which points are being used
959 forAll(cellFaces_, celli)
960 {
961 const faceList& faces = cellFaces_[celli];
962 forAll(faces, i)
963 {
964 const labelList& labels = faces[i];
965 forAll(labels, j)
966 {
967 oldToNew[labels[j]]++;
968 }
969 }
970 }
971
972 // The new ordering and the count of unused points
973 label pointi = 0;
974 forAll(oldToNew, i)
975 {
976 if (oldToNew[i] >= 0)
977 {
978 oldToNew[i] = pointi++;
979 }
980 }
981
982 // Report unused points
983 if (nPoints > pointi)
984 {
985 Info<< "Unused points = " << (nPoints - pointi) << endl;
986 nPoints = pointi;
987
988 // Adjust points and truncate
989 inplaceReorder(oldToNew, points_);
990 points_.setSize(nPoints);
991
992 // Adjust cellFaces - with mesh shapes this might be faster
993 for (faceList& faces : cellFaces_)
994 {
995 for (face& f : faces)
996 {
997 inplaceRenumber(oldToNew, f);
998 }
999 }
1000
1001 // Adjust baffles
1002 for (face& f : baffleFaces_)
1003 {
1004 inplaceRenumber(oldToNew, f);
1005 }
1006 }
1007}
1008
1009
1010// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1011
1013{
1014 readPoints
1015 (
1016 starFileName(geometryFile_, STARCDCore::VRT_FILE),
1017 scaleFactor
1018 );
1019 readCells
1020 (
1021 starFileName(geometryFile_, STARCDCore::CEL_FILE)
1022 );
1023 cullPoints();
1024 readBoundary
1025 (
1026 starFileName(geometryFile_, STARCDCore::BND_FILE)
1027 );
1028
1029 return true;
1030}
1031
1032
1033// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
1034
1036(
1037 const fileName& prefix,
1038 const objectRegistry& registry,
1039 const scalar scaleFactor,
1040 const bool keepSolids
1041)
1042:
1043 meshReader(prefix, scaleFactor),
1044 keepSolids_(keepSolids),
1045 cellShapes_(0),
1046 mapToFoamPointId_(0),
1047 mapToFoamCellId_(0)
1048{
1049 readAux(registry);
1050}
1051
1052
1053// ************************************************************************* //
scalar y
Various functions to operate on Lists.
label n
bool found(const Key &key) const
Return true if hashed entry is found in table.
Definition: HashTableI.H:100
Input from file stream, using an ISstream.
Definition: IFstream.H:57
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:233
Generic input stream using a standard (STL) stream.
Definition: ISstream.H:58
ISstream & get(char &c)
Raw, low-level get character function.
Definition: ISstreamI.H:56
virtual Istream & read(token &t)
Return next token from stream.
Definition: ISstream.C:530
void setSize(const label n)
Alias for resize()
Definition: List.H:218
A HashTable to objects of type <T> with a label key.
Definition: Map.H:60
Generic output stream using a standard (STL) stream.
Definition: OSstream.H:57
A List obtained as a section of another List.
Definition: SubList.H:70
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
void readDict(const objectRegistry &, const word &name="boundaryRegion", const fileName &instance="constant")
Read constant/boundaryRegion.
Maps a geometry to a set of cell primitives.
Definition: cellModel.H:73
@ PRISM
prism
Definition: cellModel.H:83
@ UNKNOWN
unknown
Definition: cellModel.H:80
An analytical geometric cellShape.
Definition: cellShape.H:72
void readDict(const objectRegistry &, const word &name="cellTable", const fileName &instance="constant")
Read constant/cellTable.
Definition: cellTable.C:312
reference ref() const
A reference to the entry (Error if not found)
Definition: dictionary.H:225
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
static const Map< FixedList< int, 6 > > starToFoamFaceAddr
Face addressing from PROSTAR faces to OpenFOAM faces.
Definition: STARCDCore.H:129
Read PROSTAR vrt/cel/bnd files. The protected data in meshReader are filled.
label readPoints(const fileName &, const scalar scaleFactor)
Read points from file, return the max prostar id used.
boundaryRegion boundaryRegion_
Boundary region data.
virtual bool readGeometry(const scalar scaleFactor=1.0)
Read the mesh from the file(s)
void cullPoints()
Remove unused points.
void readBoundary(const fileName &)
Read boundary (cell/face) definitions.
virtual void readCells(const fileName &)
Read cell connectivities from file.
void readAux(const objectRegistry &)
Read auxiliary data from constant/{boundaryRegion,cellTable}.
A class for handling file names.
Definition: fileName.H:76
Identify cell faces in terms of cell Id and face Id.
Definition: meshReader.H:74
This class supports creating polyMeshes with baffles.
Definition: meshReader.H:69
cellTable cellTable_
Cell table persistent data saved as a dictionary.
Definition: meshReader.H:254
Registry of regIOobjects.
A token holds an item read from Istream.
Definition: token.H:69
bool isLabel() const noexcept
Token is LABEL.
Definition: tokenI.H:497
label labelToken() const
Return label value.
Definition: tokenI.H:513
A class for handling words, derived from Foam::string.
Definition: word.H:68
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
const labelList nFaces(UPstream::listGatherValues< label >(aMesh.nFaces()))
const label nPatches
label nPoints
label cellId
void inplaceLower(std::string &s)
Inplace transform string with std::tolower on each character.
Definition: stringOps.C:1194
Namespace for OpenFOAM.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
Definition: labelList.C:38
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values (not the indices) of a list.
List< label > labelList
A List of labels.
Definition: List.H:66
static void readToNewline(ISstream &is)
messageStream Info
Information stream (stdout output on master, null elsewhere)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
void inplaceReorder(const labelUList &oldToNew, ListType &input, const bool prune=false)
Inplace reorder the elements of a list.
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
errorManip< error > abort(error &err)
Definition: errorManip.H:144
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
error FatalError
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
labelList f(nPoints)
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333
static const char *const typeName
The type name used in ensight case files.