ENH: improve ensightFile output support (#1579)

- indirect lists, lists of labels
- writeString() methods to avoid any ambiguities

- support handling of mixed element/node data in ensightCase
This commit is contained in:
Mark Olesen
2020-02-06 11:45:49 +01:00
committed by Andrew Heather
parent 4fea7b3bb4
commit c7e8f22baf
10 changed files with 327 additions and 173 deletions

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2018 OpenCFD Ltd. Copyright (C) 2016-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -26,15 +26,10 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "ensightCase.H" #include "ensightCase.H"
#include "stringListOps.H" #include "ensightGeoFile.H"
#include "Time.H" #include "Time.H"
#include "cloud.H" #include "cloud.H"
#include "IOmanip.H" #include "IOmanip.H"
#include "globalIndex.H"
#include "ensightFile.H"
#include "ensightGeoFile.H"
#include "demandDrivenData.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -69,7 +64,7 @@ void Foam::ensightCase::initialize()
else else
{ {
DetailInfo DetailInfo
<<"Warning: re-using existing directory" << nl << "Warning: re-using existing directory" << nl
<< " " << ensightDir_ << endl; << " " << ensightDir_ << endl;
} }
} }
@ -78,7 +73,7 @@ void Foam::ensightCase::initialize()
mkDir(dataDir()); mkDir(dataDir());
// The case file is always ASCII // The case file is always ASCII
os_ = new OFstream(ensightDir_/caseName_, IOstream::ASCII); os_.reset(new OFstream(ensightDir_/caseName_, IOstream::ASCII));
// Format options // Format options
os_->setf(ios_base::left); os_->setf(ios_base::left);
@ -126,7 +121,7 @@ Foam::label Foam::ensightCase::checkTimeset(const labelHashSet& lookup) const
void Foam::ensightCase::writeHeader() const void Foam::ensightCase::writeHeader() const
{ {
if (os_) // master only if (os_) // True on master only
{ {
this->rewind(); this->rewind();
*os_ *os_
@ -218,7 +213,7 @@ void Foam::ensightCase::writeTimeset
const scalar timeCorrection const scalar timeCorrection
) const ) const
{ {
// make a copy // Make a copy
labelHashSet hashed(lookup); labelHashSet hashed(lookup);
hashed.erase(-1); hashed.erase(-1);
@ -282,9 +277,10 @@ void Foam::ensightCase::noteGeometry(const bool moving) const
void Foam::ensightCase::noteCloud(const word& cloudName) const void Foam::ensightCase::noteCloud(const word& cloudName) const
{ {
// Force into existence
if (!cloudVars_.found(cloudName)) if (!cloudVars_.found(cloudName))
{ {
cloudVars_.insert(cloudName, HashTable<string>()); cloudVars_.emplace(cloudName);
} }
cloudTimes_.insert(timeIndex_); cloudTimes_.insert(timeIndex_);
@ -388,9 +384,9 @@ Foam::ensightCase::ensightCase
) )
: :
options_(new options(opts)), options_(new options(opts)),
os_(nullptr),
ensightDir_(ensightDir), ensightDir_(ensightDir),
caseName_(caseName + ".case"), caseName_(caseName + ".case"),
os_(nullptr),
changed_(false), changed_(false),
timeIndex_(0), timeIndex_(0),
timeValue_(0), timeValue_(0),
@ -398,6 +394,7 @@ Foam::ensightCase::ensightCase
geomTimes_(), geomTimes_(),
cloudTimes_(), cloudTimes_(),
variables_(), variables_(),
nodeVariables_(),
cloudVars_() cloudVars_()
{ {
initialize(); initialize();
@ -412,9 +409,9 @@ Foam::ensightCase::ensightCase
) )
: :
options_(new options(format)), options_(new options(format)),
os_(nullptr),
ensightDir_(ensightDir), ensightDir_(ensightDir),
caseName_(caseName + ".case"), caseName_(caseName + ".case"),
os_(nullptr),
changed_(false), changed_(false),
timeIndex_(0), timeIndex_(0),
timeValue_(0), timeValue_(0),
@ -422,21 +419,13 @@ Foam::ensightCase::ensightCase
geomTimes_(), geomTimes_(),
cloudTimes_(), cloudTimes_(),
variables_(), variables_(),
nodeVariables_(),
cloudVars_() cloudVars_()
{ {
initialize(); initialize();
} }
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::ensightCase::~ensightCase()
{
deleteDemandDrivenData(options_);
deleteDemandDrivenData(os_);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::ensightCase::nextTime(const scalar value) void Foam::ensightCase::nextTime(const scalar value)
@ -580,7 +569,7 @@ void Foam::ensightCase::write() const
// //
if (variables_.size() || cloudVars_.size()) if (variables_.size() || cloudVars_.size())
{ {
// start of variables // Start of variables
*os_ *os_
<< nl << nl
<< "VARIABLE" << nl; << "VARIABLE" << nl;
@ -598,7 +587,7 @@ void Foam::ensightCase::write() const
<< ensType.c_str() << ensType.c_str()
<< <<
( (
nodeValues() (nodeVariables_.found(varName) || nodeValues())
? " per node: 1 " // time-set 1 ? " per node: 1 " // time-set 1
: " per element: 1 " // time-set 1 : " per element: 1 " // time-set 1
) )
@ -678,7 +667,7 @@ void Foam::ensightCase::write() const
Foam::autoPtr<Foam::ensightGeoFile> Foam::autoPtr<Foam::ensightGeoFile>
Foam::ensightCase::newGeometry Foam::ensightCase::newGeometry
( (
const bool moving bool moving
) const ) const
{ {
autoPtr<Foam::ensightGeoFile> output; autoPtr<Foam::ensightGeoFile> output;
@ -749,8 +738,12 @@ Foam::Ostream& Foam::ensightCase::printInfo(Ostream& os) const
os << "Ensight case:" << nl os << "Ensight case:" << nl
<< " path: " << ensightDir_ << nl << " path: " << ensightDir_ << nl
<< " name: " << caseName_ << nl << " name: " << caseName_ << nl
<< " format: " << format() << nl << " format: " << format() << nl;
<< " values per " << (nodeValues() ? "node" : "element") << nl;
if (nodeValues())
{
os << " values per node" << nl;
}
return os; return os;
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016 OpenCFD Ltd. Copyright (C) 2016-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -32,6 +32,9 @@ Description
SourceFiles SourceFiles
ensightCase.C ensightCase.C
ensightCaseI.H
ensightCaseOptions.C
ensightCaseTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -42,17 +45,18 @@ SourceFiles
#include "HashSet.H" #include "HashSet.H"
#include "InfoProxy.H" #include "InfoProxy.H"
#include "Map.H" #include "Map.H"
#include "HashSet.H"
#include "OSspecific.H" #include "OSspecific.H"
#include "Pstream.H" #include "Pstream.H"
#include "ensightGeoFile.H" #include "ensightGeoFile.H"
#include <memory>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
// Forward declarations // Forward Declarations
class ensightCase; class ensightCase;
class instant; class instant;
class Time; class Time;
@ -65,7 +69,7 @@ class ensightCase
{ {
public: public:
// Forward declarations // Forward Declarations
class options; class options;
// Public Data // Public Data
@ -76,12 +80,16 @@ public:
//- The name for geometry files //- The name for geometry files
static const char* geometryName; static const char* geometryName;
private: private:
// Private data // Private Data
//- Case writing options //- Case writing options
const options* options_; const std::unique_ptr<options> options_;
//- Output stream (master only)
mutable std::unique_ptr<OFstream> os_;
//- Output path (absolute) //- Output path (absolute)
fileName ensightDir_; fileName ensightDir_;
@ -89,9 +97,6 @@ private:
//- Case name (with ".case" ending) //- Case name (with ".case" ending)
word caseName_; word caseName_;
//- Output stream (master only)
mutable OFstream* os_;
//- Track state changes since last write //- Track state changes since last write
mutable bool changed_; mutable bool changed_;
@ -119,6 +124,9 @@ private:
//- Fields/Variables with the ensight type //- Fields/Variables with the ensight type
mutable HashTable<string> variables_; mutable HashTable<string> variables_;
//- Remember fields that are to be treated as point data
mutable HashSet<string> nodeVariables_;
//- Cloud names and variables //- Cloud names and variables
mutable HashTable<HashTable<string>> cloudVars_; mutable HashTable<HashTable<string>> cloudVars_;
@ -214,7 +222,7 @@ public:
//- Destructor //- Destructor
~ensightCase(); ~ensightCase() = default;
// Member Functions // Member Functions
@ -236,7 +244,7 @@ public:
//- Consistent zero-padded integer value //- Consistent zero-padded integer value
inline word padded(const label i) const; inline word padded(const label i) const;
//- Use values per nodes instead of per element //- Force use of values per node instead of per element
inline bool nodeValues() const; inline bool nodeValues() const;
//- Write clouds into their own directory instead in "data" directory //- Write clouds into their own directory instead in "data" directory
@ -269,8 +277,7 @@ public:
// Addition of entries to case file // Addition of entries to case file
//- Open stream for new geometry file (on master). //- Open stream for new geometry file (on master).
autoPtr<ensightGeoFile> newGeometry(const bool moving = false) const; autoPtr<ensightGeoFile> newGeometry(bool moving = false) const;
//- Open stream for new cloud positions (on master). //- Open stream for new cloud positions (on master).
// Note the use of ensightFile, not ensightGeoFile. // Note the use of ensightFile, not ensightGeoFile.
@ -279,11 +286,19 @@ public:
const word& cloudName const word& cloudName
) const; ) const;
//- Open stream for new data file (on master), with current index. //- Open stream for new data file (on master), with current index.
// Optionally marking as containing POINT_DATA
template<class Type> template<class Type>
autoPtr<ensightFile> newData(const word& varName) const; autoPtr<ensightFile> newData
(
const word& varName,
const bool isPointData = false
) const;
//- Open stream for new data file (on master), with current index
//- and marking as containing POINT_DATA
template<class Type>
autoPtr<ensightFile> newPointData(const word& varName) const;
//- Open stream for new cloud data file (on master), with current index. //- Open stream for new cloud data file (on master), with current index.
template<class Type> template<class Type>
@ -313,28 +328,29 @@ public:
//- Configuration options for the ensightCase //- Configuration options for the ensightCase
class ensightCase::options class ensightCase::options
{ {
private: // Private Data
//- Ascii/Binary file output //- Ascii/Binary file output
IOstream::streamFormat format_; IOstream::streamFormat format_;
//- Width of mask for subdirectories //- Remove existing directory and sub-directories on creation
label width_; bool overwrite_;
//- The '*' mask appropriate for subdirectories //- Force use of values per node instead of per element
word mask_; bool nodeValues_;
//- The printf format for zero-padded subdirectory numbers //- Write clouds into their own directory
string printf_; bool separateCloud_;
//- Remove existing directory and sub-directories on creation //- Width of mask for subdirectories
bool overwrite_; label width_;
//- Write values at nodes //- The '*' mask appropriate for subdirectories
bool nodeValues_; word mask_;
//- The printf format for zero-padded subdirectory numbers
string printf_;
//- Write clouds into their own directory
bool separateCloud_;
public: public:
@ -363,9 +379,6 @@ public:
//- Remove existing directory and sub-directories on creation //- Remove existing directory and sub-directories on creation
bool overwrite() const; bool overwrite() const;
//- Use values per nodes instead of per element
bool nodeValues() const;
//- Write clouds into their own directory instead in "data" directory //- Write clouds into their own directory instead in "data" directory
bool separateCloud() const; bool separateCloud() const;
@ -379,12 +392,20 @@ public:
//- Remove existing directory and sub-directories on creation //- Remove existing directory and sub-directories on creation
void overwrite(bool); void overwrite(bool);
//- Use values per nodes instead of per element
void nodeValues(bool);
//- Write clouds into their own directory instead in "data" directory //- Write clouds into their own directory instead in "data" directory
void separateCloud(bool); void separateCloud(bool);
// Housekeeping
//- Force use of values per node instead of per element
bool nodeValues() const;
//- Force use of values per node instead of per element
// Deprecated(2020-02) - The newData() method with a second parameter
// is more flexible.
// \deprecated(2020-02) - newData() with second parameter
void nodeValues(bool);
}; };

View File

@ -32,14 +32,14 @@ License
Foam::ensightCase::options::options(IOstream::streamFormat format) Foam::ensightCase::options::options(IOstream::streamFormat format)
: :
format_(format), format_(format),
width_(0),
mask_(),
printf_(),
overwrite_(false), overwrite_(false),
nodeValues_(false), nodeValues_(false),
separateCloud_(false) separateCloud_(false),
width_(0),
mask_(),
printf_()
{ {
width(8); // Ensures that mask and printf-format are properly resized width(8); // Fill mask and setup printf-format
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016 OpenCFD Ltd. Copyright (C) 2016-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -34,7 +34,8 @@ template<class Type>
Foam::autoPtr<Foam::ensightFile> Foam::autoPtr<Foam::ensightFile>
Foam::ensightCase::newData Foam::ensightCase::newData
( (
const word& name const word& name,
const bool isPointData
) const ) const
{ {
autoPtr<ensightFile> output; autoPtr<ensightFile> output;
@ -42,9 +43,10 @@ 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
output().write output().write
( (
string string
@ -55,14 +57,31 @@ Foam::ensightCase::newData
); );
output().newline(); output().newline();
// note field variable for later use // Remember the field variable for later use
noteVariable(varName, ensightPTraits<Type>::typeName); noteVariable(varName, ensightPTraits<Type>::typeName);
// Could warn about existing variables that changed representation
if (isPointData)
{
nodeVariables_.set(varName);
}
} }
return output; return output;
} }
template<class Type>
Foam::autoPtr<Foam::ensightFile>
Foam::ensightCase::newPointData
(
const word& name
) const
{
return newData<Type>(name, true); // POINT_DATA
}
template<class Type> template<class Type>
Foam::autoPtr<Foam::ensightFile> Foam::autoPtr<Foam::ensightFile>
Foam::ensightCase::newCloudData Foam::ensightCase::newCloudData
@ -78,7 +97,7 @@ Foam::ensightCase::newCloudData
const ensight::VarName varName(name); const ensight::VarName varName(name);
output = createCloudFile(cloudName, varName); output = createCloudFile(cloudName, varName);
// description // Description
output().write output().write
( (
string string
@ -89,7 +108,7 @@ Foam::ensightCase::newCloudData
); );
output().newline(); output().newline();
// note cloud variable for later use // Remember the cloud variable for later use
noteCloud(cloudName, varName, ensightPTraits<Type>::typeName); noteCloud(cloudName, varName, ensightPTraits<Type>::typeName);
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2016-2019 OpenCFD Ltd. Copyright (C) 2016-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -29,7 +29,6 @@ License
#include "ensightFile.H" #include "ensightFile.H"
#include "error.H" #include "error.H"
#include "UList.H" #include "UList.H"
#include <cstring> #include <cstring>
#include <sstream> #include <sstream>
@ -39,10 +38,12 @@ bool Foam::ensightFile::allowUndef_ = false;
Foam::scalar Foam::ensightFile::undefValue_ = Foam::floatScalarVGREAT; Foam::scalar Foam::ensightFile::undefValue_ = Foam::floatScalarVGREAT;
// default is width 8 // Default is width 8
Foam::string Foam::ensightFile::mask_ = "********"; Foam::string Foam::ensightFile::mask_ = "********";
Foam::string Foam::ensightFile::dirFmt_ = "%08d"; Foam::string Foam::ensightFile::dirFmt_ = "%08d";
const char* const Foam::ensightFile::coordinates = "coordinates";
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
@ -85,6 +86,20 @@ Foam::label Foam::ensightFile::subDirWidth()
} }
bool Foam::ensightFile::isUndef(const UList<scalar>& field)
{
for (const scalar& val : field)
{
if (std::isnan(val))
{
return true;
}
}
return true;
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::ensightFile::initialize() void Foam::ensightFile::initialize()
@ -153,24 +168,13 @@ Foam::scalar Foam::ensightFile::undefValue(const scalar value)
} }
Foam::Ostream& Foam::ensightFile::write Foam::Ostream& Foam::ensightFile::writeString(const char* str)
(
const char* buf,
std::streamsize count
)
{
stdStream().write(buf, count);
return *this;
}
Foam::Ostream& Foam::ensightFile::write(const char* value)
{ {
// Output 80 chars, but allocate for trailing nul character // Output 80 chars, but allocate for trailing nul character
// to avoid -Wstringop-truncation warnings/errors. // to avoid -Wstringop-truncation warnings/errors.
char buf[80+1]; char buf[80+1];
strncpy(buf, value, 80); // max 80 chars or padded with nul if smaller strncpy(buf, str, 80); // max 80 chars or padded with nul if smaller
if (format() == IOstream::BINARY) if (format() == IOstream::BINARY)
{ {
@ -186,9 +190,38 @@ Foam::Ostream& Foam::ensightFile::write(const char* value)
} }
Foam::Ostream& Foam::ensightFile::write(const string& value) Foam::Ostream& Foam::ensightFile::writeString(const std::string& str)
{ {
return write(value.c_str()); return writeString(str.c_str());
}
Foam::Ostream& Foam::ensightFile::write(const char* str)
{
return writeString(str);
}
Foam::Ostream& Foam::ensightFile::write(const word& str)
{
return writeString(str);
}
Foam::Ostream& Foam::ensightFile::write(const string& str)
{
return writeString(str);
}
Foam::Ostream& Foam::ensightFile::write
(
const char* buf,
std::streamsize count
)
{
stdStream().write(buf, count);
return *this;
} }
@ -244,6 +277,14 @@ Foam::Ostream& Foam::ensightFile::write(const scalar value)
{ {
float fvalue(value); float fvalue(value);
// TBD: limit range?
// #if defined(WM_DP)
// if (mag(value) < scalar(floatScalarVSMALL))
// {
// fvalue = 0;
// }
// #endif
if (format() == IOstream::BINARY) if (format() == IOstream::BINARY)
{ {
write write
@ -282,17 +323,17 @@ Foam::Ostream& Foam::ensightFile::writeKeyword(const keyType& key)
{ {
if (allowUndef_) if (allowUndef_)
{ {
write(string(static_cast<const string&>(key) + " undef")); writeString(key + " undef");
newline(); newline();
write(undefValue_); write(undefValue_);
newline(); newline();
} }
else else
{ {
// ensure we get ensightFile::write(const string&) writeString(key);
write(static_cast<const string&>(key));
newline(); newline();
} }
return *this; return *this;
} }
@ -301,7 +342,7 @@ Foam::Ostream& Foam::ensightFile::writeBinaryHeader()
{ {
if (format() == IOstream::BINARY) if (format() == IOstream::BINARY)
{ {
write("C Binary"); writeString("C Binary");
} }
return *this; return *this;
@ -314,7 +355,7 @@ Foam::Ostream& Foam::ensightFile::writeBinaryHeader()
void Foam::ensightFile::beginPart(const label index) void Foam::ensightFile::beginPart(const label index)
{ {
write("part"); writeString("part");
newline(); newline();
write(index+1); // Ensight starts with 1 write(index+1); // Ensight starts with 1
newline(); newline();
@ -323,13 +364,23 @@ void Foam::ensightFile::beginPart(const label index)
void Foam::ensightFile::beginParticleCoordinates(const label nparticles) void Foam::ensightFile::beginParticleCoordinates(const label nparticles)
{ {
write("particle coordinates"); writeString("particle coordinates");
newline(); newline();
write(nparticles, 8); // unusual width write(nparticles, 8); // unusual width
newline(); newline();
} }
void Foam::ensightFile::writeLabels(const UList<label>& list)
{
for (const label val : list)
{
write(val);
newline();
}
}
void Foam::ensightFile::writeList(const UList<label>& field) void Foam::ensightFile::writeList(const UList<label>& field)
{ {
for (const label val : field) for (const label val : field)
@ -342,7 +393,7 @@ void Foam::ensightFile::writeList(const UList<label>& field)
void Foam::ensightFile::writeList(const UList<scalar>& field) void Foam::ensightFile::writeList(const UList<scalar>& field)
{ {
for (const scalar& val : field) for (const scalar val : field)
{ {
if (std::isnan(val)) if (std::isnan(val))
{ {
@ -352,30 +403,6 @@ void Foam::ensightFile::writeList(const UList<scalar>& field)
{ {
write(val); write(val);
} }
newline();
}
}
void Foam::ensightFile::writeList
(
const UList<scalar>& field,
const labelUList& addr
)
{
for (const label id : addr)
{
if (id < 0 || id >= field.size() || std::isnan(field[id]))
{
writeUndef();
}
else
{
write(field[id]);
}
newline(); newline();
} }
} }

View File

@ -37,11 +37,9 @@ Description
#define ensightFile_H #define ensightFile_H
#include "OFstream.H" #include "OFstream.H"
#include "IOstream.H"
#include "ensightFileName.H" #include "ensightFileName.H"
#include "ensightVarName.H" #include "ensightVarName.H"
#include "UList.H" #include "IndirectListBase.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -61,7 +59,7 @@ class ensightFile
//- Allow undef in results //- Allow undef in results
static bool allowUndef_; static bool allowUndef_;
//- Value to represent undef in results //- Value to represent undef in results (default: 1e+37, floatVGREAT)
static scalar undefValue_; static scalar undefValue_;
//- The '*' mask appropriate for subDir //- The '*' mask appropriate for subDir
@ -85,6 +83,12 @@ class ensightFile
public: public:
// Static Data Members
//- The keyword "coordinates"
static const char* const coordinates;
// Static Functions // Static Functions
//- Return a null ensightFile //- Return a null ensightFile
@ -118,6 +122,8 @@ public:
~ensightFile() = default; ~ensightFile() = default;
// Member Functions
// Access // Access
//- Return setting for whether 'undef' values are allowed in results //- Return setting for whether 'undef' values are allowed in results
@ -150,35 +156,42 @@ public:
// Output // Output
//- Inherit write from Ostream //- Write element keyword with trailing newline,
using Ostream::write; //- optionally with undef and the value for undefined
//- Binary write
virtual Ostream& write(const char* buf, std::streamsize count);
//- Write element keyword with trailing newline, optionally with undef
virtual Ostream& writeKeyword(const keyType& key); virtual Ostream& writeKeyword(const keyType& key);
//- Write "C Binary" for binary files (eg, geometry/measured) //- Write "C Binary" string for binary files (eg, geometry/measured)
Ostream& writeBinaryHeader(); Ostream& writeBinaryHeader();
//- Write C-string as "%79s" or as binary (max 80 chars)
Ostream& writeString(const char* str);
//- Write string as "%79s" or as binary (max 80 chars)
Ostream& writeString(const std::string& str);
//- Write undef value //- Write undef value
Ostream& writeUndef(); Ostream& writeUndef();
//- Write C-string as "%79s" or as binary (max 80 chars) //- Binary write
Ostream& write(const char*); virtual Ostream& write(const char* buf, std::streamsize count);
//- Write string as "%79s" or as binary (max 80 chars) //- Write C-string, uses writeString()
Ostream& write(const string&); virtual Ostream& write(const char* str);
//- Write word, uses writeString()
virtual Ostream& write(const word& str);
//- Write string, uses writeString()
virtual Ostream& write(const string& str);
//- Write integer as "%10d" or as binary //- Write integer as "%10d" or as binary
Ostream& write(const label); Ostream& write(const label value);
//- Write integer with specified width or as binary //- Write integer with specified width or as binary
Ostream& write(const label, const label fieldWidth); Ostream& write(const label value, const label fieldWidth);
//- Write float as "%12.5e" or as binary //- Write float as "%12.5e" or as binary
Ostream& write(const scalar); Ostream& write(const scalar value);
//- Add carriage return to ascii stream //- Add carriage return to ascii stream
void newline(); void newline();
@ -192,7 +205,17 @@ public:
//- Begin a "particle coordinates" block (measured data) //- Begin a "particle coordinates" block (measured data)
void beginParticleCoordinates(const label nparticles); void beginParticleCoordinates(const label nparticles);
//- Write a list of integers
// With carriage return after each value (ascii stream)
void writeLabels(const UList<label>& list);
//- Write a list of integers
// With carriage return after each value (ascii stream)
template<class Addr>
void writeLabels(const IndirectListBase<label, Addr>& list);
//- Write a list of integers as float values //- Write a list of integers as float values
// With carriage return after each value (ascii stream)
void writeList(const UList<label>& field); void writeList(const UList<label>& field);
//- Write a list of floats as "%12.5e" or as binary //- Write a list of floats as "%12.5e" or as binary
@ -201,7 +224,18 @@ public:
//- Write an indirect list of scalars as "%12.5e" or as binary //- Write an indirect list of scalars as "%12.5e" or as binary
// With carriage return after each value (ascii stream) // With carriage return after each value (ascii stream)
void writeList(const UList<scalar>& field, const labelUList& addr); template<class Addr>
void writeList(const IndirectListBase<scalar, Addr>& field);
// Other Methods
//- Check for any NaN in the field
static bool isUndef(const UList<scalar>& field);
//- Check for any NaN in the field
template<class Addr>
static bool isUndef(const IndirectListBase<scalar, Addr>& field);
}; };
@ -211,6 +245,12 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "ensightFileTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif #endif
// ************************************************************************* // // ************************************************************************* //

View File

@ -0,0 +1,76 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template<class Addr>
bool Foam::ensightFile::isUndef(const IndirectListBase<scalar, Addr>& field)
{
for (const scalar val : field)
{
if (std::isnan(val))
{
return true;
}
}
return true;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Addr>
void Foam::ensightFile::writeLabels(const IndirectListBase<label, Addr>& list)
{
for (const scalar val : list)
{
write(val);
newline();
}
}
template<class Addr>
void Foam::ensightFile::writeList(const IndirectListBase<scalar, Addr>& field)
{
for (const scalar val : field)
{
if (std::isnan(val))
{
writeUndef();
}
else
{
write(val);
}
newline();
}
}
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2016-2019 OpenCFD Ltd. Copyright (C) 2016-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -82,8 +82,7 @@ Foam::ensightGeoFile::ensightGeoFile
Foam::Ostream& Foam::ensightGeoFile::writeKeyword(const keyType& key) Foam::Ostream& Foam::ensightGeoFile::writeKeyword(const keyType& key)
{ {
// Ensure we get ensightFile::write(const string&) writeString(key);
write(static_cast<const string&>(key));
newline(); newline();
return *this; return *this;
@ -101,15 +100,16 @@ void Foam::ensightGeoFile::beginPart
) )
{ {
beginPart(index); beginPart(index);
write(description); writeString(description);
newline(); newline();
} }
void Foam::ensightGeoFile::beginCoordinates(const label npoints) void Foam::ensightGeoFile::beginCoordinates(const label npoints)
{ {
write("coordinates"); writeString(ensightFile::coordinates);
newline(); newline();
write(npoints); write(npoints);
newline(); newline();
} }

View File

@ -97,6 +97,8 @@ public:
~ensightGeoFile() = default; ~ensightGeoFile() = default;
// Member Functions
// Output // Output
//- Write keyword with trailing newline //- Write keyword with trailing newline

View File

@ -36,30 +36,6 @@ namespace Foam
} }
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
// TODO - move elsewhere
#if 0
bool Foam::ensightPart::isFieldDefined
(
const List<scalar>& field
// const labelUList& addr = cellIds() or faceIds()
) const
{
forAll(addr, elemI)
{
const label id = addr[i];
if (id >= field.size() || std::isnan(field[id]))
{
return false;
}
}
return true;
}
#endif
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightPart::ensightPart(const string& description) Foam::ensightPart::ensightPart(const string& description)