diff --git a/src/OpenFOAM/db/Time/Time.C b/src/OpenFOAM/db/Time/Time.C index ae83aad09290aa663ec38063cc5ea436f229bc37..b6827deac59c3741df5be655876c3802e836111b 100644 --- a/src/OpenFOAM/db/Time/Time.C +++ b/src/OpenFOAM/db/Time/Time.C @@ -73,7 +73,10 @@ Foam::Time::writeControlNames }); -Foam::Time::fmtflags Foam::Time::format_(Foam::Time::fmtflags::general); +Foam::IOstreamOption::floatFormat Foam::Time::format_ +( + IOstreamOption::floatFormat::general +); int Foam::Time::precision_(6); diff --git a/src/OpenFOAM/db/Time/Time.H b/src/OpenFOAM/db/Time/Time.H index 249858e5b6a1823672ec2017d77ee81af489a117..54245b8ee998d7033dd6cf0b3b0d347d583b24ac 100644 --- a/src/OpenFOAM/db/Time/Time.H +++ b/src/OpenFOAM/db/Time/Time.H @@ -104,15 +104,6 @@ public: saUnknown //!< Dummy no-op. Do not change current value. }; - //- Supported time directory name formats - enum fmtflags - { - general = 0, //!< default float notation - fixed = ios_base::fixed, //!< fixed-point notation - scientific = ios_base::scientific //!< scientific notation - }; - - //- Names for writeControls static const Enum<writeControls> writeControlNames; @@ -179,9 +170,8 @@ protected: //- Signal handler for write and clean exit upon signal sigStopAtWriteNow sigStopAtWriteNow_; - - //- Time directory name format - static fmtflags format_; + //- Format for time directory names (general | fixed | scientific) + static IOstreamOption::floatFormat format_; //- Time directory name precision static int precision_; diff --git a/src/OpenFOAM/db/Time/TimeIO.C b/src/OpenFOAM/db/Time/TimeIO.C index 30848008657a20c4cdd5884b4687493d64ce32c5..1312df395ae779eb4c2ca3ae22fea687b075dd15 100644 --- a/src/OpenFOAM/db/Time/TimeIO.C +++ b/src/OpenFOAM/db/Time/TimeIO.C @@ -329,29 +329,8 @@ void Foam::Time::readDict() } } - if (controlDict_.found("timeFormat")) - { - const word formatName(controlDict_.get<word>("timeFormat")); - - if (formatName == "general") - { - format_ = fmtflags::general; - } - else if (formatName == "fixed") - { - format_ = fmtflags::fixed; - } - else if (formatName == "scientific") - { - format_ = fmtflags::scientific; - } - else - { - WarningInFunction - << "Unsupported time format " << formatName - << endl; - } - } + format_ = + IOstreamOption::floatFormatEnum("timeFormat", controlDict_, format_); controlDict_.readIfPresent("timePrecision", precision_); diff --git a/src/OpenFOAM/db/options/IOstreamOption.C b/src/OpenFOAM/db/options/IOstreamOption.C index 08be7382397d00f23352f4c5a39aa820278ce392..32e588aaa259cb2e31b99d72e394e1a201c1c852 100644 --- a/src/OpenFOAM/db/options/IOstreamOption.C +++ b/src/OpenFOAM/db/options/IOstreamOption.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018-2020 OpenCFD Ltd. + Copyright (C) 2018-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -35,6 +35,17 @@ License const Foam::IOstreamOption::versionNumber Foam::IOstreamOption::currentVersion; +const Foam::Enum +< + Foam::IOstreamOption::floatFormat +> +Foam::IOstreamOption::floatFormatNames +({ + { floatFormat::general, "general" }, + { floatFormat::fixed, "fixed" }, + { floatFormat::scientific, "scientific" }, +}); + const Foam::Enum < Foam::IOstreamOption::streamFormat @@ -48,27 +59,72 @@ Foam::IOstreamOption::formatNames // * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * // +Foam::IOstreamOption::floatFormat +Foam::IOstreamOption::floatFormatEnum +( + const word& fmtName, + const floatFormat deflt +) +{ + // Handle bad input graciously. A no-op for an empty string + + if (!fmtName.empty()) + { + const auto iter = floatFormatNames.cfind(fmtName); + + if (iter.good()) + { + return iter.val(); + } + + // Fall-through to warning + + WarningInFunction + << "Unknown float format specifier '" << fmtName + << "' using '" << floatFormatNames[deflt] + << "' from " << floatFormatNames << nl; + } + + return deflt; +} + + +Foam::IOstreamOption::floatFormat +Foam::IOstreamOption::floatFormatEnum +( + const word& key, + const dictionary& dict, + const floatFormat deflt +) +{ + return floatFormatNames.getOrDefault(key, dict, deflt, true); // warnOnly +} + + Foam::IOstreamOption::streamFormat Foam::IOstreamOption::formatEnum ( - const word& formatName, + const word& fmtName, const streamFormat deflt ) { // Handle bad input graciously. A no-op for an empty string - if (!formatName.empty()) + if (!fmtName.empty()) { - if (formatNames.contains(formatName)) + const auto iter = formatNames.cfind(fmtName); + + if (iter.good()) { - return formatNames[formatName]; + return iter.val(); } // Fall-through to warning WarningInFunction - << "Unknown format specifier '" << formatName - << "', using '" << formatNames[deflt] << "'\n"; + << "Unknown stream format specifier '" << fmtName + << "' using '" << formatNames[deflt] + << "' from " << formatNames << nl; } return deflt; @@ -83,7 +139,7 @@ Foam::IOstreamOption::formatEnum const streamFormat deflt ) { - return formatNames.getOrDefault(key, dict, deflt, true); // failsafe=true + return formatNames.getOrDefault(key, dict, deflt, true); // warnOnly } @@ -114,8 +170,7 @@ Foam::IOstreamOption::compressionEnum WarningInFunction << "Unknown compression specifier '" << compName - << "', using compression " - << (deflt ? "on" : "off" ) << nl; + << "' using compression " << (deflt ? "on" : "off") << nl; } return deflt; @@ -132,7 +187,7 @@ Foam::IOstreamOption::compressionEnum { return ( - Switch(key, dict, Switch(bool(deflt)), true) // failsafe=true + Switch(key, dict, Switch(bool(deflt)), true) // warnOnly ? compressionType::COMPRESSED : compressionType::UNCOMPRESSED ); diff --git a/src/OpenFOAM/db/options/IOstreamOption.H b/src/OpenFOAM/db/options/IOstreamOption.H index 5b16cd3e3dcd5e368822e5fb4e871fe80c64778a..15f243eb245334cf7cef2b2f57098a35b9954a48 100644 --- a/src/OpenFOAM/db/options/IOstreamOption.H +++ b/src/OpenFOAM/db/options/IOstreamOption.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2015 OpenFOAM Foundation - Copyright (C) 2018-2022 OpenCFD Ltd. + Copyright (C) 2018-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -48,6 +48,7 @@ SourceFiles #define Foam_IOstreamOption_H #include "word.H" +#include <ios> // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -97,6 +98,17 @@ public: ATOMIC //!< atomic = true }; + //- Float formats (eg, time directory name formats) + enum class floatFormat : unsigned + { + //! default float notation + general = unsigned(0), + //! fixed-point notation + fixed = unsigned(std::ios_base::fixed), + //! scientific notation + scientific = unsigned(std::ios_base::scientific) + }; + //- Representation of a major/minor version number class versionNumber @@ -134,7 +146,7 @@ public: explicit versionNumber(const token& tok); //- Failsafe construct from dictionary lookup. - versionNumber(const word& keyword, const dictionary& dict); + versionNumber(const word& key, const dictionary& dict); // Member Functions @@ -168,13 +180,16 @@ public: // Positive when 'this' is greater than other. int compare(const versionNumber& other) const noexcept { - return number_ - other.number_; + return (number_ - other.number_); } }; // Public Static Data + //- Names for float formats (general, fixed, scientific) + static const Enum<floatFormat> floatFormatNames; + //- Stream format names (ascii, binary) static const Enum<streamFormat> formatNames; @@ -182,6 +197,75 @@ public: static const versionNumber currentVersion; + // Static Helpers + + //- Lookup floatFormat enum corresponding to the string + //- (general | fixed | scientific). + // + // If the string is not recognized, emit warning and return default. + // Silent if the string itself is empty. + // + // \note Can be used as constructor substitute for the enumeration + static floatFormat floatFormatEnum + ( + const word& fmtName, + const floatFormat deflt = floatFormat::general + ); + + //- getOrDefault floatFormat from dictionary, + //- warn only on bad enumeration. + static floatFormat floatFormatEnum + ( + const word& key, //!< Lookup key. Uses LITERAL (not REGEX) + const dictionary& dict, //!< dictionary + const floatFormat deflt = floatFormat::general + ); + + //- Lookup streamFormat enum corresponding to the string + //- (ascii | binary). + // + // If the string is not recognized, emit warning and return default. + // Silent if the string itself is empty. + // + // \note Can be used as constructor substitute for the enumeration + static streamFormat formatEnum + ( + const word& fmtName, + const streamFormat deflt = streamFormat::ASCII + ); + + //- getOrDefault streamFormat from dictionary, + //- warn only on bad enumeration. + static streamFormat formatEnum + ( + const word& key, //!< Lookup key. Uses LITERAL (not REGEX) + const dictionary& dict, //!< dictionary + const streamFormat deflt = streamFormat::ASCII + ); + + //- The compression enum corresponding to the string. + // Expects switch values (true/false, on/off, ...) + // + // If the string is not recognized, emit warning and return default. + // Silent if the string itself is empty. + // + // \note Can be used as constructor substitute for the enumeration + static compressionType compressionEnum + ( + const word& compName, + const compressionType deflt = compressionType::UNCOMPRESSED + ); + + //- getOrDefault compressionType from dictionary, + //- warn only on bad enumeration. + static compressionType compressionEnum + ( + const word& key, //!< Lookup key. Uses LITERAL (not REGEX) + const dictionary& dict, //!< dictionary + const compressionType deflt = compressionType::UNCOMPRESSED + ); + + private: // Private Data @@ -252,51 +336,6 @@ public: {} - // Static Member Functions - - //- The stream format enum corresponding to the string - //- (ascii | binary). - // - // If the string is not recognized, emit warning and return default. - // Silent if the string itself is empty. - // - // \note Can be used as constructor substitute for the enumeration - static streamFormat formatEnum - ( - const word& formatName, - const streamFormat deflt = streamFormat::ASCII - ); - - //- Failsafe construct streamFormat from optional dictionary lookup - static streamFormat formatEnum - ( - const word& key, //!< Lookup key. Uses LITERAL (not REGEX) - const dictionary& dict, //!< dictionary - const streamFormat deflt = streamFormat::ASCII - ); - - //- The compression enum corresponding to the string. - // Expects switch values (true/false, on/off, ...) - // - // If the string is not recognized, emit warning and return default. - // Silent if the string itself is empty. - // - // \note Can be used as constructor substitute for the enumeration - static compressionType compressionEnum - ( - const word& compName, - const compressionType deflt = compressionType::UNCOMPRESSED - ); - - //- Failsafe construct compressionType from optional dictionary lookup - static compressionType compressionEnum - ( - const word& key, //!< Lookup key. Uses LITERAL (not REGEX) - const dictionary& dict, //!< dictionary - const compressionType deflt = compressionType::UNCOMPRESSED - ); - - // Member Functions //- Get the current stream format diff --git a/src/fileFormats/ensight/file/ensightCase.C b/src/fileFormats/ensight/file/ensightCase.C index 144afad96a2f53f97ee9e53b55a5a4e267312b2b..648ae075f788f1e1865fbf0360893db5b5813e1e 100644 --- a/src/fileFormats/ensight/file/ensightCase.C +++ b/src/fileFormats/ensight/file/ensightCase.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2022 OpenCFD Ltd. + Copyright (C) 2016-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -56,6 +56,44 @@ Foam::word Foam::ensightCase::padded(const int nwidth, const label value) } +void Foam::ensightCase::setTimeFormat +( + OSstream& os, + IOstreamOption::floatFormat timeFmt, + const int timePrec +) +{ + os.setf(std::ios_base::left); + os.setf + ( + std::ios_base::fmtflags(timeFmt), + std::ios_base::floatfield + ); + + if (timePrec > 0) + { + os.precision(timePrec); + } +} + + +void Foam::ensightCase::setTimeFormat +( + OSstream& os, + const ensightCase::options& opts +) +{ + os.setf(std::ios_base::left); + os.setf + ( + std::ios_base::fmtflags(opts.timeFormat()), + std::ios_base::floatfield + ); + + os.precision(opts.timePrecision()); +} + + void Foam::ensightCase::printTimeset ( OSstream& os, @@ -184,7 +222,7 @@ Foam::fileName Foam::ensightCase::dataDir() const void Foam::ensightCase::initialize() { - if (Pstream::master()) + if (UPstream::master()) { // EnSight and EnSight/data directories must exist @@ -211,11 +249,7 @@ void Foam::ensightCase::initialize() // The case file is always ASCII os_.reset(new OFstream(ensightDir_/caseName_, IOstreamOption::ASCII)); - - // Format options - os_->setf(ios_base::left); - os_->setf(ios_base::scientific, ios_base::floatfield); - os_->precision(5); + ensightCase::setTimeFormat(*os_, *options_); // Format options writeHeader(); } @@ -468,7 +502,7 @@ Foam::ensightCase::createDataFile const word& name ) const { - if (Pstream::master()) + if (UPstream::master()) { // The data/ITER subdirectory must exist // Note that data/ITER is indeed a valid ensight::FileName @@ -490,7 +524,7 @@ Foam::ensightCase::createCloudFile const word& name ) const { - if (Pstream::master()) + if (UPstream::master()) { // Write // eg -> "data/********/lagrangian/<cloudName>/positions" @@ -584,7 +618,7 @@ void Foam::ensightCase::setTime(const scalar value, const label index) timeIndex_ = index; timeValue_ = value; - if (Pstream::master()) + if (UPstream::master()) { // The data/ITER subdirectory must exist // Note that data/ITER is indeed a valid ensight::FileName @@ -810,7 +844,7 @@ Foam::ensightCase::newGeometry { autoPtr<Foam::ensightGeoFile> output; - if (Pstream::master()) + if (UPstream::master()) { // Set the path of the ensight file fileName path; @@ -844,7 +878,7 @@ Foam::ensightCase::newCloud { autoPtr<Foam::ensightFile> output; - if (Pstream::master()) + if (UPstream::master()) { output = createCloudFile(cloudName, "positions"); diff --git a/src/fileFormats/ensight/file/ensightCase.H b/src/fileFormats/ensight/file/ensightCase.H index c6247f4cf419e8760eb0ddcc6393d228aac44b61..185e59dcfbb9901cd5e7ea36fd21bf721350de30 100644 --- a/src/fileFormats/ensight/file/ensightCase.H +++ b/src/fileFormats/ensight/file/ensightCase.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2022 OpenCFD Ltd. + Copyright (C) 2016-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -57,6 +57,7 @@ namespace Foam // Forward Declarations class bitSet; +class dictionary; class ensightCase; class instant; class OSstream; @@ -333,6 +334,21 @@ public: // Output Helpers + //- Set output time format for ensight case file + static void setTimeFormat + ( + OSstream& os, + IOstreamOption::floatFormat timeFmt, + const int timePrec + ); + + //- Set output time format for ensight case file + static void setTimeFormat + ( + OSstream& os, + const ensightCase::options& opts + ); + //- Print time-set for ensight case file with a single time static void printTimeset ( @@ -388,7 +404,7 @@ class ensightCase::options { // Private Data - //- Ascii/Binary file output + //- The output file format (ascii/binary) IOstreamOption::streamFormat format_; //- Remove existing directory and sub-directories on creation @@ -400,8 +416,14 @@ class ensightCase::options //- Write clouds into their own directory bool separateCloud_; + //- Time format for case file (default: scientific) + IOstreamOption::floatFormat timeFormat_; + + //- Time precision for case file (default: 5) + int timePrecision_; + //- Width of mask for subdirectories - label width_; + int width_; //- The '*' mask appropriate for subdirectories word mask_; @@ -415,16 +437,39 @@ public: // Constructors //- Construct with the specified format (default is binary) - options(IOstreamOption::streamFormat fmt = IOstreamOption::BINARY); + explicit options + ( + IOstreamOption::streamFormat fmt = IOstreamOption::BINARY + ); + + //- If present, construct with the format specified in the dictionary + //- or use default (binary) + options + ( + //! The lookup name for the format, typically 'format' + //! or 'writeFormat' etc. + const word& formatKeyword, + const dictionary& dict, + IOstreamOption::streamFormat fmt = IOstreamOption::BINARY + ); // Member Functions // Access - //- Ascii/Binary file output + //- The output file format (ascii/binary) IOstreamOption::streamFormat format() const noexcept { return format_; } + //- Time format for case file (general/fixed/scientific) + IOstreamOption::floatFormat timeFormat() const noexcept + { + return timeFormat_; + } + + //- Time precision for case file + int timePrecision() const noexcept { return timePrecision_; } + //- The '*' mask appropriate for sub-directories const word& mask() const noexcept { return mask_; } @@ -432,7 +477,7 @@ public: word padded(const label i) const; //- Return current width of mask and padded. - label width() const noexcept { return width_; } + int width() const noexcept { return width_; } //- Remove existing directory and sub-directories on creation bool overwrite() const noexcept { return overwrite_; } @@ -445,7 +490,22 @@ public: //- Set width of mask and padded. // Default width is 8 digits, max width is 31 digits. - void width(const label i); + void width(const int i); + + //- Set the time format for case file + void timeFormat(IOstreamOption::floatFormat fmt) noexcept + { + timeFormat_ = fmt; + } + + //- Set the time precision for case file + void timePrecision(int prec) noexcept { timePrecision_ = prec; } + + //- Set the time format for case file + void timeFormat(const word& key, const dictionary& dict); + + //- Set the time precision for case file + void timePrecision(const word& key, const dictionary& dict); //- Remove existing directory and sub-directories on creation void overwrite(bool on) noexcept { overwrite_ = on; } diff --git a/src/fileFormats/ensight/file/ensightCaseOptions.C b/src/fileFormats/ensight/file/ensightCaseOptions.C index ec1594107635f4eea6360102018b00a302375f9b..515701bb6b5fbc7447e1292b4a7531379c317f32 100644 --- a/src/fileFormats/ensight/file/ensightCaseOptions.C +++ b/src/fileFormats/ensight/file/ensightCaseOptions.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2022 OpenCFD Ltd. + Copyright (C) 2016-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -26,15 +26,24 @@ License \*---------------------------------------------------------------------------*/ #include "ensightCase.H" +#include "dictionary.H" // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::ensightCase::options::options(IOstreamOption::streamFormat fmt) : - format_(fmt), + format_ + ( + // Can only be ASCII or BINARY + (fmt == IOstreamOption::streamFormat::ASCII) + ? IOstreamOption::streamFormat::ASCII + : IOstreamOption::streamFormat::BINARY + ), overwrite_(false), nodeValues_(false), separateCloud_(false), + timeFormat_(IOstreamOption::floatFormat::scientific), + timePrecision_(5), width_(0), mask_(), printf_() @@ -43,6 +52,17 @@ Foam::ensightCase::options::options(IOstreamOption::streamFormat fmt) } +Foam::ensightCase::options::options +( + const word& formatKeyword, + const dictionary& dict, + IOstreamOption::streamFormat fmt +) +: + options(IOstreamOption::formatEnum(formatKeyword, dict, fmt)) +{} + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // Foam::word Foam::ensightCase::options::padded(const label i) const @@ -58,7 +78,7 @@ Foam::word Foam::ensightCase::options::padded(const label i) const } -void Foam::ensightCase::options::width(const label n) +void Foam::ensightCase::options::width(const int n) { // Enforce min/max sanity limits if (n < 1 || n > 31) @@ -74,4 +94,27 @@ void Foam::ensightCase::options::width(const label n) } +void Foam::ensightCase::options::timeFormat +( + const word& key, + const dictionary& dict +) +{ + timeFormat_ = IOstreamOption::floatFormatEnum(key, dict, timeFormat_); +} + + +void Foam::ensightCase::options::timePrecision +( + const word& key, + const dictionary& dict +) +{ + if (!key.empty()) + { + dict.readIfPresent(key, timePrecision_, keyType::LITERAL); + } +} + + // ************************************************************************* // diff --git a/src/fileFormats/ensight/file/ensightCaseTemplates.C b/src/fileFormats/ensight/file/ensightCaseTemplates.C index e5e7d455e9c1a672ac3a9fa1f6f36325433d7931..8b1105ead66668d87c1ec0827fd0467354dbac2e 100644 --- a/src/fileFormats/ensight/file/ensightCaseTemplates.C +++ b/src/fileFormats/ensight/file/ensightCaseTemplates.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2020 OpenCFD Ltd. + Copyright (C) 2016-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -40,19 +40,16 @@ Foam::ensightCase::newData { autoPtr<ensightFile> output; - if (Pstream::master()) + if (UPstream::master()) { const ensight::VarName varName(name); output = createDataFile(varName); // Description - output().write + output().writeString ( - string - ( - padded(timeIndex_) / varName - + " <" + pTraits<Type>::typeName + ">" - ) + padded(timeIndex_) / varName + + " <" + pTraits<Type>::typeName + ">" ); output().newline(); @@ -91,19 +88,16 @@ Foam::ensightCase::newCloudData { autoPtr<ensightFile> output; - if (Pstream::master()) + if (UPstream::master()) { const ensight::VarName varName(name); output = createCloudFile(cloudName, varName); // Description - output().write + output().writeString ( - string - ( - padded(timeIndex_) / cloudName / varName - + " <" + pTraits<Type>::typeName + ">" - ) + padded(timeIndex_) / cloudName / varName + + " <" + pTraits<Type>::typeName + ">" ); output().newline(); diff --git a/src/fileFormats/ensight/file/ensightFile.C b/src/fileFormats/ensight/file/ensightFile.C index e10cb056d844b6370c3e0ff34a103e350a43e58f..dca789e4c15d0f4a59757cb466a1b0ffbd90fec7 100644 --- a/src/fileFormats/ensight/file/ensightFile.C +++ b/src/fileFormats/ensight/file/ensightFile.C @@ -147,7 +147,7 @@ float Foam::ensightFile::undefValue(float value) noexcept // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -Foam::Ostream& Foam::ensightFile::writeString(const char* str, size_t len) +void Foam::ensightFile::writeString(const char* str, size_t len) { // Output 79 chars (ASCII) or 80 chars (BINARY) char buf[80]; @@ -165,41 +165,47 @@ Foam::Ostream& Foam::ensightFile::writeString(const char* str, size_t len) else { buf[79] = 0; // Max 79 in ASCII + + // TBD: Extra safety - trap newline in ASCII? + // char* p = ::strchr(buf, '\n'); + // if (p) *p = 0; + stdStream() << buf; syncState(); } - - return *this; } -Foam::Ostream& Foam::ensightFile::writeString(const char* str) +void Foam::ensightFile::writeString(const char* str) { - return writeString(str, strlen(str)); + writeString(str, strlen(str)); } -Foam::Ostream& Foam::ensightFile::writeString(const std::string& str) +void Foam::ensightFile::writeString(const std::string& str) { - return writeString(str.data(), str.size()); + writeString(str.data(), str.size()); } Foam::Ostream& Foam::ensightFile::write(const char* str) { - return writeString(str, strlen(str)); + writeString(str, strlen(str)); + return *this; } Foam::Ostream& Foam::ensightFile::write(const word& str) { - return writeString(str.data(), str.size()); + writeString(str.data(), str.size()); + return *this; } Foam::Ostream& Foam::ensightFile::write(const std::string& str) { - return writeString(str.data(), str.size()); + writeString(str.data(), str.size()); + return *this; } @@ -304,10 +310,9 @@ void Foam::ensightFile::newline() } -Foam::Ostream& Foam::ensightFile::writeUndef() +void Foam::ensightFile::writeUndef() { write(undefValue_); - return *this; } @@ -330,14 +335,27 @@ Foam::Ostream& Foam::ensightFile::writeKeyword(const keyType& key) } -Foam::Ostream& Foam::ensightFile::writeBinaryHeader() +void Foam::ensightFile::writeBinaryHeader() { if (format() == IOstreamOption::BINARY) { writeString("C Binary"); + // Is binary: newline() is a no-op } +} - return *this; + +void Foam::ensightFile::beginTimeStep() +{ + writeString("BEGIN TIME STEP"); + newline(); +} + + +void Foam::ensightFile::endTimeStep() +{ + writeString("END TIME STEP"); + newline(); } diff --git a/src/fileFormats/ensight/file/ensightFile.H b/src/fileFormats/ensight/file/ensightFile.H index e472f25720aa8a3d1dafed607170856f82b95022..e565f3eb2cbe22ec0b4142d0dc82a4314f978e80 100644 --- a/src/fileFormats/ensight/file/ensightFile.H +++ b/src/fileFormats/ensight/file/ensightFile.H @@ -146,19 +146,25 @@ public: // Output //- Write "C Binary" string for binary files (eg, geometry/measured) - Ostream& writeBinaryHeader(); + void writeBinaryHeader(); + + //- Write "BEGIN TIME STEP" string and newline + void beginTimeStep(); + + //- Write "END TIME STEP" string and newline + void endTimeStep(); //- Write character/string content as "%79s" or as binary (max 80 chars) - Ostream& writeString(const char* str, size_t len); + void writeString(const char* str, size_t len); //- Write C-string as "%79s" or as binary (max 80 chars) - Ostream& writeString(const char* str); + void writeString(const char* str); //- Write string as "%79s" or as binary (max 80 chars) - Ostream& writeString(const std::string& str); + void writeString(const std::string& str); //- Write undef value - Ostream& writeUndef(); + void writeUndef(); //- Write element keyword with trailing newline, diff --git a/src/fileFormats/ensight/file/ensightGeoFile.C b/src/fileFormats/ensight/file/ensightGeoFile.C index 46ab3066ceb76aa0e63f56fe8366e923e658fccc..f5da0c33ca12ec4c79b4a9c6cc6044876161900b 100644 --- a/src/fileFormats/ensight/file/ensightGeoFile.C +++ b/src/fileFormats/ensight/file/ensightGeoFile.C @@ -34,23 +34,32 @@ License void Foam::ensightGeoFile::init() { writeBinaryHeader(); + beginGeometry(); +} + +void Foam::ensightGeoFile::beginGeometry() +{ // Description line 1 - write("Ensight Geometry File"); + writeString("Ensight Geometry File"); newline(); // Description line 2 - write(string("Written by OpenFOAM " + std::to_string(foamVersion::api))); + writeString("Written by OpenFOAM " + std::to_string(foamVersion::api)); newline(); - write("node id assign"); + writeString("node id assign"); newline(); - write("element id assign"); + writeString("element id assign"); newline(); } +void Foam::ensightGeoFile::endGeometry() +{} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::ensightGeoFile::ensightGeoFile @@ -96,7 +105,7 @@ Foam::Ostream& Foam::ensightGeoFile::writeKeyword(const keyType& key) void Foam::ensightGeoFile::beginPart ( const label index, - const string& description + const std::string& description ) { beginPart(index); diff --git a/src/fileFormats/ensight/file/ensightGeoFile.H b/src/fileFormats/ensight/file/ensightGeoFile.H index 9fbc12490226e9a754b3b92da55f769453fc0f35..86d2d9beed719e808e6d6d5ddcb952d238bfb178 100644 --- a/src/fileFormats/ensight/file/ensightGeoFile.H +++ b/src/fileFormats/ensight/file/ensightGeoFile.H @@ -52,16 +52,21 @@ class ensightGeoFile { // Private Member Functions - //- Initialize outputs the header information + //- Initialize outputs the header information and beginGeometry void init(); + //- Start of geometry information + void beginGeometry(); + + //- End of geometry information + void endGeometry(); + //- No copy construct ensightGeoFile(const ensightGeoFile&) = delete; //- No copy assignment void operator=(const ensightGeoFile&) = delete; - public: // Static Functions @@ -111,7 +116,7 @@ public: using ensightFile::beginPart; //- Begin a "part" (0-based index), with a description. - void beginPart(const label index, const string& description); + void beginPart(const label index, const std::string& description); //- Begin a "coordinates" block void beginCoordinates(const label npoints); diff --git a/src/functionObjects/utilities/ensightWrite/ensightWrite.C b/src/functionObjects/utilities/ensightWrite/ensightWrite.C index c25755e45befe32b64ca01c9a1c6115229a97a93..7b203564170df5688615e5eaa26b53c5588e13f5 100644 --- a/src/functionObjects/utilities/ensightWrite/ensightWrite.C +++ b/src/functionObjects/utilities/ensightWrite/ensightWrite.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2022 OpenCFD Ltd. + Copyright (C) 2016-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -97,10 +97,7 @@ Foam::functionObjects::ensightWrite::ensightWrite : fvMeshFunctionObject(name, runTime, dict), writeOpts_(), - caseOpts_ - ( - IOstreamOption::formatEnum("format", dict, runTime.writeFormat()) - ), + caseOpts_("format", dict, IOstreamOption::BINARY), outputDir_(), consecutive_(false), meshState_(polyMesh::TOPO_CHANGE), @@ -180,6 +177,9 @@ bool Foam::functionObjects::ensightWrite::read(const dictionary& dict) caseOpts_.width(dict.getOrDefault<label>("width", 8)); caseOpts_.overwrite(dict.getOrDefault("overwrite", false)); + caseOpts_.timeFormat("timeFormat", dict); + caseOpts_.timePrecision("timePrecision", dict); + // Output directory diff --git a/src/functionObjects/utilities/ensightWrite/ensightWrite.H b/src/functionObjects/utilities/ensightWrite/ensightWrite.H index c8dc1e3a5d169f877278d7686ce46345dad81ff9..3ba712be80c9e0a1bb6f94f5ea4afd8fcba125b9 100644 --- a/src/functionObjects/utilities/ensightWrite/ensightWrite.H +++ b/src/functionObjects/utilities/ensightWrite/ensightWrite.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2022 OpenCFD Ltd. + Copyright (C) 2016-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -42,6 +42,9 @@ Description writeInterval 1; format binary; + timeFormat scientific; + timePrecision 5; + overwrite true; width 12; @@ -95,11 +98,13 @@ Description \heading Ensight Output Options \table Property | Description | Required | Default - format | ascii or binary format | no | same as simulation + format | ascii or binary format | no | binary width | Mask width for \c data/XXXX | no | 8 directory | The output directory name | no | postProcessing/NAME overwrite | Remove existing directory | no | false consecutive | Consecutive output numbering | no | false + timeFormat | Time format (ensight case) | no | scientific + timePrecision | Time precision (ensight case) | no | 5 \endtable \heading Output Selection diff --git a/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriter.C b/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriter.C index 91b20276d3539c2dbae5dc29d37a9d73a51ef0d6..e32da21c519eff01f5e148fc9c7f3fa85905d8dc 100644 --- a/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriter.C +++ b/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriter.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2021-2022 OpenCFD Ltd. + Copyright (C) 2021-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -176,7 +176,7 @@ void Foam::coordSetWriters::ensightWriter::writeGeometry Foam::coordSetWriters::ensightWriter::ensightWriter() : coordSetWriter(), - writeFormat_(IOstreamOption::ASCII), + caseOpts_(IOstreamOption::BINARY), collateTimes_(true), caching_("fieldsDict") // Historic name {} @@ -185,13 +185,13 @@ Foam::coordSetWriters::ensightWriter::ensightWriter() Foam::coordSetWriters::ensightWriter::ensightWriter(const dictionary& options) : coordSetWriter(options), - writeFormat_ - ( - IOstreamOption::formatEnum("format", options, IOstreamOption::ASCII) - ), + caseOpts_("format", options, IOstreamOption::BINARY), collateTimes_(options.getOrDefault("collateTimes", true)), caching_("fieldsDict") // Historic name -{} +{ + caseOpts_.timeFormat("timeFormat", options); + caseOpts_.timePrecision("timePrecision", options); +} Foam::coordSetWriters::ensightWriter::ensightWriter diff --git a/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriter.H b/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriter.H index fc03292a6a60831aa4a81f691fb44fedcb5b25b9..28d53709060137fee1f4a8e927912e25669f1369 100644 --- a/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriter.H +++ b/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriter.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2021-2022 OpenCFD Ltd. + Copyright (C) 2021-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -44,8 +44,11 @@ Description Format options: \table Property | Description | Required | Default - format | ascii/binary | no | ascii + format | ascii/binary | no | binary collateTimes | use common geometry for times | no | true + timeFormat | Time format (ensight case) | no | scientific + timePrecision | Time precision (ensight case) | no | 5 + \endtable \endtable SourceFiles @@ -57,6 +60,7 @@ SourceFiles #define Foam_coordSetWriters_ensightWriter_H #include "coordSetWriter.H" +#include "ensightCase.H" #include "ensightWriterCaching.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -91,8 +95,8 @@ class ensightWriter // Private Data - //- Output format option (default: ASCII) - IOstreamOption::streamFormat writeFormat_; + //- Ensight case options + ensightCase::options caseOpts_; //- Collate times (default: true) bool collateTimes_; diff --git a/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterCollated.C b/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterCollated.C index c6babf60516bd11f71b9014dfdd04e544f08d4e0..3e378c2933c88909de956a47b6a132f2c0e05cd8 100644 --- a/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterCollated.C +++ b/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterCollated.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2022 OpenCFD Ltd. + Copyright (C) 2022-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -148,7 +148,7 @@ Foam::fileName Foam::coordSetWriters::ensightWriter::writeCollated ( geomFile.path(), geomFile.name(), - writeFormat_ + caseOpts_.format() ); writeGeometry(osGeom, elemOutput); @@ -160,7 +160,7 @@ Foam::fileName Foam::coordSetWriters::ensightWriter::writeCollated ( dataDir, varName, - writeFormat_ + caseOpts_.format() ); if (verbose_) @@ -177,11 +177,7 @@ Foam::fileName Foam::coordSetWriters::ensightWriter::writeCollated if (stateChanged) { OFstream osCase(outputFile, IOstreamOption::ASCII); - - // Format options - osCase.setf(ios_base::left); - osCase.setf(ios_base::scientific, ios_base::floatfield); - osCase.precision(5); + ensightCase::setTimeFormat(osCase, caseOpts_); // time-format if (verbose_) { diff --git a/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterUncollated.C b/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterUncollated.C index 1bfa2933f364a394aad7296307bd30efbcad2516..f4a56dcce842811bd05c9d9e6a91cfcc0c2285b1 100644 --- a/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterUncollated.C +++ b/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterUncollated.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2022 OpenCFD Ltd. + Copyright (C) 2022-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -101,13 +101,13 @@ Foam::fileName Foam::coordSetWriters::ensightWriter::writeUncollated ( baseDir, baseName + ".00000000.mesh", - writeFormat_ + caseOpts_.format() ); ensightFile osField ( baseDir, baseName + ".00000000." + varName, - writeFormat_ + caseOpts_.format() ); writeGeometry(osGeom, elemOutput); @@ -119,11 +119,7 @@ Foam::fileName Foam::coordSetWriters::ensightWriter::writeUncollated // Update case file { OFstream osCase(outputFile, IOstreamOption::ASCII); - - // Format options - osCase.setf(ios_base::left); - osCase.setf(ios_base::scientific, ios_base::floatfield); - osCase.precision(5); + ensightCase::setTimeFormat(osCase, caseOpts_); // time-format osCase << "FORMAT" << nl diff --git a/src/surfMesh/writers/ensight/ensightSurfaceWriter.C b/src/surfMesh/writers/ensight/ensightSurfaceWriter.C index 8cdcc1bd2f7a30198b2bedee1b9f13cb76c8f6d7..253ad3fa8f157112f1e59b14c180ab2c6ecf40b6 100644 --- a/src/surfMesh/writers/ensight/ensightSurfaceWriter.C +++ b/src/surfMesh/writers/ensight/ensightSurfaceWriter.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2014 OpenFOAM Foundation - Copyright (C) 2015-2022 OpenCFD Ltd. + Copyright (C) 2015-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -55,7 +55,7 @@ namespace surfaceWriters Foam::surfaceWriters::ensightWriter::ensightWriter() : surfaceWriter(), - writeFormat_(IOstreamOption::ASCII), + caseOpts_(IOstreamOption::BINARY), collateTimes_(true), caching_("fieldsDict") // Historic name {} @@ -67,13 +67,13 @@ Foam::surfaceWriters::ensightWriter::ensightWriter ) : surfaceWriter(options), - writeFormat_ - ( - IOstreamOption::formatEnum("format", options, IOstreamOption::ASCII) - ), + caseOpts_("format", options, IOstreamOption::BINARY), collateTimes_(options.getOrDefault("collateTimes", true)), caching_("fieldsDict") // Historic name -{} +{ + caseOpts_.timeFormat("timeFormat", options); + caseOpts_.timePrecision("timePrecision", options); +} Foam::surfaceWriters::ensightWriter::ensightWriter diff --git a/src/surfMesh/writers/ensight/ensightSurfaceWriter.H b/src/surfMesh/writers/ensight/ensightSurfaceWriter.H index e0c3a4b3166b400322dcd36fabdbe30ca3940cd6..1fc8e1844043ed897e84cd8f602112192d420620 100644 --- a/src/surfMesh/writers/ensight/ensightSurfaceWriter.H +++ b/src/surfMesh/writers/ensight/ensightSurfaceWriter.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011 OpenFOAM Foundation - Copyright (C) 2015-2022 OpenCFD Ltd. + Copyright (C) 2015-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -44,12 +44,14 @@ Description Format options for ensight: \table Property | Description | Required | Default - format | ascii/binary | no | ascii + format | ascii/binary | no | binary collateTimes | Use common geometry for times | no | true scale | Output geometry scaling | no | 1 transform | Output coordinate transform | no | fieldLevel | Subtract field level before scaling | no | empty dict fieldScale | Output field scaling | no | empty dict + timeFormat | Time format (ensight case) | no | scientific + timePrecision | Time precision (ensight case) | no | 5 \endtable The collated format maintains an internal list of the known times @@ -65,6 +67,7 @@ SourceFiles #define Foam_surfaceWriters_ensightWriter_H #include "surfaceWriter.H" +#include "ensightCase.H" #include "ensightWriterCaching.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -84,8 +87,8 @@ class ensightWriter { // Private Data - //- Output format option (default: ASCII) - IOstreamOption::streamFormat writeFormat_; + //- Ensight case options + ensightCase::options caseOpts_; //- Collate times (default: true) bool collateTimes_; diff --git a/src/surfMesh/writers/ensight/ensightSurfaceWriterCollated.C b/src/surfMesh/writers/ensight/ensightSurfaceWriterCollated.C index 378ee23109b9c9f291e126d85f415b90e9ce2d89..1d5595564ec992bcb34af0bf46ba573d0dbf1bdd 100644 --- a/src/surfMesh/writers/ensight/ensightSurfaceWriterCollated.C +++ b/src/surfMesh/writers/ensight/ensightSurfaceWriterCollated.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2014 OpenFOAM Foundation - Copyright (C) 2015-2022 OpenCFD Ltd. + Copyright (C) 2015-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -163,7 +163,7 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated ( geomFile.path(), geomFile.name(), - writeFormat_ + caseOpts_.format() ); part.write(osGeom); // serial } @@ -173,7 +173,7 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated ( dataDir, varName, - writeFormat_ + caseOpts_.format() ); if (verbose_) @@ -191,11 +191,7 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated if (stateChanged) { OFstream osCase(outputFile, IOstreamOption::ASCII); - - // Format options - osCase.setf(ios_base::left); - osCase.setf(ios_base::scientific, ios_base::floatfield); - osCase.precision(5); + ensightCase::setTimeFormat(osCase, caseOpts_); // time-format if (verbose_) { diff --git a/src/surfMesh/writers/ensight/ensightSurfaceWriterUncollated.C b/src/surfMesh/writers/ensight/ensightSurfaceWriterUncollated.C index 6e1f65f682a8acea0da26eed5f253b73d3bfa3e6..27f5e9e6d51246acc9a415bfb9dd8499516175f8 100644 --- a/src/surfMesh/writers/ensight/ensightSurfaceWriterUncollated.C +++ b/src/surfMesh/writers/ensight/ensightSurfaceWriterUncollated.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2014 OpenFOAM Foundation - Copyright (C) 2015-2022 OpenCFD Ltd. + Copyright (C) 2015-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -73,7 +73,7 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated() ( outputDir, baseName + ".00000000.mesh", - writeFormat_ + caseOpts_.format() ); ensightOutputSurface part @@ -85,7 +85,9 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated() part.write(osGeom); // serial // Update case file - OFstream osCase(outputFile); + OFstream osCase(outputFile, IOstreamOption::ASCII); + ensightCase::setTimeFormat(osCase, caseOpts_); // time-format + osCase << "FORMAT" << nl << "type: ensight gold" << nl @@ -176,13 +178,13 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated ( baseDir, baseName + ".00000000.mesh", - writeFormat_ + caseOpts_.format() ); ensightFile osField ( baseDir, baseName + ".00000000." + varName, - writeFormat_ + caseOpts_.format() ); // Ensight Geometry @@ -203,11 +205,7 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated // Update case file { OFstream osCase(outputFile, IOstreamOption::ASCII); - - // Format options - osCase.setf(ios_base::left); - osCase.setf(ios_base::scientific, ios_base::floatfield); - osCase.precision(5); + ensightCase::setTimeFormat(osCase, caseOpts_); // time-format osCase << "FORMAT" << nl