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 -------------------------------------------------------------------------------
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 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
31 
33 //- Output newline in ascii mode, no-op in binary mode
34 inline static void newline(Foam::OSstream& os)
35 {
36  if (os.format() == Foam::IOstream::ASCII)
37  {
38  os << '\n';
39  }
40 }
41 
42 
43 template<class Face>
44 inline 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 
53 template<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 
111 template<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 
154 template<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 
298 template<class Face>
300 (
302  const fileName& filename,
303  const MeshedSurfaceProxy<Face>& surf
304 )
305 {
306  // ASCII only, allow output compression
307  autoPtr<OFstream> osPtr
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 
337 template<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 
350 template<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 // ************************************************************************* //
Foam::fileFormats::FLMAZsurfaceFormat::write
static void write(const fileName &filename, const MeshedSurfaceProxy< Face > &surf, IOstreamOption=IOstreamOption(), const dictionary &=dictionary::null)
Write surface mesh components by proxy.
Definition: FLMAsurfaceFormat.C:352
FLMAsurfaceFormat.H
Foam::faceMap
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Definition: blockMeshMergeTopological.C:94
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::MeshedSurfaceProxy::useFaceMap
bool useFaceMap() const
Can/should use faceMap?
Definition: MeshedSurfaceProxy.H:203
Foam::fileFormats::FLMAsurfaceFormat
Provide a means of writing AVL/FIRE FLMA format.
Definition: FLMAsurfaceFormat.H:66
Foam::zone
Base class for mesh zones.
Definition: zone.H:63
Foam::MeshedSurfaceProxy::points
const pointField & points() const
Return const access to the points.
Definition: MeshedSurfaceProxy.H:171
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::MeshedSurfaceProxy
A proxy for writing MeshedSurface, UnsortedMeshedSurface and surfMesh to various file formats.
Definition: MeshedSurface.H:82
Foam::MeshedSurfaceProxy::faceMap
const labelUList & faceMap() const
Const access to the faceMap, zero-sized when unused.
Definition: MeshedSurfaceProxy.H:191
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::IOstreamOption
The IOstreamOption is a simple container for options an IOstream can normally have.
Definition: IOstreamOption.H:63
Foam::fileFormats::FLMAsurfaceFormat::write
static void write(OSstream &os, const MeshedSurfaceProxy< Face > &surf)
Write surface mesh components by proxy.
Definition: FLMAsurfaceFormat.C:156
Foam::autoPtr::good
bool good() const noexcept
True if the managed pointer is non-null.
Definition: autoPtr.H:145
Foam::OSstream
Generic output stream using a standard (STL) 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:123
Foam::mv
bool mv(const fileName &src, const fileName &dst, const bool followLink=false)
Rename src to dst.
Definition: MSwindows.C:939
os
OBJstream os(runTime.globalPath()/outputName)
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:53
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
Foam::IOstreamOption::ASCII
"ascii" (normal default)
Definition: IOstreamOption.H:72
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::zoneIdentifier::name
const word & name() const noexcept
The zone name.
Definition: zoneIdentifier.H:123
f
labelList f(nPoints)
Foam::Vector< scalar >
Foam::List< surfZone >
Foam::surfZone
A surface zone on a MeshedSurface.
Definition: surfZone.H:56
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:36
Foam::autoPtr::clear
void clear() noexcept
Same as reset(nullptr)
Definition: autoPtr.H:176
Foam::IOstreamOption::compressionType
compressionType
Compression treatment (UNCOMPRESSED | COMPRESSED)
Definition: IOstreamOption.H:77
Foam::MeshedSurfaceProxy::surfFaces
const UList< Face > & surfFaces() const
Return const access to the faces.
Definition: MeshedSurfaceProxy.H:177
Foam::UList::size
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Foam::MeshedSurfaceProxy::surfZones
const UList< surfZone > & surfZones() const
Const access to the surface zones.
Definition: MeshedSurfaceProxy.H:185