ENH: Updated ensight surface file reading

This commit is contained in:
Andrew Heather
2016-06-29 20:43:20 +01:00
parent a415752eb5
commit fe13ff56fc
7 changed files with 486 additions and 78 deletions

View File

@ -0,0 +1,14 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
if [ -f "$FFTW_ARCH_PATH/include/fftw3.h" ] || \
[ "${FFTW_ARCH_PATH##*-}" = system -a -f "/usr/include/fftw3.h" ]
then
wmake
else
echo
echo "Skipping noise utility (no FFTW)"
echo
fi
#------------------------------------------------------------------------------

View File

@ -1,5 +1,6 @@
ensight/file/ensightFile.C ensight/file/ensightFile.C
ensight/file/ensightGeoFile.C ensight/file/ensightGeoFile.C
ensight/readFile/ensightReadFile.C
ensight/part/ensightPart.C ensight/part/ensightPart.C
ensight/part/ensightPartIO.C ensight/part/ensightPartIO.C
ensight/part/ensightPartCells.C ensight/part/ensightPartCells.C

View File

@ -0,0 +1,157 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "ensightReadFile.H"
#include <sstream>
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightReadFile::ensightReadFile
(
const fileName& pathname,
IOstream::streamFormat format
)
:
IFstream(pathname, format)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::ensightReadFile::~ensightReadFile()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::Istream& Foam::ensightReadFile::read
(
char* buf,
std::streamsize count
)
{
stdStream().read(buf, count);
return *this;
}
Foam::Istream& Foam::ensightReadFile::read(string& value)
{
if (format() == IOstream::BINARY)
{
char buf[80];
read(reinterpret_cast<char*>(buf), sizeof(buf));
string strBuf(value);
const size_t iEnd = strBuf.find('\0', 0);
if (iEnd == string::npos)
{
value = buf;
}
else
{
value = strBuf.substr(0, iEnd - 1);
}
}
else
{
value = "";
while (value.empty() && !eof())
{
getLine(value);
}
}
return *this;
}
Foam::Istream& Foam::ensightReadFile::read(label& value)
{
int ivalue;
if (format() == IOstream::BINARY)
{
read
(
reinterpret_cast<char*>(&ivalue),
sizeof(ivalue)
);
}
else
{
stdStream() >> ivalue;
}
value = ivalue;
return *this;
}
Foam::Istream& Foam::ensightReadFile::read(scalar& value)
{
float fvalue;
if (format() == IOstream::BINARY)
{
read
(
reinterpret_cast<char*>(&fvalue),
sizeof(fvalue)
);
value = fvalue;
}
else
{
stdStream() >> value;
}
return *this;
}
Foam::Istream& Foam::ensightReadFile::readKeyword(string& key)
{
read(key);
return *this;
}
Foam::Istream& Foam::ensightReadFile::readBinaryHeader()
{
if (format() == IOstream::BINARY)
{
string buffer;
read(buffer);
}
return *this;
}
// ************************************************************************* //

View File

@ -0,0 +1,110 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Class
Foam::ensightReadFile
Description
Ensight output with specialized read() for strings, integers and floats.
Correctly handles binary read as well.
\*---------------------------------------------------------------------------*/
#ifndef ensightReadFile_H
#define ensightReadFile_H
#include "IFstream.H"
#include "IOstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightReadFile Declaration
\*---------------------------------------------------------------------------*/
class ensightReadFile
:
public IFstream
{
// Private Member Functions
//- Disallow default bitwise assignment
void operator=(const ensightReadFile&);
//- Disallow default copy constructor
ensightReadFile(const ensightReadFile&);
public:
// Constructors
//- Construct from pathname
ensightReadFile
(
const fileName& pathname,
IOstream::streamFormat format=IOstream::BINARY
);
//- Destructor
~ensightReadFile();
// Output
//- Inherit read from Istream
using Istream::read;
//- Binary read
virtual Istream& read(char* buf, std::streamsize count);
//- Read string as "%80s" or as binary
Istream& read(string& value);
//- Read integer as "%10d" or as binary
Istream& read(label& value);
//- Read float as "%12.5e" or as binary
Istream& read(scalar& value);
//- Read element keyword
virtual Istream& readKeyword(string& key);
//- Read "C Binary" for binary files (eg, geometry/measured)
Istream& readBinaryHeader();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -59,6 +59,48 @@ void Foam::ensightSurfaceReader::skip(const label n, IFstream& is) const
} }
void Foam::ensightSurfaceReader::readGeometryHeader(ensightReadFile& is) const
{
// Binary flag string if applicable
is.readBinaryHeader();
string buffer;
// Ensight Geometry File
is.read(buffer);
if (debug) Info<< "buffer: " << buffer << endl;
// Description - 1
is.read(buffer);
if (debug) Info<< "buffer: " << buffer << endl;
// Node info
is.read(buffer);
if (debug) Info<< "buffer: " << buffer << endl;
// Element info
is.read(buffer);
if (debug) Info<< "buffer: " << buffer << endl;
// Part
is.read(buffer);
if (debug) Info<< "buffer: " << buffer << endl;
// Part number
label ibuffer;
is.read(ibuffer);
if (debug) Info<< "ibuffer: " << ibuffer << endl;
// Description - 2
is.read(buffer);
if (debug) Info<< "buffer: " << buffer << endl;
// Co-ordinates
is.read(buffer);
if (debug) Info<< "buffer: " << buffer << endl;
}
void Foam::ensightSurfaceReader::debugSection void Foam::ensightSurfaceReader::debugSection
( (
const word& expected, const word& expected,
@ -74,6 +116,11 @@ void Foam::ensightSurfaceReader::debugSection
<< "' but read the word '" << actual << "'" << "' but read the word '" << actual << "'"
<< exit(FatalIOError); << exit(FatalIOError);
} }
if (debug)
{
Info<< "Read section header: " << expected << endl;
}
} }
@ -91,6 +138,8 @@ void Foam::ensightSurfaceReader::readCase(IFstream& is)
<< exit(FatalError); << exit(FatalError);
} }
string buffer;
// Read the file // Read the file
debugSection("FORMAT", is); debugSection("FORMAT", is);
skip(3, is); // type: ensight gold skip(3, is); // type: ensight gold
@ -124,8 +173,8 @@ void Foam::ensightSurfaceReader::readCase(IFstream& is)
if (debug) if (debug)
{ {
Info<< "fieldNames: " << fieldNames << nl Info<< "fieldNames: " << fieldNames_ << nl
<< "fieldFileNames: " << fieldFileNames << endl; << "fieldFileNames: " << fieldFileNames_ << endl;
} }
// Start reading time information // Start reading time information
@ -142,7 +191,7 @@ void Foam::ensightSurfaceReader::readCase(IFstream& is)
} }
// Read the time values // Read the time values
skip(2, is); // time values: skip(2, is);
timeValues_.setSize(nTimeSteps_); timeValues_.setSize(nTimeSteps_);
for (label i = 0; i < nTimeSteps_; i++) for (label i = 0; i < nTimeSteps_; i++)
{ {
@ -161,6 +210,7 @@ void Foam::ensightSurfaceReader::readCase(IFstream& is)
Foam::ensightSurfaceReader::ensightSurfaceReader(const fileName& fName) Foam::ensightSurfaceReader::ensightSurfaceReader(const fileName& fName)
: :
surfaceReader(fName), surfaceReader(fName),
streamFormat_(IOstream::ASCII),
baseDir_(fName.path()), baseDir_(fName.path()),
meshFileName_(), meshFileName_(),
fieldNames_(), fieldNames_(),
@ -193,31 +243,71 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry()
if (!surfPtr_.valid()) if (!surfPtr_.valid())
{ {
IFstream is(baseDir_/meshFileName_); IFstream isBinary(baseDir_/meshFileName_, IOstream::BINARY);
if (!is.good()) if (!isBinary.good())
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Cannot read file " << is.name() << "Cannot read file " << isBinary.name()
<< exit(FatalError); << exit(FatalError);
} }
token t; streamFormat_ = IOstream::BINARY;
while (is.good())
{ {
is >> t; istream& is = isBinary.stdStream();
if (t.isWord()) char buffer[80];
is.read(buffer, 80);
char test[80];
label nChar = 0;
for (label i = 0; i < 80; ++i)
{ {
word wordToken = t.wordToken(); if (buffer[i] == '\0')
if (wordToken == "coordinates")
{ {
break; break;
} }
test[i] = buffer[i];
nChar++;
}
string testStr(test, nChar);
if
(
(testStr.find("binary", 0) == string::npos)
&& (testStr.find("Binary", 0) == string::npos)
)
{
streamFormat_ = IOstream::ASCII;
} }
} }
label nPoints(readLabel(is)); if (debug)
{
Info<< "stream format: ";
if (streamFormat_ == IOstream::ASCII)
{
Info<< "ascii" << endl;
}
else
{
Info<< "binary" << endl;
}
}
ensightReadFile is(baseDir_/meshFileName_, streamFormat_);
if (debug)
{
Info<< "File: " << is.name() << endl;
}
readGeometryHeader(is);
label nPoints;
is.read(nPoints);
if (debug) if (debug)
{ {
@ -231,7 +321,7 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry()
{ {
forAll(points, pointI) forAll(points, pointI)
{ {
x[pointI] = readScalar(is); is.read(x[pointI]);
} }
points.replace(dir, x); points.replace(dir, x);
@ -241,39 +331,34 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry()
// Read faces - may be a mix of tris, quads and polys // Read faces - may be a mix of tris, quads and polys
DynamicList<face> faces(ceil(nPoints/3)); DynamicList<face> faces(ceil(nPoints/3));
DynamicList<Tuple2<string, label> > schema(faces.size());
while (is.good()) string faceType = "";
label nFace = 0;
while (is.good()) // (is.peek() != EOF)
{ {
token t(is); is.read(faceType);
if (is.eof()) if (!is.good())
{ {
break; break;
} }
word faceType(t.wordToken());
if (debug) if (debug)
{ {
Info<< "faceType: " << faceType << endl; Info<< "faceType: " << faceType << endl;
} }
label nFace(readLabel(is));
if (debug)
{
Info<< "nFace: " << nFace << endl;
}
if (faceType == "tria3") if (faceType == "tria3")
{ {
is.read(nFace);
label np = 3; label np = 3;
for (label faceI = 0; faceI < nFace; faceI++) for (label faceI = 0; faceI < nFace; ++faceI)
{ {
face f(np); face f(np);
for (label fpI = 0; fpI < np; fpI++) for (label fpI = 0; fpI < np; fpI++)
{ {
f[fpI] = readLabel(is); is.read(f[fpI]);
} }
faces.append(f); faces.append(f);
@ -281,13 +366,15 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry()
} }
else if (faceType == "quad4") else if (faceType == "quad4")
{ {
is.read(nFace);
label np = 4; label np = 4;
for (label faceI = 0; faceI < nFace; faceI++) for (label faceI = 0; faceI < nFace; ++faceI)
{ {
face f(np); face f(np);
for (label fpI = 0; fpI < np; fpI++) for (label fpI = 0; fpI < np; fpI++)
{ {
f[fpI] = readLabel(is); is.read(f[fpI]);
} }
faces.append(f); faces.append(f);
@ -295,36 +382,48 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry()
} }
else if (faceType == "nsided") else if (faceType == "nsided")
{ {
is.read(nFace);
labelList np(nFace); labelList np(nFace);
for (label faceI = 0; faceI < nFace; faceI++) for (label faceI = 0; faceI < nFace; ++faceI)
{ {
np[faceI] = readLabel(is); is.read(np[faceI]);
} }
for (label faceI = 0; faceI < nFace; faceI++) for (label faceI = 0; faceI < nFace; ++faceI)
{ {
face f(np[faceI]); face f(np[faceI]);
for (label fpI = 0; fpI < f.size(); fpI++) for (label fpI = 0; fpI < f.size(); ++fpI)
{ {
f[fpI] = readLabel(is); is.read(f[fpI]);
} }
faces.append(f); faces.append(f);
} }
} }
else if (faceType != "") else
{ {
WarningInFunction if (debug)
<< "Unknown face type: " << faceType {
<< ". Aborting read and continuing with current elements " WarningInFunction
<< "only" << endl; << "Unknown face type: " << faceType
<< ". Aborting read and continuing with current "
<< "elements only" << endl;
}
break;
} }
schema.append(Tuple2<string, label>(faceType, nFace));
} }
schema_.transfer(schema);
if (debug) if (debug)
{ {
Info<< "read nFaces: " << faces.size() << endl; Info<< "read nFaces: " << faces.size() << nl
<< "file schema: " << schema_ << endl;
} }
// Convert from 1-based Ensight addressing to 0-based OF addressing
forAll(faces, faceI) forAll(faces, faceI)
{ {
face& f = faces[faceI]; face& f = faces[faceI];

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenCFD Ltd. \\ / A nd | Copyright (C) 2015-2016 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -36,6 +36,8 @@ SourceFiles
#define ensightSurfaceReader_H #define ensightSurfaceReader_H
#include "surfaceReader.H" #include "surfaceReader.H"
#include "ensightReadFile.H"
#include "Tuple2.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -54,6 +56,9 @@ protected:
// Protected Data // Protected Data
//- Format flag
IOstream::streamFormat streamFormat_;
//- Base directory //- Base directory
fileName baseDir_; fileName baseDir_;
@ -81,6 +86,8 @@ protected:
//- Pointer to the surface //- Pointer to the surface
autoPtr<meshedSurface> surfPtr_; autoPtr<meshedSurface> surfPtr_;
List<Tuple2<string, label> > schema_;
// Protected Member Functions // Protected Member Functions
@ -93,6 +100,9 @@ protected:
//- Helper function to skip forward n steps in stream //- Helper function to skip forward n steps in stream
void skip(const label n, IFstream& is) const; void skip(const label n, IFstream& is) const;
//- Read (and throw away) geometry file header
void readGeometryHeader(ensightReadFile& is) const;
//- Helper function to return Type after skipping n tokens //- Helper function to return Type after skipping n tokens
template<class Type> template<class Type>
void readSkip(IFstream& is, const label nSkip, Type& value) const; void readSkip(IFstream& is, const label nSkip, Type& value) const;

View File

@ -64,7 +64,8 @@ Foam::tmp<Foam::Field<Type> > Foam::ensightSurfaceReader::readField
const word indexStr = oss.str(); const word indexStr = oss.str();
fieldFileName.replace("****", indexStr); fieldFileName.replace("****", indexStr);
IFstream is(baseDir_/fieldFileName);
ensightReadFile is(baseDir_/fieldFileName, streamFormat_);
if (!is.good()) if (!is.good())
{ {
@ -75,7 +76,9 @@ Foam::tmp<Foam::Field<Type> > Foam::ensightSurfaceReader::readField
} }
// Check that data type is as expected // Check that data type is as expected
word primitiveType(is); string primitiveType;
is.read(primitiveType);
if (debug) if (debug)
{ {
@ -90,52 +93,66 @@ Foam::tmp<Foam::Field<Type> > Foam::ensightSurfaceReader::readField
<< exit(FatalIOError); << exit(FatalIOError);
} }
tmp<Field<Type> > tField(new Field<Type>()); scalar value;
string strValue;
label n;
if (surfPtr_.valid())
{
n = surfPtr_->size();
}
else
{
n = 1000;
}
Type value;
word wValue;
label iValue; label iValue;
// Read header info: part index, e.g. part 1 // Read header info: part index, e.g. part 1
is >> wValue >> iValue; is.read(strValue);
is.read(iValue);
// Read data file // Allocate storage for data as a list per component
// - Assume that file contains a mix of words and numbers, and that all List<DynamicList<scalar> > values(pTraits<Type>::nComponents);
// numbers relate to face values, e.g. header comprises of words and label n = surfPtr_->size();
// element types are also words, e.g. tria3, quad4, nsided forAll(values, cmptI)
DynamicList<Type> values(n);
while (is.good())
{ {
token t(is); values.setSize(n);
}
if (is.eof()) // Read data file using schema generated while reading the surface
forAll(schema_, i)
{
if (debug)
{ {
break; const string& faceType = schema_[i].first();
Info<< "Reading face type " << faceType << " data" << endl;
} }
if (t.isWord()) const label nFace = schema_[i].second();
if (nFace != 0)
{ {
wValue = t.wordToken(); is.read(strValue);
}
else for
{ (
is.putBack(t); direction cmptI=0;
is >> value; cmptI < pTraits<Type>::nComponents;
values.append(value); ++cmptI
)
{
for (label faceI = 0; faceI < nFace; ++faceI)
{
is.read(value);
values[cmptI].append(value);
}
}
} }
} }
tField().transfer(values); tmp<Field<Type> > tField(new Field<Type>(n, pTraits<Type>::zero));
Field<Type>& field = tField.ref();
for
(
direction cmptI=0;
cmptI < pTraits<Type>::nComponents;
++cmptI
)
{
field.replace(cmptI, values[cmptI]);
values[cmptI].clear();
}
return tField; return tField;
} }