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
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2018-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -24,10 +24,11 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Description
Print max limits.
Print some numerical limits.
\*---------------------------------------------------------------------------*/
#include <cmath>
#include <limits>
#include "int.H"
#include "uint.H"
@ -37,21 +38,63 @@ Description
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:
int main(int argc, char *argv[])
{
//NONE Info<<"int16:" << pTraits<int16_t>::max << nl;
Info<< "=max=" << nl;
Info<< "uint8:" << pTraits<uint8_t>::max << nl;
Info<< "int16:" << std::numeric_limits<int16_t>::max() << nl;
Info<< "int32:" << pTraits<int32_t>::max << nl;
Info<< "uint32:" << pTraits<uint32_t>::max << nl;
Info<< "int64:" << pTraits<int64_t>::max << nl;
Info<< "uint64:" << pTraits<uint64_t>::max << nl;
//NONE cout<<"int16:" << pTraits<int16_t>::max << nl;
cout<< "=max=" << nl;
cout<< "uint8:" << pTraits<uint8_t>::max << nl;
cout<< "int16:" << std::numeric_limits<int16_t>::max() << nl;
cout<< "int32:" << pTraits<int32_t>::max << nl;
cout<< "uint32:" << pTraits<uint32_t>::max << nl;
cout<< "int64:" << pTraits<int64_t>::max << nl;
cout<< "uint64:" << pTraits<uint64_t>::max << nl;
Info<< nl;
cout<< nl;
cout<< "int16:" << std::numeric_limits<int16_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<< "uint64:" << pTraits<uint64_t>::max << nl;
Info<< nl << "=digits=" << nl;
cout<< nl << "=digits=" << nl;
cout<< "int16:" << std::numeric_limits<int16_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<< "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()
<< " VGREAT:" << floatScalarVGREAT << nl;
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;
cout<< nl << "=double=" << nl;
PrintFloatLimits(double, nan);
Info<< nl << "=double=" << nl;
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;
cout<< "---\nEnd\n" << std::endl;
return 0;
}

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[];
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

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

View File

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

View File

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

View File

@ -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

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
readers = readers
$(readers)/common/surfaceReader.C
$(readers)/ensight/ensightSurfaceReader.C
writers = writers
$(writers)/common/surfaceWriter.C

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2015 OpenCFD Ltd.
Copyright (C) 2015-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
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
Description
Base class for surface readers
Abstract base class for surface readers with fields.
SourceFiles
surfaceReader.C
\*---------------------------------------------------------------------------*/
#ifndef surfaceReader_H
#define surfaceReader_H
#ifndef Foam_surfaceReader_H
#define Foam_surfaceReader_H
#include "typeInfo.H"
#include "autoPtr.H"
@ -64,6 +64,7 @@ public:
//- Runtime type information
TypeName("surfaceReader");
// Declare run-time constructor selection table
declareRunTimeSelectionTable
@ -91,7 +92,7 @@ public:
// Constructors
//- Construct from fileName
surfaceReader(const fileName& fName);
explicit surfaceReader(const fileName& fName);
//- Destructor

View File

@ -26,6 +26,7 @@ License
\*---------------------------------------------------------------------------*/
#include "ensightSurfaceReader.H"
#include "ensightCase.H"
#include "stringOps.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
{
@ -105,7 +106,7 @@ void Foam::ensightSurfaceReader::readLine(IFstream& is, string& line) const
void Foam::ensightSurfaceReader::debugSection
(
const word& expected,
IFstream& is
ISstream& is
) const
{
string actual;
@ -139,11 +140,8 @@ Foam::fileName Foam::ensightSurfaceReader::replaceMask
if (nMask)
{
std::ostringstream oss;
oss << std::setfill('0') << std::setw(nMask) << timeIndex;
const std::string maskStr(nMask, '*');
const std::string indexStr = oss.str();
const Foam::word indexStr(ensightCase::padded(nMask, timeIndex));
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;
@ -324,7 +322,7 @@ void Foam::ensightSurfaceReader::readCase(IFstream& is)
// Read the time values
readLine(is, buffer); // time values:
timeValues_.setSize(nTimeSteps_);
timeValues_.resize_nocopy(nTimeSteps_);
for (label i = 0; i < nTimeSteps_; ++i)
{
scalar t(readScalar(is));
@ -342,7 +340,7 @@ void Foam::ensightSurfaceReader::readCase(IFstream& is)
Foam::ensightSurfaceReader::ensightSurfaceReader(const fileName& fName)
:
surfaceReader(fName),
streamFormat_(IOstreamOption::ASCII),
readFormat_(IOstreamOption::ASCII), // Placeholder value
baseDir_(fName.path()),
meshFileName_(),
fieldNames_(),
@ -369,66 +367,16 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
if (!surfPtr_)
{
fileName meshInstance(replaceMask(meshFileName_, timeIndex));
IFstream isBinary(baseDir_/meshInstance, IOstreamOption::BINARY);
// Auto-detect ascii/binary format
ensightReadFile is(baseDir_/replaceMask(meshFileName_, timeIndex));
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_);
// Format detected from the geometry
readFormat_ = is.format();
DebugInfo
<< "File: " << is.name() << nl;
<< "File: " << is.name()
<< " format: "
<< IOstreamOption::formatNames[readFormat_] << endl;
Pair<idTypes> idHandling = readGeometryHeader(is);
@ -460,19 +408,23 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
pointField points(nPoints);
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
DynamicList<face> faces(ceil(nPoints/3));
DynamicList<Tuple2<string, label>> schema(faces.size());
// Read faces - may be a mix of tria3, quad4, nsided
DynamicList<face> dynFaces(nPoints/3);
DynamicList<faceInfoTuple> faceTypeInfo(16);
string faceType;
label faceCount = 0;
while (is.good()) // (is.peek() != EOF)
{
// The element type
is.read(faceType);
if (!is.good())
@ -480,15 +432,22 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
break;
}
label nFace = 0;
if (faceType == "tria3")
if
(
faceType
== ensightFaces::elemNames[ensightFaces::elemType::TRIA3]
)
{
is.read(nFace);
is.read(faceCount);
faceTypeInfo.append
(
faceInfoTuple(ensightFaces::elemType::TRIA3, faceCount)
);
DebugInfo
<< "faceType <" << faceType.c_str() << "> count: "
<< nFace << nl;
<< faceCount << nl;
if
(
@ -497,30 +456,39 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
)
{
DebugInfo
<< "Ignore " << nFace << " element ids" << nl;
<< "Ignore " << faceCount << " element ids" << nl;
// Read and discard labels
discard<label>(nFace, is);
discard<label>(faceCount, is);
}
face f(3);
for (label facei = 0; facei < nFace; ++facei)
for (label facei = 0; facei < faceCount; ++facei)
{
face f(3);
for (label& fp : f)
{
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
<< "faceType <" << faceType.c_str() << "> count: "
<< nFace << nl;
<< faceCount << nl;
if
(
@ -529,30 +497,39 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
)
{
DebugInfo
<< "Ignore " << nFace << " element ids" << nl;
<< "Ignore " << faceCount << " element ids" << nl;
// Read and discard labels
discard<label>(nFace, is);
discard<label>(faceCount, is);
}
face f(4);
for (label facei = 0; facei < nFace; ++facei)
for (label facei = 0; facei < faceCount; ++facei)
{
face f(4);
for (label& fp : f)
{
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
<< "faceType <" << faceType.c_str() << "> count: "
<< nFace << nl;
<< faceCount << nl;
if
(
@ -561,18 +538,18 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
)
{
DebugInfo
<< "Ignore " << nFace << " element ids" << nl;
<< "Ignore " << faceCount << " element ids" << nl;
// Read and discard labels
discard<label>(nFace, is);
discard<label>(faceCount, is);
}
labelList np(nFace);
for (label facei = 0; facei < nFace; ++facei)
labelList np(faceCount);
for (label facei = 0; facei < faceCount; ++facei)
{
is.read(np[facei]);
}
for (label facei = 0; facei < nFace; ++facei)
for (label facei = 0; facei < faceCount; ++facei)
{
face f(np[facei]);
for (label& fp : f)
@ -580,7 +557,7 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
is.read(fp);
}
faces.append(f);
dynFaces.append(std::move(f));
}
}
else
@ -594,21 +571,21 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
}
break;
}
schema.append(Tuple2<string, label>(faceType, nFace));
}
schema_.transfer(schema);
faceTypeInfo_.transfer(faceTypeInfo);
faceList faces(std::move(dynFaces));
DebugInfo
<< "read nFaces: " << faces.size() << nl
<< "file schema: " << schema_ << nl;
<< "file schema: " << faceTypeInfo_ << nl;
// Convert from 1-based Ensight addressing to 0-based OF addressing
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
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2015-2021 OpenCFD Ltd.
Copyright (C) 2015-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,15 +31,16 @@ Description
SourceFiles
ensightSurfaceReader.C
ensightSurfaceReaderTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef ensightSurfaceReader_H
#define ensightSurfaceReader_H
#ifndef Foam_ensightSurfaceReader_H
#define Foam_ensightSurfaceReader_H
#include "surfaceReader.H"
#include "ensightFaces.H"
#include "ensightReadFile.H"
#include "StringStream.H"
#include "Pair.H"
#include "Tuple2.H"
@ -58,7 +59,7 @@ class ensightSurfaceReader
{
protected:
// Protected Data
// Data Types
//- Handling of node/element id types (off, assign, ignore, given)
enum idTypes : unsigned char
@ -68,8 +69,15 @@ protected:
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
IOstreamOption::streamFormat streamFormat_;
IOstreamOption::streamFormat readFormat_;
//- Base directory
fileName baseDir_;
@ -98,19 +106,20 @@ protected:
//- Pointer to the surface
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
void skip(const label n, Istream& is) const;
//- 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
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.
static fileName replaceMask
@ -124,16 +133,11 @@ protected:
Pair<idTypes> readGeometryHeader(ensightReadFile& is) const;
//- Read the case file
void readCase(IFstream& is);
void readCase(ISstream& is);
//- Helper function to return Type after skipping n tokens
template<class Type>
void readFromLine
(
const label nSkip,
IStringStream& is,
Type& value
) const;
void readFromLine(const label nSkip, Istream& is, Type& value) const;
//- Helper function to return Type after skipping n tokens
template<class Type>
@ -188,7 +192,7 @@ public:
const scalar& refValue = pTraits<scalar>::zero
) const;
//- Return a scalar field at a given time
//- Return a vector field at a given time
virtual tmp<Field<vector>> field
(
const label timeIndex,
@ -234,6 +238,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2015-2020 OpenCFD Ltd.
Copyright (C) 2015-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,8 +25,8 @@ License
\*---------------------------------------------------------------------------*/
#include <iomanip>
#include <sstream>
#include "UIListStream.H"
#include "ensightPTraits.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -34,7 +34,7 @@ template<class Type>
void Foam::ensightSurfaceReader::readFromLine
(
const label nSkip,
IStringStream& is,
Istream& is,
Type& value
) const
{
@ -52,7 +52,7 @@ void Foam::ensightSurfaceReader::readFromLine
Type& value
) const
{
IStringStream is(buffer);
UIListStream is(buffer.data(), buffer.length());
readFromLine(nSkip, is, value);
}
@ -67,11 +67,15 @@ Foam::tmp<Foam::Field<Type>> Foam::ensightSurfaceReader::readField
{
DebugInFunction << endl;
const word& fieldName(fieldNames_[fieldIndex]);
const word& fieldName = fieldNames_[fieldIndex];
const label fileIndex = timeStartIndex_ + timeIndex*timeIncrement_;
fileName fieldFileName(replaceMask(fieldFileNames_[fieldIndex], fileIndex));
ensightReadFile is(baseDir_/fieldFileName, streamFormat_);
// Use previously detected ascii/binary format
ensightReadFile is
(
baseDir_/replaceMask(fieldFileNames_[fieldIndex], fileIndex),
readFormat_
);
if (!is.good())
{
@ -82,22 +86,28 @@ Foam::tmp<Foam::Field<Type>> Foam::ensightSurfaceReader::readField
}
// Check that data type is as expected
// (assumes OpenFOAM generated the data set)
string primitiveType;
is.read(primitiveType);
DebugInfo << "primitiveType: " << primitiveType << endl;
if (primitiveType != pTraits<Type>::typeName)
if
(
primitiveType != ensightPTraits<Type>::typeName
&& 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;
<< "Expected <" << ensightPTraits<Type>::typeName
<< "> values for <" << pTraits<Type>::typeName
<< "> but found " << primitiveType << 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;
label iValue;
@ -105,52 +115,50 @@ Foam::tmp<Foam::Field<Type>> Foam::ensightSurfaceReader::readField
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);
}
label begFace = 0;
// Read data file using schema generated while reading the surface
forAll(schema_, i)
// Loop through different element types when reading the field values
for (const faceInfoTuple& facesInfo : faceTypeInfo_)
{
// [faceType, faceCount]
const label endFace = begFace + facesInfo.second();
DebugInfo
<< "Reading face type "
<< schema_[i].first() << " data" << endl;
<< "Reading <" << pTraits<Type>::typeName << "> face type "
<< ensightFaces::elemNames[facesInfo.first()]
<< " data:" << facesInfo.second() << endl;
const label nFace = schema_[i].second();
if (nFace != 0)
if (begFace < endFace)
{
// The element type, optionally with 'undef'
is.read(strValue);
for
(
direction cmptI=0;
cmptI < pTraits<Type>::nComponents;
++cmptI
)
if (strValue.find("undef") != std::string::npos)
{
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);
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;
}

View File

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

View File

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