Files
openfoam/src/conversion/fire/FIREMeshWriter.C
Mark Olesen c0e86940b0 ENH: minor improvements for Enum
- found() method for consistency with other classes

- operator()(name, deflt) for similarity to lookupOrDefault,
  but without a dictionary
2017-11-28 09:15:04 +01:00

365 lines
9.4 KiB
C

/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "FIREMeshWriter.H"
#include "Time.H"
#include "HashTable.H"
#include "OFstream.H"
#include "processorPolyPatch.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
bool Foam::fileFormats::FIREMeshWriter::binary = false;
bool Foam::fileFormats::FIREMeshWriter::compress = false;
bool Foam::fileFormats::FIREMeshWriter::prefixBoundary = true;
//! \cond fileScope
//- Output newline in ascii mode, no-op in binary mode
inline static void newline(Foam::OSstream& os)
{
if (os.format() == Foam::IOstream::ASCII)
{
os << Foam::endl;
}
}
//! \endcond
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
bool Foam::fileFormats::FIREMeshWriter::writeGeometry(OSstream& os) const
{
const faceList& faces = mesh_.faces();
const pointField& points = mesh_.points();
const cellList& cells = mesh_.cells();
// Points
// ~~~~~~
// Set the precision of the points data to 10
os.precision(10);
Info<< "points: " << points.size() << endl;
putFireLabel(os, points.size());
newline(os);
forAll(points, ptI)
{
// scaling is normally 1 (ie, none)
putFirePoint(os, scaleFactor_ * points[ptI]);
}
newline(os); // readability
// Faces
// ~~~~~
// OPENFOAM - faces normals are outward-facing.
// FIRE - faces normals are inward-facing.
Info<< "faces: " << faces.size() << endl;
putFireLabel(os, faces.size());
newline(os);
forAll(faces, faceI)
{
// flip face
putFireLabels(os, faces[faceI].reverseFace());
}
newline(os); // readability
// Cells
// ~~~~~
Info<< "cells: " << cells.size() << endl;
putFireLabel(os, cells.size());
newline(os);
forAll(cells, cellId)
{
putFireLabels(os, cells[cellId]);
}
newline(os); // readability
return os.good();
}
bool Foam::fileFormats::FIREMeshWriter::writeSelections(OSstream& os) const
{
label nZones = 0;
label nPatches = 0;
// remap name between patches and cell-zones conflicts!
HashTable<word, label> patchNames;
HashTable<word, label> zoneNames;
wordHashSet usedPatchNames;
wordHashSet usedZoneNames;
// boundaries, skipping empty and processor patches
forAll(mesh_.boundaryMesh(), patchI)
{
const polyPatch& patch = mesh_.boundaryMesh()[patchI];
if (patch.size() && !isA<processorPolyPatch>(patch))
{
++nPatches;
const word oldName = patch.name();
word newName;
if (prefixBoundary)
{
newName = "BND_" + oldName;
if (usedPatchNames.found(newName))
{
newName = "BND_patch" + ::Foam::name(patchI);
}
}
else
{
newName = oldName;
if (usedPatchNames.found(newName))
{
newName = "patch" + ::Foam::name(patchI);
}
}
usedPatchNames.set(newName);
patchNames.set(patchI, newName);
}
}
// cellzones, skipping empty zones
forAll(mesh_.cellZones(), zoneI)
{
const cellZone& cZone = mesh_.cellZones()[zoneI];
if (cZone.size())
{
++nZones;
const word oldName = cZone.name();
word newName = oldName;
if (usedPatchNames.found(newName) || usedZoneNames.found(newName))
{
newName = "CEL_zone" + ::Foam::name(zoneI);
}
usedZoneNames.set(newName);
zoneNames.set(zoneI, newName);
}
}
//
// actually write things
//
putFireLabel(os, (nZones + nPatches));
newline(os);
// do cell zones
forAll(mesh_.cellZones(), zoneI)
{
const cellZone& cZone = mesh_.cellZones()[zoneI];
if (cZone.size())
{
Info<< "cellZone " << zoneI
<< " (size: " << cZone.size()
<< ") name: " << zoneNames[zoneI] << nl;
putFireString(os, zoneNames[zoneI]);
putFireLabel(os, static_cast<int>(FIRECore::cellSelection));
newline(os);
putFireLabels(os, cZone);
newline(os); // readability
}
}
// do boundaries, skipping empty and processor patches
forAll(mesh_.boundaryMesh(), patchI)
{
const polyPatch& patch = mesh_.boundaryMesh()[patchI];
if (patch.size() && !isA<processorPolyPatch>(patch))
{
Info<< "patch " << patchI
<< " (start: " << patch.start() << " size: " << patch.size()
<< ") name: " << patchNames[patchI]
<< endl;
putFireString(os, patchNames[patchI]);
putFireLabel(os, static_cast<int>(FIRECore::faceSelection));
newline(os);
putFireLabels(os, patch.size(), patch.start());
newline(os); // readability
}
newline(os); // readability
}
return os.good();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fileFormats::FIREMeshWriter::FIREMeshWriter
(
const polyMesh& mesh,
const scalar scaleFactor
)
:
meshWriter(mesh, scaleFactor)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::fileFormats::FIREMeshWriter::~FIREMeshWriter()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::fileFormats::FIREMeshWriter::write(const fileName& meshName) const
{
bool useBinary = binary;
bool useCompress = compress;
fileName baseName(meshName);
if (baseName.empty())
{
baseName = meshWriter::defaultMeshName;
const Time& t = mesh_.time();
if
(
t.timeName() != "0"
&& t.timeName() != t.constant()
)
{
baseName += "_" + t.timeName();
}
}
else
{
const word ext = baseName.ext();
if (FIRECore::file3dExtensions.found(ext))
{
FIRECore::fileExt3d fireFileType = FIRECore::file3dExtensions[ext];
if (fireFileType == FIRECore::fileExt3d::POLY_ASCII)
{
useBinary = false;
useCompress = false;
}
else if (fireFileType == FIRECore::fileExt3d::POLY_BINARY)
{
useBinary = true;
useCompress = false;
}
else if (fireFileType == FIRECore::fileExt3d::POLY_ASCII_Z)
{
useBinary = false;
useCompress = true;
}
else if (fireFileType == FIRECore::fileExt3d::POLY_BINARY_Z)
{
useBinary = true;
useCompress = true;
}
}
baseName = baseName.lessExt();
}
// A slight hack. Cannot generate compressed files with the desired ending
// So create and rename later
const fileName filename = FIRECore::fireFileName
(
baseName,
useBinary ? FIRECore::POLY_BINARY : FIRECore::POLY_ASCII
);
autoPtr<OFstream> osPtr
(
new OFstream
(
filename,
(useBinary ? IOstream::BINARY : IOstream::ASCII),
IOstream::currentVersion,
(useCompress ? IOstream::COMPRESSED : IOstream::UNCOMPRESSED)
)
);
if (osPtr->good())
{
Info<< "Writing output to ";
if (useCompress)
{
// output .fpmaz instead of .fpma
Info<< '"' << osPtr().name().c_str() << "z\"" << endl;
}
else
{
Info<< osPtr().name() << endl;
}
writeGeometry(osPtr());
writeSelections(osPtr());
osPtr.clear(); // implicitly close the file
if (useCompress)
{
// rename .fpma.gz -> .fpmaz
// The '.gz' is automatically added by OFstream in compression mode
Foam::mv(filename + ".gz", filename + "z");
}
}
else
{
Info<<"could not open file for writing " << filename << endl;
return false;
}
return true;
}
// ************************************************************************* //