From 1afd27db6c13cf41fd706d4e2b461d91d1eea22a Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Mon, 11 Jul 2022 15:25:11 +0200 Subject: [PATCH] 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:Qdot" becomes "PaSR_psiReactionThermo_Qdot" instead of "PaSR_psiReactionThermo__Qdot" ENH: additional ensightCase::padded static method --- src/fileFormats/ensight/file/ensightCase.C | 27 +++++++++++++++---- src/fileFormats/ensight/file/ensightCase.H | 6 +++++ .../ensight/file/ensightCaseTemplates.C | 2 +- src/fileFormats/ensight/file/ensightFile.H | 4 +-- .../ensight/name/ensightFileNameI.H | 6 +++-- .../ensight/ensightCoordSetWriterCollated.C | 13 ++++++--- .../ensight/ensightCoordSetWriterUncollated.C | 4 +-- .../ensight/ensightSurfaceWriterCollated.C | 13 ++++++--- .../ensight/ensightSurfaceWriterUncollated.C | 3 ++- 9 files changed, 57 insertions(+), 21 deletions(-) diff --git a/src/fileFormats/ensight/file/ensightCase.C b/src/fileFormats/ensight/file/ensightCase.C index 66af71b5b6..91c97333cf 100644 --- a/src/fileFormats/ensight/file/ensightCase.C +++ b/src/fileFormats/ensight/file/ensightCase.C @@ -31,6 +31,8 @@ License #include "cloud.H" #include "IOmanip.H" #include "OSstream.H" +#include +#include // * * * * * * * * * * * * * * 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//positions" // or -> "lagrangian//********/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; diff --git a/src/fileFormats/ensight/file/ensightCase.H b/src/fileFormats/ensight/file/ensightCase.H index dbdb306266..0e390d2629 100644 --- a/src/fileFormats/ensight/file/ensightCase.H +++ b/src/fileFormats/ensight/file/ensightCase.H @@ -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 diff --git a/src/fileFormats/ensight/file/ensightCaseTemplates.C b/src/fileFormats/ensight/file/ensightCaseTemplates.C index 5cbadf5388..309c9d70aa 100644 --- a/src/fileFormats/ensight/file/ensightCaseTemplates.C +++ b/src/fileFormats/ensight/file/ensightCaseTemplates.C @@ -90,7 +90,7 @@ Foam::ensightCase::newCloudData const word& name ) const { - autoPtr output; + autoPtr output; if (Pstream::master()) { diff --git a/src/fileFormats/ensight/file/ensightFile.H b/src/fileFormats/ensight/file/ensightFile.H index 71ee812bde..4a7145b394 100644 --- a/src/fileFormats/ensight/file/ensightFile.H +++ b/src/fileFormats/ensight/file/ensightFile.H @@ -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, diff --git a/src/fileFormats/ensight/name/ensightFileNameI.H b/src/fileFormats/ensight/name/ensightFileNameI.H index 6cf6f48135..193c546eb0 100644 --- a/src/fileFormats/ensight/name/ensightFileNameI.H +++ b/src/fileFormats/ensight/name/ensightFileNameI.H @@ -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(*this); + string::stripInvalid(*this); // Avoid characters that upset Windows or others string::replaceAny(":<>[]", '_'); + removeRepeated('_'); + // Minor cleanup of fileName removeRepeated('/'); removeEnd('/'); diff --git a/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterCollated.C b/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterCollated.C index 759544e15a..f406baa49e 100644 --- a/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterCollated.C +++ b/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterCollated.C @@ -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 diff --git a/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterUncollated.C b/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterUncollated.C index 4849dc1ff9..95752bb590 100644 --- a/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterUncollated.C +++ b/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterUncollated.C @@ -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 diff --git a/src/surfMesh/writers/ensight/ensightSurfaceWriterCollated.C b/src/surfMesh/writers/ensight/ensightSurfaceWriterCollated.C index 18da187096..c1e835cd12 100644 --- a/src/surfMesh/writers/ensight/ensightSurfaceWriterCollated.C +++ b/src/surfMesh/writers/ensight/ensightSurfaceWriterCollated.C @@ -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 diff --git a/src/surfMesh/writers/ensight/ensightSurfaceWriterUncollated.C b/src/surfMesh/writers/ensight/ensightSurfaceWriterUncollated.C index 9d73cc06f7..1a336ffcf4 100644 --- a/src/surfMesh/writers/ensight/ensightSurfaceWriterUncollated.C +++ b/src/surfMesh/writers/ensight/ensightSurfaceWriterUncollated.C @@ -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