BUG: incorrect ensight filename references (fixes #2532)

- Ensight places restrictions both on variable names and on file
  names. When generating the variable to file name correspondence for
  use in the Ensight case file, previously used the less stringent
  variable name for both sides of the variable table.

  This would lead to situations where the (valid) variable name
  referred to the wrong file name. Now apply the file-name restriction
  consistently when creating the variable table. This is especially
  necessary since the stem of the filename additionally has
  specific characters (eg, ":<>[]") that can be problematic for the
  shell or file-system.

ENH: avoid repeated '_' in qualified ensight names.

- when replacing undesirable characters (eg, ":<>[]") with '_', avoid
  duplicates.

  Eg, "PaSR<psiReactionThermo>:Qdot" becomes
      "PaSR_psiReactionThermo_Qdot" instead of
      "PaSR_psiReactionThermo__Qdot"

ENH: additional ensightCase::padded static method
This commit is contained in:
Mark Olesen
2022-07-11 15:25:11 +02:00
parent d222cb1cee
commit 1afd27db6c
9 changed files with 57 additions and 21 deletions

View File

@ -31,6 +31,8 @@ License
#include "cloud.H"
#include "IOmanip.H"
#include "OSstream.H"
#include <iomanip>
#include <sstream>
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -40,6 +42,20 @@ const char* Foam::ensightCase::geometryName = "geometry";
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::word Foam::ensightCase::padded(const int nwidth, const label value)
{
if (nwidth < 1)
{
return Foam::name(value);
}
std::ostringstream oss;
oss << std::setfill('0') << std::setw(nwidth) << value;
return word(oss.str(), false); // stripping=false
}
void Foam::ensightCase::printTimeset
(
OSstream& os,
@ -456,6 +472,7 @@ Foam::ensightCase::createDataFile
{
// The data/ITER subdirectory must exist
// Note that data/ITER is indeed a valid ensight::FileName
const fileName outdir = dataDir()/padded(timeIndex_);
mkDir(outdir);
@ -698,9 +715,9 @@ void Foam::ensightCase::write() const
// Field variables (always use timeset 1)
const wordList varNames(variables_.sortedToc());
// NB: The output file name is stricter than the variable name
for (const word& varName : varNames)
for (const word& varName : variables_.sortedToc())
{
const string& ensType = variables_[varName];
@ -713,7 +730,7 @@ void Foam::ensightCase::write() const
: " per element: 1 " // time-set 1
)
<< setw(15) << varName << ' '
<< (dataMask/varName).c_str() << nl;
<< (dataMask/ensight::FileName(varName)).c_str() << nl;
}
@ -721,6 +738,7 @@ void Foam::ensightCase::write() const
// Write
// as -> "data/********/lagrangian/<cloudName>/positions"
// or -> "lagrangian/<cloudName>/********/positions"
// NB: The output file name is stricter than the variable name
label cloudNo = 0;
for (const word& cloudName : cloudNames)
@ -744,8 +762,7 @@ void Foam::ensightCase::write() const
<< word::printf("measured node: %-5d", tsCloud) // width 20
<< setw(15)
<< ("c" + Foam::name(cloudNo) + varName).c_str() << ' '
<< (masked/varName).c_str()
<< nl;
<< (masked/ensight::FileName(varName)).c_str() << nl;
}
++cloudNo;

View File

@ -226,6 +226,12 @@ public:
~ensightCase() = default;
// Static Functions
//- Stringified zero-padded integer value
static word padded(const int nwidth, const label value);
// Member Functions
// Access

View File

@ -90,7 +90,7 @@ Foam::ensightCase::newCloudData
const word& name
) const
{
autoPtr<Foam::ensightFile> output;
autoPtr<ensightFile> output;
if (Pstream::master())
{

View File

@ -101,7 +101,7 @@ public:
// Constructors
//- Construct from pathName.
// The entire pathName is checked for valid ensight naming.
// The entire pathName is adjusted for valid ensight file naming.
explicit ensightFile
(
const fileName& pathname,
@ -109,7 +109,7 @@ public:
);
//- Construct from path and name.
// Only the name portion is checked for valid ensight naming.
// Only the name portion is adjusted for valid ensight file naming.
ensightFile
(
const fileName& path,

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2020 OpenCFD Ltd.
Copyright (C) 2016-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -61,11 +61,13 @@ inline bool Foam::ensight::FileName::valid(char c)
inline void Foam::ensight::FileName::stripInvalid()
{
string::stripInvalid<FileName>(*this);
string::stripInvalid<ensight::FileName>(*this);
// Avoid characters that upset Windows or others
string::replaceAny(":<>[]", '_');
removeRepeated('_');
// Minor cleanup of fileName
removeRepeated('/');
removeEnd('/');

View File

@ -72,7 +72,7 @@ Foam::fileName Foam::coordSetWriters::ensightWriter::writeCollated
// - NAME1/data/00000000/VAR2
// Names "data" and "geometry" as per ensightCase:
const char* fmt = "%08d";
const int maskWidth = 8;
const char* mask = "data/********/";
// Ignore the useTimeDir setting - manage ourselves
@ -118,12 +118,17 @@ Foam::fileName Foam::coordSetWriters::ensightWriter::writeCollated
// or just the masking part for moving geometries.
const fileName geometryName
(
"data"/word::printf(fmt, geomIndex)/ensightCase::geometryName
"data"
/ ensightCase::padded(maskWidth, geomIndex)
/ ensightCase::geometryName
);
// Location for data (and possibly the geometry as well)
fileName dataDir = baseDir/"data"/word::printf(fmt, timeIndex);
const fileName dataDir
(
baseDir/"data"/ensightCase::padded(maskWidth, timeIndex)
);
// As per mkdir -p "data/00000000"
mkDir(dataDir);
@ -240,7 +245,7 @@ Foam::fileName Foam::coordSetWriters::ensightWriter::writeCollated
: " per element: 1 " // time-set 1
)
<< setw(15) << varName << ' '
<< mask << varName << nl;
<< mask << ensight::FileName(varName).c_str() << nl;
}
osCase

View File

@ -90,7 +90,6 @@ Foam::fileName Foam::coordSetWriters::ensightWriter::writeUncollated
merge();
{
if (!isDir(outputFile.path()))
{
@ -142,7 +141,8 @@ Foam::fileName Foam::coordSetWriters::ensightWriter::writeUncollated
: " per element: 1 " // time-set 1
)
<< setw(15) << varName << ' '
<< baseName.c_str() << ".********." << varName << nl;
<< baseName.c_str() << ".********."
<< ensight::FileName(varName).c_str() << nl;
osCase
<< nl

View File

@ -69,7 +69,7 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated
// - SURF1/data/00000000/VAR2
// Names "data" and "geometry" as per ensightCase:
const char* fmt = "%08d";
const int maskWidth = 8;
const char* mask = "data/********/";
@ -125,12 +125,17 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated
// or just the masking part for moving geometries.
const fileName geometryName
(
"data"/word::printf(fmt, geomIndex)/ensightCase::geometryName
"data"
/ ensightCase::padded(maskWidth, geomIndex)
/ ensightCase::geometryName
);
// Location for data (and possibly the geometry as well)
fileName dataDir = baseDir/"data"/word::printf(fmt, timeIndex);
const fileName dataDir
(
baseDir/"data"/ensightCase::padded(maskWidth, timeIndex)
);
// As per mkdir -p "data/00000000"
mkDir(dataDir);
@ -253,7 +258,7 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated
: " per element: 1 " // time-set 1
)
<< setw(15) << varName << ' '
<< mask << varName << nl;
<< mask << ensight::FileName(varName).c_str() << nl;
}
osCase

View File

@ -224,7 +224,8 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated
: " per element: 1 " // time-set 1
)
<< setw(15) << varName << ' '
<< baseName.c_str() << ".********." << varName << nl;
<< baseName.c_str() << ".********."
<< ensight::FileName(varName).c_str() << nl;
osCase
<< nl