From 1452cc08275207ca42f5c7a865558f60c79c6e8d Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Tue, 7 Jun 2016 17:16:09 +0100 Subject: [PATCH] BUG: ensight writers not catching special reserved characters (fixes #122) - most notably the '%' which is used as a separator in places caused problems. EHN: only use valid ensight file/variable names for writers - fixed: foamToEnsightParts, ensightSurfaceWriter - pending: foamToEnsight BUG: no geometry written for foamToEnsightParts with moving mesh (fixes #142) - an incorrect path was causing the issue --- applications/test/ensightFile/Make/files | 3 + applications/test/ensightFile/Make/options | 10 ++ .../test/ensightFile/Test-ensightFile.C | 77 ++++++++++++ .../foamToEnsightParts/checkHasMovingMesh.H | 1 + .../foamToEnsightParts/ensightOutputCase.H | 64 ++++++++-- .../ensightOutputFunctions.C | 45 ++++--- .../foamToEnsightParts/foamToEnsightParts.C | 30 +++-- src/conversion/ensight/file/ensightFile.C | 76 ++++++------ src/conversion/ensight/file/ensightFile.H | 36 ++++-- src/conversion/ensight/file/ensightGeoFile.C | 37 ++++-- src/conversion/ensight/file/ensightGeoFile.H | 21 +++- src/conversion/ensight/name/ensightFileName.H | 106 +++++++++++++++++ .../ensight/name/ensightFileNameI.H | 83 +++++++++++++ src/conversion/ensight/name/ensightVarName.H | 111 ++++++++++++++++++ src/conversion/ensight/name/ensightVarNameI.H | 100 ++++++++++++++++ src/conversion/ensight/part/ensightParts.C | 3 +- .../writers/ensight/ensightSurfaceWriter.C | 7 +- .../ensight/ensightSurfaceWriterTemplates.C | 82 ++++++++++--- 18 files changed, 779 insertions(+), 113 deletions(-) create mode 100644 applications/test/ensightFile/Make/files create mode 100644 applications/test/ensightFile/Make/options create mode 100644 applications/test/ensightFile/Test-ensightFile.C create mode 100644 src/conversion/ensight/name/ensightFileName.H create mode 100644 src/conversion/ensight/name/ensightFileNameI.H create mode 100644 src/conversion/ensight/name/ensightVarName.H create mode 100644 src/conversion/ensight/name/ensightVarNameI.H diff --git a/applications/test/ensightFile/Make/files b/applications/test/ensightFile/Make/files new file mode 100644 index 0000000000..856556c316 --- /dev/null +++ b/applications/test/ensightFile/Make/files @@ -0,0 +1,3 @@ +Test-ensightFile.C + +EXE = $(FOAM_USER_APPBIN)/Test-ensightFile diff --git a/applications/test/ensightFile/Make/options b/applications/test/ensightFile/Make/options new file mode 100644 index 0000000000..a4f7656262 --- /dev/null +++ b/applications/test/ensightFile/Make/options @@ -0,0 +1,10 @@ +EXE_INC = \ + -I$(LIB_SRC)/conversion/lnInclude \ + -I$(LIB_SRC)/fileFormats/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude + +EXE_LIBS = \ + -lconversion \ + -lfileFormats \ + -lmeshTools + diff --git a/applications/test/ensightFile/Test-ensightFile.C b/applications/test/ensightFile/Test-ensightFile.C new file mode 100644 index 0000000000..6921176bc2 --- /dev/null +++ b/applications/test/ensightFile/Test-ensightFile.C @@ -0,0 +1,77 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +Application + Test-ensightFile + +Description + check cleanup of ensight file and variable names + +\*---------------------------------------------------------------------------*/ + +#include "argList.H" +#include "ensightFileName.H" +#include "ensightVarName.H" +#include "IOstreams.H" + +using namespace Foam; + +void printCleaning(const fileName& pathName) +{ + Info<< "input = " << pathName << nl; + Info<< "file = " << ensight::FileName(pathName) << nl; + Info<< "var = " << ensight::VarName(pathName) << nl; + Info<< nl; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Main program: + +int main(int argc, char *argv[]) +{ + argList::noBanner(); + argList::noParallel(); + argList::validArgs.insert("fileName .. fileNameN"); + + argList args(argc, argv, false, true); + + if (args.size() <= 1 && args.options().empty()) + { + args.printUsage(); + } + + fileName pathName; + + for (label argI=1; argI < args.size(); ++argI) + { + pathName = args[argI]; + printCleaning(pathName); + } + + Info<< "\nEnd\n" << endl; + return 0; +} + + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/checkHasMovingMesh.H b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/checkHasMovingMesh.H index 454cb3ebb6..d59f258d35 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/checkHasMovingMesh.H +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/checkHasMovingMesh.H @@ -1,4 +1,5 @@ // check for "points" in all of the result directories +// - could restrict to the selected times bool hasMovingMesh = false; if (timeDirs.size() > 1) diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputCase.H b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputCase.H index 0d22159079..83bae0f842 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputCase.H +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputCase.H @@ -8,7 +8,7 @@ if (timeDirs[0].value() < 0) } // the case file is always ASCII -Info << "write case: " << caseFileName.c_str() << endl; +Info<< "write case: " << caseFileName.c_str() << endl; OFstream caseFile(ensightDir/caseFileName, IOstream::ASCII); caseFile.setf(ios_base::left); @@ -20,7 +20,9 @@ caseFile << "FORMAT" << nl << setw(16) << "type:" << "ensight gold" << nl << nl; -if (hasMovingMesh) +// time-set for geometries +// TODO: split off into separate time-set, but need to verify ensight spec +if (geometryTimesUsed.size()) { caseFile << "GEOMETRY" << nl @@ -43,7 +45,7 @@ forAllConstIter(HashTable>, cloudFields, cloudIter) caseFile << setw(16) << "measured: 2" << fileName(dataMask/cloud::prefix/cloudName/"positions").c_str() - << nl; + << nl; } caseFile << nl << "VARIABLE" << nl; @@ -87,9 +89,8 @@ forAllConstIter(HashTable, volumeFields, fieldIter) } } + // TODO: allow similar/different time-steps for each cloud - - label cloudNo = 0; forAllConstIter(HashTable>, cloudFields, cloudIter) { @@ -135,7 +136,7 @@ forAllConstIter(HashTable>, cloudFields, cloudIter) // add time values caseFile << nl << "TIME" << nl; -// time set 1 - geometry and volume fields +// time set 1 - volume fields if (fieldTimesUsed.size()) { caseFile @@ -161,9 +162,9 @@ if (fieldTimesUsed.size()) count = 0; forAll(fieldTimesUsed, i) { + const label& index = fieldTimesUsed[i]; caseFile - << " " << setw(12) - << timeIndices[fieldTimesUsed[i]] + timeCorrection; + << " " << setw(12) << timeIndices[index] + timeCorrection; if (++count % 6 == 0) { @@ -173,6 +174,49 @@ if (fieldTimesUsed.size()) caseFile << nl << nl; } + +// time set 2 - geometry +// THIS NEEDS MORE CHECKING +#if 0 +if (geometryTimesUsed.size()) +{ + caseFile + << "time set: " << 2 << nl + << "number of steps: " << geometryTimesUsed.size() << nl + << "filename numbers:" << nl; + + label count = 0; + forAll(geometryTimesUsed, i) + { + caseFile + << " " << setw(12) << geometryTimesUsed[i]; + + if (++count % 6 == 0) + { + caseFile << nl; + } + } + + caseFile + << nl << "time values:" << nl; + + count = 0; + forAll(geometryTimesUsed, i) + { + const label& index = geometryTimesUsed[i]; + caseFile + << " " << setw(12) << timeIndices[index] + timeCorrection; + + if (++count % 6 == 0) + { + caseFile << nl; + } + } + caseFile << nl << nl; +} +#endif + +// time set - clouds // TODO: allow similar/different time-steps for each cloud cloudNo = 0; forAllConstIter(HashTable>, cloudTimesUsed, cloudIter) @@ -205,9 +249,9 @@ forAllConstIter(HashTable>, cloudTimesUsed, cloudIter) count = 0; forAll(timesUsed, i) { + const label& index = timesUsed[i]; caseFile - << " " << setw(12) - << timeIndices[timesUsed[i]] + timeCorrection; + << " " << setw(12) << timeIndices[index] + timeCorrection; if (++count % 6 == 0) { diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputFunctions.C b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputFunctions.C index 309b49a82d..2c92bee9cc 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputFunctions.C +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputFunctions.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -47,6 +47,8 @@ void Foam::ensightCaseEntry const label timeSet ) { + const ensight::VarName varName(fieldName); + caseFile.setf(ios_base::left); fileName dirName(dataMask); @@ -68,9 +70,9 @@ void Foam::ensightCaseEntry << ensightType.c_str() << " per measured node: " << ts << " " << setw(15) - << ("c" + Foam::name(cloudNo) + fieldName).c_str() + << ("c" + Foam::name(cloudNo) + varName).c_str() << " " - << (dirName/fieldName).c_str() + << (dirName/varName).c_str() << nl; } else @@ -78,9 +80,9 @@ void Foam::ensightCaseEntry caseFile << ensightType.c_str() << " per element: " - << setw(15) << fieldName + << setw(15) << varName << " " - << (dirName/fieldName).c_str() + << (dirName/varName).c_str() << nl; } } @@ -97,16 +99,16 @@ void Foam::ensightParticlePositions { Cloud parcels(mesh, cloudName, false); - fileName cloudDir = subDir/cloud::prefix/cloudName; - fileName postFileName = cloudDir/"positions"; + const fileName postFileName = + subDir/cloud::prefix/cloudName/"positions"; // the ITER/lagrangian subdirectory must exist - mkDir(dataDir/cloudDir); - ensightFile os(dataDir/postFileName, format); + mkDir(dataDir/postFileName.path()); + ensightFile os(dataDir, postFileName, format); // tag binary format (just like geometry files) os.writeBinaryHeader(); - os.write(postFileName); + os.write(postFileName); // description os.newline(); os.write("particle coordinates"); os.newline(); @@ -161,14 +163,19 @@ void Foam::ensightLagrangianField { Info<< " " << fieldObject.name() << flush; - fileName cloudDir = subDir/cloud::prefix/cloudName; - fileName postFileName = cloudDir/fieldObject.name(); + const fileName postFileName = + subDir/cloud::prefix/cloudName + /ensight::VarName(fieldObject.name()); - string title = - postFileName + " with " + pTraits::typeName + " values"; + // the ITER/lagrangian subdirectory was already created + // when writing positions - ensightFile os(dataDir/postFileName, format); - os.write(title); + ensightFile os(dataDir, postFileName, format); + os.write + ( + // description + string(postFileName + " with " + pTraits::typeName + " values") + ); os.newline(); IOField field(fieldObject); @@ -219,10 +226,10 @@ void Foam::ensightVolField { Info<< " " << fieldObject.name() << flush; - fileName postFileName = subDir/fieldObject.name(); + const fileName postFileName = subDir/ensight::VarName(fieldObject.name()); - ensightFile os(dataDir/postFileName, format); - os.write(postFileName); + ensightFile os(dataDir, postFileName, format); + os.write(postFileName); // description os.newline(); // ie, volField diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C index 6aecc40fc2..0a3cdf6509 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -166,9 +166,9 @@ int main(int argc, char *argv[]) ensightDir = args.rootPath()/args.globalCaseName()/ensightDir; } - fileName dataDir = ensightDir/"data"; - fileName caseFileName = "Ensight.case"; - fileName dataMask = fileName("data")/ensightFile::mask(); + const fileName caseFileName = "Ensight.case"; + const fileName dataDir = ensightDir/"data"; + const fileName dataMask = dataDir.name()/ensightFile::mask(); // Ensight and Ensight/data directories must exist // do not remove old data - we might wish to convert new results @@ -178,6 +178,8 @@ int main(int argc, char *argv[]) Info<<"Warning: re-using existing directory" << nl << " " << ensightDir << endl; } + + // as per mkdir -p "Ensight/data" mkDir(ensightDir); mkDir(dataDir); @@ -216,6 +218,9 @@ int main(int argc, char *argv[]) // map times used Map timeIndices; + // TODO: Track the time indices used by the geometry + DynamicList