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:
Mark Olesen
2022-07-14 16:37:04 +02:00
parent c4d18e97a3
commit b4612b4c04
26 changed files with 440 additions and 438 deletions

View File

@ -43,7 +43,6 @@ Foam::ensightCase::newData
if (Pstream::master())
{
const ensight::VarName varName(name);
output = createDataFile(varName);
// Description

View File

@ -36,57 +36,14 @@ License
bool Foam::ensightFile::allowUndef_ = false;
Foam::scalar Foam::ensightFile::undefValue_ = Foam::floatScalarVGREAT;
// Default is width 8
Foam::string Foam::ensightFile::mask_ = "********";
Foam::string Foam::ensightFile::dirFmt_ = "%08d";
float Foam::ensightFile::undefValue_ = Foam::floatScalarVGREAT;
const char* const Foam::ensightFile::coordinates = "coordinates";
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::string Foam::ensightFile::mask()
{
return mask_;
}
Foam::string Foam::ensightFile::subDir(const label n)
{
char buf[32];
sprintf(buf, dirFmt_.c_str(), n);
return buf;
}
void Foam::ensightFile::subDirWidth(const label n)
{
// enforce max limit to avoid buffer overflow in subDir()
if (n < 1 || n > 31)
{
return;
}
// appropriate printf format
std::ostringstream oss;
oss << "%0" << n << "d";
dirFmt_ = oss.str();
// set mask accordingly
mask_.resize(n, '*');
}
Foam::label Foam::ensightFile::subDirWidth()
{
return mask_.size();
}
bool Foam::ensightFile::isUndef(const UList<scalar>& field)
bool Foam::ensightFile::hasUndef(const UList<scalar>& field)
{
for (const scalar& val : field)
{
@ -102,13 +59,13 @@ bool Foam::ensightFile::isUndef(const UList<scalar>& field)
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::ensightFile::initialize()
void Foam::ensightFile::init()
{
// ascii formatting specs
// The ASCII formatting specs for ensight files
setf
(
ios_base::scientific,
ios_base::floatfield
std::ios_base::scientific,
std::ios_base::floatfield
);
precision(5);
}
@ -124,7 +81,7 @@ Foam::ensightFile::ensightFile
:
OFstream(ensight::FileName(pathname), fmt)
{
initialize();
init();
}
@ -137,37 +94,45 @@ Foam::ensightFile::ensightFile
:
OFstream(path/ensight::FileName(name), fmt)
{
initialize();
init();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
bool Foam::ensightFile::allowUndef()
bool Foam::ensightFile::allowUndef() noexcept
{
return allowUndef_;
}
bool Foam::ensightFile::allowUndef(bool enabled)
// float Foam::ensightFile::undefValue() noexcept
// {
// return undefValue_;
// }
bool Foam::ensightFile::allowUndef(bool on) noexcept
{
bool old = allowUndef_;
allowUndef_ = enabled;
allowUndef_ = on;
return old;
}
Foam::scalar Foam::ensightFile::undefValue(const scalar value)
float Foam::ensightFile::undefValue(float value) noexcept
{
// enable its use too
allowUndef_ = true;
scalar old = undefValue_;
float old = undefValue_;
undefValue_ = value;
return old;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::Ostream& Foam::ensightFile::writeString(const char* str)
{
// Output 80 chars, but allocate for trailing nul character
@ -253,14 +218,14 @@ Foam::Ostream& Foam::ensightFile::write(const int64_t val)
}
Foam::Ostream& Foam::ensightFile::write(const floatScalar val)
Foam::Ostream& Foam::ensightFile::write(const float val)
{
if (format() == IOstreamOption::BINARY)
{
write
(
reinterpret_cast<const char *>(&val),
sizeof(floatScalar)
sizeof(float)
);
}
else
@ -273,7 +238,7 @@ Foam::Ostream& Foam::ensightFile::write(const floatScalar val)
}
Foam::Ostream& Foam::ensightFile::write(const doubleScalar val)
Foam::Ostream& Foam::ensightFile::write(const double val)
{
float fvalue(narrowFloat(val));

View File

@ -60,19 +60,13 @@ class ensightFile
static bool allowUndef_;
//- Value to represent undef in results (default: 1e+37, floatVGREAT)
static scalar undefValue_;
//- The '*' mask appropriate for subDir
static string mask_;
//- The printf format for zero-padded subdirectory numbers
static string dirFmt_;
static float undefValue_;
// Private Member Functions
//- Initialize by setting the ASCII output formatting
void initialize();
//- Initialize sets the ASCII output formatting
void init();
//- No copy construct
ensightFile(const ensightFile&) = delete;
@ -83,6 +77,12 @@ class ensightFile
public:
// Public Data Types
//- Ensight uses \c float not \d double for floating-point
typedef float floatType;
// Static Data Members
//- The keyword "coordinates"
@ -100,8 +100,8 @@ public:
// Constructors
//- Construct from pathName.
// The entire pathName is adjusted for valid ensight file naming.
//- Construct from path-name.
// The path-name is adjusted for valid ensight file naming.
explicit ensightFile
(
const fileName& pathname,
@ -127,31 +127,18 @@ public:
// Access
//- Return setting for whether 'undef' values are allowed in results
static bool allowUndef();
//- The '*' mask appropriate for subDir
static string mask();
//- Consistent zero-padded numbers for subdirectories
static string subDir(const label);
//- Set width of subDir and mask. Default width is 8 digits.
// Max width is 31 digits.
static void subDirWidth(const label);
//- Return current width of subDir and mask.
static label subDirWidth();
static bool allowUndef() noexcept;
// Edit
//- Enable/disable use of \c undef keyword and value
static bool allowUndef(bool enabled);
static bool allowUndef(bool on) noexcept;
//- Assign the value to represent undef in the results
// Returns the previous value
// NB: do not use values larger than floatScalarVGREAT
static scalar undefValue(const scalar value);
static float undefValue(float value) noexcept;
// Output
@ -209,10 +196,10 @@ public:
Ostream& write(const label value, const label fieldWidth);
//- Write floating-point as "%12.5e" or as binary
virtual Ostream& write(const floatScalar val);
virtual Ostream& write(const float val);
//- Write floating-point as "%12.5e" or as binary
virtual Ostream& write(const doubleScalar val);
//- Write floating-point as "%12.5e" or as binary (narrowed to float)
virtual Ostream& write(const double val);
//- Add carriage return to ascii stream
void newline();
@ -252,11 +239,11 @@ public:
// Other Methods
//- Check for any NaN in the field
static bool isUndef(const UList<scalar>& field);
static bool hasUndef(const UList<scalar>& field);
//- Check for any NaN in the field
template<class Addr>
static bool isUndef(const IndirectListBase<scalar, Addr>& field);
static bool hasUndef(const IndirectListBase<scalar, Addr>& field);
};

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
Copyright (C) 2020-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -28,7 +28,7 @@ License
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template<class Addr>
bool Foam::ensightFile::isUndef(const IndirectListBase<scalar, Addr>& field)
bool Foam::ensightFile::hasUndef(const IndirectListBase<scalar, Addr>& field)
{
for (const scalar val : field)
{

View File

@ -31,7 +31,7 @@ License
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::ensightGeoFile::initialize()
void Foam::ensightGeoFile::init()
{
writeBinaryHeader();
@ -61,7 +61,7 @@ Foam::ensightGeoFile::ensightGeoFile
:
ensightFile(pathname, fmt)
{
initialize();
init();
}
@ -74,7 +74,7 @@ Foam::ensightGeoFile::ensightGeoFile
:
ensightFile(path, name, fmt)
{
initialize();
init();
}

View File

@ -52,8 +52,8 @@ class ensightGeoFile
{
// Private Member Functions
//- Initialize by outputting header information
void initialize();
//- Initialize outputs the header information
void init();
//- No copy construct
ensightGeoFile(const ensightGeoFile&) = delete;
@ -75,8 +75,8 @@ public:
// Constructors
//- Construct from pathName.
// The entire pathName is checked for valid ensight naming.
//- Construct from path-name.
// The path-name is adjusted for valid ensight file naming.
explicit ensightGeoFile
(
const fileName& pathname,
@ -84,7 +84,7 @@ public:
);
//- Construct from path and name.
// Only the name portion is checked for valid ensight naming.
// Only the name portion is adjusted for valid ensight file naming.
ensightGeoFile
(
const fileName& path,

View File

@ -400,7 +400,7 @@ void Foam::ensightOutput::writeFaceConnectivity
os.newline();
}
if (etype == ensightFaces::NSIDED)
if (etype == ensightFaces::elemType::NSIDED)
{
// Face sizes (number of points per face)
@ -492,7 +492,7 @@ void Foam::ensightOutput::writeFaceConnectivity
os.newline();
}
if (etype == ensightFaces::NSIDED)
if (etype == ensightFaces::elemType::NSIDED)
{
// Face sizes (number of points per face)

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2021 OpenCFD Ltd.
Copyright (C) 2016-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -186,22 +186,22 @@ void Foam::ensightCells::classifyImpl
{
const cellModel& model = shapes[id].model();
elemType etype(NFACED);
elemType etype(elemType::NFACED);
if (model == tet)
{
etype = TETRA4;
etype = elemType::TETRA4;
}
else if (model == pyr)
{
etype = PYRAMID5;
etype = elemType::PYRAMID5;
}
else if (model == prism)
{
etype = PENTA6;
etype = elemType::PENTA6;
}
else if (model == hex)
{
etype = HEXA8;
etype = elemType::HEXA8;
}
++sizes_[etype];
@ -217,22 +217,22 @@ void Foam::ensightCells::classifyImpl
{
const cellModel& model = shapes[id].model();
elemType etype(NFACED);
elemType etype(elemType::NFACED);
if (model == tet)
{
etype = TETRA4;
etype = elemType::TETRA4;
}
else if (model == pyr)
{
etype = PYRAMID5;
etype = elemType::PYRAMID5;
}
else if (model == prism)
{
etype = PENTA6;
etype = elemType::PENTA6;
}
else if (model == hex)
{
etype = HEXA8;
etype = elemType::HEXA8;
}
add(etype, id);

View File

@ -44,7 +44,7 @@ void Foam::ensightCells::writePolysConnectivity
const bool parallel
)
{
constexpr ensightCells::elemType etype(ensightCells::NFACED);
constexpr ensightCells::elemType etype(ensightCells::elemType::NFACED);
const label nTotal = part.total(etype);
const labelUList& addr = part.cellIds(etype);
@ -201,7 +201,7 @@ void Foam::ensightCells::writeShapeConnectivity
const bool parallel
)
{
if (etype == ensightCells::NFACED)
if (etype == ensightCells::elemType::NFACED)
{
FatalErrorInFunction
<< "Called for ensight NFACED cell. Programming error\n"
@ -303,7 +303,7 @@ void Foam::ensightCells::write
{
const auto etype = ensightCells::elemType(typei);
if (etype == ensightCells::NFACED)
if (etype == ensightCells::elemType::NFACED)
{
writePolysConnectivity
(

View File

@ -27,8 +27,69 @@ License
#include "ensightReadFile.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::IOstreamOption::streamFormat
Foam::ensightReadFile::detectBinaryHeader(const fileName& pathname)
{
IOstreamOption::streamFormat fmt(IOstreamOption::BINARY);
// Detect BINARY vs ASCII by testing for initial "(C|Fortran) Binary"
{
IFstream is(pathname, IOstreamOption::BINARY);
if (!is.good())
{
FatalErrorInFunction
<< "Cannot read file " << is.name() << nl
<< exit(FatalError);
}
istream& iss = is.stdStream();
// Binary string is *exactly* 80 characters
std::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)
)
{
fmt = IOstreamOption::ASCII;
}
}
return fmt;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightReadFile::ensightReadFile
(
const fileName& pathname
)
:
IFstream(pathname, ensightReadFile::detectBinaryHeader(pathname))
{}
Foam::ensightReadFile::ensightReadFile
(
const fileName& pathname,

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2021 OpenCFD Ltd.
Copyright (C) 2016-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -32,8 +32,8 @@ Description
\*---------------------------------------------------------------------------*/
#ifndef ensightReadFile_H
#define ensightReadFile_H
#ifndef Foam_ensightReadFile_H
#define Foam_ensightReadFile_H
#include "IFstream.H"
#include "IOstream.H"
@ -51,7 +51,9 @@ class ensightReadFile
:
public IFstream
{
// Private Member Functions
public:
// Generated Methods
//- No copy construct
ensightReadFile(const ensightReadFile&) = delete;
@ -60,15 +62,16 @@ class ensightReadFile
void operator=(const ensightReadFile&) = delete;
public:
// Constructors
//- Construct from pathname. Default format is binary.
explicit ensightReadFile
//- Construct from pathname, auto-detect the format
explicit ensightReadFile(const fileName& pathname);
//- Construct from pathname, use the specified (ascii/binary) format
ensightReadFile
(
const fileName& pathname,
IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
IOstreamOption::streamFormat fmt
);
@ -76,7 +79,17 @@ public:
~ensightReadFile() = default;
// Output
// Static Functions
//- Detect if the file is \em binary by testing for initial
//- "(C|Fortran) Binary"
static IOstreamOption::streamFormat detectBinaryHeader
(
const fileName& pathname
);
// Read Functions
//- Inherit read from Istream
using Istream::read;

View File

@ -35,8 +35,8 @@ Description
\*---------------------------------------------------------------------------*/
#ifndef ensightPTraits_H
#define ensightPTraits_H
#ifndef Foam_ensightPTraits_H
#define Foam_ensightPTraits_H
#include "fieldTypes.H"
#include "direction.H"
@ -57,49 +57,32 @@ struct ensightPTraits
static const char* const typeName;
//- Ordering table: return OpenFOAM component given Ensight component
// This is used for the symmTensor ordering: Ensight requires
// xx yy zz xy xz yz
// Primarily used for remapping of symmTensor.
// OpenFOAM uses (XX, XY, XZ, YY, YZ, ZZ) order,
// Ensight uses (XX, YY, ZZ, XY, YZ, XZ) order (like VTK).
static const direction componentOrder[];
};
// Specializations
template<>
const char* const ensightPTraits<label>::typeName;
template<> const char* const ensightPTraits<label>::typeName;
template<> const direction ensightPTraits<label>::componentOrder[];
template<>
const direction ensightPTraits<label>::componentOrder[];
template<> const char* const ensightPTraits<scalar>::typeName;
template<> const direction ensightPTraits<scalar>::componentOrder[];
template<>
const char* const ensightPTraits<scalar>::typeName;
template<> const char* const ensightPTraits<vector>::typeName;
template<> const direction ensightPTraits<vector>::componentOrder[];
template<>
const direction ensightPTraits<scalar>::componentOrder[];
template<> const char* const ensightPTraits<sphericalTensor>::typeName;
template<> const direction ensightPTraits<sphericalTensor>::componentOrder[];
template<>
const char* const ensightPTraits<vector>::typeName;
template<> const char* const ensightPTraits<symmTensor>::typeName;
template<> const direction ensightPTraits<symmTensor>::componentOrder[];
template<>
const direction ensightPTraits<vector>::componentOrder[];
template<>
const char* const ensightPTraits<sphericalTensor>::typeName;
template<>
const direction ensightPTraits<sphericalTensor>::componentOrder[];
template<>
const char* const ensightPTraits<symmTensor>::typeName;
template<>
const direction ensightPTraits<symmTensor>::componentOrder[];
template<>
const char* const ensightPTraits<tensor>::typeName;
template<>
const direction ensightPTraits<tensor>::componentOrder[];
template<> const char* const ensightPTraits<tensor>::typeName;
template<> const direction ensightPTraits<tensor>::componentOrder[];
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //