Loading...
Searching...
No Matches
FLMAsurfaceFormat.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) 2016-2022 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
28#include "FLMAsurfaceFormat.H"
29
30// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
31
32namespace
33{
34
35// Output newline in ascii mode, no-op in binary mode
36inline void newline(Foam::OSstream& os)
37{
38 if (os.format() == Foam::IOstreamOption::ASCII)
39 {
40 os << '\n';
41 }
42}
43
44
45template<class Face>
46inline int countFaces(const Face& f)
47{
48 int n = (f.size() - 2); // number triangles can be determined directly
49 return n == 2 ? 1 : n; // quads don't need triangulation
50}
51
52} // End anonymous namespace
53
54
55// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
56
57template<class Face>
58inline void Foam::fileFormats::FLMAsurfaceFormat<Face>::writeShell
59(
60 OSstream& os,
61 const Face& f
62)
63{
64 if (os.format() == IOstreamOption::BINARY)
65 {
66 if (f.size() == 3 || f.size() == 4)
67 {
68 putFireLabel(os, f.size());
69 for (const label verti : f)
70 {
71 putFireLabel(os, verti);
72 }
73 }
74 else
75 {
76 // simple triangulation about f[0].
77 // better triangulation should have been done before
78 for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
79 {
80 const label fp2 = f.fcIndex(fp1);
81
82 putFireLabel(os, 3);
83 putFireLabel(os, f[0]);
84 putFireLabel(os, f[fp1]);
85 putFireLabel(os, f[fp2]);
86 }
87 }
88 }
89 else
90 {
91 // ASCII
92 if (f.size() == 3 || f.size() == 4)
93 {
94 os << ' ' << f.size();
95 for (const label verti : f)
96 {
97 os << ' ' << verti;
98 }
99 os << nl;
100 }
101 else
102 {
103 for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
104 {
105 const label fp2 = f.fcIndex(fp1);
106 os << ' ' << 3 << ' '
107 << f[0] << ' ' << f[fp1] << ' ' << f[fp2]
108 << nl;
109 }
110 }
111 }
112}
113
114
115template<class Face>
116inline void Foam::fileFormats::FLMAsurfaceFormat<Face>::writeType
117(
118 OSstream& os,
119 const Face& f
120)
121{
122 if (os.format() == IOstreamOption::BINARY)
123 {
124 if (f.size() == 4)
125 {
126 putFireLabel(os, fireQuad);
127 }
128 else
129 {
130 const label n = countFaces(f);
131 for (label i=0; i < n; ++i)
132 {
133 putFireLabel(os, fireTri);
134 }
135 }
136 }
137 else
138 {
139 // ASCII
140 if (f.size() == 4)
141 {
142 os << ' ' << fireQuad;
143 }
144 else
145 {
146 const label n = countFaces(f);
147 for (label i=0; i < n; ++i)
148 {
149 os << ' ' << fireTri;
150 }
151 }
153}
154
155
156// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
157
158template<class Face>
160(
161 OSstream& os,
162 const MeshedSurfaceProxy<Face>& surf
163)
164{
165 if (!os.good())
166 {
168 << "bad output state "
169 << exit(FatalError);
170 }
171
172 const UList<point>& pointLst = surf.points();
173 const UList<Face>& faceLst = surf.surfFaces();
174 const UList<label>& faceMap = surf.faceMap();
175
176 // for no zones, suppress the group name
177 const surfZoneList zones
178 (
179 surf.surfZones().empty()
180 ? surfaceFormatsCore::oneZone(faceLst, word::null)
181 : surf.surfZones()
182 );
183
184 const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
185
186
187 // determine the number of faces by counting the
188 // tri/quads/triangulated) faces in each zone
189 label nFaces = 0;
190 labelList zoneCount(zones.size());
191
192 {
193 label faceIndex = 0;
194 forAll(zones, zonei)
195 {
196 const surfZone& zone = zones[zonei];
197
198 label selCount = 0;
199 for (label nLocal = zone.size(); nLocal--; ++faceIndex)
200 {
201 const label facei =
202 (useFaceMap ? faceMap[faceIndex] : faceIndex);
203
204 const Face& f = faceLst[facei];
205
206 selCount += countFaces(f);
207 }
208
209 zoneCount[zonei] = selCount;
210 nFaces += selCount;
211 }
212 }
213
214
215 // Points
216 // ~~~~~~
217
218 // Set the precision of the points data to 10
219 os.precision(10);
220
221 Info<< nl << "points: " << pointLst.size() << endl;
222 putFireLabel(os, pointLst.size());
223 newline(os);
224
225 for (const point& pt : pointLst)
226 {
227 // scaling is normally 1
228 putFirePoint(os, pt);
229 }
230 newline(os); // readability
231
232 // Faces indices
233 {
234 Info<< "faces: " << nFaces << endl;
235 putFireLabel(os, nFaces);
236 newline(os);
237
238 label faceIndex = 0;
239 for (const surfZone& zone : zones)
240 {
241 for (label nLocal = zone.size(); nLocal--; ++faceIndex)
242 {
243 const label facei =
244 (useFaceMap ? faceMap[faceIndex] : faceIndex);
245
246 const Face& f = faceLst[facei];
247
248 writeShell(os, f);
249 }
250 }
251 newline(os);
252 newline(os); // readability
253 }
254
255
256 // Face types
257 {
258 putFireLabel(os, nFaces);
259 newline(os);
260
261 label faceIndex = 0;
262 for (const surfZone& zone : zones)
263 {
264 for (label nLocal = zone.size(); nLocal--; ++faceIndex)
265 {
266 const label facei =
267 (useFaceMap ? faceMap[faceIndex] : faceIndex);
268
269 const Face& f = faceLst[facei];
270
271 writeType(os, f);
272 }
273 }
274 newline(os);
275 newline(os); // readability
276 }
277
278 // Selections (cell)
279 {
280 putFireLabel(os, zones.size());
281 newline(os);
282
283 label faceIndex = 0;
284 forAll(zones, zonei)
285 {
286 const surfZone& zone = zones[zonei];
287 const label selCount = zoneCount[zonei];
288
289 putFireString(os, zone.name());
290 putFireLabel(os, static_cast<int>(FIRECore::cellSelection));
291 newline(os);
292
293 putFireLabels(os, selCount, faceIndex);
294 faceIndex += selCount;
295
296 newline(os); // readability
297 }
298 }
299}
300
301
302template<class Face>
304(
305 IOstreamOption::compressionType comp,
306 const fileName& filename,
307 const MeshedSurfaceProxy<Face>& surf
308)
309{
310 // ASCII only, allow output compression
311 autoPtr<OFstream> osPtr
312 (
313 new OFstream(filename, IOstreamOption(IOstreamOption::ASCII, comp))
314 );
315
316 if (osPtr->good())
317 {
318 FLMAsurfaceFormat<Face>::write(*osPtr, surf);
319
320 if (comp == IOstreamOption::COMPRESSED)
321 {
322 // Close the file
323 osPtr.clear();
324
325 // Rename .flmaz.gz -> .flmaz
326 // The '.gz' is automatically added by OFstream in compression mode
327 Foam::mv(filename + ".gz", filename);
328 }
329 }
330 else
331 {
333 << "Cannot write file " << filename << nl
334 << exit(FatalError);
336}
337
338
339// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
340
341template<class Face>
343(
344 const fileName& filename,
345 const MeshedSurfaceProxy<Face>& surf,
347 const dictionary&
348)
349{
350 FLMAsurfaceFormat<Face>::write
351 (
353 filename,
354 surf
355 );
356}
357
358
359template<class Face>
361(
362 const fileName& filename,
363 const MeshedSurfaceProxy<Face>& surf,
365 const dictionary&
366)
367{
369 (
371 filename,
372 surf
373 );
374}
375
376
377// ************************************************************************* //
label n
A simple container for options an IOstream can normally have.
@ ASCII
"ascii" (normal default)
compressionType
Compression treatment (UNCOMPRESSED | COMPRESSED).
@ UNCOMPRESSED
compression = false
@ COMPRESSED
compression = true
A proxy for writing MeshedSurface, UnsortedMeshedSurface and surfMesh to various file formats.
const UList< surfZone > & surfZones() const noexcept
Const access to the surface zones.
const UList< Face > & surfFaces() const noexcept
Return const access to the faces.
const labelUList & faceMap() const noexcept
Const access to the faceMap, zero-sized when unused.
const pointField & points() const noexcept
Return const access to the points.
bool useFaceMap() const noexcept
Can/should use faceMap?
Output to file stream as an OSstream, normally using std::ofstream for the actual output.
Definition OFstream.H:75
Generic output stream using a standard (STL) stream.
Definition OSstream.H:53
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:89
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition autoPtr.H:65
void clear() noexcept
Same as reset(nullptr).
Definition autoPtr.H:255
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
static void putFireLabel(OSstream &, const label)
Write an integer (ascii or binary).
Definition FIRECore.C:199
static void putFireString(OSstream &, const std::string &)
Write a string (ascii or binary).
Definition FIRECore.C:339
static void putFireLabels(OSstream &, const labelUList &)
Write multiple integers (ascii or binary).
Definition FIRECore.C:224
static void putFirePoint(OSstream &, const point &)
Write a point x/y/z (ascii or binary).
Definition FIRECore.C:308
static void write(const fileName &filename, const MeshedSurfaceProxy< Face > &surf, IOstreamOption=IOstreamOption(), const dictionary &=dictionary::null)
Write surface mesh components (by proxy).
static void write(OSstream &os, const MeshedSurfaceProxy< Face > &surf)
Write surface mesh components (by proxy).
static List< surfZone > oneZone(const Container &container, const word &name="zone0")
Return a surfZone list with a single entry, the size of which corresponds to that of the container.
A class for handling file names.
Definition fileName.H:75
A surface zone on a MeshedSurface.
Definition surfZone.H:55
static const word null
An empty word.
Definition word.H:84
const word & name() const noexcept
The zone name.
Base class for mesh zones.
Definition zone.H:63
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
OBJstream os(runTime.globalPath()/outputName)
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
List< label > labelList
A List of labels.
Definition List.H:62
List< surfZone > surfZoneList
List of surfZone.
messageStream Info
Information stream (stdout output on master, null elsewhere).
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
vector point
Point is a vector.
Definition point.H:37
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
bool mv(const fileName &src, const fileName &dst, const bool followLink=false)
Rename src to dst.
Definition POSIX.C:1326
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
labelList f(nPoints)
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299