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.
This commit is contained in:
Mark Olesen 2018-05-08 08:15:31 +02:00
parent 2f567e53de
commit dbe16de58c
4 changed files with 104 additions and 64 deletions

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd. \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -171,9 +171,9 @@ Foam::scalar Foam::ensightCase::writeTimeset() const
<< "filename numbers:" << nl; << "filename numbers:" << nl;
count = 0; count = 0;
forAll(indices, idx) for (const label idx : indices)
{ {
*os_ << " " << setw(12) << indices[idx]; *os_ << ' ' << setw(12) << idx;
if (++count % 6 == 0) if (++count % 6 == 0)
{ {
@ -191,9 +191,9 @@ Foam::scalar Foam::ensightCase::writeTimeset() const
*os_ << "time values:" << nl; *os_ << "time values:" << nl;
count = 0; 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) if (++count % 6 == 0)
{ {
@ -220,7 +220,7 @@ void Foam::ensightCase::writeTimeset
labelHashSet hashed(lookup); labelHashSet hashed(lookup);
hashed.erase(-1); hashed.erase(-1);
const labelList indices = hashed.sortedToc(); const labelList indices(hashed.sortedToc());
label count = indices.size(); label count = indices.size();
*os_ *os_
@ -229,9 +229,9 @@ void Foam::ensightCase::writeTimeset
<< "filename numbers:" << nl; << "filename numbers:" << nl;
count = 0; count = 0;
forAll(indices, idx) for (const label idx : indices)
{ {
*os_ << " " << setw(12) << indices[idx]; *os_ << ' ' << setw(12) << idx;
if (++count % 6 == 0) if (++count % 6 == 0)
{ {
@ -247,9 +247,9 @@ void Foam::ensightCase::writeTimeset
*os_ << "time values:" << nl; *os_ << "time values:" << nl;
count = 0; 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) if (++count % 6 == 0)
{ {
@ -333,19 +333,17 @@ Foam::ensightCase::createDataFile
const word& name const word& name
) const ) const
{ {
autoPtr<ensightFile> output;
if (Pstream::master()) 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 // Note that data/ITER is indeed a valid ensight::FileName
const fileName outdir = dataDir()/padded(timeIndex_); const fileName outdir = dataDir()/padded(timeIndex_);
mkDir(outdir); mkDir(outdir);
output.reset(new ensightFile(outdir, name, format())); return autoPtr<ensightFile>::New(outdir, name, format());
} }
return output; return nullptr;
} }
@ -356,8 +354,6 @@ Foam::ensightCase::createCloudFile
const word& name const word& name
) const ) const
{ {
autoPtr<Foam::ensightFile> output;
if (Pstream::master()) if (Pstream::master())
{ {
// Write // Write
@ -373,10 +369,10 @@ Foam::ensightCase::createCloudFile
mkDir(outdir); // should be unnecessary after newCloud() mkDir(outdir); // should be unnecessary after newCloud()
output.reset(new ensightFile(outdir, name, format())); return autoPtr<ensightFile>::New(outdir, name, format());
} }
return output; return nullptr;
} }
@ -490,7 +486,7 @@ void Foam::ensightCase::write() const
if (!os_) return; // master only if (!os_) return; // master only
// geometry timeset // 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_); label tsGeom = staticGeom ? 0 : checkTimeset(geomTimes_);
// cloud timeset // cloud timeset
@ -684,12 +680,12 @@ Foam::ensightCase::newGeometry
path = ensightDir_; path = ensightDir_;
} }
output.reset(new ensightGeoFile(path, geometryName, format()));
noteGeometry(moving); // note for later use noteGeometry(moving); // note for later use
return autoPtr<ensightGeoFile>::New(path, geometryName, format());
} }
return output; return nullptr;
} }

View File

@ -183,16 +183,15 @@ private:
) const; ) const;
//- Disallow default bitwise copy construct //- No copy construct
ensightCase(const ensightCase&) = delete; ensightCase(const ensightCase&) = delete;
//- Disallow default bitwise assignment //- No copy assignment
void operator=(const ensightCase&) = delete; void operator=(const ensightCase&) = delete;
public: public:
// Constructors // Constructors
//- Construct from components //- Construct from components

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd. \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -37,7 +37,7 @@ Foam::ensightCase::options::options(IOstream::streamFormat format)
nodeValues_(false), nodeValues_(false),
separateCloud_(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<int>(i)); ::snprintf(buf, 32, printf_.c_str(), static_cast<int>(i));
buf[31] = 0; buf[31] = 0;
// no stripping required // No stripping required
return word(buf, false); return word(buf, false);
} }
@ -76,16 +76,16 @@ Foam::label Foam::ensightCase::options::width() const
void Foam::ensightCase::options::width(const label n) void Foam::ensightCase::options::width(const label n)
{ {
// enforce min/max sanity limits // Enforce min/max sanity limits
if (n < 1 || n > 31) if (n < 1 || n > 31)
{ {
return; return;
} }
// set mask accordingly // Set mask accordingly
mask_.resize(n, '*'); mask_.resize(n, '*');
// appropriate printf format // Appropriate printf format
printf_ = "%0" + std::to_string(n) + "d"; printf_ = "%0" + std::to_string(n) + "d";
} }

View File

@ -26,6 +26,7 @@ License
#include "IOmanip.H" #include "IOmanip.H"
#include "Fstream.H" #include "Fstream.H"
#include "OSspecific.H" #include "OSspecific.H"
#include "ensightCase.H"
#include "ensightPartFaces.H" #include "ensightPartFaces.H"
#include "ensightSerialOutput.H" #include "ensightSerialOutput.H"
#include "ensightPTraits.H" #include "ensightPTraits.H"
@ -69,7 +70,13 @@ Foam::fileName Foam::ensightSurfaceWriter::writeUncollated
mkDir(baseDir); 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 ensightGeoFile osGeom
( (
baseDir, baseDir,
@ -103,14 +110,17 @@ Foam::fileName Foam::ensightSurfaceWriter::writeUncollated
? " per node: 1 " // time-set 1 ? " per node: 1 " // time-set 1
: " per element: 1 " // time-set 1 : " per element: 1 " // time-set 1
) )
<< setw(15) << varName << setw(15) << varName << ' '
<< " " << surfName.c_str() << ".********." << varName << nl << surfName.c_str() << ".********." << varName << nl;
osCase
<< nl << nl
<< "TIME" << nl; << "TIME" << nl;
printTimeset(osCase, 1, timeValue); printTimeset(osCase, 1, timeValue);
osCase << "# end" << nl; osCase << "# end" << nl;
ensightPartFaces ensPart ensightPartFaces ensPart
( (
0, 0,
@ -153,14 +163,18 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated
// use surface name as sub-directory for results // use surface name as sub-directory for results
// eg, something like this: // eg, something like this:
// - SURF1/SURF1.case // - SURF1/SURF1.case
// - SURF1/SURF1.0000.mesh // - SURF1/SURF1/data/00000000/geometry
// - SURF1/SURF1/data/0000/VAR1 // - SURF1/SURF1/data/00000000/VAR1
// - SURF1/SURF1/data/0000/VAR2 // - SURF1/SURF1/data/00000000/VAR2
// and // and
// - SURF2/SURF2.case // - SURF2/SURF2.case
// - SURF2/SURF2.0000.mesh // - SURF2/SURF2/data/00000000/geometry
// - SURF2/SURF2/data/0000/VAR1 // - SURF2/SURF2/data/00000000/VAR1
// - SURF2/SURF2/data/0000/VAR2 // - 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 baseDir = outputDir.path()/surfName;
const fileName timeDir = outputDir.name(); const fileName timeDir = outputDir.name();
@ -172,9 +186,10 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated
mkDir(baseDir); mkDir(baseDir);
} }
label meshIndex = 0, timeIndex = 0; label meshIndex = 0;
label timeIndex = 0;
fileName meshFile; fileName geometryName;
// Do case file // Do case file
{ {
@ -228,11 +243,8 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated
meshes[meshIndex] = meshValue; meshes[meshIndex] = meshValue;
times[timeIndex] = timeValue; times[timeIndex] = timeValue;
// surfName already validated geometryName =
meshFile = "data"/word::printf(fmt, meshIndex)/ensightCase::geometryName;
(
baseDir/"data"/word::printf("%06d", meshIndex)/"geometry"
);
// Add my information to dictionary // Add my information to dictionary
@ -281,20 +293,49 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated
dict.write(os, false); 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) if (verbose)
{ {
Info<< "Writing case file to " << osCase.name() << endl; 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 osCase
<< "FORMAT" << nl << "FORMAT" << nl
<< "type: ensight gold" << nl << "type: ensight gold" << nl
<< nl << nl
<< "GEOMETRY" << nl << "GEOMETRY" << nl;
<< "model: 2 " // time-set 2
<< " data/******/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 << nl
<< "VARIABLE" << nl; << "VARIABLE" << nl;
@ -317,23 +358,34 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated
? " per node: 1 " // time-set 1 ? " per node: 1 " // time-set 1
: " per element: 1 " // time-set 1 : " per element: 1 " // time-set 1
) )
<< setw(15) << varName << setw(15) << varName << ' '
<< " data/******/" << varName << mask << varName << nl;
<< nl;
} }
osCase << nl;
osCase osCase
<< nl
<< "TIME" << nl; << "TIME" << nl;
printTimeset(osCase, 1, times); printTimeset(osCase, 1, times);
if (tsGeom == 2)
{
printTimeset(osCase, 2, meshes); printTimeset(osCase, 2, meshes);
}
osCase << "# end" << nl; 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 // Write geometry
ensightPartFaces ensPart ensightPartFaces ensPart
( (
@ -354,13 +406,6 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated
osGeom << ensPart; osGeom << ensPart;
} }
// Location for data
fileName dataDir = baseDir/"data"/word::printf("%06d", timeIndex);
// As per mkdir -p "data/000000"
mkDir(dataDir);
// Write field // Write field
ensightFile osField ensightFile osField
( (