mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: cleanup ensight surface reader (#2535)
- some central (core) bits under fileFormats, - general surface reading relocated from sampling to surfMesh since it does not use any sampling-specific components and will permit re-use in meshTools (for example) - remove old mask, subDir methods from ensightFile which were previously relocated to ensightCase - improve handling of 'undef' values when generating and reading, respect Ensight component ordering when reading.
This commit is contained in:
@ -54,12 +54,6 @@ sampledSurface/sampledSurface/sampledSurfaceRegister.C
|
||||
sampledSurface/sampledSurfaces/sampledSurfaces.C
|
||||
sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.C
|
||||
|
||||
readers = sampledSurface/readers
|
||||
|
||||
$(readers)/surfaceReader.C
|
||||
$(readers)/surfaceReaderNew.C
|
||||
$(readers)/ensight/ensightSurfaceReader.C
|
||||
|
||||
graphField/writePatchGraph.C
|
||||
graphField/writeCellGraph.C
|
||||
graphField/makeGraph.C
|
||||
|
||||
@ -1,693 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 "ensightSurfaceReader.H"
|
||||
#include "stringOps.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(ensightSurfaceReader, 0);
|
||||
addToRunTimeSelectionTable(surfaceReader, ensightSurfaceReader, fileName);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Read and discard specified number of elements
|
||||
template<class Type>
|
||||
static inline void discard(label n, ensightReadFile& is)
|
||||
{
|
||||
Type val;
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
is.read(val);
|
||||
--n;
|
||||
}
|
||||
}
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::ensightSurfaceReader::skip(const label n, Istream& is) const
|
||||
{
|
||||
label i = 0;
|
||||
token tok;
|
||||
while (is.good() && (i < n))
|
||||
{
|
||||
is >> tok;
|
||||
++i;
|
||||
|
||||
DebugInfo
|
||||
<< "Skipping token " << tok << nl;
|
||||
}
|
||||
|
||||
if (i != n)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Requested to skip " << n << " tokens, but stream exited after "
|
||||
<< i << " tokens. Last token read: " << tok
|
||||
<< nl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::ensightSurfaceReader::readLine(IFstream& is, string& line) const
|
||||
{
|
||||
do
|
||||
{
|
||||
is.getLine(line);
|
||||
|
||||
// Trim out any '#' comments
|
||||
const auto pos = line.find('#');
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
line.erase(pos);
|
||||
}
|
||||
stringOps::inplaceTrimRight(line);
|
||||
}
|
||||
while (line.empty() && is.good());
|
||||
}
|
||||
|
||||
|
||||
void Foam::ensightSurfaceReader::debugSection
|
||||
(
|
||||
const word& expected,
|
||||
IFstream& is
|
||||
) const
|
||||
{
|
||||
string actual;
|
||||
readLine(is, actual);
|
||||
|
||||
if (expected != actual)
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "Expected section header '" << expected
|
||||
<< "' but read " << actual << nl
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
DebugInfo
|
||||
<< "Read section header: " << expected << nl;
|
||||
}
|
||||
|
||||
|
||||
Foam::fileName Foam::ensightSurfaceReader::replaceMask
|
||||
(
|
||||
const fileName& fName,
|
||||
const label timeIndex
|
||||
)
|
||||
{
|
||||
fileName result(fName);
|
||||
|
||||
const auto nMask = stringOps::count(fName, '*');
|
||||
|
||||
// If there are any '*' chars, they are assumed to be contiguous
|
||||
// Eg, data/******/geometry
|
||||
|
||||
if (nMask)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << std::setfill('0') << std::setw(nMask) << timeIndex;
|
||||
|
||||
const std::string maskStr(nMask, '*');
|
||||
const std::string indexStr = oss.str();
|
||||
result.replace(maskStr, indexStr);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Foam::Pair<Foam::ensightSurfaceReader::idTypes>
|
||||
Foam::ensightSurfaceReader::readGeometryHeader(ensightReadFile& is) const
|
||||
{
|
||||
// Binary flag string if applicable
|
||||
is.readBinaryHeader();
|
||||
|
||||
string buffer;
|
||||
|
||||
Pair<idTypes> idHandling(idTypes::NONE, idTypes::NONE);
|
||||
|
||||
// Ensight Geometry File
|
||||
is.read(buffer);
|
||||
DebugInfo<< "buffer [" << buffer.length() << "] " << buffer << nl;
|
||||
|
||||
// Description - 1
|
||||
is.read(buffer);
|
||||
DebugInfo<< "buffer [" << buffer.length() << "] " << buffer << nl;
|
||||
|
||||
// "node id (off|assign|given|ignore)" - "given" is not actually supported
|
||||
is.read(buffer);
|
||||
DebugInfo<< "buffer [" << buffer.length() << "] " << buffer << nl;
|
||||
|
||||
if (buffer.find("ignore") != std::string::npos)
|
||||
{
|
||||
idHandling.first() = idTypes::IGNORE;
|
||||
}
|
||||
else if (buffer.find("given") != std::string::npos)
|
||||
{
|
||||
idHandling.first() = idTypes::GIVEN;
|
||||
}
|
||||
|
||||
// "element id (off|assign|given|ignore)"
|
||||
is.read(buffer);
|
||||
DebugInfo<< "buffer [" << buffer.length() << "] " << buffer << nl;
|
||||
|
||||
if (buffer.find("ignore") != std::string::npos)
|
||||
{
|
||||
idHandling.second() = idTypes::IGNORE;
|
||||
}
|
||||
else if (buffer.find("given") != std::string::npos)
|
||||
{
|
||||
idHandling.second() = idTypes::GIVEN;
|
||||
}
|
||||
|
||||
|
||||
// "part" - but could also be an optional "extents"
|
||||
is.read(buffer);
|
||||
DebugInfo<< "buffer [" << buffer.length() << "] " << buffer << nl;
|
||||
|
||||
if (buffer.find("extents") != std::string::npos)
|
||||
{
|
||||
// Optional extents - read and discard 6 floats
|
||||
// (xmin, xmax, ymin, ymax, zmin, zmax)
|
||||
|
||||
discard<scalar>(6, is);
|
||||
|
||||
// Part
|
||||
is.read(buffer);
|
||||
DebugInfo<< "buffer [" << buffer.length() << "] " << buffer << nl;
|
||||
}
|
||||
|
||||
// The part number
|
||||
label ivalue;
|
||||
is.read(ivalue);
|
||||
DebugInfo<< "ivalue: " << ivalue << nl;
|
||||
|
||||
// Part description / name
|
||||
is.read(buffer);
|
||||
DebugInfo<< "buffer [" << buffer.length() << "] " << buffer << nl;
|
||||
|
||||
// "coordinates"
|
||||
is.read(buffer);
|
||||
DebugInfo<< "buffer [" << buffer.length() << "] " << buffer << nl;
|
||||
|
||||
return idHandling;
|
||||
}
|
||||
|
||||
|
||||
void Foam::ensightSurfaceReader::readCase(IFstream& is)
|
||||
{
|
||||
DebugInFunction << endl;
|
||||
|
||||
if (!is.good())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Cannot read file " << is.name()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
string buffer;
|
||||
|
||||
// Read the file
|
||||
|
||||
debugSection("FORMAT", is);
|
||||
readLine(is, buffer); // type: ensight gold
|
||||
|
||||
debugSection("GEOMETRY", is);
|
||||
readLine(is, buffer);
|
||||
|
||||
// GEOMETRY with any of these
|
||||
// model: 1 xxx.0000.mesh
|
||||
// model: xxx.0000.mesh
|
||||
// model: data/directory/geometry
|
||||
//
|
||||
// - use the last entry
|
||||
meshFileName_ = stringOps::splitSpace(buffer).last().str();
|
||||
|
||||
DebugInfo << "mesh file:" << meshFileName_ << endl;
|
||||
|
||||
debugSection("VARIABLE", is);
|
||||
|
||||
// Read the field description
|
||||
DynamicList<word> fieldNames(16);
|
||||
DynamicList<string> fieldFileNames(16);
|
||||
|
||||
while (is.good())
|
||||
{
|
||||
readLine(is, buffer);
|
||||
|
||||
if (buffer == "TIME")
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Read the field name and associated file name. Eg,
|
||||
// scalar per element: 1 p data/********/p
|
||||
|
||||
const auto parsed = stringOps::splitSpace(buffer);
|
||||
|
||||
if (buffer.find(':') == string::npos || parsed.size() < 4)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Error reading field file name. Current buffer: "
|
||||
<< buffer << endl;
|
||||
continue;
|
||||
}
|
||||
else if (debug)
|
||||
{
|
||||
Info<< "variable line: " << parsed.size();
|
||||
for (const auto& s : parsed)
|
||||
{
|
||||
Info<< " " << s.str();
|
||||
}
|
||||
Info<< nl;
|
||||
}
|
||||
|
||||
fieldNames.append(parsed[parsed.size()-2].str());
|
||||
fieldFileNames.append(parsed.last().str());
|
||||
}
|
||||
fieldNames_.transfer(fieldNames);
|
||||
fieldFileNames_.transfer(fieldFileNames);
|
||||
|
||||
DebugInfo
|
||||
<< "fieldNames: " << fieldNames_ << nl
|
||||
<< "fieldFileNames: " << fieldFileNames_ << nl;
|
||||
|
||||
// Start reading time information
|
||||
readLine(is, buffer); // time set: <int>
|
||||
|
||||
readLine(is, buffer);
|
||||
readFromLine(3, buffer, nTimeSteps_); // number of steps: <int>
|
||||
readLine(is, buffer);
|
||||
readFromLine(3, buffer, timeStartIndex_); // filename start number: <int>
|
||||
readLine(is, buffer);
|
||||
readFromLine(2, buffer, timeIncrement_); // filename increment: <int>
|
||||
|
||||
DebugInfo
|
||||
<< "nTimeSteps: " << nTimeSteps_ << nl
|
||||
<< "timeStartIndex: " << timeStartIndex_ << nl
|
||||
<< "timeIncrement: " << timeIncrement_ << nl;
|
||||
|
||||
// Read the time values
|
||||
readLine(is, buffer); // time values:
|
||||
timeValues_.setSize(nTimeSteps_);
|
||||
for (label i = 0; i < nTimeSteps_; ++i)
|
||||
{
|
||||
scalar t(readScalar(is));
|
||||
|
||||
timeValues_[i].value() = t;
|
||||
// TODO: use character representation of t directly instead of
|
||||
// regenerating from scalar value
|
||||
timeValues_[i].name() = Foam::name(t);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::ensightSurfaceReader::ensightSurfaceReader(const fileName& fName)
|
||||
:
|
||||
surfaceReader(fName),
|
||||
streamFormat_(IOstreamOption::ASCII),
|
||||
baseDir_(fName.path()),
|
||||
meshFileName_(),
|
||||
fieldNames_(),
|
||||
fieldFileNames_(),
|
||||
nTimeSteps_(0),
|
||||
timeStartIndex_(0),
|
||||
timeIncrement_(1),
|
||||
timeValues_(),
|
||||
surfPtr_(nullptr)
|
||||
{
|
||||
IFstream is(fName);
|
||||
readCase(is);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
|
||||
|
||||
const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
|
||||
(
|
||||
const label timeIndex
|
||||
)
|
||||
{
|
||||
DebugInFunction << endl;
|
||||
|
||||
if (!surfPtr_)
|
||||
{
|
||||
fileName meshInstance(replaceMask(meshFileName_, timeIndex));
|
||||
IFstream isBinary(baseDir_/meshInstance, IOstreamOption::BINARY);
|
||||
|
||||
if (!isBinary.good())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Cannot read file " << isBinary.name()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
streamFormat_ = IOstreamOption::BINARY;
|
||||
{
|
||||
istream& iss = isBinary.stdStream();
|
||||
|
||||
// Binary string is *exactly* 80 characters
|
||||
string buf(size_t(80), '\0');
|
||||
iss.read(&buf[0], 80);
|
||||
|
||||
if (!iss)
|
||||
{
|
||||
// Truncated?
|
||||
buf.erase(iss.gcount());
|
||||
}
|
||||
|
||||
// Truncate at the first embedded '\0'
|
||||
const auto endp = buf.find('\0');
|
||||
if (endp != std::string::npos)
|
||||
{
|
||||
buf.erase(endp);
|
||||
}
|
||||
|
||||
// Contains "C Binary" ?
|
||||
if
|
||||
(
|
||||
(buf.find("binary") == std::string::npos)
|
||||
&& (buf.find("Binary") == std::string::npos)
|
||||
)
|
||||
{
|
||||
streamFormat_ = IOstreamOption::ASCII;
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "stream format: ";
|
||||
if (streamFormat_ == IOstreamOption::ASCII)
|
||||
{
|
||||
Info<< "ascii" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "binary" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ensightReadFile is(baseDir_/meshInstance, streamFormat_);
|
||||
|
||||
DebugInfo
|
||||
<< "File: " << is.name() << nl;
|
||||
|
||||
Pair<idTypes> idHandling = readGeometryHeader(is);
|
||||
|
||||
label nPoints;
|
||||
is.read(nPoints);
|
||||
|
||||
DebugInfo
|
||||
<< "nPoints: " << nPoints << nl;
|
||||
|
||||
if (idHandling.first() == idTypes::GIVEN)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Treating node id 'given' as being 'ignore'" << nl
|
||||
<< "If something fails, this could be the reason" << nl
|
||||
<< endl;
|
||||
|
||||
idHandling.first() = idTypes::IGNORE;
|
||||
}
|
||||
|
||||
if (idHandling.first() == idTypes::IGNORE)
|
||||
{
|
||||
DebugInfo
|
||||
<< "Ignore " << nPoints << " node ids" << nl;
|
||||
|
||||
// Read and discard labels
|
||||
discard<label>(nPoints, is);
|
||||
}
|
||||
|
||||
pointField points(nPoints);
|
||||
for (direction cmpt = 0; cmpt < vector::nComponents; ++cmpt)
|
||||
{
|
||||
for (point& pt : points)
|
||||
{
|
||||
is.read(pt[cmpt]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Read faces - may be a mix of tris, quads and polys
|
||||
DynamicList<face> faces(ceil(nPoints/3));
|
||||
DynamicList<Tuple2<string, label>> schema(faces.size());
|
||||
string faceType;
|
||||
while (is.good()) // (is.peek() != EOF)
|
||||
{
|
||||
is.read(faceType);
|
||||
|
||||
if (!is.good())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
label nFace = 0;
|
||||
|
||||
if (faceType == "tria3")
|
||||
{
|
||||
is.read(nFace);
|
||||
|
||||
DebugInfo
|
||||
<< "faceType <" << faceType.c_str() << "> count: "
|
||||
<< nFace << nl;
|
||||
|
||||
if
|
||||
(
|
||||
idHandling.second() == idTypes::IGNORE
|
||||
|| idHandling.second() == idTypes::GIVEN
|
||||
)
|
||||
{
|
||||
DebugInfo
|
||||
<< "Ignore " << nFace << " element ids" << nl;
|
||||
|
||||
// Read and discard labels
|
||||
discard<label>(nFace, is);
|
||||
}
|
||||
|
||||
face f(3);
|
||||
for (label facei = 0; facei < nFace; ++facei)
|
||||
{
|
||||
for (label& fp : f)
|
||||
{
|
||||
is.read(fp);
|
||||
}
|
||||
|
||||
faces.append(f);
|
||||
}
|
||||
}
|
||||
else if (faceType == "quad4")
|
||||
{
|
||||
is.read(nFace);
|
||||
|
||||
DebugInfo
|
||||
<< "faceType <" << faceType.c_str() << "> count: "
|
||||
<< nFace << nl;
|
||||
|
||||
if
|
||||
(
|
||||
idHandling.second() == idTypes::IGNORE
|
||||
|| idHandling.second() == idTypes::GIVEN
|
||||
)
|
||||
{
|
||||
DebugInfo
|
||||
<< "Ignore " << nFace << " element ids" << nl;
|
||||
|
||||
// Read and discard labels
|
||||
discard<label>(nFace, is);
|
||||
}
|
||||
|
||||
face f(4);
|
||||
for (label facei = 0; facei < nFace; ++facei)
|
||||
{
|
||||
for (label& fp : f)
|
||||
{
|
||||
is.read(fp);
|
||||
}
|
||||
|
||||
faces.append(f);
|
||||
}
|
||||
}
|
||||
else if (faceType == "nsided")
|
||||
{
|
||||
is.read(nFace);
|
||||
|
||||
DebugInfo
|
||||
<< "faceType <" << faceType.c_str() << "> count: "
|
||||
<< nFace << nl;
|
||||
|
||||
if
|
||||
(
|
||||
idHandling.second() == idTypes::IGNORE
|
||||
|| idHandling.second() == idTypes::GIVEN
|
||||
)
|
||||
{
|
||||
DebugInfo
|
||||
<< "Ignore " << nFace << " element ids" << nl;
|
||||
|
||||
// Read and discard labels
|
||||
discard<label>(nFace, is);
|
||||
}
|
||||
|
||||
labelList np(nFace);
|
||||
for (label facei = 0; facei < nFace; ++facei)
|
||||
{
|
||||
is.read(np[facei]);
|
||||
}
|
||||
for (label facei = 0; facei < nFace; ++facei)
|
||||
{
|
||||
face f(np[facei]);
|
||||
for (label& fp : f)
|
||||
{
|
||||
is.read(fp);
|
||||
}
|
||||
|
||||
faces.append(f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Unknown face type: <" << faceType.c_str()
|
||||
<< ">. Stopping read and continuing with current "
|
||||
<< "elements only" << endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
schema.append(Tuple2<string, label>(faceType, nFace));
|
||||
}
|
||||
|
||||
schema_.transfer(schema);
|
||||
|
||||
DebugInfo
|
||||
<< "read nFaces: " << faces.size() << nl
|
||||
<< "file schema: " << schema_ << nl;
|
||||
|
||||
// Convert from 1-based Ensight addressing to 0-based OF addressing
|
||||
for (face& f : faces)
|
||||
{
|
||||
for (label& pointi : f)
|
||||
{
|
||||
--pointi;
|
||||
}
|
||||
}
|
||||
|
||||
surfPtr_.reset(new meshedSurface(std::move(points), std::move(faces)));
|
||||
}
|
||||
|
||||
return *surfPtr_;
|
||||
}
|
||||
|
||||
|
||||
Foam::instantList Foam::ensightSurfaceReader::times() const
|
||||
{
|
||||
return timeValues_;
|
||||
}
|
||||
|
||||
|
||||
Foam::wordList Foam::ensightSurfaceReader::fieldNames
|
||||
(
|
||||
const label timeIndex
|
||||
) const
|
||||
{
|
||||
return fieldNames_;
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::Field<Foam::scalar>> Foam::ensightSurfaceReader::field
|
||||
(
|
||||
const label timeIndex,
|
||||
const label fieldIndex,
|
||||
const scalar& refValue
|
||||
) const
|
||||
{
|
||||
return readField<scalar>(timeIndex, fieldIndex);
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::Field<Foam::vector>> Foam::ensightSurfaceReader::field
|
||||
(
|
||||
const label timeIndex,
|
||||
const label fieldIndex,
|
||||
const vector& refValue
|
||||
) const
|
||||
{
|
||||
return readField<vector>(timeIndex, fieldIndex);
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::Field<Foam::sphericalTensor>>
|
||||
Foam::ensightSurfaceReader::field
|
||||
(
|
||||
const label timeIndex,
|
||||
const label fieldIndex,
|
||||
const sphericalTensor& refValue
|
||||
) const
|
||||
{
|
||||
return readField<sphericalTensor>(timeIndex, fieldIndex);
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::Field<Foam::symmTensor>> Foam::ensightSurfaceReader::field
|
||||
(
|
||||
const label timeIndex,
|
||||
const label fieldIndex,
|
||||
const symmTensor& refValue
|
||||
) const
|
||||
{
|
||||
return readField<symmTensor>(timeIndex, fieldIndex);
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::Field<Foam::tensor>> Foam::ensightSurfaceReader::field
|
||||
(
|
||||
const label timeIndex,
|
||||
const label fieldIndex,
|
||||
const tensor& refValue
|
||||
) const
|
||||
{
|
||||
return readField<tensor>(timeIndex, fieldIndex);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,239 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2015-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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/>.
|
||||
|
||||
Class
|
||||
Foam::ensightSurfaceReader
|
||||
|
||||
Description
|
||||
Ensight format surface reader
|
||||
|
||||
SourceFiles
|
||||
ensightSurfaceReader.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef ensightSurfaceReader_H
|
||||
#define ensightSurfaceReader_H
|
||||
|
||||
#include "surfaceReader.H"
|
||||
#include "ensightReadFile.H"
|
||||
#include "StringStream.H"
|
||||
#include "Pair.H"
|
||||
#include "Tuple2.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class ensightSurfaceReader Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class ensightSurfaceReader
|
||||
:
|
||||
public surfaceReader
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected Data
|
||||
|
||||
//- Handling of node/element id types (off, assign, ignore, given)
|
||||
enum idTypes : unsigned char
|
||||
{
|
||||
NONE = 0, //!< "off", "assign"
|
||||
IGNORE = 1, //!< Read but "ignore"
|
||||
GIVEN = 2 //!< Use "given" values (not supported)
|
||||
};
|
||||
|
||||
//- Format flag
|
||||
IOstreamOption::streamFormat streamFormat_;
|
||||
|
||||
//- Base directory
|
||||
fileName baseDir_;
|
||||
|
||||
//- Name of mesh file, including any subdirectory
|
||||
fileName meshFileName_;
|
||||
|
||||
//- Field names
|
||||
List<word> fieldNames_;
|
||||
|
||||
//- Field file names
|
||||
List<string> fieldFileNames_;
|
||||
|
||||
//- Number of time steps
|
||||
label nTimeSteps_;
|
||||
|
||||
//- Start time index
|
||||
label timeStartIndex_;
|
||||
|
||||
//- Time increment
|
||||
label timeIncrement_;
|
||||
|
||||
//- Times
|
||||
instantList timeValues_;
|
||||
|
||||
//- Pointer to the surface
|
||||
autoPtr<meshedSurface> surfPtr_;
|
||||
|
||||
List<Tuple2<string, label>> schema_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Helper function to skip forward n steps in stream
|
||||
void skip(const label n, Istream& is) const;
|
||||
|
||||
//- Helper function to read an ascii line from file
|
||||
void readLine(IFstream& is, string& buffer) const;
|
||||
|
||||
//- Read and check a section header
|
||||
void debugSection(const word& expected, IFstream& is) const;
|
||||
|
||||
//- Replace the '*' mask chars with a 0 padded string.
|
||||
static fileName replaceMask
|
||||
(
|
||||
const fileName& fName,
|
||||
const label timeIndex
|
||||
);
|
||||
|
||||
//- Read (and discard) geometry file header.
|
||||
// \return information about node/element id handling
|
||||
Pair<idTypes> readGeometryHeader(ensightReadFile& is) const;
|
||||
|
||||
//- Read the case file
|
||||
void readCase(IFstream& is);
|
||||
|
||||
//- Helper function to return Type after skipping n tokens
|
||||
template<class Type>
|
||||
void readFromLine
|
||||
(
|
||||
const label nSkip,
|
||||
IStringStream& is,
|
||||
Type& value
|
||||
) const;
|
||||
|
||||
//- Helper function to return Type after skipping n tokens
|
||||
template<class Type>
|
||||
void readFromLine
|
||||
(
|
||||
const label nSkip,
|
||||
const string& buffer,
|
||||
Type& value
|
||||
) const;
|
||||
|
||||
//- Helper function to return a field
|
||||
template<class Type>
|
||||
tmp<Field<Type>> readField
|
||||
(
|
||||
const label timeIndex,
|
||||
const label fieldIndex
|
||||
) const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("ensight");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from fileName
|
||||
explicit ensightSurfaceReader(const fileName& fName);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~ensightSurfaceReader() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Return a reference to the surface geometry
|
||||
virtual const meshedSurface& geometry(const label timeIndex);
|
||||
|
||||
//- Return a list of the available times
|
||||
virtual instantList times() const;
|
||||
|
||||
//- Return a list of the available fields at a given time
|
||||
virtual wordList fieldNames(const label timeIndex) const;
|
||||
|
||||
//- Return a scalar field at a given time
|
||||
virtual tmp<Field<scalar>> field
|
||||
(
|
||||
const label timeIndex,
|
||||
const label fieldIndex,
|
||||
const scalar& refValue = pTraits<scalar>::zero
|
||||
) const;
|
||||
|
||||
//- Return a scalar field at a given time
|
||||
virtual tmp<Field<vector>> field
|
||||
(
|
||||
const label timeIndex,
|
||||
const label fieldIndex,
|
||||
const vector& refValue = pTraits<vector>::zero
|
||||
) const;
|
||||
|
||||
//- Return a sphericalTensor field at a given time
|
||||
virtual tmp<Field<sphericalTensor>> field
|
||||
(
|
||||
const label timeIndex,
|
||||
const label fieldIndex,
|
||||
const sphericalTensor& refValue = pTraits<sphericalTensor>::zero
|
||||
) const;
|
||||
|
||||
//- Return a symmTensor field at a given time
|
||||
virtual tmp<Field<symmTensor>> field
|
||||
(
|
||||
const label timeIndex,
|
||||
const label fieldIndex,
|
||||
const symmTensor& refValue = pTraits<symmTensor>::zero
|
||||
) const;
|
||||
|
||||
//- Return a tensor field at a given time
|
||||
virtual tmp<Field<tensor>> field
|
||||
(
|
||||
const label timeIndex,
|
||||
const label fieldIndex,
|
||||
const tensor& refValue = pTraits<tensor>::zero
|
||||
) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "ensightSurfaceReaderTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,158 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2015-2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::ensightSurfaceReader::readFromLine
|
||||
(
|
||||
const label nSkip,
|
||||
IStringStream& is,
|
||||
Type& value
|
||||
) const
|
||||
{
|
||||
skip(nSkip, is);
|
||||
|
||||
is >> value;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::ensightSurfaceReader::readFromLine
|
||||
(
|
||||
const label nSkip,
|
||||
const string& buffer,
|
||||
Type& value
|
||||
) const
|
||||
{
|
||||
IStringStream is(buffer);
|
||||
|
||||
readFromLine(nSkip, is, value);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>> Foam::ensightSurfaceReader::readField
|
||||
(
|
||||
const label timeIndex,
|
||||
const label fieldIndex
|
||||
) const
|
||||
{
|
||||
DebugInFunction << endl;
|
||||
|
||||
const word& fieldName(fieldNames_[fieldIndex]);
|
||||
const label fileIndex = timeStartIndex_ + timeIndex*timeIncrement_;
|
||||
|
||||
fileName fieldFileName(replaceMask(fieldFileNames_[fieldIndex], fileIndex));
|
||||
ensightReadFile is(baseDir_/fieldFileName, streamFormat_);
|
||||
|
||||
if (!is.good())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Cannot read file " << is.name()
|
||||
<< " for field " << fieldName
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
// Check that data type is as expected
|
||||
string primitiveType;
|
||||
is.read(primitiveType);
|
||||
|
||||
|
||||
DebugInfo << "primitiveType: " << primitiveType << endl;
|
||||
|
||||
if (primitiveType != pTraits<Type>::typeName)
|
||||
{
|
||||
IOWarningInFunction(is)
|
||||
<< "Expected '" << pTraits<Type>::typeName
|
||||
<< "' values but found type " << primitiveType << nl
|
||||
<< " This may be okay, but could also indicate an error"
|
||||
<< nl << nl;
|
||||
}
|
||||
|
||||
scalar value;
|
||||
string strValue;
|
||||
label iValue;
|
||||
|
||||
// Read header info: part index, e.g. part 1
|
||||
is.read(strValue);
|
||||
is.read(iValue);
|
||||
|
||||
// Allocate storage for data as a list per component
|
||||
List<DynamicList<scalar>> values(pTraits<Type>::nComponents);
|
||||
label n = surfPtr_->size();
|
||||
forAll(values, cmptI)
|
||||
{
|
||||
values[cmptI].setCapacity(n);
|
||||
}
|
||||
|
||||
// Read data file using schema generated while reading the surface
|
||||
forAll(schema_, i)
|
||||
{
|
||||
DebugInfo
|
||||
<< "Reading face type "
|
||||
<< schema_[i].first() << " data" << endl;
|
||||
|
||||
const label nFace = schema_[i].second();
|
||||
|
||||
if (nFace != 0)
|
||||
{
|
||||
is.read(strValue);
|
||||
|
||||
for
|
||||
(
|
||||
direction cmptI=0;
|
||||
cmptI < pTraits<Type>::nComponents;
|
||||
++cmptI
|
||||
)
|
||||
{
|
||||
for (label faceI = 0; faceI < nFace; ++faceI)
|
||||
{
|
||||
is.read(value);
|
||||
values[cmptI].append(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto tfield = tmp<Field<Type>>::New(n, Zero);
|
||||
auto& field = tfield.ref();
|
||||
|
||||
for (direction cmpti=0; cmpti < pTraits<Type>::nComponents; ++cmpti)
|
||||
{
|
||||
field.replace(cmpti, values[cmpti]);
|
||||
values[cmpti].clear();
|
||||
}
|
||||
|
||||
return tfield;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,47 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 "surfaceReader.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(surfaceReader, 0);
|
||||
defineRunTimeSelectionTable(surfaceReader, fileName);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::surfaceReader::surfaceReader(const fileName& fName)
|
||||
:
|
||||
fileName_(fName)
|
||||
{}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,163 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2015 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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/>.
|
||||
|
||||
Class
|
||||
Foam::surfaceReader
|
||||
|
||||
Description
|
||||
Base class for surface readers
|
||||
|
||||
SourceFiles
|
||||
surfaceReader.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef surfaceReader_H
|
||||
#define surfaceReader_H
|
||||
|
||||
#include "typeInfo.H"
|
||||
#include "autoPtr.H"
|
||||
#include "MeshedSurfaces.H"
|
||||
#include "runTimeSelectionTables.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class surfaceReader Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class surfaceReader
|
||||
{
|
||||
protected:
|
||||
|
||||
//- File name
|
||||
fileName fileName_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("surfaceReader");
|
||||
|
||||
// Declare run-time constructor selection table
|
||||
|
||||
declareRunTimeSelectionTable
|
||||
(
|
||||
autoPtr,
|
||||
surfaceReader,
|
||||
fileName,
|
||||
(
|
||||
const fileName& fName
|
||||
),
|
||||
(fName)
|
||||
);
|
||||
|
||||
|
||||
// Selectors
|
||||
|
||||
//- Return a reference to the selected surfaceReader
|
||||
static autoPtr<surfaceReader> New
|
||||
(
|
||||
const word& readType,
|
||||
const fileName& fName
|
||||
);
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from fileName
|
||||
surfaceReader(const fileName& fName);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~surfaceReader() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Return a reference to the surface geometry
|
||||
virtual const meshedSurface& geometry(const label timeIndex) = 0;
|
||||
|
||||
//- Return a list of the available times
|
||||
virtual instantList times() const = 0;
|
||||
|
||||
//- Return a list of the available fields at a given time
|
||||
virtual wordList fieldNames(const label timeIndex) const = 0;
|
||||
|
||||
//- Return a scalar field at a given time
|
||||
virtual tmp<Field<scalar>> field
|
||||
(
|
||||
const label timeIndex,
|
||||
const label fieldIndex,
|
||||
const scalar& refValue = pTraits<scalar>::zero
|
||||
) const = 0;
|
||||
|
||||
//- Return a vector field at a given time
|
||||
virtual tmp<Field<vector>> field
|
||||
(
|
||||
const label timeIndex,
|
||||
const label fieldIndex,
|
||||
const vector& refValue = pTraits<vector>::zero
|
||||
) const = 0;
|
||||
|
||||
//- Return a sphericalTensor field at a given time
|
||||
virtual tmp<Field<sphericalTensor>> field
|
||||
(
|
||||
const label timeIndex,
|
||||
const label fieldIndex,
|
||||
const sphericalTensor& refValue = pTraits<sphericalTensor>::zero
|
||||
) const = 0;
|
||||
|
||||
//- Return a symmTensor field at a given time
|
||||
virtual tmp<Field<symmTensor>> field
|
||||
(
|
||||
const label timeIndex,
|
||||
const label fieldIndex,
|
||||
const symmTensor& refValue = pTraits<symmTensor>::zero
|
||||
) const = 0;
|
||||
|
||||
//- Return a tensor field at a given time
|
||||
virtual tmp<Field<tensor>> field
|
||||
(
|
||||
const label timeIndex,
|
||||
const label fieldIndex,
|
||||
const tensor& refValue = pTraits<tensor>::zero
|
||||
) const = 0;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,54 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2015-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 "surfaceReader.H"
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
Foam::autoPtr<Foam::surfaceReader> Foam::surfaceReader::New
|
||||
(
|
||||
const word& readerType,
|
||||
const fileName& fName
|
||||
)
|
||||
{
|
||||
auto* ctorPtr = fileNameConstructorTable(readerType);
|
||||
|
||||
if (!ctorPtr)
|
||||
{
|
||||
FatalErrorInLookup
|
||||
(
|
||||
"reader",
|
||||
readerType,
|
||||
*fileNameConstructorTablePtr_
|
||||
) << exit(FatalError);
|
||||
}
|
||||
|
||||
return autoPtr<surfaceReader>(ctorPtr(fName));
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user