BUG: UListIO: byteSize overflowing on really big faceLists
[OpenFOAM-2.0.x.git] / src / surfMesh / surfaceFormats / starcd / STARCDsurfaceFormat.C
blob31e09c8a10bcdc0225e58ccf1f1ffe750a83d3b7
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
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
13     the Free Software Foundation, either version 3 of the License, or
14     (at your 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, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "STARCDsurfaceFormat.H"
27 #include "ListOps.H"
29 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
31 template<class Face>
32 inline void Foam::fileFormats::STARCDsurfaceFormat<Face>::writeShell
34     Ostream& os,
35     const Face& f,
36     const label cellId,
37     const label cellTableId
40     os  << cellId                    // includes 1 offset
41         << ' ' << starcdShellShape_  // 3(shell) shape
42         << ' ' << f.size()
43         << ' ' << cellTableId
44         << ' ' << starcdShellType_;  // 4(shell)
46     // primitives have <= 8 vertices, but prevent overrun anyhow
47     // indent following lines for ease of reading
48     label count = 0;
49     forAll(f, fp)
50     {
51         if ((count % 8) == 0)
52         {
53             os  << nl << "  " << cellId;
54         }
55         os  << ' ' << f[fp] + 1;
56         count++;
57     }
58     os  << endl;
62 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
64 template<class Face>
65 Foam::fileFormats::STARCDsurfaceFormat<Face>::STARCDsurfaceFormat
67     const fileName& filename
70     read(filename);
74 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
76 template<class Face>
77 bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
79     const fileName& filename
82     const bool mustTriangulate = this->isTri();
83     this->clear();
85     fileName baseName = filename.lessExt();
87     // read cellTable names (if possible)
88     Map<word> cellTableLookup;
90     {
91         IFstream is(baseName + ".inp");
92         if (is.good())
93         {
94             cellTableLookup = readInpCellTable(is);
95         }
96     }
99     // STAR-CD index of points
100     List<label> pointId;
102     // read points from .vrt file
103     readPoints
104     (
105         IFstream(baseName + ".vrt")(),
106         this->storedPoints(),
107         pointId
108     );
110     // Build inverse mapping (STAR-CD pointId -> index)
111     Map<label> mapPointId(2*pointId.size());
112     forAll(pointId, i)
113     {
114         mapPointId.insert(pointId[i], i);
115     }
116     pointId.clear();
118     //
119     // read .cel file
120     // ~~~~~~~~~~~~~~
121     IFstream is(baseName + ".cel");
122     if (!is.good())
123     {
124         FatalErrorIn
125         (
126             "fileFormats::STARCDsurfaceFormat::read(const fileName&)"
127         )
128             << "Cannot read file " << is.name()
129             << exit(FatalError);
130     }
132     readHeader(is, "PROSTAR_CELL");
134     DynamicList<Face>  dynFaces;
135     DynamicList<label> dynZones;
136     DynamicList<word>  dynNames;
137     DynamicList<label> dynSizes;
138     Map<label> lookup;
140     // assume the cellTableIds are not intermixed
141     bool sorted = true;
142     label zoneI = 0;
144     label lineLabel, shapeId, nLabels, cellTableId, typeId;
145     DynamicList<label> vertexLabels(64);
147     while ((is >> lineLabel).good())
148     {
149         is >> shapeId >> nLabels >> cellTableId >> typeId;
151         vertexLabels.clear();
152         vertexLabels.reserve(nLabels);
154         // read indices - max 8 per line
155         for (label i = 0; i < nLabels; ++i)
156         {
157             label vrtId;
158             if ((i % 8) == 0)
159             {
160                is >> lineLabel;
161             }
162             is >> vrtId;
164             // convert original vertex id to point label
165             vertexLabels.append(mapPointId[vrtId]);
166         }
168         if (typeId == starcdShellType_)
169         {
170             // Convert groupID into zoneID
171             Map<label>::const_iterator fnd = lookup.find(cellTableId);
172             if (fnd != lookup.end())
173             {
174                 if (zoneI != fnd())
175                 {
176                     // cellTableIds are intermixed
177                     sorted = false;
178                 }
179                 zoneI = fnd();
180             }
181             else
182             {
183                 zoneI = dynSizes.size();
184                 lookup.insert(cellTableId, zoneI);
186                 Map<word>::const_iterator tableNameIter =
187                     cellTableLookup.find(cellTableId);
189                 if (tableNameIter == cellTableLookup.end())
190                 {
191                     dynNames.append
192                     (
193                         word("cellTable_") + ::Foam::name(cellTableId)
194                     );
195                 }
196                 else
197                 {
198                     dynNames.append(tableNameIter());
199                 }
201                 dynSizes.append(0);
202             }
204             SubList<label> vertices(vertexLabels, vertexLabels.size());
205             if (mustTriangulate && nLabels > 3)
206             {
207                 face f(vertices);
209                 faceList triFaces(f.nTriangles());
210                 label nTri = 0;
211                 f.triangles(this->points(), nTri, triFaces);
213                 forAll(triFaces, faceI)
214                 {
215                     // a triangular face, but not yet a triFace
216                     dynFaces.append
217                     (
218                         triFace
219                         (
220                             static_cast<labelUList&>(triFaces[faceI])
221                         )
222                     );
223                     dynZones.append(zoneI);
224                     dynSizes[zoneI]++;
225                 }
226             }
227             else
228             {
229                 dynFaces.append(Face(vertices));
230                 dynZones.append(zoneI);
231                 dynSizes[zoneI]++;
232             }
233         }
234     }
235     mapPointId.clear();
237     this->sortFacesAndStore(dynFaces.xfer(), dynZones.xfer(), sorted);
239     // add zones, culling empty ones
240     this->addZones(dynSizes, dynNames, true);
241     return true;
245 template<class Face>
246 void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
248     const fileName& filename,
249     const MeshedSurfaceProxy<Face>& surf
252     const pointField& pointLst = surf.points();
253     const List<Face>&  faceLst = surf.faces();
254     const List<label>& faceMap = surf.faceMap();
256     const List<surfZone>& zones =
257     (
258         surf.surfZones().empty()
259       ? surfaceFormatsCore::oneZone(faceLst)
260       : surf.surfZones()
261     );
263     const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
266     fileName baseName = filename.lessExt();
268     writePoints(OFstream(baseName + ".vrt")(), pointLst);
269     OFstream os(baseName + ".cel");
270     writeHeader(os, "CELL");
272     label faceIndex = 0;
273     forAll(zones, zoneI)
274     {
275         const surfZone& zone = zones[zoneI];
277         if (useFaceMap)
278         {
279             forAll(zone, localFaceI)
280             {
281                 const Face& f = faceLst[faceMap[faceIndex++]];
282                 writeShell(os, f, faceIndex, zoneI + 1);
283             }
284         }
285         else
286         {
287             forAll(zone, localFaceI)
288             {
289                 const Face& f = faceLst[faceIndex++];
290                 writeShell(os, f, faceIndex, zoneI + 1);
291             }
292         }
293     }
295     // write simple .inp file
296     writeCase
297     (
298         OFstream(baseName + ".inp")(),
299         pointLst,
300         faceLst.size(),
301         zones
302     );
306 // ************************************************************************* //