From dbe16de58c6256daa01246d005b9ab44508b4db4 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Tue, 8 May 2018 08:15:31 +0200 Subject: [PATCH] ENH: cleaner, more consistent ensight case surface output files - use same data mask width as ensightCase (8 digits) - consolidate geometry time steps with data time steps if possible, for a cleaner case file. --- src/fileFormats/ensight/file/ensightCase.C | 42 +++---- src/fileFormats/ensight/file/ensightCase.H | 5 +- .../ensight/file/ensightCaseOptions.C | 12 +- .../ensight/ensightSurfaceWriterTemplates.C | 109 +++++++++++++----- 4 files changed, 104 insertions(+), 64 deletions(-) diff --git a/src/fileFormats/ensight/file/ensightCase.C b/src/fileFormats/ensight/file/ensightCase.C index 2338cfbf0d..8eb5b324a3 100644 --- a/src/fileFormats/ensight/file/ensightCase.C +++ b/src/fileFormats/ensight/file/ensightCase.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -171,9 +171,9 @@ Foam::scalar Foam::ensightCase::writeTimeset() const << "filename numbers:" << nl; count = 0; - forAll(indices, idx) + for (const label idx : indices) { - *os_ << " " << setw(12) << indices[idx]; + *os_ << ' ' << setw(12) << idx; if (++count % 6 == 0) { @@ -191,9 +191,9 @@ Foam::scalar Foam::ensightCase::writeTimeset() const *os_ << "time values:" << nl; count = 0; - forAll(indices, idx) + for (const label idx : indices) { - *os_ << " " << setw(12) << timesUsed_[indices[idx]] + timeCorrection; + *os_ << ' ' << setw(12) << timesUsed_[idx] + timeCorrection; if (++count % 6 == 0) { @@ -220,7 +220,7 @@ void Foam::ensightCase::writeTimeset labelHashSet hashed(lookup); hashed.erase(-1); - const labelList indices = hashed.sortedToc(); + const labelList indices(hashed.sortedToc()); label count = indices.size(); *os_ @@ -229,9 +229,9 @@ void Foam::ensightCase::writeTimeset << "filename numbers:" << nl; count = 0; - forAll(indices, idx) + for (const label idx : indices) { - *os_ << " " << setw(12) << indices[idx]; + *os_ << ' ' << setw(12) << idx; if (++count % 6 == 0) { @@ -247,9 +247,9 @@ void Foam::ensightCase::writeTimeset *os_ << "time values:" << nl; count = 0; - forAll(indices, idx) + for (const label idx : indices) { - *os_ << " " << setw(12) << timesUsed_[indices[idx]] + timeCorrection; + *os_ << ' ' << setw(12) << timesUsed_[idx] + timeCorrection; if (++count % 6 == 0) { @@ -333,19 +333,17 @@ Foam::ensightCase::createDataFile const word& name ) const { - autoPtr output; - if (Pstream::master()) { - // the data/ITER subdirectory must exist + // The data/ITER subdirectory must exist // Note that data/ITER is indeed a valid ensight::FileName const fileName outdir = dataDir()/padded(timeIndex_); mkDir(outdir); - output.reset(new ensightFile(outdir, name, format())); + return autoPtr::New(outdir, name, format()); } - return output; + return nullptr; } @@ -356,8 +354,6 @@ Foam::ensightCase::createCloudFile const word& name ) const { - autoPtr output; - if (Pstream::master()) { // Write @@ -373,10 +369,10 @@ Foam::ensightCase::createCloudFile mkDir(outdir); // should be unnecessary after newCloud() - output.reset(new ensightFile(outdir, name, format())); + return autoPtr::New(outdir, name, format()); } - return output; + return nullptr; } @@ -490,7 +486,7 @@ void Foam::ensightCase::write() const if (!os_) return; // master only // geometry timeset - bool staticGeom = (geomTimes_.size() == 1 && geomTimes_.found(-1)); + const bool staticGeom = (geomTimes_.size() == 1 && geomTimes_.found(-1)); label tsGeom = staticGeom ? 0 : checkTimeset(geomTimes_); // cloud timeset @@ -684,12 +680,12 @@ Foam::ensightCase::newGeometry path = ensightDir_; } - output.reset(new ensightGeoFile(path, geometryName, format())); - noteGeometry(moving); // note for later use + + return autoPtr::New(path, geometryName, format()); } - return output; + return nullptr; } diff --git a/src/fileFormats/ensight/file/ensightCase.H b/src/fileFormats/ensight/file/ensightCase.H index 1b516eed0a..b96184d812 100644 --- a/src/fileFormats/ensight/file/ensightCase.H +++ b/src/fileFormats/ensight/file/ensightCase.H @@ -183,16 +183,15 @@ private: ) const; - //- Disallow default bitwise copy construct + //- No copy construct ensightCase(const ensightCase&) = delete; - //- Disallow default bitwise assignment + //- No copy assignment void operator=(const ensightCase&) = delete; public: - // Constructors //- Construct from components diff --git a/src/fileFormats/ensight/file/ensightCaseOptions.C b/src/fileFormats/ensight/file/ensightCaseOptions.C index 20eb42fce9..7449185551 100644 --- a/src/fileFormats/ensight/file/ensightCaseOptions.C +++ b/src/fileFormats/ensight/file/ensightCaseOptions.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -37,7 +37,7 @@ Foam::ensightCase::options::options(IOstream::streamFormat format) nodeValues_(false), separateCloud_(false) { - width(8); // ensures that the mask and printf-format are also resized + width(8); // Ensures that mask and printf-format are properly resized } @@ -63,7 +63,7 @@ Foam::word Foam::ensightCase::options::padded(const label i) const ::snprintf(buf, 32, printf_.c_str(), static_cast(i)); buf[31] = 0; - // no stripping required + // No stripping required return word(buf, false); } @@ -76,16 +76,16 @@ Foam::label Foam::ensightCase::options::width() const void Foam::ensightCase::options::width(const label n) { - // enforce min/max sanity limits + // Enforce min/max sanity limits if (n < 1 || n > 31) { return; } - // set mask accordingly + // Set mask accordingly mask_.resize(n, '*'); - // appropriate printf format + // Appropriate printf format printf_ = "%0" + std::to_string(n) + "d"; } diff --git a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C index f04011fe01..4036ab8cb6 100644 --- a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C +++ b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C @@ -26,6 +26,7 @@ License #include "IOmanip.H" #include "Fstream.H" #include "OSspecific.H" +#include "ensightCase.H" #include "ensightPartFaces.H" #include "ensightSerialOutput.H" #include "ensightPTraits.H" @@ -69,7 +70,13 @@ Foam::fileName Foam::ensightSurfaceWriter::writeUncollated mkDir(baseDir); } - OFstream osCase(baseDir/surfName + ".case"); + OFstream osCase(baseDir/surfName + ".case", IOstream::ASCII); + + // Format options + osCase.setf(ios_base::left); + osCase.setf(ios_base::scientific, ios_base::floatfield); + osCase.precision(5); + ensightGeoFile osGeom ( baseDir, @@ -103,14 +110,17 @@ Foam::fileName Foam::ensightSurfaceWriter::writeUncollated ? " per node: 1 " // time-set 1 : " per element: 1 " // time-set 1 ) - << setw(15) << varName - << " " << surfName.c_str() << ".********." << varName << nl + << setw(15) << varName << ' ' + << surfName.c_str() << ".********." << varName << nl; + + osCase << nl << "TIME" << nl; printTimeset(osCase, 1, timeValue); osCase << "# end" << nl; + ensightPartFaces ensPart ( 0, @@ -153,14 +163,18 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated // use surface name as sub-directory for results // eg, something like this: // - SURF1/SURF1.case - // - SURF1/SURF1.0000.mesh - // - SURF1/SURF1/data/0000/VAR1 - // - SURF1/SURF1/data/0000/VAR2 + // - SURF1/SURF1/data/00000000/geometry + // - SURF1/SURF1/data/00000000/VAR1 + // - SURF1/SURF1/data/00000000/VAR2 // and // - SURF2/SURF2.case - // - SURF2/SURF2.0000.mesh - // - SURF2/SURF2/data/0000/VAR1 - // - SURF2/SURF2/data/0000/VAR2 + // - SURF2/SURF2/data/00000000/geometry + // - SURF2/SURF2/data/00000000/VAR1 + // - SURF2/SURF2/data/00000000/VAR2 + + // Names "data" and "geometry" as per ensightCase: + const char* fmt = "%08d"; + const char* mask = "data/********/"; const fileName baseDir = outputDir.path()/surfName; const fileName timeDir = outputDir.name(); @@ -172,9 +186,10 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated mkDir(baseDir); } - label meshIndex = 0, timeIndex = 0; + label meshIndex = 0; + label timeIndex = 0; - fileName meshFile; + fileName geometryName; // Do case file { @@ -228,11 +243,8 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated meshes[meshIndex] = meshValue; times[timeIndex] = timeValue; - // surfName already validated - meshFile = - ( - baseDir/"data"/word::printf("%06d", meshIndex)/"geometry" - ); + geometryName = + "data"/word::printf(fmt, meshIndex)/ensightCase::geometryName; // Add my information to dictionary @@ -281,20 +293,49 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated dict.write(os, false); } - OFstream osCase(baseDir/surfName + ".case"); + OFstream osCase(baseDir/surfName + ".case", IOstream::ASCII); + + // Format options + osCase.setf(ios_base::left); + osCase.setf(ios_base::scientific, ios_base::floatfield); + osCase.precision(5); if (verbose) { Info<< "Writing case file to " << osCase.name() << endl; } + // The geometry can be any of the following: + // 0: constant/static + // 1: moving, with the same frequency as the data + // 2: moving, with different frequency as the data + + const label tsGeom = + (meshes.size() == 1 ? 0 : meshes == times ? 1 : 2); + osCase << "FORMAT" << nl << "type: ensight gold" << nl << nl - << "GEOMETRY" << nl - << "model: 2 " // time-set 2 - << " data/******/geometry" << nl + << "GEOMETRY" << nl; + + + if (tsGeom) + { + // moving + osCase + << "model: " << tsGeom << " " // time-set (1|2) + << mask << geometryName.name() << nl; + } + else + { + // steady + osCase + << "model: " + << geometryName.c_str() << nl; + } + + osCase << nl << "VARIABLE" << nl; @@ -317,23 +358,34 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated ? " per node: 1 " // time-set 1 : " per element: 1 " // time-set 1 ) - << setw(15) << varName - << " data/******/" << varName - << nl; + << setw(15) << varName << ' ' + << mask << varName << nl; } - osCase << nl; osCase + << nl << "TIME" << nl; printTimeset(osCase, 1, times); - printTimeset(osCase, 2, meshes); + if (tsGeom == 2) + { + printTimeset(osCase, 2, meshes); + } osCase << "# end" << nl; } } + // Location for data (and possibly the geometry as well) + fileName dataDir = baseDir/"data"/word::printf(fmt, timeIndex); + + // As per mkdir -p "data/00000000" + mkDir(dataDir); + + + const fileName meshFile(baseDir/geometryName); + // Write geometry ensightPartFaces ensPart ( @@ -354,13 +406,6 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated osGeom << ensPart; } - - // Location for data - fileName dataDir = baseDir/"data"/word::printf("%06d", timeIndex); - - // As per mkdir -p "data/000000" - mkDir(dataDir); - // Write field ensightFile osField (