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 | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2016-2020 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
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 "STARCDsurfaceFormat.H"
30#include "ListOps.H"
31#include "faceTraits.H"
32
33// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
34
35template<class Face>
37(
38 Ostream& os,
39 const Face& f,
40 const label cellId,
41 const label cellTableId
42)
43{
44 os << (cellId + 1)
45 << ' ' << starcdShell // 3(shell) shape
46 << ' ' << f.size()
47 << ' ' << (cellTableId + 1)
48 << ' ' << starcdShellType; // 4(shell)
49
50 // Primitives have <= 8 vertices, but prevent overrun anyhow
51 // indent following lines for ease of reading
52 label count = 0;
53 for (const label pointi : f)
54 {
55 if ((count % 8) == 0)
56 {
57 os << nl << " " << (cellId + 1);
58 }
59 os << ' ' << (pointi + 1);
60 ++count;
61 }
62 os << nl;
63}
64
65
66// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
67
68template<class Face>
70(
71 const fileName& filename
72)
73{
74 read(filename);
75}
76
77
78// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
79
80template<class Face>
82(
83 const fileName& filename
84)
85{
86 // Clear everything
87 this->clear();
88
89 fileName baseName = filename.lessExt();
90
91 // Read cellTable names (if possible)
92 Map<word> cellTableLookup = readInpCellTable
93 (
94 IFstream(starFileName(baseName, STARCDCore::INP_FILE))()
95 );
96
97
98 // STARCD index of points
99 List<label> pointId;
100
101 // read points from .vrt file
102 readPoints
103 (
104 IFstream(starFileName(baseName, STARCDCore::VRT_FILE))(),
105 this->storedPoints(),
106 pointId
107 );
108
109 // Build inverse mapping (STARCD pointId -> index)
110 Map<label> mapPointId(2*pointId.size());
111 forAll(pointId, i)
112 {
113 mapPointId.insert(pointId[i], i);
114 }
115 pointId.clear();
116
117
118 // Read .cel file
119 // ~~~~~~~~~~~~~~
120 IFstream is(starFileName(baseName, STARCDCore::CEL_FILE));
121 if (!is.good())
122 {
124 << "Cannot read file " << is.name() << nl
125 << exit(FatalError);
126 }
127
128 readHeader(is, STARCDCore::HEADER_CEL);
129
130 DynamicList<label> dynElemId; // STARCD element id (1-based)
131 DynamicList<Face> dynFaces;
132
133 DynamicList<label> dynZones;
134 DynamicList<word> dynNames;
135 DynamicList<label> dynSizes;
137
138 // Assume the cellTableIds are not intermixed
139 bool sorted = true;
140 label zoneId = 0;
141
142 // Element id gets trashed with decompose into a triangle!
143 bool ignoreElemId = false;
144
145 label ignoredLabel, shapeId, nLabels, cellTableId, typeId;
146 DynamicList<label> vertexLabels(64);
147
148 token tok;
149
150 while (is.read(tok).good() && tok.isLabel())
151 {
152 // First token is the element id (1-based)
153 label elemId = tok.labelToken();
154
155 is >> shapeId
156 >> nLabels
157 >> cellTableId
158 >> typeId;
159
160 vertexLabels.clear();
161 vertexLabels.reserve(nLabels);
162
163 // Read indices - max 8 per line
164 for (label i = 0; i < nLabels; ++i)
165 {
166 label vrtId;
167 if ((i % 8) == 0)
168 {
169 is >> ignoredLabel; // Skip cellId for continuation lines
170 }
171 is >> vrtId;
172
173 // Convert original vertex id to point label
174 vertexLabels.append(mapPointId[vrtId]);
175 }
176
177 if (typeId == starcdShellType)
178 {
179 // Convert cellTableId to zoneId
180 const auto iterGroup = lookup.cfind(cellTableId);
181 if (iterGroup.found())
182 {
183 if (zoneId != *iterGroup)
184 {
185 // cellTableIds are intermixed
186 sorted = false;
187 }
188 zoneId = *iterGroup;
189 }
190 else
191 {
192 zoneId = dynSizes.size();
193 lookup.insert(cellTableId, zoneId);
194
195 const auto iterTableName = cellTableLookup.cfind(cellTableId);
196
197 if (iterTableName.found())
198 {
199 dynNames.append(*iterTableName);
200 }
201 else
202 {
203 dynNames.append("cellTable_" + ::Foam::name(cellTableId));
204 }
205
206 dynSizes.append(0);
207 }
208
209 SubList<label> vertices(vertexLabels, vertexLabels.size());
210 if (faceTraits<Face>::isTri() && nLabels > 3)
211 {
212 // The face needs triangulation
213 ignoreElemId = true;
214 dynElemId.clear();
215
216 face f(vertices);
217
218 faceList trias(f.nTriangles());
219 label nTri = 0;
220 f.triangles(this->points(), nTri, trias);
221
222 for (const face& tri : trias)
223 {
224 // A triangular 'face', convert to 'triFace' etc
225 dynFaces.append(Face(tri));
226 dynZones.append(zoneId);
227 dynSizes[zoneId]++;
228 }
229 }
230 else if (nLabels >= 3)
231 {
232 --elemId; // Convert 1-based -> 0-based
233 dynElemId.append(elemId);
234
235 dynFaces.append(Face(vertices));
236 dynZones.append(zoneId);
237 dynSizes[zoneId]++;
238 }
239 }
240 }
241 mapPointId.clear();
242
243
244 if (ignoreElemId)
245 {
246 dynElemId.clear();
247 }
248
249
250 this->sortFacesAndStore(dynFaces, dynZones, dynElemId, sorted);
251
252 // Add zones (retaining empty ones)
253 this->addZones(dynSizes, dynNames);
254 this->addZonesToFaces(); // for labelledTri
255
256 return true;
257}
258
259
260template<class Face>
262(
263 const fileName& filename,
264 const MeshedSurfaceProxy<Face>& surf,
265 IOstreamOption streamOpt,
266 const dictionary&
267)
268{
269 // ASCII only, allow output compression
270 streamOpt.format(IOstream::ASCII);
271
272 const UList<point>& pointLst = surf.points();
273 const UList<Face>& faceLst = surf.surfFaces();
274 const UList<label>& faceMap = surf.faceMap();
275 const UList<label>& elemIds = surf.faceIds();
276
277 const surfZoneList zones =
278 (
279 surf.surfZones().empty()
280 ? surfaceFormatsCore::oneZone(faceLst)
281 : surf.surfZones()
282 );
283
284 const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
285
286 // Possible to use faceIds?
287 // - cannot if there are negative ids (eg, encoded solid/side)
288 const bool useOrigFaceIds =
289 (
290 !useFaceMap
291 && elemIds.size() == faceLst.size()
292 && !ListOps::found(elemIds, lessOp1<label>(0))
293 );
294
295
296 fileName baseName = filename.lessExt();
297
298 // The .vrt file
299 {
300 OFstream os(starFileName(baseName, STARCDCore::VRT_FILE), streamOpt);
301 writePoints(os, pointLst);
302 }
303
304 // The .cel file
305 OFstream os(starFileName(baseName, STARCDCore::CEL_FILE), streamOpt);
306 writeHeader(os, STARCDCore::HEADER_CEL);
307
308 label faceIndex = 0;
309 label zoneIndex = 0;
310 label elemId = 0;
311 for (const surfZone& zone : zones)
312 {
313 for (label nLocal = zone.size(); nLocal--; ++faceIndex)
314 {
315 const label facei =
316 (useFaceMap ? faceMap[faceIndex] : faceIndex);
317
318 const Face& f = faceLst[facei];
319
320 if (useOrigFaceIds)
321 {
322 elemId = elemIds[facei];
323 }
324
325 writeShell(os, f, elemId, zoneIndex);
326 ++elemId;
327 }
328
329 ++zoneIndex;
330 }
331
332 // Simple .inp file - always UNCOMPRESSED
333 {
334 OFstream os(starFileName(baseName, STARCDCore::INP_FILE));
335
336 writeCase
337 (
338 os,
339 pointLst,
340 faceLst.size(),
341 zones
342 );
343 }
344}
345
346
347// ************************************************************************* //
Various functions to operate on Lists.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:72
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:391
void append(const T &val)
Copy append an element to the end of this list.
Definition: DynamicListI.H:503
void reserve(const label len)
Definition: DynamicListI.H:333
const_iterator cfind(const Key &key) const
Find and return an const_iterator set at the hashed entry.
Definition: HashTableI.H:141
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
Definition: HashTableI.H:180
void clear()
Clear all entries from table.
Definition: HashTable.C:678
Input from file stream, using an ISstream.
Definition: IFstream.H:57
virtual const fileName & name() const
Read/write access to the name of the stream.
Definition: ISstream.H:113
The IOstreamOption is a simple container for options an IOstream can normally have.
streamFormat format() const noexcept
Get the current stream format.
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:233
virtual Istream & read(token &t)
Return next token from stream.
Definition: ISstream.C:530
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:116
A HashTable to objects of type <T> with a label key.
Definition: Map.H:60
A proxy for writing MeshedSurface, UnsortedMeshedSurface and surfMesh to various file formats.
const UList< surfZone > & surfZones() const
Const access to the surface zones.
const UList< Face > & surfFaces() const
Return const access to the faces.
bool useFaceMap() const
Can/should use faceMap?
const labelUList & faceIds() const
Const access to the faceIds, zero-sized when unused.
const pointField & points() const
Return const access to the points.
const labelUList & faceMap() const
Const access to the faceMap, zero-sized when unused.
Output to file stream, using an OSstream.
Definition: OFstream.H:57
virtual bool read()
Re-read model coefficients if they have changed.
A List obtained as a section of another List.
Definition: SubList.H:70
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:94
bool empty() const noexcept
True if the UList is empty (ie, size() is zero)
Definition: UListI.H:427
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
Traits class for faces.
Definition: faceTraits.H:51
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Read/write the surface shells from PROSTAR vrt/cel files.
A class for handling file names.
Definition: fileName.H:76
fileName lessExt() const
Return file name without extension (part before last .)
Definition: fileNameI.H:230
virtual bool write()
Write the output fields.
Lookup type of boundary radiation properties.
Definition: lookup.H:66
A surface zone on a MeshedSurface.
Definition: surfZone.H:59
A token holds an item read from Istream.
Definition: token.H:69
bool isLabel() const noexcept
Token is LABEL.
Definition: tokenI.H:497
label labelToken() const
Return label value.
Definition: tokenI.H:513
Base class for mesh zones.
Definition: zone.H:67
patchWriters clear()
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
OBJstream os(runTime.globalPath()/outputName)
const pointField & points
label cellId
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition: BitOps.H:78
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
pointField vertices(const blockVertexList &bvl)
error FatalError
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
labelList f(nPoints)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333