initial commit for version 1.5.x patch release
[OpenFOAM-1.5.x.git] / src / conversion / meshReader / starcd / STARCDMeshReader.C
blob084a79270412ec189609019c5404da0a6cbcdfde
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     option) any later version.
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.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM; if not, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "STARCDMeshReader.H"
28 #include "cyclicPolyPatch.H"
29 #include "emptyPolyPatch.H"
30 #include "wallPolyPatch.H"
31 #include "symmetryPolyPatch.H"
32 #include "cellModeller.H"
33 #include "SortableList.H"
34 #include "IFstream.H"
35 #include "IOMap.H"
37 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39 const char* Foam::meshReaders::STARCD::defaultBoundaryName =
40     "Default_Boundary_Region";
42 const char* Foam::meshReaders::STARCD::defaultSolidBoundaryName =
43     "Default_Boundary_Solid";
45 bool Foam::meshReaders::STARCD::keepSolids = false;
47 const int Foam::meshReaders::STARCD::starToFoamFaceAddr[4][6] =
49     { 4, 5, 2, 3, 0, 1 },     // 11 = pro-STAR hex
50     { 0, 1, 4, -1, 2, 3 },    // 12 = pro-STAR prism
51     { 3, -1, 2, -1, 1, 0 },   // 13 = pro-STAR tetra
52     { 0, -1, 4, 2, 1, 3 }     // 14 = pro-STAR pyramid
56 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
58 void Foam::meshReaders::STARCD::readToNewline(IFstream& is)
60     char ch = '\n';
61     do
62     {
63         (is).get(ch);
64     }
65     while ((is) && ch != '\n');
69 bool Foam::meshReaders::STARCD::readHeader(IFstream& is, word fileSignature)
71     if (!is.good())
72     {
73         FatalErrorIn("meshReaders::STARCD::readHeader()")
74             << "cannot read " << fileSignature  << "  " << is.name()
75             << abort(FatalError);
76     }
78     word header;
79     label majorVersion;
81     is >> header;
82     is >> majorVersion;
84     // skip the rest of the line
85     readToNewline(is);
87     // add other checks ...
88     if (header != fileSignature)
89     {
90         Info<< "header mismatch " << fileSignature << "  " << is.name()
91             << endl;
92     }
94     return true;
98 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
100 void Foam::meshReaders::STARCD::readAux(const objectRegistry& registry)
102     boundaryRegion_.readDict(registry);
103     cellTable_.readDict(registry);
107 // read in the points from the .vrt file
109 /*---------------------------------------------------------------------------*\
110 Line 1:
111   PROSTAR_VERTEX [newline]
113 Line 2:
114   <version> 0 0 0 0 0 0 0 [newline]
116 Body:
117   <vertexId>  <x>  <y>  <z> [newline]
119 \*---------------------------------------------------------------------------*/
120 void Foam::meshReaders::STARCD::readPoints
122     const fileName& inputName,
123     const scalar scaleFactor
126     const word fileSignature = "PROSTAR_VERTEX";
127     label nPoints = 0, maxId = 0;
129     // Pass 1:
130     // get # points and maximum vertex label
131     {
132         IFstream is(inputName);
133         readHeader(is, fileSignature);
135         label lineLabel;
136         scalar x, y, z;
138         while ((is >> lineLabel).good())
139         {
140             nPoints++;
141             maxId = max(maxId, lineLabel);
142             is >> x >> y >> z;
143         }
144     }
146     Info<< "Number of points  = " << nPoints << endl;
148     // set sizes and reset to invalid values
150     points_.setSize(nPoints);
151     mapToFoamPointId_.setSize(maxId+1);
153     //- original Point number for a given vertex
154     // might need again in the future
155     ////     labelList origPointId(nPoints);
156     ////     origPointId = -1;
158     mapToFoamPointId_ = -1;
160     // Pass 2:
161     // construct pointList and conversion table
162     // from Star vertex numbers to Foam point labels
163     if (nPoints > 0)
164     {
165         IFstream is(inputName);
166         readHeader(is, fileSignature);
168         label lineLabel;
170         label pointI = 0;
171         while ((is >> lineLabel).good())
172         {
173             is  >> points_[pointI].x()
174                 >> points_[pointI].y()
175                 >> points_[pointI].z();
177             // might need again in the future
178             ////  origPointId[pointI] = lineLabel;
179             mapToFoamPointId_[lineLabel] = pointI;
180             pointI++;
181         }
183         if (nPoints > pointI)
184         {
185             nPoints = pointI;
186             points_.setSize(nPoints);
187             // might need again in the future
188             //// origPointId.setSize(nPoints);
189         }
191         if (scaleFactor > 1.0 + SMALL || scaleFactor < 1.0 - SMALL)
192         {
193             points_ *= scaleFactor;
194         }
195     }
196     else
197     {
198         FatalErrorIn("meshReaders::STARCD::readPoints()")
199             << "no points in file " << inputName
200             << abort(FatalError);
201     }
206 // read in the cells from the .cel file
208 /*---------------------------------------------------------------------------*\
209 Line 1:
210   PROSTAR_CELL [newline]
212 Line 2:
213   <version> 0 0 0 0 0 0 0 [newline]
215 Body:
216   <cellId>  <shapeId>  <nLabels>  <cellTableId>  <typeId> [newline]
217   <cellId>  <int1> .. <int8>
218   <cellId>  <int9> .. <int16>
220  with shapeId:
221  *   1 = point
222  *   2 = line
223  *   3 = shell
224  *  11 = hexa
225  *  12 = prism
226  *  13 = tetra
227  *  14 = pyramid
228  * 255 = polyhedron
230  with typeId
231  *   1 = fluid
232  *   2 = solid
233  *   3 = baffle
234  *   4 = shell
235  *   5 = line
236  *   6 = point
238 For primitive cell shapes, the number of vertices will never exceed 8 (hexa)
239 and corresponds to <nLabels>.
240 For polyhedral, <nLabels> includess an index table comprising beg/end pairs
241 for each cell face.
243 Strictly speaking, we only need the cellModeller for adding boundaries.
244 \*---------------------------------------------------------------------------*/
246 void Foam::meshReaders::STARCD::readCells(const fileName& inputName)
248     const word fileSignature = "PROSTAR_CELL";
249     label nFluids = 0, nSolids = 0, nBaffles = 0, nShells = 0;
250     label maxId = 0;
252     bool unknownVertices = false;
255     // Pass 1:
256     // count nFluids, nSolids, nBaffle, nShell and maxId
257     // also see if polyhedral cells were used
258     {
259         IFstream is(inputName);
260         readHeader(is, fileSignature);
262         label lineLabel, shapeId, nLabels, cellTableId, typeId;
264         while ((is >> lineLabel).good())
265         {
266             label starCellId = lineLabel;
267             is  >> shapeId
268                 >> nLabels
269                 >> cellTableId
270                 >> typeId;
272             // skip the rest of the line
273             readToNewline(is);
275             // max 8 indices per line
276             while (nLabels > 0)
277             {
278                 readToNewline(is);
279                 nLabels -= 8;
280             }
282             if (typeId == starcdFluidType)
283             {
284                 nFluids++;
285                 maxId = max(maxId, starCellId);
287                 if (!cellTable_.found(cellTableId))
288                 {
289                     cellTable_.setName(cellTableId);
290                     cellTable_.setMaterial(cellTableId, "fluid");
291                 }
292             }
293             else if (typeId == starcdSolidType)
294             {
295                 nSolids++;
296                 if (keepSolids)
297                 {
298                     maxId = max(maxId, starCellId);
299                 }
301                 if (!cellTable_.found(cellTableId))
302                 {
303                     cellTable_.setName(cellTableId);
304                     cellTable_.setMaterial(cellTableId, "solid");
305                 }
307             }
308             else if (typeId == starcdBaffleType)
309             {
310                 // baffles have no cellTable entry
311                 nBaffles++;
312                 maxId = max(maxId, starCellId);
313             }
314             else if (typeId == starcdShellType)
315             {
316                 nShells++;
317                 if (!cellTable_.found(cellTableId))
318                 {
319                     cellTable_.setName(cellTableId);
320                     cellTable_.setMaterial(cellTableId, "shell");
321                 }
322             }
324         }
325     }
327     Info<< "Number of fluids  = " << nFluids << nl
328         << "Number of baffles = " << nBaffles << nl;
329     if (keepSolids)
330     {
331         Info<< "Number of solids  = " << nSolids << nl;
332     }
333     else
334     {
335         Info<< "Ignored   solids  = " << nSolids << nl;
336     }
337     Info<< "Ignored   shells  = " << nShells << endl;
340     label nCells;
341     if (keepSolids)
342     {
343         nCells = nFluids + nSolids;
344     }
345     else
346     {
347         nCells = nFluids;
348     }
350     cellFaces_.setSize(nCells);
351     cellShapes_.setSize(nCells);
352     cellTableId_.setSize(nCells);
354     // information for the interfaces
355     baffleFaces_.setSize(nBaffles);
357     // extra space for baffles
358     origCellId_.setSize(nCells + nBaffles);
359     mapToFoamCellId_.setSize(maxId+1);
360     mapToFoamCellId_ = -1;
363     // avoid undefined shapes for polyhedra
364     cellShape genericShape(*unknownModel, labelList(0));
366     // Pass 2:
367     // construct cellFaces_ and possibly cellShapes_
368     if (nCells <= 0)
369     {
370         FatalErrorIn("meshReaders::STARCD::readCells()")
371             << "no cells in file " << inputName
372             << abort(FatalError);
373     }
374     else
375     {
376         IFstream is(inputName);
377         readHeader(is, fileSignature);
379         labelList starLabels(64);
380         label lineLabel, shapeId, nLabels, cellTableId, typeId;
382         label cellI = 0;
383         label baffleI = 0;
385         while ((is >> lineLabel).good())
386         {
387             label starCellId = lineLabel;
388             is  >> shapeId
389                 >> nLabels
390                 >> cellTableId
391                 >> typeId;
393             if (nLabels > starLabels.size())
394             {
395                 starLabels.setSize(nLabels);
396             }
397             starLabels = -1;
399             // read indices - max 8 per line
400             for (label i = 0; i < nLabels; ++i)
401             {
402                 if ((i % 8) == 0)
403                 {
404                     is >> lineLabel;
405                 }
406                 is >> starLabels[i];
407             }
409             // skip solid cells
410             if (typeId == starcdSolidType && !keepSolids)
411             {
412                 continue;
413             }
415             // determine the foam cell shape
416             const cellModel* curModelPtr = NULL;
418             // fluid/solid cells
419             switch (shapeId)
420             {
421                 case starcdHex:
422                     curModelPtr = hexModel;
423                     break;
424                 case starcdPrism:
425                     curModelPtr = prismModel;
426                     break;
427                 case starcdTet:
428                     curModelPtr = tetModel;
429                     break;
430                 case starcdPyr:
431                     curModelPtr = pyrModel;
432                     break;
433             }
435             if (curModelPtr)
436             {
437                 // primitive cell - use shapes
439                 // convert orig vertex Id to point label
440                 bool isBad = false;
441                 for (label i=0; i < nLabels; ++i)
442                 {
443                     label pointId = mapToFoamPointId_[starLabels[i]];
444                     if (pointId < 0)
445                     {
446                         Info<< "Cells inconsistent with vertex file. "
447                             << "Star vertex " << starLabels[i]
448                             << " does not exist" << endl;
449                         isBad = true;
450                         unknownVertices = true;
451                     }
452                     starLabels[i] = pointId;
453                 }
455                 if (isBad)
456                 {
457                     continue;
458                 }
460                 // record original cell number and lookup
461                 origCellId_[cellI] = starCellId;
462                 mapToFoamCellId_[starCellId] = cellI;
464                 cellTableId_[cellI] = cellTableId;
465                 cellShapes_[cellI] = cellShape
466                 (
467                     *curModelPtr,
468                     SubList<label>(starLabels, nLabels)
469                 );
471                 cellFaces_[cellI] = cellShapes_[cellI].faces();
472                 cellI++;
473             }
474             else if (shapeId == starcdPoly)
475             {
476                 // polyhedral cell
477                 label nFaces = starLabels[0] - 1;
479                 // convert orig vertex id to point label
480                 // start with offset (skip the index table)
481                 bool isBad = false;
482                 for (label i=starLabels[0]; i < nLabels; ++i)
483                 {
484                     label pointId = mapToFoamPointId_[starLabels[i]];
485                     if (pointId < 0)
486                     {
487                         Info<< "Cells inconsistent with vertex file. "
488                             << "Star vertex " << starLabels[i]
489                             << " does not exist" << endl;
490                         isBad = true;
491                         unknownVertices = true;
492                     }
493                     starLabels[i] = pointId;
494                 }
496                 if (isBad)
497                 {
498                     continue;
499                 }
501                 // traverse beg/end indices
502                 faceList faces(nFaces);
503                 label faceI = 0;
504                 for (label i=0; i < nFaces; ++i)
505                 {
506                     label beg = starLabels[i];
507                     label n   = starLabels[i+1] - beg;
509                     face f
510                     (
511                         SubList<label>(starLabels, n, beg)
512                     );
514                     f.collapse();
516                     // valid faces only
517                     if (f.size() >= 3)
518                     {
519                         faces[faceI++] = f;
520                     }
521                 }
523                 if (nFaces > faceI)
524                 {
525                     Info<< "star cell " << starCellId << " has "
526                         << (nFaces - faceI)
527                         << " empty faces - could cause boundary "
528                         << "addressing problems"
529                         << endl;
531                     nFaces = faceI;
532                     faces.setSize(nFaces);
533                 }
535                 if (nFaces < 4)
536                 {
537                     FatalErrorIn("meshReaders::STARCD::readCells()")
538                         << "star cell " << starCellId << " has " << nFaces
539                         << abort(FatalError);
540                 }
542                 // record original cell number and lookup
543                 origCellId_[cellI] = starCellId;
544                 mapToFoamCellId_[starCellId] = cellI;
546                 cellTableId_[cellI] = cellTableId;
547                 cellShapes_[cellI]  = genericShape;
548                 cellFaces_[cellI]   = faces;
549                 cellI++;
550             }
551             else if (typeId == starcdBaffleType)
552             {
553                 // baffles
555                 // convert orig vertex id to point label
556                 bool isBad = false;
557                 for (label i=0; i < nLabels; ++i)
558                 {
559                     label pointId = mapToFoamPointId_[starLabels[i]];
560                     if (pointId < 0)
561                     {
562                         Info<< "Baffles inconsistent with vertex file. "
563                             << "Star vertex " << starLabels[i]
564                             << " does not exist" << endl;
565                         isBad = true;
566                         unknownVertices = true;
567                     }
568                     starLabels[i] = pointId;
569                 }
571                 if (isBad)
572                 {
573                     continue;
574                 }
577                 face f
578                 (
579                     SubList<label>(starLabels, nLabels)
580                 );
582                 f.collapse();
584                 // valid faces only
585                 if (f.size() >= 3)
586                 {
587                     baffleFaces_[baffleI] = f;
588                     // insert lookup addressing in normal list
589                     mapToFoamCellId_[starCellId]  = nCells + baffleI;
590                     origCellId_[nCells + baffleI] = starCellId;
591                     baffleI++;
592                 }
593             }
594         }
596         baffleFaces_.setSize(baffleI);
597     }
599     if (unknownVertices)
600     {
601         FatalErrorIn("meshReaders::STARCD::readCells()")
602             << "cells with unknown vertices"
603             << abort(FatalError);
604     }
606     // truncate lists
608 #ifdef DEBUG_READING
609     Info<< "CELLS READ" << endl;
610 #endif
612     // cleanup
613     mapToFoamPointId_.clear();
617 // read in the boundaries from the .bnd file
619 /*---------------------------------------------------------------------------*\
620 Line 1:
621   PROSTAR_BOUNDARY [newline]
623 Line 2:
624   <version> 0 0 0 0 0 0 0 [newline]
626 Body:
627   <boundId>  <cellId>  <cellFace>  <regionId>  0  <boundaryType> [newline]
629 where boundaryType is truncated to 4 characters from one of the following:
630 INLET
631 PRESSSURE
632 OUTLET
633 BAFFLE
634 etc,
635 \*---------------------------------------------------------------------------*/
637 void Foam::meshReaders::STARCD::readBoundary(const fileName& inputName)
639     const word fileSignature = "PROSTAR_BOUNDARY";
640     label nPatches = 0, nFaces = 0, nBafflePatches = 0, maxId = 0;
641     label lineLabel, starCellId, cellFaceId, starRegion, configNumber;
642     word patchType;
644     labelList mapToFoamPatchId(1000, -1);
645     labelList nPatchFaces(1000, 0);
646     labelList origRegion(1000, 0);
647     patchTypes_.setSize(1000);
649     // this is what we seem to need
650     // these MUST correspond to starToFoamFaceAddr
651     //
652     Map<label> faceLookupIndex;
654     faceLookupIndex.insert(hexModel->index(), 0);
655     faceLookupIndex.insert(prismModel->index(), 1);
656     faceLookupIndex.insert(tetModel->index(), 2);
657     faceLookupIndex.insert(pyrModel->index(), 3);
659     // Pass 1:
660     // collect
661     // no. of faces (nFaces), no. of patches (nPatches)
662     // and for each of these patches the number of faces
663     // (nPatchFaces[patchLabel])
664     //
665     // and a conversion table from Star regions to (Foam) patchLabels
666     //
667     // additionally note the no. of baffle patches (nBafflePatches)
668     // so that we sort these to the end of the patch list
669     // - this makes it easier to transfer them to an adjacent patch if reqd
670     {
671         IFstream is(inputName);
673         if (is.good())
674         {
675             readHeader(is, fileSignature);
677             while ((is >> lineLabel).good())
678             {
679                 nFaces++;
680                 is  >> starCellId
681                     >> cellFaceId
682                     >> starRegion
683                     >> configNumber
684                     >> patchType;
686                 // Build translation table to convert star patch to foam patch
687                 label patchLabel = mapToFoamPatchId[starRegion];
688                 if (patchLabel == -1)
689                 {
690                     patchLabel = nPatches;
691                     mapToFoamPatchId[starRegion] = patchLabel;
692                     origRegion[patchLabel] = starRegion;
693                     patchTypes_[patchLabel] = patchType;
695                     maxId = max(maxId, starRegion);
697                     if (patchType == "BAFF")    // should actually be case-insensitive
698                     {
699                         nBafflePatches++;
700                     }
701                     nPatches++;
702                 }
704                 nPatchFaces[patchLabel]++;
705             }
707             if (nPatches == 0)
708             {
709                 Info<< "No boundary faces in file " << inputName << endl;
710             }
711         }
712         else
713         {
714             Info<< "Could not read boundary file " << inputName << endl;
715         }
716     }
718     // keep empty patch region in reserve
719     nPatches++;
720     Info<< "Number of patches = " << nPatches
721         << " (including extra for missing)" << endl;
723     // resize
724     origRegion.setSize(nPatches);
725     patchTypes_.setSize(nPatches);
726     patchNames_.setSize(nPatches);
727     nPatchFaces.setSize(nPatches);
729     // add our empty patch
730     origRegion[nPatches-1] = 0;
731     nPatchFaces[nPatches-1] = 0;
732     patchTypes_[nPatches-1] = "none";
734     // create names
735     // - use 'Label' entry from "constant/boundaryRegion" dictionary
736     forAll(patchTypes_, patchI)
737     {
738         bool foundName = false, foundType = false;
740         Map<dictionary>::const_iterator
741             iter = boundaryRegion_.find(origRegion[patchI]);
743         if
744         (
745             iter != boundaryRegion_.end()
746         )
747         {
748             foundType = iter().readIfPresent
749             (
750                 "BoundaryType",
751                 patchTypes_[patchI]
752             );
754             foundName = iter().readIfPresent
755             (
756                 "Label",
757                 patchNames_[patchI]
758             );
759         }
761         // consistent names, in long form and in lowercase
762         if (!foundType)
763         {
764             // transform
765             forAllIter(string, patchTypes_[patchI], i)
766             {
767                 *i = tolower(*i);
768             }
770             if (patchTypes_[patchI] == "symp")
771             {
772                 patchTypes_[patchI] = "symplane";
773             }
774             else if (patchTypes_[patchI] == "cycl")
775             {
776                 patchTypes_[patchI] = "cyclic";
777             }
778             else if (patchTypes_[patchI] == "baff")
779             {
780                 patchTypes_[patchI] = "baffle";
781             }
782             else if (patchTypes_[patchI] == "moni")
783             {
784                 patchTypes_[patchI] = "monitoring";
785             }
786         }
788         // create a name if needed
789         if (!foundName)
790         {
791             patchNames_[patchI] =
792                 patchTypes_[patchI] + "_" + name(origRegion[patchI]);
793         }
794     }
796     // enforce name "Default_Boundary_Region"
797     patchNames_[nPatches-1] = defaultBoundaryName;
799     // sort according to ascending region numbers, but leave
800     // Default_Boundary_Region as the last patch
801     {
802         SortableList<label> sortedOrder(SubList<label>(origRegion, nPatches-1));
804         labelList oldToNew = identity(nPatches);
805         forAll(sortedOrder, i)
806         {
807             oldToNew[sortedOrder.indices()[i]] = i;
808         }
810         inplaceReorder(oldToNew, origRegion);
811         inplaceReorder(oldToNew, patchTypes_);
812         inplaceReorder(oldToNew, patchNames_);
813         inplaceReorder(oldToNew, nPatchFaces);
814     }
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);
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         }
836         inplaceReorder(oldToNew, origRegion);
837         inplaceReorder(oldToNew, patchTypes_);
838         inplaceReorder(oldToNew, patchNames_);
839         inplaceReorder(oldToNew, nPatchFaces);
840     }
842     mapToFoamPatchId.setSize(maxId+1, -1);
843     forAll(origRegion, patchI)
844     {
845         mapToFoamPatchId[origRegion[patchI]] = patchI;
846     }
848     boundaryIds_.setSize(nPatches);
849     forAll(boundaryIds_, patchI)
850     {
851         boundaryIds_[patchI].setSize(nPatchFaces[patchI]);
852         nPatchFaces[patchI] = 0;
853     }
856     // Pass 2:
857     //
858     if (nPatches > 1 && mapToFoamCellId_.size() > 1)
859     {
860         IFstream is(inputName);
861         readHeader(is, fileSignature);
863         while ((is >> lineLabel).good())
864         {
865             is
866                 >> starCellId
867                 >> cellFaceId
868                 >> starRegion
869                 >> configNumber
870                 >> patchType;
872             label patchI = mapToFoamPatchId[starRegion];
874             // zero-based indexing
875             cellFaceId--;
877             label cellId = -1;
879             // convert to FOAM cell number
880             if (starCellId < mapToFoamCellId_.size())
881             {
882                 cellId = mapToFoamCellId_[starCellId];
883             }
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                 }
911                 boundaryIds_[patchI][nPatchFaces[patchI]] =
912                     cellFaceIdentifier(cellId, cellFaceId);
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     }
923     // retain original information in patchPhysicalTypes_ - overwrite latter
924     patchPhysicalTypes_.setSize(patchTypes_.size());
927     forAll(boundaryIds_, patchI)
928     {
929         // resize - avoid invalid boundaries
930         if (nPatchFaces[patchI] < boundaryIds_[patchI].size())
931         {
932             boundaryIds_[patchI].setSize(nPatchFaces[patchI]);
933         }
935         word origType = patchTypes_[patchI];
936         patchPhysicalTypes_[patchI] = origType;
938         if (origType == "symplane")
939         {
940             patchTypes_[patchI] = symmetryPolyPatch::typeName;
941             patchPhysicalTypes_[patchI] = patchTypes_[patchI];
942         }
943         else if (origType == "wall")
944         {
945             patchTypes_[patchI] = wallPolyPatch::typeName;
946             patchPhysicalTypes_[patchI] = patchTypes_[patchI];
947         }
948         else if (origType == "cyclic")
949         {
950             // incorrect. should be cyclicPatch but this
951             // requires info on connected faces.
952             patchTypes_[patchI] = cyclicPolyPatch::typeName;
953             patchPhysicalTypes_[patchI] = patchTypes_[patchI];
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         }
967         Info<< "patch " << patchI
968             << " (region " << origRegion[patchI]
969             << ": " << origType << ") type: '" << patchTypes_[patchI]
970             << "' name: " << patchNames_[patchI] << endl;
971     }
973     // cleanup
974     mapToFoamCellId_.clear();
975     cellShapes_.clear();
980 // remove unused points
982 void Foam::meshReaders::STARCD::cullPoints()
984     label nPoints = points_.size();
985     labelList oldToNew(nPoints, -1);
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     }
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     }
1011     // report unused points
1012     if (nPoints > pointI)
1013     {
1014         Info<< "Unused    points  = " << (nPoints - pointI) << endl;
1015         nPoints = pointI;
1017         // adjust points and truncate
1018         inplaceReorder(oldToNew, points_);
1019         points_.setSize(nPoints);
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         }
1031         // adjust baffles
1032         forAll(baffleFaces_, faceI)
1033         {
1034             inplaceRenumber(oldToNew, baffleFaces_[faceI]);
1035         }
1036     }
1040 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1042 bool Foam::meshReaders::STARCD::readGeometry(const scalar scaleFactor)
1044     // Info<< "called meshReaders::STARCD::readGeometry" << endl;
1046     readPoints(geometryFile_ + ".vrt", scaleFactor);
1047     readCells(geometryFile_ + ".cel");
1048     cullPoints();
1049     readBoundary(geometryFile_ + ".bnd");
1051     return true;
1055 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
1057 Foam::meshReaders::STARCD::STARCD
1059     const fileName& prefix,
1060     const objectRegistry& registry,
1061     const scalar scaleFactor
1064     meshReader(prefix, scaleFactor),
1065     cellShapes_(0),
1066     mapToFoamPointId_(0),
1067     mapToFoamCellId_(0)
1069     readAux(registry);
1073 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
1075 Foam::meshReaders::STARCD::~STARCD()
1079 // ************************************************************************* //