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-2020 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// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
31
33//- Output newline in ascii mode, no-op in binary mode
34inline static void newline(Foam::OSstream& os)
35{
36 if (os.format() == Foam::IOstream::ASCII)
37 {
38 os << '\n';
39 }
40}
41
42
43template<class Face>
44inline static int countFaces(const Face& f)
45{
46 int n = (f.size() - 2); // number triangles can be determined directly
47 return n == 2 ? 1 : n; // quads don't need triangulation
48}
49
51
52
53template<class Face>
55(
56 OSstream& os,
57 const Face& f
58)
59{
60 if (os.format() == IOstream::BINARY)
61 {
62 if (f.size() == 3 || f.size() == 4)
63 {
64 putFireLabel(os, f.size());
65 for (const label verti : f)
66 {
67 putFireLabel(os, verti);
68 }
69 }
70 else
71 {
72 // simple triangulation about f[0].
73 // better triangulation should have been done before
74 for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
75 {
76 const label fp2 = f.fcIndex(fp1);
77
78 putFireLabel(os, 3);
79 putFireLabel(os, f[0]);
80 putFireLabel(os, f[fp1]);
81 putFireLabel(os, f[fp2]);
82 }
83 }
84 }
85 else
86 {
87 // ASCII
88 if (f.size() == 3 || f.size() == 4)
89 {
90 os << ' ' << f.size();
91 for (const label verti : f)
92 {
93 os << ' ' << verti;
94 }
95 os << nl;
96 }
97 else
98 {
99 for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
100 {
101 const label fp2 = f.fcIndex(fp1);
102 os << ' ' << 3 << ' '
103 << f[0] << ' ' << f[fp1] << ' ' << f[fp2]
104 << nl;
105 }
106 }
107 }
108}
109
110
111template<class Face>
113(
114 OSstream& os,
115 const Face& f
116)
117{
118 if (os.format() == IOstream::BINARY)
119 {
120 if (f.size() == 4)
121 {
122 putFireLabel(os, fireQuad);
123 }
124 else
125 {
126 const label n = countFaces(f);
127 for (label i=0; i < n; ++i)
128 {
129 putFireLabel(os, fireTri);
130 }
131 }
132 }
133 else
134 {
135 // ASCII
136 if (f.size() == 4)
137 {
138 os << ' ' << fireQuad;
139 }
140 else
141 {
142 const label n = countFaces(f);
143 for (label i=0; i < n; ++i)
144 {
145 os << ' ' << fireTri;
146 }
147 }
148 }
149}
150
151
152// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
153
154template<class Face>
156(
157 OSstream& os,
158 const MeshedSurfaceProxy<Face>& surf
159)
160{
161 if (!os.good())
162 {
164 << "bad output state "
165 << exit(FatalError);
166 }
167
168 const UList<point>& pointLst = surf.points();
169 const UList<Face>& faceLst = surf.surfFaces();
170 const UList<label>& faceMap = surf.faceMap();
171
172 // for no zones, suppress the group name
173 const surfZoneList zones =
174 (
175 surf.surfZones().empty()
176 ? surfaceFormatsCore::oneZone(faceLst, word::null)
177 : surf.surfZones()
178 );
179
180 const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
181
182
183 // determine the number of faces by counting the
184 // tri/quads/triangulated) faces in each zone
185 label nFaces = 0;
186 labelList zoneCount(zones.size());
187
188 {
189 label faceIndex = 0;
190 forAll(zones, zonei)
191 {
192 const surfZone& zone = zones[zonei];
193
194 label selCount = 0;
195 for (label nLocal = zone.size(); nLocal--; ++faceIndex)
196 {
197 const label facei =
198 (useFaceMap ? faceMap[faceIndex] : faceIndex);
199
200 const Face& f = faceLst[facei];
201
202 selCount += countFaces(f);
203 }
204
205 zoneCount[zonei] = selCount;
206 nFaces += selCount;
207 }
208 }
209
210
211 // Points
212 // ~~~~~~
213
214 // Set the precision of the points data to 10
215 os.precision(10);
216
217 Info<< nl << "points: " << pointLst.size() << endl;
218 putFireLabel(os, pointLst.size());
219 newline(os);
220
221 for (const point& pt : pointLst)
222 {
223 // scaling is normally 1
224 putFirePoint(os, pt);
225 }
226 newline(os); // readability
227
228 // Faces indices
229 {
230 Info<< "faces: " << nFaces << endl;
231 putFireLabel(os, nFaces);
232 newline(os);
233
234 label faceIndex = 0;
235 for (const surfZone& zone : zones)
236 {
237 for (label nLocal = zone.size(); nLocal--; ++faceIndex)
238 {
239 const label facei =
240 (useFaceMap ? faceMap[faceIndex] : faceIndex);
241
242 const Face& f = faceLst[facei];
243
244 writeShell(os, f);
245 }
246 }
247 newline(os);
248 newline(os); // readability
249 }
250
251
252 // Face types
253 {
254 putFireLabel(os, nFaces);
255 newline(os);
256
257 label faceIndex = 0;
258 for (const surfZone& zone : zones)
259 {
260 for (label nLocal = zone.size(); nLocal--; ++faceIndex)
261 {
262 const label facei =
263 (useFaceMap ? faceMap[faceIndex] : faceIndex);
264
265 const Face& f = faceLst[facei];
266
267 writeType(os, f);
268 }
269 }
270 newline(os);
271 newline(os); // readability
272 }
273
274 // Selections (cell)
275 {
276 putFireLabel(os, zones.size());
277 newline(os);
278
279 label faceIndex = 0;
280 forAll(zones, zonei)
281 {
282 const surfZone& zone = zones[zonei];
283 const label selCount = zoneCount[zonei];
284
285 putFireString(os, zone.name());
286 putFireLabel(os, static_cast<int>(FIRECore::cellSelection));
287 newline(os);
288
289 putFireLabels(os, selCount, faceIndex);
290 faceIndex += selCount;
291
292 newline(os); // readability
293 }
294 }
295}
296
297
298template<class Face>
300(
302 const fileName& filename,
303 const MeshedSurfaceProxy<Face>& surf
304)
305{
306 // ASCII only, allow output compression
308 (
309 new OFstream(filename, IOstreamOption(IOstream::ASCII, comp))
310 );
311
312 if (osPtr->good())
313 {
314 FLMAsurfaceFormat<Face>::write(*osPtr, surf);
315
316 if (comp == IOstream::COMPRESSED)
317 {
318 // Close the file
319 osPtr.clear();
320
321 // Rename .flmaz.gz -> .flmaz
322 // The '.gz' is automatically added by OFstream in compression mode
323 Foam::mv(filename + ".gz", filename);
324 }
325 }
326 else
327 {
329 << "Cannot write file " << filename << nl
330 << exit(FatalError);
331 }
332}
333
334
335// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
336
337template<class Face>
339(
340 const fileName& filename,
341 const MeshedSurfaceProxy<Face>& surf,
343 const dictionary&
344)
345{
346 FLMAsurfaceFormat<Face>::write(IOstream::UNCOMPRESSED, filename, surf);
347}
348
349
350template<class Face>
352(
353 const fileName& filename,
354 const MeshedSurfaceProxy<Face>& surf,
356 const dictionary&
357)
358{
359 FLMAsurfaceFormat<Face>::write(IOstream::COMPRESSED, filename, surf);
360}
361
362
363// ************************************************************************* //
label n
The IOstreamOption is a simple container for options an IOstream can normally have.
compressionType
Compression treatment (UNCOMPRESSED | COMPRESSED)
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 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
Generic output stream using a standard (STL) stream.
Definition: OSstream.H:57
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
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
void clear() noexcept
Same as reset(nullptr)
Definition: autoPtr.H:176
bool good() const noexcept
True if the managed pointer is non-null.
Definition: autoPtr.H:145
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
Provide a means of writing AVL/FIRE FLMA format.
A class for handling file names.
Definition: fileName.H:76
virtual bool write()
Write the output fields.
writeType
Enumeration for what to write. Used as a bit-pattern.
A surface zone on a MeshedSurface.
Definition: surfZone.H:59
const word & name() const noexcept
The zone name.
Base class for mesh zones.
Definition: zone.H:67
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
OBJstream os(runTime.globalPath()/outputName)
const labelList nFaces(UPstream::listGatherValues< label >(aMesh.nFaces()))
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
messageStream Info
Information stream (stdout output on master, null elsewhere)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
error FatalError
bool mv(const fileName &src, const fileName &dst, const bool followLink=false)
Rename src to dst.
Definition: MSwindows.C:947
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