FreeFOAM The Cross-Platform CFD Toolkit
STARCDsurfaceFormat.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) 1991-2010 OpenCFD Ltd.
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 "STARCDsurfaceFormat.H"
27 #include <OpenFOAM/ListOps.H>
28 
29 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
30 
31 template<class Face>
33 (
34  Ostream& os,
35  const Face& f,
36  const label cellId,
37  const label cellTableId
38 )
39 {
40  os << cellId // includes 1 offset
41  << ' ' << starcdShellShape_ // 3(shell) shape
42  << ' ' << f.size()
43  << ' ' << cellTableId
44  << ' ' << starcdShellType_; // 4(shell)
45 
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;
59 }
60 
61 
62 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
63 
64 template<class Face>
66 (
67  const fileName& filename
68 )
69 {
70  read(filename);
71 }
72 
73 
74 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
75 
76 template<class Face>
78 (
79  const fileName& filename
80 )
81 {
82  const bool mustTriangulate = this->isTri();
83  this->clear();
84 
85  fileName baseName = filename.lessExt();
86 
87  // STAR-CD index of points
88  List<label> pointId;
89 
90  // read points from .vrt file
91  readPoints
92  (
93  IFstream(baseName + ".vrt")(),
94  this->storedPoints(),
95  pointId
96  );
97 
98  // Build inverse mapping (STAR-CD pointId -> index)
99  Map<label> mapPointId(2*pointId.size());
100  forAll(pointId, i)
101  {
102  mapPointId.insert(pointId[i], i);
103  }
104  pointId.clear();
105 
106  //
107  // read .cel file
108  // ~~~~~~~~~~~~~~
109  IFstream is(baseName + ".cel");
110  if (!is.good())
111  {
113  (
114  "fileFormats::STARCDsurfaceFormat::read(const fileName&)"
115  )
116  << "Cannot read file " << is.name()
117  << exit(FatalError);
118  }
119 
120  readHeader(is, "PROSTAR_CELL");
121 
122  DynamicList<Face> dynFaces;
123  DynamicList<label> dynZones;
124  DynamicList<word> dynNames;
125  DynamicList<label> dynSizes;
126  Map<label> lookup;
127 
128  // assume the cellTableIds are not intermixed
129  bool sorted = true;
130  label zoneI = 0;
131 
132  label lineLabel, shapeId, nLabels, cellTableId, typeId;
133  DynamicList<label> vertexLabels(64);
134 
135  while ((is >> lineLabel).good())
136  {
137  is >> shapeId >> nLabels >> cellTableId >> typeId;
138 
139  vertexLabels.clear();
140  vertexLabels.reserve(nLabels);
141 
142  // read indices - max 8 per line
143  for (label i = 0; i < nLabels; ++i)
144  {
145  label vrtId;
146  if ((i % 8) == 0)
147  {
148  is >> lineLabel;
149  }
150  is >> vrtId;
151 
152  // convert original vertex id to point label
153  vertexLabels.append(mapPointId[vrtId]);
154  }
155 
156  if (typeId == starcdShellType_)
157  {
158  // Convert groupID into zoneID
159  Map<label>::const_iterator fnd = lookup.find(cellTableId);
160  if (fnd != lookup.end())
161  {
162  if (zoneI != fnd())
163  {
164  // cellTableIds are intermixed
165  sorted = false;
166  }
167  zoneI = fnd();
168  }
169  else
170  {
171  zoneI = dynSizes.size();
172  lookup.insert(cellTableId, zoneI);
173  dynNames.append(word("cellTable_") + ::Foam::name(zoneI));
174  dynSizes.append(0);
175  }
176 
177  SubList<label> vertices(vertexLabels, vertexLabels.size());
178  if (mustTriangulate && nLabels > 3)
179  {
180  face f(vertices);
181 
182  faceList triFaces(f.nTriangles());
183  label nTri = 0;
184  f.triangles(this->points(), nTri, triFaces);
185 
186  forAll(triFaces, faceI)
187  {
188  // a triangular face, but not yet a triFace
189  dynFaces.append
190  (
191  triFace
192  (
193  static_cast<UList<label>&>(triFaces[faceI])
194  )
195  );
196  dynZones.append(zoneI);
197  dynSizes[zoneI]++;
198  }
199  }
200  else
201  {
202  dynFaces.append(Face(vertices));
203  dynZones.append(zoneI);
204  dynSizes[zoneI]++;
205  }
206  }
207  }
208  mapPointId.clear();
209 
210  sortFacesAndStore(dynFaces.xfer(), dynZones.xfer(), sorted);
211 
212  // add zones, culling empty ones
213  this->addZones(dynSizes, dynNames, true);
214  return true;
215 }
216 
217 
218 template<class Face>
220 (
221  const fileName& filename,
222  const MeshedSurfaceProxy<Face>& surf
223 )
224 {
225  const pointField& pointLst = surf.points();
226  const List<Face>& faceLst = surf.faces();
227  const List<label>& faceMap = surf.faceMap();
228 
229  const List<surfZone>& zones =
230  (
231  surf.surfZones().size() > 1
232  ? surf.surfZones()
233  : oneZone(faceLst)
234  );
235 
236  const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
237 
238 
239  fileName baseName = filename.lessExt();
240 
241  writePoints(OFstream(baseName + ".vrt")(), pointLst);
242  OFstream os(baseName + ".cel");
243  writeHeader(os, "CELL");
244 
245  label faceIndex = 0;
246  forAll(zones, zoneI)
247  {
248  const surfZone& zone = zones[zoneI];
249 
250  if (useFaceMap)
251  {
252  forAll(zone, localFaceI)
253  {
254  const Face& f = faceLst[faceMap[faceIndex++]];
255  writeShell(os, f, faceIndex, zoneI + 1);
256  }
257  }
258  else
259  {
260  forAll(zone, localFaceI)
261  {
262  const Face& f = faceLst[faceIndex++];
263  writeShell(os, f, faceIndex, zoneI + 1);
264  }
265  }
266  }
267 
268  // write simple .inp file
269  writeCase
270  (
271  OFstream(baseName + ".inp")(),
272  pointLst,
273  faceLst.size(),
274  zones
275  );
276 }
277 
278 
279 // ************************ vim: set sw=4 sts=4 et: ************************ //