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

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -24,10 +24,11 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Description Description
Print max limits. Print some numerical limits.
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include <cmath>
#include <limits> #include <limits>
#include "int.H" #include "int.H"
#include "uint.H" #include "uint.H"
@ -37,21 +38,63 @@ Description
using namespace Foam; using namespace Foam;
std::ostream& print(const char* tag, float val)
{
std::cout
<< tag << val
<< " 0x" << std::hex << *reinterpret_cast<const uint32_t*>(&val);
return std::cout;
}
std::ostream& print(const char* tag, double val)
{
std::cout
<< tag << val
<< " 0x" << std::hex << *reinterpret_cast<const uint64_t*>(&val);
return std::cout;
}
// Have (float|double)Scalar(GREAT|SMALL|..)
#define PrintFloatLimits(FloatType, NanFunction) \
{ \
print("max:", std::numeric_limits<FloatType>::max()); \
print(" VGREAT:", FloatType##ScalarVGREAT); \
print(" ROOTVGREAT:", FloatType##ScalarROOTVGREAT) << nl; \
\
print("min:", std::numeric_limits<FloatType>::min()); \
print(" VSMALL:", FloatType##ScalarVSMALL); \
print(" ROOTVSMALL:", FloatType##ScalarROOTVSMALL) << nl; \
\
print("epsilon:", std::numeric_limits<FloatType>::epsilon()); \
print(" SMALL:", FloatType##ScalarSMALL); \
print(" ROOTSMALL:", FloatType##ScalarROOTSMALL) << nl; \
\
print("1/epsilon:", 1/std::numeric_limits<FloatType>::epsilon()); \
print(" GREAT:", FloatType##ScalarGREAT); \
print(" ROOTGREAT:", FloatType##ScalarROOTGREAT) << nl; \
\
print("nan:", std::NanFunction("nan")) << nl; \
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program: // Main program:
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
//NONE Info<<"int16:" << pTraits<int16_t>::max << nl; //NONE cout<<"int16:" << pTraits<int16_t>::max << nl;
Info<< "=max=" << nl; cout<< "=max=" << nl;
Info<< "uint8:" << pTraits<uint8_t>::max << nl; cout<< "uint8:" << pTraits<uint8_t>::max << nl;
Info<< "int16:" << std::numeric_limits<int16_t>::max() << nl; cout<< "int16:" << std::numeric_limits<int16_t>::max() << nl;
Info<< "int32:" << pTraits<int32_t>::max << nl; cout<< "int32:" << pTraits<int32_t>::max << nl;
Info<< "uint32:" << pTraits<uint32_t>::max << nl; cout<< "uint32:" << pTraits<uint32_t>::max << nl;
Info<< "int64:" << pTraits<int64_t>::max << nl; cout<< "int64:" << pTraits<int64_t>::max << nl;
Info<< "uint64:" << pTraits<uint64_t>::max << nl; cout<< "uint64:" << pTraits<uint64_t>::max << nl;
Info<< nl; cout<< nl;
cout<< "int16:" << std::numeric_limits<int16_t>::max() << nl; cout<< "int16:" << std::numeric_limits<int16_t>::max() << nl;
cout<< "int32:" << pTraits<int32_t>::max << nl; cout<< "int32:" << pTraits<int32_t>::max << nl;
@ -59,7 +102,7 @@ int main(int argc, char *argv[])
cout<< "int64:" << pTraits<int64_t>::max << nl; cout<< "int64:" << pTraits<int64_t>::max << nl;
cout<< "uint64:" << pTraits<uint64_t>::max << nl; cout<< "uint64:" << pTraits<uint64_t>::max << nl;
Info<< nl << "=digits=" << nl; cout<< nl << "=digits=" << nl;
cout<< "int16:" << std::numeric_limits<int16_t>::digits << nl; cout<< "int16:" << std::numeric_limits<int16_t>::digits << nl;
cout<< "int32:" << std::numeric_limits<int32_t>::digits << nl; cout<< "int32:" << std::numeric_limits<int32_t>::digits << nl;
@ -70,29 +113,15 @@ int main(int argc, char *argv[])
cout<< "double:" << std::numeric_limits<double>::digits << nl; cout<< "double:" << std::numeric_limits<double>::digits << nl;
cout<< "long double:" << std::numeric_limits<long double>::digits << nl; cout<< "long double:" << std::numeric_limits<long double>::digits << nl;
Info<< nl << "=float=" << nl; // std::nanl (long double)
cout<< nl;
cout<< nl << "=float=" << nl;
PrintFloatLimits(float, nanf);
cout<< "max:" << std::numeric_limits<float>::max() cout<< nl << "=double=" << nl;
<< " VGREAT:" << floatScalarVGREAT << nl; PrintFloatLimits(double, nan);
cout<< "min:" << std::numeric_limits<float>::min()
<< " VSMALL:" << floatScalarVSMALL << nl;
cout<< "epsilon:" << std::numeric_limits<float>::epsilon()
<< " SMALL:" << floatScalarSMALL << nl;
cout<< "1/epsilon:" << 1.0f/std::numeric_limits<float>::epsilon()
<< " GREAT:" << floatScalarGREAT << nl;
Info<< nl << "=double=" << nl; cout<< "---\nEnd\n" << std::endl;
cout<< "max:" << std::numeric_limits<double>::max()
<< " VGREAT:" << doubleScalarVGREAT << nl;
cout<< "min:" << std::numeric_limits<double>::min()
<< " VSMALL:" << doubleScalarVSMALL << nl;
cout<< "epsilon:" << std::numeric_limits<double>::epsilon()
<< " SMALL:" << doubleScalarSMALL << nl;
cout<< "1/epsilon:" << 1.0f/std::numeric_limits<double>::epsilon()
<< " GREAT:" << doubleScalarGREAT << nl;
Info << "---\nEnd\n" << endl;
return 0; return 0;
} }

View File

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

View File

@ -36,57 +36,14 @@ License
bool Foam::ensightFile::allowUndef_ = false; bool Foam::ensightFile::allowUndef_ = false;
Foam::scalar Foam::ensightFile::undefValue_ = Foam::floatScalarVGREAT; float Foam::ensightFile::undefValue_ = Foam::floatScalarVGREAT;
// Default is width 8
Foam::string Foam::ensightFile::mask_ = "********";
Foam::string Foam::ensightFile::dirFmt_ = "%08d";
const char* const Foam::ensightFile::coordinates = "coordinates"; const char* const Foam::ensightFile::coordinates = "coordinates";
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::string Foam::ensightFile::mask() bool Foam::ensightFile::hasUndef(const UList<scalar>& field)
{
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)
{ {
for (const scalar& val : field) for (const scalar& val : field)
{ {
@ -102,13 +59,13 @@ bool Foam::ensightFile::isUndef(const UList<scalar>& field)
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::ensightFile::initialize() void Foam::ensightFile::init()
{ {
// ascii formatting specs // The ASCII formatting specs for ensight files
setf setf
( (
ios_base::scientific, std::ios_base::scientific,
ios_base::floatfield std::ios_base::floatfield
); );
precision(5); precision(5);
} }
@ -124,7 +81,7 @@ Foam::ensightFile::ensightFile
: :
OFstream(ensight::FileName(pathname), fmt) OFstream(ensight::FileName(pathname), fmt)
{ {
initialize(); init();
} }
@ -137,37 +94,45 @@ Foam::ensightFile::ensightFile
: :
OFstream(path/ensight::FileName(name), fmt) OFstream(path/ensight::FileName(name), fmt)
{ {
initialize(); init();
} }
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
bool Foam::ensightFile::allowUndef() bool Foam::ensightFile::allowUndef() noexcept
{ {
return allowUndef_; 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_; bool old = allowUndef_;
allowUndef_ = enabled; allowUndef_ = on;
return old; return old;
} }
Foam::scalar Foam::ensightFile::undefValue(const scalar value) float Foam::ensightFile::undefValue(float value) noexcept
{ {
// enable its use too // enable its use too
allowUndef_ = true; allowUndef_ = true;
scalar old = undefValue_; float old = undefValue_;
undefValue_ = value; undefValue_ = value;
return old; return old;
} }
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::Ostream& Foam::ensightFile::writeString(const char* str) Foam::Ostream& Foam::ensightFile::writeString(const char* str)
{ {
// Output 80 chars, but allocate for trailing nul character // 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) if (format() == IOstreamOption::BINARY)
{ {
write write
( (
reinterpret_cast<const char *>(&val), reinterpret_cast<const char *>(&val),
sizeof(floatScalar) sizeof(float)
); );
} }
else 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)); float fvalue(narrowFloat(val));

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -27,8 +27,69 @@ License
#include "ensightReadFile.H" #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 * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightReadFile::ensightReadFile
(
const fileName& pathname
)
:
IFstream(pathname, ensightReadFile::detectBinaryHeader(pathname))
{}
Foam::ensightReadFile::ensightReadFile Foam::ensightReadFile::ensightReadFile
( (
const fileName& pathname, const fileName& pathname,

View File

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

View File

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

View File

@ -62,7 +62,9 @@ static void writeTrackField
) )
{ {
// Write field (serial only) // Write field (serial only)
os.writeKeyword(ensightPTraits<Type>::typeName); os.write(ensightPTraits<Type>::typeName);
os.newline();
forAll(fieldPtrs, tracki) forAll(fieldPtrs, tracki)
{ {
// Write as point data // Write as point data

View File

@ -59,7 +59,7 @@ void surfaceNoise::initialise(const fileName& fName)
readerPtr_ = surfaceReader::New(readerType_, fName); readerPtr_ = surfaceReader::New(readerType_, fName);
// Find the index of the pressure data // Find the index of the pressure data
const List<word> fieldNames(readerPtr_->fieldNames(0)); const wordList fieldNames(readerPtr_->fieldNames(0));
pIndex_ = fieldNames.find(pName_); pIndex_ = fieldNames.find(pName_);
if (pIndex_ == -1) if (pIndex_ == -1)
{ {
@ -109,7 +109,7 @@ void surfaceNoise::initialise(const fileName& fName)
// Read the surface geometry // Read the surface geometry
// Note: hard-coded to read mesh from first time index // Note: hard-coded to read mesh from first time index
const meshedSurface& surf = readerPtr_->geometry(0); const meshedSurface& surf = readerPtr_->geometry(0);
nFace_ = surf.size(); nFace_ = surf.nFaces();
} }
Pstream::broadcasts Pstream::broadcasts

View File

@ -105,8 +105,8 @@ SeeAlso
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef noiseModels_surfaceNoise_H #ifndef Foam_noiseModels_surfaceNoise_H
#define noiseModels_surfaceNoise_H #define Foam_noiseModels_surfaceNoise_H
#include "noiseModel.H" #include "noiseModel.H"
#include "labelList.H" #include "labelList.H"
@ -117,7 +117,7 @@ SeeAlso
namespace Foam namespace Foam
{ {
// Forward declarations // Forward Declarations
class surfaceReader; class surfaceReader;
class surfaceWriter; class surfaceWriter;
@ -132,7 +132,6 @@ class surfaceNoise
: :
public noiseModel public noiseModel
{ {
protected: protected:
// Protected Data // Protected Data
@ -215,8 +214,9 @@ public:
//- Runtime type information //- Runtime type information
TypeName("surfaceNoise"); TypeName("surfaceNoise");
//- Constructor //- Constructor
surfaceNoise(const dictionary& dict, const bool readFields = true); explicit surfaceNoise(const dictionary& dict, const bool readFields=true);
//- Destructor //- Destructor
virtual ~surfaceNoise() = default; virtual ~surfaceNoise() = default;

View File

@ -54,12 +54,6 @@ sampledSurface/sampledSurface/sampledSurfaceRegister.C
sampledSurface/sampledSurfaces/sampledSurfaces.C sampledSurface/sampledSurfaces/sampledSurfaces.C
sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.C sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.C
readers = sampledSurface/readers
$(readers)/surfaceReader.C
$(readers)/surfaceReaderNew.C
$(readers)/ensight/ensightSurfaceReader.C
graphField/writePatchGraph.C graphField/writePatchGraph.C
graphField/writeCellGraph.C graphField/writeCellGraph.C
graphField/makeGraph.C graphField/makeGraph.C

View File

@ -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));
}
// ************************************************************************* //

View File

@ -57,6 +57,11 @@ triSurface/fields/triSurfaceFields.C
triSurface/patches/surfacePatch.C triSurface/patches/surfacePatch.C
readers = readers
$(readers)/common/surfaceReader.C
$(readers)/ensight/ensightSurfaceReader.C
writers = writers writers = writers
$(writers)/common/surfaceWriter.C $(writers)/common/surfaceWriter.C

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2015 OpenCFD Ltd. Copyright (C) 2015-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -44,4 +44,29 @@ Foam::surfaceReader::surfaceReader(const fileName& fName)
{} {}
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
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));
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -27,15 +27,15 @@ Class
Foam::surfaceReader Foam::surfaceReader
Description Description
Base class for surface readers Abstract base class for surface readers with fields.
SourceFiles SourceFiles
surfaceReader.C surfaceReader.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef surfaceReader_H #ifndef Foam_surfaceReader_H
#define surfaceReader_H #define Foam_surfaceReader_H
#include "typeInfo.H" #include "typeInfo.H"
#include "autoPtr.H" #include "autoPtr.H"
@ -64,6 +64,7 @@ public:
//- Runtime type information //- Runtime type information
TypeName("surfaceReader"); TypeName("surfaceReader");
// Declare run-time constructor selection table // Declare run-time constructor selection table
declareRunTimeSelectionTable declareRunTimeSelectionTable
@ -91,7 +92,7 @@ public:
// Constructors // Constructors
//- Construct from fileName //- Construct from fileName
surfaceReader(const fileName& fName); explicit surfaceReader(const fileName& fName);
//- Destructor //- Destructor

View File

@ -26,6 +26,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "ensightSurfaceReader.H" #include "ensightSurfaceReader.H"
#include "ensightCase.H"
#include "stringOps.H" #include "stringOps.H"
#include "addToRunTimeSelectionTable.H" #include "addToRunTimeSelectionTable.H"
@ -84,7 +85,7 @@ void Foam::ensightSurfaceReader::skip(const label n, Istream& is) const
} }
void Foam::ensightSurfaceReader::readLine(IFstream& is, string& line) const void Foam::ensightSurfaceReader::readLine(ISstream& is, string& line) const
{ {
do do
{ {
@ -105,7 +106,7 @@ void Foam::ensightSurfaceReader::readLine(IFstream& is, string& line) const
void Foam::ensightSurfaceReader::debugSection void Foam::ensightSurfaceReader::debugSection
( (
const word& expected, const word& expected,
IFstream& is ISstream& is
) const ) const
{ {
string actual; string actual;
@ -139,11 +140,8 @@ Foam::fileName Foam::ensightSurfaceReader::replaceMask
if (nMask) if (nMask)
{ {
std::ostringstream oss;
oss << std::setfill('0') << std::setw(nMask) << timeIndex;
const std::string maskStr(nMask, '*'); const std::string maskStr(nMask, '*');
const std::string indexStr = oss.str(); const Foam::word indexStr(ensightCase::padded(nMask, timeIndex));
result.replace(maskStr, indexStr); result.replace(maskStr, indexStr);
} }
@ -229,7 +227,7 @@ Foam::ensightSurfaceReader::readGeometryHeader(ensightReadFile& is) const
} }
void Foam::ensightSurfaceReader::readCase(IFstream& is) void Foam::ensightSurfaceReader::readCase(ISstream& is)
{ {
DebugInFunction << endl; DebugInFunction << endl;
@ -324,7 +322,7 @@ void Foam::ensightSurfaceReader::readCase(IFstream& is)
// Read the time values // Read the time values
readLine(is, buffer); // time values: readLine(is, buffer); // time values:
timeValues_.setSize(nTimeSteps_); timeValues_.resize_nocopy(nTimeSteps_);
for (label i = 0; i < nTimeSteps_; ++i) for (label i = 0; i < nTimeSteps_; ++i)
{ {
scalar t(readScalar(is)); scalar t(readScalar(is));
@ -342,7 +340,7 @@ void Foam::ensightSurfaceReader::readCase(IFstream& is)
Foam::ensightSurfaceReader::ensightSurfaceReader(const fileName& fName) Foam::ensightSurfaceReader::ensightSurfaceReader(const fileName& fName)
: :
surfaceReader(fName), surfaceReader(fName),
streamFormat_(IOstreamOption::ASCII), readFormat_(IOstreamOption::ASCII), // Placeholder value
baseDir_(fName.path()), baseDir_(fName.path()),
meshFileName_(), meshFileName_(),
fieldNames_(), fieldNames_(),
@ -369,66 +367,16 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
if (!surfPtr_) if (!surfPtr_)
{ {
fileName meshInstance(replaceMask(meshFileName_, timeIndex)); // Auto-detect ascii/binary format
IFstream isBinary(baseDir_/meshInstance, IOstreamOption::BINARY); ensightReadFile is(baseDir_/replaceMask(meshFileName_, timeIndex));
if (!isBinary.good()) // Format detected from the geometry
{ readFormat_ = is.format();
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 DebugInfo
<< "File: " << is.name() << nl; << "File: " << is.name()
<< " format: "
<< IOstreamOption::formatNames[readFormat_] << endl;
Pair<idTypes> idHandling = readGeometryHeader(is); Pair<idTypes> idHandling = readGeometryHeader(is);
@ -460,19 +408,23 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
pointField points(nPoints); pointField points(nPoints);
for (direction cmpt = 0; cmpt < vector::nComponents; ++cmpt) for (direction cmpt = 0; cmpt < vector::nComponents; ++cmpt)
{ {
for (point& pt : points) for (point& p : points)
{ {
is.read(pt[cmpt]); is.read(p[cmpt]);
} }
} }
// Read faces - may be a mix of tris, quads and polys // Read faces - may be a mix of tria3, quad4, nsided
DynamicList<face> faces(ceil(nPoints/3)); DynamicList<face> dynFaces(nPoints/3);
DynamicList<Tuple2<string, label>> schema(faces.size()); DynamicList<faceInfoTuple> faceTypeInfo(16);
string faceType; string faceType;
label faceCount = 0;
while (is.good()) // (is.peek() != EOF) while (is.good()) // (is.peek() != EOF)
{ {
// The element type
is.read(faceType); is.read(faceType);
if (!is.good()) if (!is.good())
@ -480,15 +432,22 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
break; break;
} }
label nFace = 0; if
(
if (faceType == "tria3") faceType
== ensightFaces::elemNames[ensightFaces::elemType::TRIA3]
)
{ {
is.read(nFace); is.read(faceCount);
faceTypeInfo.append
(
faceInfoTuple(ensightFaces::elemType::TRIA3, faceCount)
);
DebugInfo DebugInfo
<< "faceType <" << faceType.c_str() << "> count: " << "faceType <" << faceType.c_str() << "> count: "
<< nFace << nl; << faceCount << nl;
if if
( (
@ -497,30 +456,39 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
) )
{ {
DebugInfo DebugInfo
<< "Ignore " << nFace << " element ids" << nl; << "Ignore " << faceCount << " element ids" << nl;
// Read and discard labels // Read and discard labels
discard<label>(nFace, is); discard<label>(faceCount, is);
} }
face f(3); for (label facei = 0; facei < faceCount; ++facei)
for (label facei = 0; facei < nFace; ++facei)
{ {
face f(3);
for (label& fp : f) for (label& fp : f)
{ {
is.read(fp); is.read(fp);
} }
faces.append(f); dynFaces.append(std::move(f));
} }
} }
else if (faceType == "quad4") else if
(
faceType
== ensightFaces::elemNames[ensightFaces::elemType::QUAD4]
)
{ {
is.read(nFace); is.read(faceCount);
faceTypeInfo.append
(
faceInfoTuple(ensightFaces::elemType::QUAD4, faceCount)
);
DebugInfo DebugInfo
<< "faceType <" << faceType.c_str() << "> count: " << "faceType <" << faceType.c_str() << "> count: "
<< nFace << nl; << faceCount << nl;
if if
( (
@ -529,30 +497,39 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
) )
{ {
DebugInfo DebugInfo
<< "Ignore " << nFace << " element ids" << nl; << "Ignore " << faceCount << " element ids" << nl;
// Read and discard labels // Read and discard labels
discard<label>(nFace, is); discard<label>(faceCount, is);
} }
face f(4); for (label facei = 0; facei < faceCount; ++facei)
for (label facei = 0; facei < nFace; ++facei)
{ {
face f(4);
for (label& fp : f) for (label& fp : f)
{ {
is.read(fp); is.read(fp);
} }
faces.append(f); dynFaces.append(std::move(f));
} }
} }
else if (faceType == "nsided") else if
(
faceType
== ensightFaces::elemNames[ensightFaces::elemType::NSIDED]
)
{ {
is.read(nFace); is.read(faceCount);
faceTypeInfo.append
(
faceInfoTuple(ensightFaces::elemType::NSIDED, faceCount)
);
DebugInfo DebugInfo
<< "faceType <" << faceType.c_str() << "> count: " << "faceType <" << faceType.c_str() << "> count: "
<< nFace << nl; << faceCount << nl;
if if
( (
@ -561,18 +538,18 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
) )
{ {
DebugInfo DebugInfo
<< "Ignore " << nFace << " element ids" << nl; << "Ignore " << faceCount << " element ids" << nl;
// Read and discard labels // Read and discard labels
discard<label>(nFace, is); discard<label>(faceCount, is);
} }
labelList np(nFace); labelList np(faceCount);
for (label facei = 0; facei < nFace; ++facei) for (label facei = 0; facei < faceCount; ++facei)
{ {
is.read(np[facei]); is.read(np[facei]);
} }
for (label facei = 0; facei < nFace; ++facei) for (label facei = 0; facei < faceCount; ++facei)
{ {
face f(np[facei]); face f(np[facei]);
for (label& fp : f) for (label& fp : f)
@ -580,7 +557,7 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
is.read(fp); is.read(fp);
} }
faces.append(f); dynFaces.append(std::move(f));
} }
} }
else else
@ -594,21 +571,21 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
} }
break; break;
} }
schema.append(Tuple2<string, label>(faceType, nFace));
} }
schema_.transfer(schema); faceTypeInfo_.transfer(faceTypeInfo);
faceList faces(std::move(dynFaces));
DebugInfo DebugInfo
<< "read nFaces: " << faces.size() << nl << "read nFaces: " << faces.size() << nl
<< "file schema: " << schema_ << nl; << "file schema: " << faceTypeInfo_ << nl;
// Convert from 1-based Ensight addressing to 0-based OF addressing // Convert from 1-based Ensight addressing to 0-based OF addressing
for (face& f : faces) for (face& f : faces)
{ {
for (label& pointi : f) for (label& fp : f)
{ {
--pointi; --fp;
} }
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2015-2021 OpenCFD Ltd. Copyright (C) 2015-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -31,15 +31,16 @@ Description
SourceFiles SourceFiles
ensightSurfaceReader.C ensightSurfaceReader.C
ensightSurfaceReaderTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef ensightSurfaceReader_H #ifndef Foam_ensightSurfaceReader_H
#define ensightSurfaceReader_H #define Foam_ensightSurfaceReader_H
#include "surfaceReader.H" #include "surfaceReader.H"
#include "ensightFaces.H"
#include "ensightReadFile.H" #include "ensightReadFile.H"
#include "StringStream.H"
#include "Pair.H" #include "Pair.H"
#include "Tuple2.H" #include "Tuple2.H"
@ -58,7 +59,7 @@ class ensightSurfaceReader
{ {
protected: protected:
// Protected Data // Data Types
//- Handling of node/element id types (off, assign, ignore, given) //- Handling of node/element id types (off, assign, ignore, given)
enum idTypes : unsigned char enum idTypes : unsigned char
@ -68,8 +69,15 @@ protected:
GIVEN = 2 //!< Use "given" values (not supported) GIVEN = 2 //!< Use "given" values (not supported)
}; };
//- Tuple of face type (tria3, quad4, nsided) and count
typedef Tuple2<ensightFaces::elemType, label> faceInfoTuple;
// Protected Data
//- Format flag //- Format flag
IOstreamOption::streamFormat streamFormat_; IOstreamOption::streamFormat readFormat_;
//- Base directory //- Base directory
fileName baseDir_; fileName baseDir_;
@ -98,19 +106,20 @@ protected:
//- Pointer to the surface //- Pointer to the surface
autoPtr<meshedSurface> surfPtr_; autoPtr<meshedSurface> surfPtr_;
List<Tuple2<string, label>> schema_; //- List of face-type/count tuples
List<faceInfoTuple> faceTypeInfo_;
// Protected Member Functions // Private Member Functions
//- Helper function to skip forward n steps in stream //- Helper function to skip forward n steps in stream
void skip(const label n, Istream& is) const; void skip(const label n, Istream& is) const;
//- Helper function to read an ascii line from file //- Helper function to read an ascii line from file
void readLine(IFstream& is, string& buffer) const; void readLine(ISstream& is, string& buffer) const;
//- Read and check a section header //- Read and check a section header
void debugSection(const word& expected, IFstream& is) const; void debugSection(const word& expected, ISstream& is) const;
//- Replace the '*' mask chars with a 0 padded string. //- Replace the '*' mask chars with a 0 padded string.
static fileName replaceMask static fileName replaceMask
@ -124,16 +133,11 @@ protected:
Pair<idTypes> readGeometryHeader(ensightReadFile& is) const; Pair<idTypes> readGeometryHeader(ensightReadFile& is) const;
//- Read the case file //- Read the case file
void readCase(IFstream& is); void readCase(ISstream& is);
//- 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 readFromLine void readFromLine(const label nSkip, Istream& is, Type& value) const;
(
const label nSkip,
IStringStream& is,
Type& value
) 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>
@ -188,7 +192,7 @@ public:
const scalar& refValue = pTraits<scalar>::zero const scalar& refValue = pTraits<scalar>::zero
) const; ) const;
//- Return a scalar field at a given time //- Return a vector field at a given time
virtual tmp<Field<vector>> field virtual tmp<Field<vector>> field
( (
const label timeIndex, const label timeIndex,
@ -234,6 +238,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif #endif
// ************************************************************************* // // ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2015-2020 OpenCFD Ltd. Copyright (C) 2015-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -25,8 +25,8 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include <iomanip> #include "UIListStream.H"
#include <sstream> #include "ensightPTraits.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -34,7 +34,7 @@ template<class Type>
void Foam::ensightSurfaceReader::readFromLine void Foam::ensightSurfaceReader::readFromLine
( (
const label nSkip, const label nSkip,
IStringStream& is, Istream& is,
Type& value Type& value
) const ) const
{ {
@ -52,7 +52,7 @@ void Foam::ensightSurfaceReader::readFromLine
Type& value Type& value
) const ) const
{ {
IStringStream is(buffer); UIListStream is(buffer.data(), buffer.length());
readFromLine(nSkip, is, value); readFromLine(nSkip, is, value);
} }
@ -67,11 +67,15 @@ Foam::tmp<Foam::Field<Type>> Foam::ensightSurfaceReader::readField
{ {
DebugInFunction << endl; DebugInFunction << endl;
const word& fieldName(fieldNames_[fieldIndex]); const word& fieldName = fieldNames_[fieldIndex];
const label fileIndex = timeStartIndex_ + timeIndex*timeIncrement_; const label fileIndex = timeStartIndex_ + timeIndex*timeIncrement_;
fileName fieldFileName(replaceMask(fieldFileNames_[fieldIndex], fileIndex)); // Use previously detected ascii/binary format
ensightReadFile is(baseDir_/fieldFileName, streamFormat_); ensightReadFile is
(
baseDir_/replaceMask(fieldFileNames_[fieldIndex], fileIndex),
readFormat_
);
if (!is.good()) if (!is.good())
{ {
@ -82,22 +86,28 @@ Foam::tmp<Foam::Field<Type>> Foam::ensightSurfaceReader::readField
} }
// Check that data type is as expected // Check that data type is as expected
// (assumes OpenFOAM generated the data set)
string primitiveType; string primitiveType;
is.read(primitiveType); is.read(primitiveType);
DebugInfo << "primitiveType: " << primitiveType << endl; DebugInfo << "primitiveType: " << primitiveType << endl;
if (primitiveType != pTraits<Type>::typeName) if
(
primitiveType != ensightPTraits<Type>::typeName
&& primitiveType != pTraits<Type>::typeName
)
{ {
IOWarningInFunction(is) IOWarningInFunction(is)
<< "Expected '" << pTraits<Type>::typeName << "Expected <" << ensightPTraits<Type>::typeName
<< "' values but found type " << primitiveType << nl << "> values for <" << pTraits<Type>::typeName
<< " This may be okay, but could also indicate an error" << "> but found " << primitiveType << nl
<< nl << nl; << " This may be okay, but could indicate an error" << nl << nl;
} }
scalar value; auto tfield = tmp<Field<Type>>::New(surfPtr_->nFaces(), Zero);
auto& field = tfield.ref();
string strValue; string strValue;
label iValue; label iValue;
@ -105,52 +115,50 @@ Foam::tmp<Foam::Field<Type>> Foam::ensightSurfaceReader::readField
is.read(strValue); is.read(strValue);
is.read(iValue); is.read(iValue);
// Allocate storage for data as a list per component label begFace = 0;
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 // Loop through different element types when reading the field values
forAll(schema_, i) for (const faceInfoTuple& facesInfo : faceTypeInfo_)
{ {
// [faceType, faceCount]
const label endFace = begFace + facesInfo.second();
DebugInfo DebugInfo
<< "Reading face type " << "Reading <" << pTraits<Type>::typeName << "> face type "
<< schema_[i].first() << " data" << endl; << ensightFaces::elemNames[facesInfo.first()]
<< " data:" << facesInfo.second() << endl;
const label nFace = schema_[i].second(); if (begFace < endFace)
if (nFace != 0)
{ {
// The element type, optionally with 'undef'
is.read(strValue); is.read(strValue);
for if (strValue.find("undef") != std::string::npos)
(
direction cmptI=0;
cmptI < pTraits<Type>::nComponents;
++cmptI
)
{ {
for (label faceI = 0; faceI < nFace; ++faceI) // Skip undef entry
scalar value;
is.read(value);
}
// Ensight fields are written component-wise
// (can be in different order than OpenFOAM uses)
for (direction d = 0; d < pTraits<Type>::nComponents; ++d)
{
const direction cmpt = ensightPTraits<Type>::componentOrder[d];
for (label facei = begFace; facei < endFace; ++facei)
{ {
scalar value;
is.read(value); is.read(value);
values[cmptI].append(value); setComponent(field[facei], cmpt) = value;
} }
} }
begFace = endFace;
} }
} }
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; return tfield;
} }

View File

@ -182,7 +182,8 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated
} }
// Write field (serial only) // Write field (serial only)
osField.writeKeyword(ensightPTraits<Type>::typeName); osField.write(ensightPTraits<Type>::typeName);
osField.newline();
part.writeData(osField, tfield(), this->isPointData()); part.writeData(osField, tfield(), this->isPointData());

View File

@ -195,7 +195,8 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated
part.write(osGeom); // serial part.write(osGeom); // serial
// Write field (serial) // Write field (serial)
osField.writeKeyword(ensightPTraits<Type>::typeName); osField.write(ensightPTraits<Type>::typeName);
osField.newline();
part.writeData(osField, tfield(), this->isPointData()); part.writeData(osField, tfield(), this->isPointData());