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 -------------------------------------------------------------------------------
11 License
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 
42 namespace 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 /*---------------------------------------------------------------------------*\
74 Line 1:
75  PROSTAR_VERTEX [newline]
76 
77 Line 2:
78  <version> 0 0 0 0 0 0 0 [newline]
79 
80 Body:
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 /*---------------------------------------------------------------------------*\
180 Line 1:
181  PROSTAR_CELL [newline]
182 
183 Line 2:
184  <version> 0 0 0 0 0 0 0 [newline]
185 
186 Body:
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 
209 For primitive cell shapes, the number of vertices will never exceed 8 (hexa)
210 and corresponds to <nLabels>.
211 For polyhedral, <nLabels> includes an index table comprising beg/end pairs
212 for each cell face.
213 
214 Strictly 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
584 }
585 
586 
587 // Read boundaries from <.bnd> file
588 //
589 /*---------------------------------------------------------------------------*\
590 Line 1:
591  PROSTAR_BOUNDARY [newline]
592 
593 Line 2:
594  <version> 0 0 0 0 0 0 0 [newline]
595 
596 Body:
597  <boundId> <cellId> <cellFace> <regionId> 0 <boundaryType> [newline]
598 
599 where boundaryType is truncated to 4 characters from one of the following:
600 INLET
601 PRESSSURE
602 OUTLET
603 BAFFLE
604 etc,
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 
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 // ************************************************************************* //
Foam::fileFormats::STARCDCore::starcdPyr
Definition: STARCDCore.H:102
Foam::cellModel::index
label index() const noexcept
Return index of model in the model list.
Definition: cellModelI.H:37
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::cellTable::setName
void setName(const label, const word &)
Assign name.
Definition: cellTable.C:294
Foam::token::labelToken
label labelToken() const
Return label value.
Definition: tokenI.H:513
Foam::token::isLabel
bool isLabel() const noexcept
Token is LABEL.
Definition: tokenI.H:497
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
STARCDMeshReader.H
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::IFstream
Input from file stream, using an ISstream.
Definition: IFstream.H:53
Foam::cellModel::HEX
hex
Definition: cellModel.H:81
Foam::SubList
A List obtained as a section of another List.
Definition: SubList.H:54
wallPolyPatch.H
symmetryPolyPatch.H
Foam::ISstream
Generic input stream using a standard (STL) stream.
Definition: ISstream.H:55
Foam::meshReader::cellFaceIdentifier
Identify cell faces in terms of cell Id and face Id.
Definition: meshReader.H:73
Foam::fileFormats::STARCDMeshReader::readCells
virtual void readCells(const fileName &)
Read cell connectivities from file.
Definition: STARCDMeshReader.C:217
Foam::Map< label >
Foam::fileFormats::STARCDCore::starcdShellType
Definition: STARCDCore.H:88
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::token
A token holds an item read from Istream.
Definition: token.H:68
Foam::meshReader::cellTableId_
labelList cellTableId_
Cell table id for each cell.
Definition: meshReader.H:251
Foam::cellModel::ptr
static const cellModel * ptr(const modelType model)
Look up pointer to cellModel by enumeration, or nullptr on failure.
Definition: cellModels.C:120
Foam::meshReader::cellTable_
cellTable cellTable_
Cell table persistent data saved as a dictionary.
Definition: meshReader.H:254
Foam::meshReader::baffleFaces_
faceList baffleFaces_
List of each baffle face.
Definition: meshReader.H:248
Foam::cellModel::TET
tet
Definition: cellModel.H:85
Foam::inplaceRenumber
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values (not the indices) of a list.
Definition: ListOpsTemplates.C:61
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::fileFormats::STARCDCore::VRT_FILE
Definition: STARCDCore.H:77
Foam::IOstream::good
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:233
Foam::fileFormats::STARCDCore::readHeader
static bool readHeader(IFstream &is, const enum fileHeader header)
Read header and check signature PROSTAR_(CELL|VERTEX|BOUNDARY)
Definition: STARCDCore.C:122
Foam::meshReader::origCellId_
labelList origCellId_
Lookup original Cell number for a given cell.
Definition: meshReader.H:219
Foam::ISstream::get
ISstream & get(char &c)
Raw, low-level get character function.
Definition: ISstreamI.H:56
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::objectRegistry
Registry of regIOobjects.
Definition: objectRegistry.H:60
Foam::fileFormats::STARCDCore::starcdSolidType
Definition: STARCDCore.H:86
oldCyclicPolyPatch.H
Foam::fileFormats::STARCDMeshReader::readGeometry
virtual bool readGeometry(const scalar scaleFactor=1.0)
Read the mesh from the file(s)
Definition: STARCDMeshReader.C:1012
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::fileFormats::STARCDMeshReader::readBoundary
void readBoundary(const fileName &)
Read boundary (cell/face) definitions.
Definition: STARCDMeshReader.C:608
nPatches
const label nPatches
Definition: printMeshSummary.H:30
cellModel.H
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
Foam::fileFormats::STARCDCore::starcdPoly
Definition: STARCDCore.H:103
IOMap.H
Foam::cellModel::PRISM
prism
Definition: cellModel.H:83
Foam::fileFormats::STARCDMeshReader::mapToFoamPointId_
labelList mapToFoamPointId_
Point labels (imported Point numbering not necessarily contiguous)
Definition: STARCDMeshReader.H:87
Foam::OSstream
Generic output stream using a standard (STL) stream.
Definition: OSstream.H:54
Foam::cellModel::ref
static const cellModel & ref(const modelType model)
Look up reference to cellModel by enumeration. Fatal on failure.
Definition: cellModels.C:157
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
IFstream.H
Foam::fileFormats::STARCDCore::starcdPrism
Definition: STARCDCore.H:100
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::cellTable::setMaterial
void setMaterial(const label, const word &)
Assign material Type.
Definition: cellTable.C:288
Foam::fileFormats::STARCDCore::starcdBaffleType
Definition: STARCDCore.H:87
Foam::fileFormats::STARCDCore::CEL_FILE
Definition: STARCDCore.H:76
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
Foam::cellShape
An analytical geometric cellShape.
Definition: cellShape.H:69
Foam::fileFormats::STARCDMeshReader::mapToFoamCellId_
labelList mapToFoamCellId_
Cell labels (imported Cell numbering not necessarily contiguous)
Definition: STARCDMeshReader.H:90
Foam::fileFormats::STARCDCore::starcdFluidType
Definition: STARCDCore.H:85
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
emptyPolyPatch.H
Foam::fileFormats::STARCDMeshReader::cullPoints
void cullPoints()
Remove unused points.
Definition: STARCDMeshReader.C:953
Foam::fileFormats::STARCDCore::BND_FILE
Definition: STARCDCore.H:78
cellId
label cellId
Definition: interrogateWallPatches.H:67
Foam::stringOps::inplaceLower
void inplaceLower(std::string &s)
Inplace transform string with std::tolower on each character.
Definition: stringOps.C:1194
Foam::fileFormats::STARCDMeshReader::readPoints
label readPoints(const fileName &, const scalar scaleFactor)
Read points from file, return the max prostar id used.
Definition: STARCDMeshReader.C:85
Foam::meshReader
This class supports creating polyMeshes with baffles.
Definition: meshReader.H:68
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::cellModel::PYR
pyr
Definition: cellModel.H:84
Foam::nl
constexpr char nl
Definition: Ostream.H:404
f
labelList f(nPoints)
Foam::List< label >
Foam::fileFormats::STARCDCore::HEADER_CEL
Definition: STARCDCore.H:68
Foam::readToNewline
static void readToNewline(ISstream &is)
Definition: STARCDMeshReader.C:46
Foam::identity
labelList identity(const label len, label start=0)
Create identity map of the given length with (map[i] == i)
Definition: labelList.C:38
Foam::List::clear
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:116
Foam::fileFormats::STARCDCore::starcdTet
Definition: STARCDCore.H:101
x
x
Definition: LISASMDCalcMethod2.H:52
Foam::ISstream::read
virtual Istream & read(token &t)
Return next token from stream.
Definition: ISstream.C:530
Foam::cellModel::UNKNOWN
unknown
Definition: cellModel.H:80
Foam::fileFormats::STARCDCore::starToFoamFaceAddr
static const Map< FixedList< int, 6 > > starToFoamFaceAddr
Face addressing from PROSTAR faces to OpenFOAM faces.
Definition: STARCDCore.H:129
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::fileFormats::STARCDMeshReader::STARCDMeshReader
STARCDMeshReader(const fileName &prefix, const objectRegistry &registry, const scalar scaleFactor=1.0, const bool keepSolids=false)
Construct from case name.
Definition: STARCDMeshReader.C:1036
Foam::inplaceReorder
void inplaceReorder(const labelUList &oldToNew, ListType &input, const bool prune=false)
Inplace reorder the elements of a list.
Definition: ListOpsTemplates.C:124
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
Foam::fileFormats::STARCDMeshReader::cellShapes_
cellShapeList cellShapes_
Cell shapes.
Definition: STARCDMeshReader.H:84
ListOps.H
Various functions to operate on Lists.
Foam::cellModel
Maps a geometry to a set of cell primitives.
Definition: cellModel.H:72
Foam::sortedOrder
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
Foam::fileFormats::STARCDMeshReader::readAux
void readAux(const objectRegistry &)
Read auxiliary data from constant/{boundaryRegion,cellTable}.
Definition: STARCDMeshReader.C:62
stringOps.H
y
scalar y
Definition: LISASMDCalcMethod1.H:14
Foam::fileFormats::STARCDCore::starcdHex
Definition: STARCDCore.H:99
Foam::meshReader::cellFaces_
faceListList cellFaces_
List of faces for every cell.
Definition: meshReader.H:245
Foam::fileFormats::STARCDCore::HEADER_BND
Definition: STARCDCore.H:70