From 02ec3981e3d7bfaa937b72172fc4df2289b5c743 Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@esi-group.com> Date: Thu, 6 Feb 2020 11:45:49 +0100 Subject: [PATCH] ENH: improve ensightFile output support (#1579) - indirect lists, lists of labels - writeString() methods to avoid any ambiguities --- src/fileFormats/ensight/file/ensightFile.C | 119 +++++++++++------- src/fileFormats/ensight/file/ensightFile.H | 74 ++++++++--- .../ensight/file/ensightFileTemplates.C | 76 +++++++++++ src/fileFormats/ensight/file/ensightGeoFile.C | 7 +- src/fileFormats/ensight/file/ensightGeoFile.H | 2 + src/fileFormats/ensight/part/ensightPart.C | 24 ---- 6 files changed, 207 insertions(+), 95 deletions(-) create mode 100644 src/fileFormats/ensight/file/ensightFileTemplates.C diff --git a/src/fileFormats/ensight/file/ensightFile.C b/src/fileFormats/ensight/file/ensightFile.C index 4cdb931fffd..9d24699518c 100644 --- a/src/fileFormats/ensight/file/ensightFile.C +++ b/src/fileFormats/ensight/file/ensightFile.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2015 OpenFOAM Foundation - Copyright (C) 2016-2019 OpenCFD Ltd. + Copyright (C) 2016-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -29,7 +29,6 @@ License #include "ensightFile.H" #include "error.H" #include "UList.H" - #include <cstring> #include <sstream> @@ -85,6 +84,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 * * * * * * * * * * * // void Foam::ensightFile::initialize() @@ -153,24 +166,13 @@ Foam::scalar Foam::ensightFile::undefValue(const scalar value) } -Foam::Ostream& Foam::ensightFile::write -( - const char* buf, - std::streamsize count -) -{ - stdStream().write(buf, count); - return *this; -} - - -Foam::Ostream& Foam::ensightFile::write(const char* value) +Foam::Ostream& Foam::ensightFile::writeString(const char* str) { // Output 80 chars, but allocate for trailing nul character // to avoid -Wstringop-truncation warnings/errors. 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) { @@ -186,9 +188,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 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 +) { - return write(value.c_str()); + stdStream().write(buf, count); + return *this; } @@ -244,6 +275,14 @@ Foam::Ostream& Foam::ensightFile::write(const scalar value) { float fvalue(value); + // TBD: limit range? + // #if defined(WM_DP) + // if (mag(value) < scalar(floatScalarVSMALL)) + // { + // fvalue = 0; + // } + // #endif + if (format() == IOstream::BINARY) { write @@ -282,17 +321,17 @@ Foam::Ostream& Foam::ensightFile::writeKeyword(const keyType& key) { if (allowUndef_) { - write(string(static_cast<const string&>(key) + " undef")); + writeString(key + " undef"); newline(); write(undefValue_); newline(); } else { - // ensure we get ensightFile::write(const string&) - write(static_cast<const string&>(key)); + writeString(key); newline(); } + return *this; } @@ -301,7 +340,7 @@ Foam::Ostream& Foam::ensightFile::writeBinaryHeader() { if (format() == IOstream::BINARY) { - write("C Binary"); + writeString("C Binary"); } return *this; @@ -314,7 +353,7 @@ Foam::Ostream& Foam::ensightFile::writeBinaryHeader() void Foam::ensightFile::beginPart(const label index) { - write("part"); + writeString("part"); newline(); write(index+1); // Ensight starts with 1 newline(); @@ -323,59 +362,45 @@ void Foam::ensightFile::beginPart(const label index) void Foam::ensightFile::beginParticleCoordinates(const label nparticles) { - write("particle coordinates"); + writeString("particle coordinates"); newline(); write(nparticles, 8); // unusual width newline(); } -void Foam::ensightFile::writeList(const UList<label>& field) +void Foam::ensightFile::writeLabels(const UList<label>& list) { - for (const label val : field) + for (const label val : list) { - write(scalar(val)); + write(val); newline(); } } -void Foam::ensightFile::writeList(const UList<scalar>& field) +void Foam::ensightFile::writeList(const UList<label>& field) { - for (const scalar& val : field) + for (const label val : field) { - if (std::isnan(val)) - { - writeUndef(); - } - else - { - write(val); - } - + write(scalar(val)); newline(); } } - -void Foam::ensightFile::writeList -( - const UList<scalar>& field, - const labelUList& addr -) +void Foam::ensightFile::writeList(const UList<scalar>& field) { - for (const label id : addr) + for (const scalar val : field) { - if (id < 0 || id >= field.size() || std::isnan(field[id])) + if (std::isnan(val)) { writeUndef(); } else { - write(field[id]); + write(val); } - newline(); } } diff --git a/src/fileFormats/ensight/file/ensightFile.H b/src/fileFormats/ensight/file/ensightFile.H index 6f78b573321..6e4f9cb5c0d 100644 --- a/src/fileFormats/ensight/file/ensightFile.H +++ b/src/fileFormats/ensight/file/ensightFile.H @@ -37,11 +37,9 @@ Description #define ensightFile_H #include "OFstream.H" -#include "IOstream.H" - #include "ensightFileName.H" #include "ensightVarName.H" -#include "UList.H" +#include "IndirectListBase.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -61,7 +59,7 @@ class ensightFile //- Allow undef in results static bool allowUndef_; - //- Value to represent undef in results + //- Value to represent undef in results (default: 1e+37, floatVGREAT) static scalar undefValue_; //- The '*' mask appropriate for subDir @@ -118,6 +116,8 @@ public: ~ensightFile() = default; + // Member Functions + // Access //- Return setting for whether 'undef' values are allowed in results @@ -150,35 +150,42 @@ public: // Output - //- Inherit write from Ostream - using Ostream::write; - - //- Binary write - virtual Ostream& write(const char* buf, std::streamsize count); - - //- Write element keyword with trailing newline, optionally with undef + //- Write element keyword with trailing newline, + //- optionally with undef and the value for undefined 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(); + //- 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 Ostream& writeUndef(); - //- Write C-string as "%79s" or as binary (max 80 chars) - Ostream& write(const char*); + //- Binary write + virtual Ostream& write(const char* buf, std::streamsize count); - //- Write string as "%79s" or as binary (max 80 chars) - Ostream& write(const string&); + //- Write C-string, uses writeString() + 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 - Ostream& write(const label); + Ostream& write(const label value); //- 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 - Ostream& write(const scalar); + Ostream& write(const scalar value); //- Add carriage return to ascii stream void newline(); @@ -192,7 +199,17 @@ public: //- Begin a "particle coordinates" block (measured data) 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 + // With carriage return after each value (ascii stream) void writeList(const UList<label>& field); //- Write a list of floats as "%12.5e" or as binary @@ -201,7 +218,18 @@ public: //- Write an indirect list of scalars as "%12.5e" or as binary // 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 +239,12 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +#ifdef NoRepository + #include "ensightFileTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + #endif // ************************************************************************* // diff --git a/src/fileFormats/ensight/file/ensightFileTemplates.C b/src/fileFormats/ensight/file/ensightFileTemplates.C new file mode 100644 index 00000000000..97b00009a30 --- /dev/null +++ b/src/fileFormats/ensight/file/ensightFileTemplates.C @@ -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(); + } +} + + +// ************************************************************************* // diff --git a/src/fileFormats/ensight/file/ensightGeoFile.C b/src/fileFormats/ensight/file/ensightGeoFile.C index 7b6006f3b38..50b92fbbf12 100644 --- a/src/fileFormats/ensight/file/ensightGeoFile.C +++ b/src/fileFormats/ensight/file/ensightGeoFile.C @@ -82,8 +82,7 @@ Foam::ensightGeoFile::ensightGeoFile Foam::Ostream& Foam::ensightGeoFile::writeKeyword(const keyType& key) { - // Ensure we get ensightFile::write(const string&) - write(static_cast<const string&>(key)); + writeString(key); newline(); return *this; @@ -101,14 +100,14 @@ void Foam::ensightGeoFile::beginPart ) { beginPart(index); - write(description); + writeString(description); newline(); } void Foam::ensightGeoFile::beginCoordinates(const label npoints) { - write("coordinates"); + writeString("coordinates"); newline(); write(npoints); newline(); diff --git a/src/fileFormats/ensight/file/ensightGeoFile.H b/src/fileFormats/ensight/file/ensightGeoFile.H index 1415ecf69f8..77a735a9c85 100644 --- a/src/fileFormats/ensight/file/ensightGeoFile.H +++ b/src/fileFormats/ensight/file/ensightGeoFile.H @@ -97,6 +97,8 @@ public: ~ensightGeoFile() = default; + // Member Functions + // Output //- Write keyword with trailing newline diff --git a/src/fileFormats/ensight/part/ensightPart.C b/src/fileFormats/ensight/part/ensightPart.C index 1a2ec97c985..2092a33f396 100644 --- a/src/fileFormats/ensight/part/ensightPart.C +++ b/src/fileFormats/ensight/part/ensightPart.C @@ -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 * * * * * * * * * * * * * * // Foam::ensightPart::ensightPart(const string& description) -- GitLab