Loading...
Searching...
No Matches
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"
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);
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
132
133 // Pass 2:
134 // construct pointList and conversion table
135 // from Star vertex numbers to Foam point labels
136 {
137 IFstream is(inputName);
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.
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);
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);
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 {
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) with "
701 << nFaces << " faces" << endl;
702
703 // resize
704 origRegion.setSize(nPatches);
705 patchTypes_.setSize(nPatches);
706 patchNames_.setSize(nPatches);
707 nPatchFaces.setSize(nPatches);
708
709 // add our empty patch
710 origRegion[nPatches-1] = 0;
711 nPatchFaces[nPatches-1] = 0;
712 patchTypes_[nPatches-1] = "none";
713
714 // create names
715 // - use 'Label' entry from "constant/boundaryRegion" dictionary
716 forAll(patchTypes_, patchi)
717 {
718 bool fndName = false, fndType = false;
719
720 auto iter = boundaryRegion_.cfind(origRegion[patchi]);
721
722 if (iter.good())
723 {
724 const dictionary& dict = *iter;
725
726 fndType = dict.readIfPresent("BoundaryType", patchTypes_[patchi]);
727 fndName = dict.readIfPresent("Label", patchNames_[patchi]);
728 }
729
730 // Consistent names. Long form and in lowercase
731 if (!fndType)
732 {
734
735 if (patchTypes_[patchi] == "symp")
736 {
737 patchTypes_[patchi] = "symplane";
738 }
739 else if (patchTypes_[patchi] == "cycl")
740 {
741 patchTypes_[patchi] = "cyclic";
742 }
743 else if (patchTypes_[patchi] == "baff")
744 {
745 patchTypes_[patchi] = "baffle";
746 }
747 else if (patchTypes_[patchi] == "moni")
748 {
749 patchTypes_[patchi] = "monitoring";
750 }
751 }
752
753 // Create a name if needed
754 if (!fndName)
755 {
756 patchNames_[patchi] =
757 patchTypes_[patchi] + "_" + name(origRegion[patchi]);
758 }
759 }
760
761 // Enforce name "Default_Boundary_Region"
763
764 // Sort according to ascending region numbers, but leave
765 // "Default_Boundary_Region" as the final patch
766 {
767 labelList sortedIndices
768 (
769 sortedOrder(SubList<label>(origRegion, nPatches-1))
770 );
771
772 labelList oldToNew = identity(nPatches);
773 forAll(sortedIndices, i)
774 {
775 oldToNew[sortedIndices[i]] = i;
776 }
777
778 inplaceReorder(oldToNew, origRegion);
779 inplaceReorder(oldToNew, patchTypes_);
780 inplaceReorder(oldToNew, patchNames_);
781 inplaceReorder(oldToNew, nPatchFaces);
782 }
783
784 // re-sort to have baffles near the end
785 nBafflePatches = 1;
786 if (nBafflePatches)
787 {
788 labelList oldToNew = identity(nPatches);
789 label newIndex = 0;
790 label baffleIndex = (nPatches-1 - nBafflePatches);
791
792 for (label i=0; i < oldToNew.size()-1; ++i)
793 {
794 if (patchTypes_[i] == "baffle")
795 {
796 oldToNew[i] = baffleIndex++;
797 }
798 else
799 {
800 oldToNew[i] = newIndex++;
801 }
802 }
803
804 inplaceReorder(oldToNew, origRegion);
805 inplaceReorder(oldToNew, patchTypes_);
806 inplaceReorder(oldToNew, patchNames_);
807 inplaceReorder(oldToNew, nPatchFaces);
808 }
809
810 mapToFoamPatchId.setSize(maxId+1, -1);
811 forAll(origRegion, patchi)
812 {
813 mapToFoamPatchId[origRegion[patchi]] = patchi;
814 }
815
816 boundaryIds_.setSize(nPatches);
817 forAll(boundaryIds_, patchi)
818 {
819 boundaryIds_[patchi].setSize(nPatchFaces[patchi]);
820 nPatchFaces[patchi] = 0;
821 }
822
823
824 // Pass 2:
825 //
826 if (nPatches > 1 && mapToFoamCellId_.size() > 1)
827 {
828 IFstream is(inputName);
830
831 while (is.read(tok).good() && tok.isLabel())
832 {
833 // Ignore boundary id (not needed)
834
835 is
836 >> starCellId
837 >> cellFaceId
838 >> starRegion
839 >> configNumber
840 >> patchType;
841
842 label patchi = mapToFoamPatchId[starRegion];
843
844 // zero-based indexing
845 cellFaceId--;
846
847 label cellId = -1;
848
849 // convert to FOAM cell number
850 if (starCellId < mapToFoamCellId_.size())
851 {
852 cellId = mapToFoamCellId_[starCellId];
853 }
854
855 if (cellId < 0)
856 {
857 Info
858 << "Boundaries inconsistent with cell file. "
859 << "Star cell " << starCellId << " does not exist"
860 << endl;
861 }
862 else
863 {
864 // restrict lookup to volume cells (no baffles)
865 if (cellId < cellShapes_.size())
866 {
867 label mapIndex = cellShapes_[cellId].model().index();
868 if (shapeLookup.found(mapIndex))
869 {
870 mapIndex = shapeLookup[mapIndex];
871 cellFaceId =
873 [mapIndex][cellFaceId];
874 }
875 }
876 else
877 {
878 // we currently use cellId >= nCells to tag baffles,
879 // we can also use a negative face number
880 cellFaceId = -1;
881 }
882
883 boundaryIds_[patchi][nPatchFaces[patchi]] =
884 cellFaceIdentifier(cellId, cellFaceId);
885
886#ifdef DEBUG_BOUNDARY
887 Info<< "bnd " << cellId << " " << cellFaceId << endl;
888#endif
889 // Increment counter of faces in current patch
890 ++nPatchFaces[patchi];
891 }
892 }
893 }
894
895 // retain original information in patchPhysicalTypes_ - overwrite latter
896 patchPhysicalTypes_.setSize(patchTypes_.size());
897
898
899 forAll(boundaryIds_, patchi)
900 {
901 // resize - avoid invalid boundaries
902 if (nPatchFaces[patchi] < boundaryIds_[patchi].size())
903 {
904 boundaryIds_[patchi].setSize(nPatchFaces[patchi]);
905 }
906
907 word origType = patchTypes_[patchi];
908 patchPhysicalTypes_[patchi] = origType;
909
910 if (origType == "symplane")
911 {
912 patchTypes_[patchi] = symmetryPolyPatch::typeName;
913 patchPhysicalTypes_[patchi] = patchTypes_[patchi];
914 }
915 else if (origType == "wall")
916 {
917 patchTypes_[patchi] = wallPolyPatch::typeName;
918 patchPhysicalTypes_[patchi] = patchTypes_[patchi];
919 }
920 else if (origType == "cyclic")
921 {
922 // incorrect. should be cyclicPatch but this
923 // requires info on connected faces.
924 patchTypes_[patchi] = oldCyclicPolyPatch::typeName;
925 patchPhysicalTypes_[patchi] = patchTypes_[patchi];
926 }
927 else if (origType == "baffle")
928 {
929 // incorrect. tag the patch until we get proper support.
930 // set physical type to a canonical "baffle"
931 patchTypes_[patchi] = emptyPolyPatch::typeName;
932 patchPhysicalTypes_[patchi] = "baffle";
933 }
934 else
935 {
936 patchTypes_[patchi] = polyPatch::typeName;
937 }
938
939 Info<< "patch " << patchi
940 << " (region " << origRegion[patchi]
941 << ": " << origType << ") type: '" << patchTypes_[patchi]
942 << "' name: " << patchNames_[patchi] << endl;
943 }
944
945 // cleanup
946 mapToFoamCellId_.clear();
947 cellShapes_.clear();
948}
949
951//
952// remove unused points
953//
955{
956 label nPoints = points_.size();
957 labelList oldToNew(nPoints, -1);
958
959 // loop through cell faces and note which points are being used
960 forAll(cellFaces_, celli)
961 {
962 const faceList& faces = cellFaces_[celli];
963 forAll(faces, i)
964 {
965 const labelList& labels = faces[i];
966 forAll(labels, j)
967 {
968 oldToNew[labels[j]]++;
969 }
970 }
971 }
972
973 // The new ordering and the count of unused points
974 label pointi = 0;
975 forAll(oldToNew, i)
976 {
977 if (oldToNew[i] >= 0)
978 {
979 oldToNew[i] = pointi++;
980 }
981 }
982
983 // Report unused points
984 if (nPoints > pointi)
985 {
986 Info<< "Unused points = " << (nPoints - pointi) << endl;
987 nPoints = pointi;
988
989 // Adjust points and truncate
990 inplaceReorder(oldToNew, points_);
991 points_.setSize(nPoints);
992
993 // Adjust cellFaces - with mesh shapes this might be faster
994 for (faceList& faces : cellFaces_)
995 {
996 for (face& f : faces)
997 {
998 inplaceRenumber(oldToNew, f);
999 }
1000 }
1001
1002 // Adjust baffles
1003 for (face& f : baffleFaces_)
1004 {
1005 inplaceRenumber(oldToNew, f);
1006 }
1007 }
1008}
1010
1011// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1012
1013bool Foam::fileFormats::STARCDMeshReader::readGeometry(const scalar scaleFactor)
1014{
1016 (
1018 scaleFactor
1019 );
1020 readCells
1021 (
1023 );
1024 cullPoints();
1026 (
1028 );
1029
1030 return true;
1031}
1033
1034// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
1035
1037(
1038 const fileName& prefix,
1039 const objectRegistry& registry,
1040 const scalar scaleFactor,
1041 const bool keepSolids
1042)
1043:
1044 meshReader(prefix, scaleFactor),
1045 keepSolids_(keepSolids),
1046 cellShapes_(0),
1049{
1050 readAux(registry);
1051}
1052
1053
1054// ************************************************************************* //
scalar y
Various functions to operate on Lists.
label n
bool found(const Key &key) const
Same as contains().
Definition HashTable.H:1370
Input from file stream as an ISstream, normally using std::ifstream for the actual input.
Definition IFstream.H:55
bool good() const noexcept
True if next operation might succeed.
Definition IOstream.H:281
Generic input stream using a standard (STL) stream.
Definition ISstream.H:54
ISstream & get(char &c)
Raw, low-level get character function.
Definition ISstreamI.H:49
virtual Istream & read(token &t) override
Return next token from stream.
Definition ISstream.C:535
void setSize(label n)
Alias for resize().
Definition List.H:536
A HashTable to objects of type <T> with a label key.
Definition Map.H:54
Generic output stream using a standard (STL) stream.
Definition OSstream.H:53
A non-owning sub-view of a List (allocated or unallocated storage).
Definition SubList.H:61
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
void readDict(const objectRegistry &obr, const word &name="boundaryRegion", const fileName &instance="constant")
Read constant/boundaryRegion.
Maps a geometry to a set of cell primitives.
Definition cellModel.H:73
@ UNKNOWN
unknown
Definition cellModel.H:83
label index() const noexcept
Return index of model in the model list.
Definition cellModelI.H:30
static const cellModel * ptr(const modelType model)
Look up pointer to cellModel by enumeration, or nullptr on failure.
Definition cellModels.C:113
static const cellModel & ref(const modelType model)
Look up reference to cellModel by enumeration. Fatal on failure.
Definition cellModels.C:150
An analytical geometric cellShape.
Definition cellShape.H:71
void readDict(const objectRegistry &, const word &name="cellTable", const fileName &instance="constant")
Read constant/cellTable.
Definition cellTable.C:288
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
A face is a list of labels corresponding to mesh vertices.
Definition face.H:71
static const Map< FixedList< int, 6 > > starToFoamFaceAddr
Face addressing from PROSTAR faces to OpenFOAM faces.
Definition STARCDCore.H:71
static fileName starFileName(const fileName &baseName, const enum fileExt ext)
Resolve base file-name for the given file-type.
Definition STARCDCore.C:170
static bool readHeader(IFstream &is, const enum fileHeader header)
Read header and check signature PROSTAR_(CELL|VERTEX|BOUNDARY).
Definition STARCDCore.C:115
static const char *const defaultBoundaryName
The name for default (unassigned) boundaries.
Definition STARCDCore.H:114
STARCDMeshReader(const fileName &prefix, const objectRegistry &registry, const scalar scaleFactor=1.0, const bool keepSolids=false)
Construct from case name.
label readPoints(const fileName &, const scalar scaleFactor)
Read points from file, return the max prostar id used.
labelList mapToFoamPointId_
Point labels (imported Point numbering not necessarily contiguous).
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.
cellShapeList cellShapes_
Cell shapes.
virtual void readCells(const fileName &)
Read cell connectivities from file.
labelList mapToFoamCellId_
Cell labels (imported Cell numbering not necessarily contiguous).
void readAux(const objectRegistry &)
Read auxiliary data from constant/{boundaryRegion,cellTable}.
A class for handling file names.
Definition fileName.H:75
Identify cell faces in terms of cell Id and face Id.
Definition meshReader.H:72
List< List< cellFaceIdentifier > > boundaryIds_
Identify boundary faces by cells and their faces.
Definition meshReader.H:283
wordList patchPhysicalTypes_
Boundary patch physical types.
Definition meshReader.H:298
wordList patchNames_
Boundary patch names.
Definition meshReader.H:293
cellTable cellTable_
Cell table persistent data saved as a dictionary.
Definition meshReader.H:334
labelList cellTableId_
Cell table id for each cell.
Definition meshReader.H:329
labelList origCellId_
Lookup original Cell number for a given cell.
Definition meshReader.H:276
pointField points_
Points supporting the mesh.
Definition meshReader.H:271
faceList baffleFaces_
List of each baffle face.
Definition meshReader.H:324
faceListList cellFaces_
List of faces for every cell.
Definition meshReader.H:319
fileName geometryFile_
Referenced filename.
Definition meshReader.H:261
wordList patchTypes_
Boundary patch types.
Definition meshReader.H:288
Registry of regIOobjects.
A token holds an item read from Istream.
Definition token.H:70
bool isLabel() const noexcept
Integral token is convertible to Foam::label.
Definition tokenI.H:843
label labelToken() const
Return integer type as label value or Error.
Definition tokenI.H:869
A class for handling words, derived from Foam::string.
Definition word.H:66
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
auto & name
label nPoints
label cellId
void inplaceLower(std::string &s)
Inplace transform string with std::tolower on each character.
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:40
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values within a list.
List< label > labelList
A List of labels.
Definition List.H:62
static void readToNewline(ISstream &is)
messageStream Info
Information stream (stdout output on master, null elsewhere).
List< face > faceList
List of faces.
Definition faceListFwd.H:41
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
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.
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...
errorManip< error > abort(error &err)
Definition errorManip.H:139
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
labelList f(nPoints)
label nPatches
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299