Loading...
Searching...
No Matches
FIREMeshWriter.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 "FIREMeshWriter.H"
29#include "Time.H"
30#include "Map.H"
31#include "OFstream.H"
32#include "processorPolyPatch.H"
33
34// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35
39
40
41// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
42
43namespace
44{
45
46// Output newline in ascii mode, no-op in binary mode
47inline void newline(Foam::OSstream& os)
48{
49 if (os.format() == Foam::IOstreamOption::ASCII)
50 {
51 os << Foam::endl;
52 }
53}
54
55} // End anonymous namespace
56
57
58// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
59
60
61bool Foam::fileFormats::FIREMeshWriter::writeGeometry(OSstream& os) const
62{
63 const faceList& faces = mesh_.faces();
64 const pointField& points = mesh_.points();
65 const cellList& cells = mesh_.cells();
66
67 // Points
68 // ~~~~~~
69
70 // Set the precision of the points data to 10
71 os.precision(10);
72
73 Info<< "points: " << points.size() << endl;
74 putFireLabel(os, points.size());
75 newline(os);
76
77 forAll(points, ptI)
78 {
79 // scaling is normally 1 (ie, none)
81 }
82 newline(os); // readability
83
84
85 // Faces
86 // ~~~~~
87 // OPENFOAM - faces normals are outward-facing.
88 // FIRE - faces normals are inward-facing.
89
90 Info<< "faces: " << faces.size() << endl;
91 putFireLabel(os, faces.size());
92 newline(os);
93
94 forAll(faces, faceI)
95 {
96 // flip face
97 putFireLabels(os, faces[faceI].reverseFace());
98 }
99 newline(os); // readability
100
101
102 // Cells
103 // ~~~~~
104
105 Info<< "cells: " << cells.size() << endl;
106 putFireLabel(os, cells.size());
107 newline(os);
108
110 {
112 }
113 newline(os); // readability
114
115 return os.good();
116}
117
118
119bool Foam::fileFormats::FIREMeshWriter::writeSelections(OSstream& os) const
120{
121 label nZones = 0;
122 label nPatches = 0;
123
124 // remap name between patches and cell-zones conflicts!
125
126 Map<word> patchNames;
127 Map<word> zoneNames;
128
129 wordHashSet usedPatchNames;
130 wordHashSet usedZoneNames;
131
132 // boundaries, skipping empty and processor patches
133 forAll(mesh_.boundaryMesh(), patchI)
134 {
135 const polyPatch& patch = mesh_.boundaryMesh()[patchI];
136 if (patch.size() && !isA<processorPolyPatch>(patch))
137 {
138 ++nPatches;
139
140 const word oldName = patch.name();
141 word newName;
142 if (prefixBoundary)
143 {
144 newName = "BND_" + oldName;
145
146 if (usedPatchNames.found(newName))
147 {
148 newName = "BND_patch" + ::Foam::name(patchI);
149 }
150 }
151 else
152 {
153 newName = oldName;
154
155 if (usedPatchNames.found(newName))
156 {
157 newName = "patch" + ::Foam::name(patchI);
158 }
159 }
160
161 usedPatchNames.set(newName);
162 patchNames.set(patchI, newName);
163 }
164 }
165
166
167 // cellzones, skipping empty zones
168 forAll(mesh_.cellZones(), zoneI)
169 {
170 const cellZone& cZone = mesh_.cellZones()[zoneI];
171 if (cZone.size())
172 {
173 ++nZones;
174
175 const word oldName = cZone.name();
176 word newName = oldName;
177
178 if (usedPatchNames.found(newName) || usedZoneNames.found(newName))
179 {
180 newName = "CEL_zone" + ::Foam::name(zoneI);
181 }
182
183 usedZoneNames.set(newName);
184 zoneNames.set(zoneI, newName);
185 }
186 }
187
188
189 //
190 // actually write things
191 //
192
193 putFireLabel(os, (nZones + nPatches));
194 newline(os);
195
196 // do cell zones
197 forAll(mesh_.cellZones(), zoneI)
198 {
199 const cellZone& cZone = mesh_.cellZones()[zoneI];
200
201 if (cZone.size())
202 {
203 Info<< "cellZone " << zoneI
204 << " (size: " << cZone.size()
205 << ") name: " << zoneNames[zoneI] << nl;
206
207 putFireString(os, zoneNames[zoneI]);
208 putFireLabel(os, static_cast<int>(FIRECore::cellSelection));
209 newline(os);
210
211 putFireLabels(os, cZone);
212 newline(os); // readability
213 }
214 }
215
216 // do boundaries, skipping empty and processor patches
217 forAll(mesh_.boundaryMesh(), patchI)
218 {
219 const polyPatch& patch = mesh_.boundaryMesh()[patchI];
220 if (patch.size() && !isA<processorPolyPatch>(patch))
221 {
222 Info<< "patch " << patchI
223 << " (start: " << patch.start() << " size: " << patch.size()
224 << ") name: " << patchNames[patchI]
225 << endl;
226
227 putFireString(os, patchNames[patchI]);
228 putFireLabel(os, static_cast<int>(FIRECore::faceSelection));
229 newline(os);
230
231 putFireLabels(os, patch.size(), patch.start());
232 newline(os); // readability
233 }
234
235 newline(os); // readability
236 }
238 return os.good();
239}
240
241
242// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
243
244Foam::fileFormats::FIREMeshWriter::FIREMeshWriter
245(
246 const polyMesh& mesh,
247 const scalar scaleFactor
248)
250 meshWriter(mesh, scaleFactor)
251{}
252
253
254// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
255
256bool Foam::fileFormats::FIREMeshWriter::write(const fileName& meshName) const
257{
258 IOstreamOption streamOpt;
259 if (binary)
260 {
262 }
263 if (compress)
264 {
266 }
267
268 fileName baseName(meshName);
269 if (baseName.empty())
270 {
272
273 const Time& t = mesh_.time();
274
275 if
276 (
277 t.timeName() != "0"
278 && t.timeName() != t.constant()
279 )
280 {
281 baseName += "_" + t.timeName();
282 }
283 }
284 else
285 {
286 const word ext(baseName.ext());
287
289 {
291
292 if (fireFileType == FIRECore::fileExt3d::POLY_ASCII)
293 {
294 streamOpt = IOstreamOption
295 (
298 );
299 }
300 else if (fireFileType == FIRECore::fileExt3d::POLY_BINARY)
301 {
302 streamOpt = IOstreamOption
303 (
306 );
307 }
308 else if (fireFileType == FIRECore::fileExt3d::POLY_ASCII_Z)
309 {
310 streamOpt = IOstreamOption
311 (
314 );
315 }
316 else if (fireFileType == FIRECore::fileExt3d::POLY_BINARY_Z)
317 {
318 streamOpt = IOstreamOption
319 (
322 );
323 }
324 }
325
326 baseName.remove_ext();
327 }
328
329
330 // A slight hack. Cannot generate compressed files with the desired ending
331 // So create and rename later
332 const fileName filename = FIRECore::fireFileName
333 (
334 baseName,
335 (
336 streamOpt.format() == IOstreamOption::BINARY
339 )
340 );
341
342 autoPtr<OFstream> osPtr(new OFstream(filename, streamOpt));
343
344 if (osPtr->good())
345 {
346 Info<< "Writing output to ";
347 if (streamOpt.compression() == IOstreamOption::COMPRESSED)
348 {
349 // output .fpmaz instead of .fpma
350 Info<< '"' << osPtr().name().c_str() << "z\"" << endl;
351 }
352 else
353 {
354 Info<< osPtr().name() << endl;
355 }
356
357 writeGeometry(osPtr());
358 writeSelections(osPtr());
359
360 osPtr.clear(); // implicitly close the file
361
362 if (streamOpt.compression() == IOstreamOption::COMPRESSED)
363 {
364 // rename .fpma.gz -> .fpmaz
365 // The '.gz' is automatically added by OFstream in compression mode
366 Foam::mv(filename + ".gz", filename + "z");
367 }
368 }
369 else
370 {
371 Info<<"could not open file for writing " << filename << endl;
372 return false;
373 }
374
375 return true;
376}
377
378
379// ************************************************************************* //
bool found
writer writeGeometry()
A simple container for options an IOstream can normally have.
compressionType compression() const noexcept
Get the stream compression.
streamFormat format() const noexcept
Get the current stream format.
@ ASCII
"ascii" (normal default)
@ UNCOMPRESSED
compression = false
@ COMPRESSED
compression = true
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
const word & constant() const noexcept
Return constant name.
Definition TimePathsI.H:131
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition Time.H:75
static word timeName(const scalar t, const int precision=precision_)
Return a time name for the given scalar time value formatted with the given precision.
Definition Time.C:714
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
static const Enum< fileExt3d > file3dExtensions
Definition FIRECore.H:111
static void putFireLabel(OSstream &, const label)
Write an integer (ascii or binary).
Definition FIRECore.C:199
static fileName fireFileName(const fileName &baseName, const enum fileExt3d)
Resolve base file-name for the given file-type.
Definition FIRECore.C:72
fileExt3d
Enumeration defining the file extensions for 3D types.
Definition FIRECore.H:88
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 bool binary
Write binary (default ascii).
static bool compress
Write with compression (default false).
static bool prefixBoundary
Prefix patches with 'BND_' before writing (default true).
virtual bool write(const fileName &meshName=fileName::null) const
Write volume mesh.
A class for handling file names.
Definition fileName.H:75
bool remove_ext()
Remove extension, returning true if string changed.
Definition stringI.H:93
word ext() const
Return file name extension (part after last .).
Definition fileNameI.H:211
scalar scaleFactor_
Scaling factor for points (eg, [m] -> [mm]).
Definition meshWriter.H:105
static string defaultMeshName
Specify a default mesh name.
Definition meshWriter.H:129
const polyMesh & mesh_
Mesh reference.
Definition meshWriter.H:100
Mesh consisting of general polyhedral cells.
Definition polyMesh.H:79
A class for handling words, derived from Foam::string.
Definition word.H:66
dynamicFvMesh & mesh
OBJstream os(runTime.globalPath()/outputName)
const pointField & points
const cellShapeList & cells
label cellId
const std::string patch
OpenFOAM patch number as a std::string.
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
Definition HashSet.H:80
messageStream Info
Information stream (stdout output on master, null elsewhere).
List< face > faceList
List of faces.
Definition faceListFwd.H:41
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
List< cell > cellList
List of cell.
Definition cellListFwd.H:41
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
Definition typeInfo.H:87
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition exprTraits.C:127
bool mv(const fileName &src, const fileName &dst, const bool followLink=false)
Rename src to dst.
Definition POSIX.C:1326
vectorField pointField
pointField is a vectorField.
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
wordList patchNames(nPatches)
label nPatches
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299