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-2017 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
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 
31 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
32 
34 //- Output newline in ascii mode, no-op in binary mode
35 inline static void newline(Foam::OSstream& os)
36 {
37  if (os.format() == Foam::IOstream::ASCII)
38  {
39  os << '\n';
40  }
41 }
42 
43 
44 template<class Face>
45 inline static int countFaces(const Face& f)
46 {
47  int n = (f.size() - 2); // number triangles can be determined directly
48  return n == 2 ? 1 : n; // quads don't need triangulation
49 }
50 
52 
53 
54 template<class Face>
56 (
57  OSstream& os,
58  const Face& f
59 )
60 {
61  if (os.format() == IOstream::BINARY)
62  {
63  if (f.size() == 3 || f.size() == 4)
64  {
65  putFireLabel(os, f.size());
66  for (const label verti : f)
67  {
68  putFireLabel(os, verti);
69  }
70  }
71  else
72  {
73  // simple triangulation about f[0].
74  // better triangulation should have been done before
75  for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
76  {
77  const label fp2 = f.fcIndex(fp1);
78 
79  putFireLabel(os, 3);
80  putFireLabel(os, f[0]);
81  putFireLabel(os, f[fp1]);
82  putFireLabel(os, f[fp2]);
83  }
84  }
85  }
86  else
87  {
88  // ASCII
89  if (f.size() == 3 || f.size() == 4)
90  {
91  os << ' ' << f.size();
92  for (const label verti : f)
93  {
94  os << ' ' << verti;
95  }
96  os << nl;
97  }
98  else
99  {
100  for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
101  {
102  const label fp2 = f.fcIndex(fp1);
103  os << ' ' << 3 << ' '
104  << f[0] << ' ' << f[fp1] << ' ' << f[fp2]
105  << nl;
106  }
107  }
108  }
109 }
110 
111 
112 template<class Face>
114 (
115  OSstream& os,
116  const Face& f
117 )
118 {
119  if (os.format() == IOstream::BINARY)
120  {
121  if (f.size() == 4)
122  {
123  putFireLabel(os, fireQuad);
124  }
125  else
126  {
127  const label n = countFaces(f);
128  for (label i=0; i < n; ++i)
129  {
130  putFireLabel(os, fireTri);
131  }
132  }
133  }
134  else
135  {
136  // ASCII
137  if (f.size() == 4)
138  {
139  os << ' ' << fireQuad;
140  }
141  else
142  {
143  const label n = countFaces(f);
144  for (label i=0; i < n; ++i)
145  {
146  os << ' ' << fireTri;
147  }
148  }
149  }
150 }
151 
152 
153 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
154 
155 template<class Face>
157 (
158  OSstream& os,
159  const MeshedSurfaceProxy<Face>& surf
160 )
161 {
162  if (!os.good())
163  {
165  << "bad output state "
166  << exit(FatalError);
167  }
168 
169  const UList<point>& pointLst = surf.points();
170  const UList<Face>& faceLst = surf.surfFaces();
171  const UList<label>& faceMap = surf.faceMap();
172 
173  // for no zones, suppress the group name
174  const surfZoneList zones =
175  (
176  surf.surfZones().empty()
177  ? surfaceFormatsCore::oneZone(faceLst, word::null)
178  : surf.surfZones()
179  );
180 
181  const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
182 
183 
184  // determine the number of faces by counting the
185  // tri/quads/triangulated) faces in each zone
186  label nFaces = 0;
187  List<label> zoneCount(zones.size());
188 
189  {
190  label faceIndex = 0;
191  forAll(zones, zoneI)
192  {
193  const surfZone& zone = zones[zoneI];
194 
195  label selCount = 0;
196  if (useFaceMap)
197  {
198  forAll(zone, localFaceI)
199  {
200  selCount += countFaces(faceLst[faceMap[faceIndex++]]);
201  }
202  }
203  else
204  {
205  forAll(zone, localFaceI)
206  {
207  selCount += countFaces(faceLst[faceIndex++]);
208  }
209  }
210 
211  zoneCount[zoneI] = selCount;
212  nFaces += selCount;
213  }
214  }
215 
216 
217  // Points
218  // ~~~~~~
219 
220  // Set the precision of the points data to 10
221  os.precision(10);
222 
223  Info<< nl << "points: " << pointLst.size() << endl;
224  putFireLabel(os, pointLst.size());
225  newline(os);
226 
227  for (const point& pt : pointLst)
228  {
229  // scaling is normally 1
230  putFirePoint(os, pt);
231  }
232  newline(os); // readability
233 
234  // Faces indices
235  {
236  Info<< "faces: " << nFaces << endl;
237  putFireLabel(os, nFaces);
238  newline(os);
239 
240  label faceIndex = 0;
241  for (const surfZone& zone : zones)
242  {
243  const label nLocalFaces = zone.size();
244 
245  if (useFaceMap)
246  {
247  for (label i=0; i<nLocalFaces; ++i)
248  {
249  writeShell(os, faceLst[faceMap[faceIndex++]]);
250  }
251  }
252  else
253  {
254  for (label i=0; i<nLocalFaces; ++i)
255  {
256  writeShell(os, faceLst[faceIndex++]);
257  }
258  }
259  }
260  newline(os);
261  newline(os); // readability
262  }
263 
264 
265  // Face types
266  {
267  putFireLabel(os, nFaces);
268  newline(os);
269 
270  label faceIndex = 0;
271  for (const surfZone& zone : zones)
272  {
273  const label nLocalFaces = zone.size();
274 
275  if (useFaceMap)
276  {
277  for (label i=0; i<nLocalFaces; ++i)
278  {
279  writeType(os, faceLst[faceMap[faceIndex++]]);
280  }
281  }
282  else
283  {
284  for (label i=0; i<nLocalFaces; ++i)
285  {
286  writeType(os, faceLst[faceIndex++]);
287  }
288  }
289  }
290  newline(os);
291  newline(os); // readability
292  }
293 
294  // Selections (cell)
295  {
296  putFireLabel(os, zones.size());
297  newline(os);
298 
299  label faceIndex = 0;
300  forAll(zones, zoneI)
301  {
302  const surfZone& zone = zones[zoneI];
303  const label selCount = zoneCount[zoneI];
304 
305  putFireString(os, zone.name());
306  putFireLabel(os, static_cast<int>(FIRECore::cellSelection));
307  newline(os);
308 
309  putFireLabels(os, selCount, faceIndex);
310  faceIndex += selCount;
311 
312  newline(os); // readability
313  }
314  }
315 }
316 
317 
318 template<class Face>
320 (
321  bool compress,
322  const fileName& filename,
323  const MeshedSurfaceProxy<Face>& surf
324 )
325 {
326  autoPtr<OFstream> osPtr
327  (
328  compress
329  ? new OFstream
330  (
331  filename,
332  IOstream::ASCII,
333  IOstream::currentVersion,
334  IOstream::COMPRESSED
335  )
336  : new OFstream(filename)
337  );
338 
339  if (osPtr->good())
340  {
341  FLMAsurfaceFormat<Face>::write(osPtr(), surf);
342  osPtr.clear(); // implicitly close the file
343 
344  if (compress)
345  {
346  // rename .flmaz.gz -> .flmaz
347  // The '.gz' is automatically added by OFstream in compression mode
348  Foam::mv(filename + ".gz", filename);
349  }
350  }
351  else
352  {
354  << "Cannot open file for writing " << filename
355  << exit(FatalError);
356  }
357 }
358 
359 
360 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
361 
362 template<class Face>
364 (
365  const fileName& filename,
366  const MeshedSurfaceProxy<Face>& surf,
367  const dictionary&
368 )
369 {
370  write(false, filename, surf);
371 }
372 
373 
374 template<class Face>
376 (
377  const fileName& filename,
378  const MeshedSurfaceProxy<Face>& surf,
379  const dictionary&
380 )
381 {
382  FLMAsurfaceFormat<Face>::write(true, filename, surf);
383 }
384 
385 
386 // ************************************************************************* //
FLMAsurfaceFormat.H
Foam::faceMap
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Definition: blockMeshMergeFast.C:94
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::MeshedSurfaceProxy::useFaceMap
bool useFaceMap() const
Use faceMap?
Definition: MeshedSurfaceProxy.H:186
Foam::fileFormats::FLMAsurfaceFormat
Provide a means of writing AVL/FIRE FLMA format.
Definition: FLMAsurfaceFormat.H:55
Foam::zone
Base class for mesh zones.
Definition: zone.H:63
Foam::IOstreamOption::format
streamFormat format() const noexcept
Get the current stream format.
Definition: IOstreamOption.H:273
Foam::MeshedSurfaceProxy::points
const pointField & points() const
Return const access to the points.
Definition: MeshedSurfaceProxy.H:160
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::MeshedSurfaceProxy
A proxy for writing MeshedSurface, UnsortedMeshedSurface and surfMesh to various file formats.
Definition: MeshedSurface.H:78
Foam::MeshedSurfaceProxy::faceMap
const labelUList & faceMap() const
Const access to the faceMap, zero-sized when unused.
Definition: MeshedSurfaceProxy.H:180
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
Foam::fileFormats::FLMAsurfaceFormat::write
static void write(OSstream &os, const MeshedSurfaceProxy< Face > &surf)
Write surface mesh components by proxy.
Definition: FLMAsurfaceFormat.C:157
Foam::OSstream
Generic output stream.
Definition: OSstream.H:54
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
Foam::mv
bool mv(const fileName &src, const fileName &dst, const bool followLink=false)
Rename src to dst.
Definition: MSwindows.C:929
Foam::zone::name
const word & name() const
Return name.
Definition: zone.H:158
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:99
Foam::OSstream::precision
virtual int precision() const
Get precision of output field.
Definition: OSstream.C:311
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
Foam::IOstreamOption::ASCII
"ascii"
Definition: IOstreamOption.H:66
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
Foam::nl
constexpr char nl
Definition: Ostream.H:372
f
labelList f(nPoints)
Foam::Vector< scalar >
Foam::List< surfZone >
Foam::surfZone
A surface zone on a MeshedSurface.
Definition: surfZone.H:65
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
Foam::vtk::write
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
Definition: foamVtkOutputTemplates.C:35
Foam::autoPtr::clear
void clear() noexcept
Delete managed object and set pointer to nullptr.
Definition: autoPtrI.H:151
Foam::UList::size
void size(const label n) noexcept
Override size to be inconsistent with allocated storage.
Definition: UListI.H:360
Foam::MeshedSurfaceProxy::surfFaces
const UList< Face > & surfFaces() const
Return const access to the faces.
Definition: MeshedSurfaceProxy.H:166
Foam::fileFormats::FLMAZsurfaceFormat::write
static void write(const fileName &filename, const MeshedSurfaceProxy< Face > &surf, const dictionary &options=dictionary::null)
Write surface mesh components by proxy.
Definition: FLMAsurfaceFormat.C:376
Foam::IOstream::good
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:216
Foam::MeshedSurfaceProxy::surfZones
const UList< surfZone > & surfZones() const
Const access to the surface zones.
Definition: MeshedSurfaceProxy.H:174