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