diff --git a/applications/test/ensightFile/Make/files b/applications/test/ensightFile/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..856556c31697747e52200d5a0c9702ca2fb4a2d1 --- /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 0000000000000000000000000000000000000000..a4f7656262c1b023744c2cad1b819aefa108ef52 --- /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 0000000000000000000000000000000000000000..6921176bc233ba6eef1f0e62dc5f45492a5c66d0 --- /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 <http://www.gnu.org/licenses/>. + +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 454cb3ebb6b61c454ae34c7254ecaf05487b3d62..d59f258d356a6103aa7200349290946a0d0a519e 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 0d221590790e6ef2dab658669ab9bd0ed819ba1e..83bae0f842363da1d144539f21bbd1ec73a473e1 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<HashTable<word>>, 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<word>, volumeFields, fieldIter) } } -// TODO: allow similar/different time-steps for each cloud - +// TODO: allow similar/different time-steps for each cloud label cloudNo = 0; forAllConstIter(HashTable<HashTable<word>>, cloudFields, cloudIter) { @@ -135,7 +136,7 @@ forAllConstIter(HashTable<HashTable<word>>, 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,50 @@ if (fieldTimesUsed.size()) count = 0; forAll(fieldTimesUsed, i) { + const label& index = fieldTimesUsed[i]; + caseFile + << " " << setw(12) << timeIndices[index] + timeCorrection; + + if (++count % 6 == 0) + { + caseFile << nl; + } + } + 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[fieldTimesUsed[i]] + timeCorrection; + << " " << setw(12) << timeIndices[index] + timeCorrection; if (++count % 6 == 0) { @@ -172,7 +214,9 @@ if (fieldTimesUsed.size()) } caseFile << nl << nl; } +#endif +// time set - clouds // TODO: allow similar/different time-steps for each cloud cloudNo = 0; forAllConstIter(HashTable<DynamicList<label>>, cloudTimesUsed, cloudIter) @@ -205,9 +249,9 @@ forAllConstIter(HashTable<DynamicList<label>>, 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 309b49a82ddaee8e1b7860fa9483b4a3c9b1007d..2c92bee9cc43b47aa3c0c017ed378fa37d996d2e 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<passiveParticle> 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<Type>::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<Type>::typeName + " values") + ); os.newline(); IOField<Type> 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<Type> diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C index 6aecc40fc2e4e237a80e8ec69a0c751ae42731cd..0a3cdf6509d7f43b17363d8d69212cfc7cfa6fbf 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<scalar> timeIndices; + // TODO: Track the time indices used by the geometry + DynamicList<label> geometryTimesUsed; + // Track the time indices used by the volume fields DynamicList<label> fieldTimesUsed; @@ -235,11 +240,12 @@ int main(int argc, char *argv[]) #include "getTimeIndex.H" - // remember the time index + // remember the time index for the volume fields fieldTimesUsed.append(timeIndex); // the data/ITER subdirectory must exist - fileName subDir = ensightFile::subDir(timeIndex); + // Note that data/ITER is indeed a valid ensight::FileName + const fileName subDir = ensightFile::subDir(timeIndex); mkDir(dataDir/subDir); // place a timestamp in the directory for future reference @@ -261,15 +267,19 @@ int main(int argc, char *argv[]) if (!optNoMesh) { - fileName geomDir; if (hasMovingMesh) { - geomDir = dataDir/subDir; + // remember the time index for the geometry + geometryTimesUsed.append(timeIndex); } - ensightGeoFile geoFile(ensightDir/geomDir/geometryName, format); + ensightGeoFile geoFile + ( + (hasMovingMesh ? dataDir/subDir : ensightDir), + geometryName, + format + ); partsList.writeGeometry(geoFile); - Info<< nl; } } diff --git a/src/conversion/ensight/file/ensightFile.C b/src/conversion/ensight/file/ensightFile.C index 09269edd329f3a59ce04ad2a8ea15259f52b9f26..5481ca57153702ca14af742b6adbcf9c8f0ef08b 100644 --- a/src/conversion/ensight/file/ensightFile.C +++ b/src/conversion/ensight/file/ensightFile.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -24,6 +24,9 @@ License \*---------------------------------------------------------------------------*/ #include "ensightFile.H" +#include "error.H" + +#include <cstring> #include <sstream> // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -33,8 +36,7 @@ bool Foam::ensightFile::allowUndef_ = false; Foam::scalar Foam::ensightFile::undefValue_ = Foam::floatScalarVGREAT; // default is width 8 -Foam::string Foam::ensightFile::mask_ = "********"; - +Foam::string Foam::ensightFile::mask_ = "********"; Foam::string Foam::ensightFile::dirFmt_ = "%08d"; @@ -79,15 +81,9 @@ Foam::label Foam::ensightFile::subDirWidth() } -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // -Foam::ensightFile::ensightFile -( - const fileName& pathname, - IOstream::streamFormat format -) -: - OFstream(pathname, format) +void Foam::ensightFile::initialize() { // ascii formatting specs setf @@ -99,6 +95,33 @@ Foam::ensightFile::ensightFile } +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::ensightFile::ensightFile +( + const fileName& pathname, + IOstream::streamFormat format +) +: + OFstream(ensight::FileName(pathname), format) +{ + initialize(); +} + + +Foam::ensightFile::ensightFile +( + const fileName& path, + const fileName& name, + IOstream::streamFormat format +) +: + OFstream(path/ensight::FileName(name), format) +{ + initialize(); +} + + // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Foam::ensightFile::~ensightFile() @@ -144,30 +167,9 @@ Foam::Ostream& Foam::ensightFile::write Foam::Ostream& Foam::ensightFile::write(const char* value) -{ - return write(string(value)); -} - - -Foam::Ostream& Foam::ensightFile::write(const string& value) { char buf[80]; - - for (string::size_type i = 0; i < 80; ++i) - { - buf[i] = 0; - } - - string::size_type n = value.size(); - if (n >= 80) - { - n = 79; - } - - for (string::size_type i = 0; i < n; ++i) - { - buf[i] = value[i]; - } + strncpy(buf, value, 80); // max 80 chars or padded with nul if smaller if (format() == IOstream::BINARY) { @@ -179,10 +181,18 @@ Foam::Ostream& Foam::ensightFile::write(const string& value) } else { + buf[79] = 0; // max 79 in ASCII, ensure it is indeed nul-terminated stdStream() << buf; } return *this; + +} + + +Foam::Ostream& Foam::ensightFile::write(const string& value) +{ + return write(value.c_str()); } diff --git a/src/conversion/ensight/file/ensightFile.H b/src/conversion/ensight/file/ensightFile.H index c9ed78157547a9cea1d13e17f5986397210fda7d..ea4a29da00908bdc115fdc9e08fc708e25757f5b 100644 --- a/src/conversion/ensight/file/ensightFile.H +++ b/src/conversion/ensight/file/ensightFile.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -36,13 +36,16 @@ Description #include "OFstream.H" #include "IOstream.H" +#include "ensightFileName.H" +#include "ensightVarName.H" + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { /*---------------------------------------------------------------------------*\ - Class ensightFile Declaration + Class ensightFile Declaration \*---------------------------------------------------------------------------*/ class ensightFile @@ -66,24 +69,41 @@ class ensightFile // Private Member Functions + //- Initialize by setting the ASCII output formatting + void initialize(); + //- Disallow default bitwise assignment - void operator=(const ensightFile&); + void operator=(const ensightFile&) = delete; //- Disallow default copy constructor - ensightFile(const ensightFile&); - + ensightFile(const ensightFile&) = delete; public: + // Forward declarations + class FileName; + class VarName; + + // Constructors - //- Construct from pathname + //- Construct from pathname. + // The entire pathname is checked for valid ensight naming. ensightFile ( const fileName& pathname, IOstream::streamFormat format=IOstream::BINARY ); + //- Construct from path and name. + // Only the name portion is checked for valid ensight naming. + ensightFile + ( + const fileName& path, + const fileName& name, + IOstream::streamFormat format=IOstream::BINARY + ); + //- Destructor ~ensightFile(); @@ -135,10 +155,10 @@ public: //- Write undef value Ostream& writeUndef(); - //- Write C-string as "%80s" or as binary + //- Write C-string as "%79s" or as binary (max 80 chars) Ostream& write(const char* value); - //- Write string as "%80s" or as binary + //- Write string as "%79s" or as binary (max 80 chars) Ostream& write(const string& value); //- Write integer as "%10d" or as binary diff --git a/src/conversion/ensight/file/ensightGeoFile.C b/src/conversion/ensight/file/ensightGeoFile.C index 77f2d9397895110ca23e8055681ed5721db4c09d..749a5d1542679c31e6106492f562c2ac1a16c479 100644 --- a/src/conversion/ensight/file/ensightGeoFile.C +++ b/src/conversion/ensight/file/ensightGeoFile.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -25,6 +25,18 @@ License #include "ensightGeoFile.H" +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::ensightGeoFile::initialize() +{ + writeBinaryHeader(); + write("Ensight Geometry File"); newline(); // description line 1 + write("====================="); newline(); // description line 2 + write("node id assign"); newline(); + write("element id assign"); newline(); +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::ensightGeoFile::ensightGeoFile @@ -35,13 +47,23 @@ Foam::ensightGeoFile::ensightGeoFile : ensightFile(pathname, format) { - writeBinaryHeader(); - write("Ensight Geometry File"); newline(); - write("====================="); newline(); - write("node id assign"); newline(); - write("element id assign"); newline(); + initialize(); } + +Foam::ensightGeoFile::ensightGeoFile +( + const fileName& path, + const fileName& name, + IOstream::streamFormat format +) +: + ensightFile(path, name, format) +{ + initialize(); +} + + // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Foam::ensightGeoFile::~ensightGeoFile() @@ -52,8 +74,7 @@ Foam::ensightGeoFile::~ensightGeoFile() Foam::Ostream& Foam::ensightGeoFile::writeKeyword(const string& key) { - write(key); - newline(); + write(key); newline(); return *this; } diff --git a/src/conversion/ensight/file/ensightGeoFile.H b/src/conversion/ensight/file/ensightGeoFile.H index c4fc94180cb8ccb072a2357ffb69a8f8c743ccfc..0fb9896bf0b40835abeb0576bd0204d89073e796 100644 --- a/src/conversion/ensight/file/ensightGeoFile.H +++ b/src/conversion/ensight/file/ensightGeoFile.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -49,24 +49,37 @@ class ensightGeoFile { // Private Member Functions + //- Initialize by outputting header information + void initialize(); + //- Disallow default bitwise assignment - void operator=(const ensightGeoFile&); + void operator=(const ensightGeoFile&) = delete; //- Disallow default copy constructor - ensightGeoFile(const ensightGeoFile&); + ensightGeoFile(const ensightGeoFile&) = delete; public: // Constructors - //- Construct from pathname + //- Construct from pathname. + // The entire pathname is checked for valid ensight naming. ensightGeoFile ( const fileName& pathname, IOstream::streamFormat format=IOstream::BINARY ); + //- Construct from path and name. + // Only the name portion is checked for valid ensight naming. + ensightGeoFile + ( + const fileName& path, + const fileName& name, + IOstream::streamFormat format=IOstream::BINARY + ); + //- Destructor ~ensightGeoFile(); diff --git a/src/conversion/ensight/name/ensightFileName.H b/src/conversion/ensight/name/ensightFileName.H new file mode 100644 index 0000000000000000000000000000000000000000..550a86f68c4d7745bcea4611358f24c47ebcaeb7 --- /dev/null +++ b/src/conversion/ensight/name/ensightFileName.H @@ -0,0 +1,106 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 <http://www.gnu.org/licenses/>. + +Class + Foam::ensight::FileName + +Description + Specification of a valid Ensight file-name. + + Spaces must be quoted, + no '*' wildcards, not '%' (structured block continuation). + + Overall line length within case file is limited to 1024, but this is not + yet addresssed. + +\*---------------------------------------------------------------------------*/ + +#ifndef ensightFileName_H +#define ensightFileName_H + +#include "fileName.H" +#include "word.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace ensight +{ + +/*---------------------------------------------------------------------------*\ + Class ensight::FileName Declaration +\*---------------------------------------------------------------------------*/ + +class FileName +: + public fileName +{ + // Private Member Functions + + //- Strip invalid characters + inline void stripInvalid(); + +public: + + // Constructors + + //- Construct as copy + inline explicit FileName(const FileName&); + + //- Construct as copy of character array + inline explicit FileName(const char*); + + //- Construct as copy of std::string + inline explicit FileName(const std::string&); + + + // Member functions + + //- Is this character valid for an ensight file-name + inline static bool valid(char); + + // Member operators + + // Assignment + + void operator=(const fileName&) = delete; + void operator=(const word&) = delete; + void operator=(const string&) = delete; + void operator=(const std::string&) = delete; + void operator=(const char*) = delete; + +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace ensight +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "ensightFileNameI.H" + +#endif + +// ************************************************************************* // diff --git a/src/conversion/ensight/name/ensightFileNameI.H b/src/conversion/ensight/name/ensightFileNameI.H new file mode 100644 index 0000000000000000000000000000000000000000..495ca6df006423dec2500d5631f46955f197f4c2 --- /dev/null +++ b/src/conversion/ensight/name/ensightFileNameI.H @@ -0,0 +1,83 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "error.H" +#include <cctype> + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +inline Foam::ensight::FileName::FileName(const FileName& fn) +: + fileName(fn, false) +{} + + +inline Foam::ensight::FileName::FileName(const char* s) +: + fileName(s, false) +{ + stripInvalid(); +} + + +inline Foam::ensight::FileName::FileName(const std::string& s) +: + fileName(s, false) +{ + stripInvalid(); +} + + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +inline void Foam::ensight::FileName::stripInvalid() +{ + string::stripInvalid<FileName>(*this); + + removeRepeated('/'); + removeTrailing('/'); + + if (empty()) + { + FatalErrorInFunction + << "ensight::FileName empty after stripping" << nl + << exit(FatalError); + } +} + + +inline bool Foam::ensight::FileName::valid(char c) +{ + return + ( + fileName::valid(c) // includes space, quotes + && c != '*' // wild-card + && c != '%' // structured block continuation + ); +} + + +// ************************************************************************* // diff --git a/src/conversion/ensight/name/ensightVarName.H b/src/conversion/ensight/name/ensightVarName.H new file mode 100644 index 0000000000000000000000000000000000000000..fe2c57aefbf50812b36e107c790c3e28a14db959 --- /dev/null +++ b/src/conversion/ensight/name/ensightVarName.H @@ -0,0 +1,111 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 <http://www.gnu.org/licenses/>. + +Class + Foam::ensight::VarName + +Description + Specification of a valid Ensight variable-name. + + \code + space !#%()*+,-./;@[]^ + \endcode + If spaces exist, they must be quoted + + Variable names cannot start with a digit. + The maximum part name length (in GUI: 49 chars) - not addresssed. + The maximum variable length (in GUI: 49 chars) - not addresssed. + +\*---------------------------------------------------------------------------*/ + +#ifndef ensightVarName_H +#define ensightVarName_H + +#include "word.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace ensight +{ + +/*---------------------------------------------------------------------------*\ + Class ensight::VarName Declaration +\*---------------------------------------------------------------------------*/ + +class VarName +: + public word +{ + // Private Member Functions + + //- Strip invalid characters + inline void stripInvalid(); + + +public: + + + // Constructors + + //- Construct as copy + inline explicit VarName(const VarName&); + + //- Construct as copy of character array + inline explicit VarName(const char*); + + //- Construct as copy of std::string + inline explicit VarName(const std::string&); + + + // Member functions + + //- Is this character valid for an ensight var-name + inline static bool valid(char); + + + // Member operators + + // Assignment + + void operator=(const word&) = delete; + void operator=(const string&) = delete; + void operator=(const std::string&) = delete; + void operator=(const char*) = delete; + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace ensight +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "ensightVarNameI.H" + +#endif + +// ************************************************************************* // diff --git a/src/conversion/ensight/name/ensightVarNameI.H b/src/conversion/ensight/name/ensightVarNameI.H new file mode 100644 index 0000000000000000000000000000000000000000..17bec6125a78c5c64bf97be18b3e77e5f5b22a5c --- /dev/null +++ b/src/conversion/ensight/name/ensightVarNameI.H @@ -0,0 +1,100 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "error.H" +#include <cctype> + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +inline Foam::ensight::VarName::VarName(const VarName& vn) +: + word(vn, false) +{} + + +inline Foam::ensight::VarName::VarName(const char* s) +: + word(s, false) +{ + stripInvalid(); +} + + +inline Foam::ensight::VarName::VarName(const std::string& s) +: + word(s, false) +{ + stripInvalid(); +} + + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +inline void Foam::ensight::VarName::stripInvalid() +{ + string::stripInvalid<VarName>(*this); + + if (empty()) + { + FatalErrorInFunction + << "ensight::VarName empty after stripping" << nl + << exit(FatalError); + } + + // prefix with '_' to avoid starting with leading digits + std::string::iterator iter = begin(); + if (isdigit(*iter)) + { + insert(iter, '_'); + } +} + + +inline bool Foam::ensight::VarName::valid(char c) +{ + return + ( + word::valid(c) // includes space, quotes, /\;{} + && c != '!' + && c != '#' + && c != '%' + && c != '(' + && c != ')' + && c != '*' + && c != '+' + && c != ',' + && c != '-' + && c != '.' + && c != '@' + && c != '[' + && c != ']' + && c != '^' + ); +} + + +// ************************************************************************* // diff --git a/src/conversion/ensight/part/ensightParts.C b/src/conversion/ensight/part/ensightParts.C index dce9cabfed270c0e39e5951665295093455e1332..a7675bf4839c3fb428f3ec8b4532e06ac021a919 100644 --- a/src/conversion/ensight/part/ensightParts.C +++ b/src/conversion/ensight/part/ensightParts.C @@ -183,13 +183,14 @@ void Foam::ensightParts::renumber void Foam::ensightParts::writeGeometry(ensightGeoFile& os) const { // with some feedback - Info<< "write geometry part:" << nl << flush; + Info<< "write geometry part (" << flush; forAll(partsList_, partI) { Info<< " " << partI << flush; partsList_[partI].writeGeometry(os); } + Info<< " )" << endl; } diff --git a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C index 89eadae4fe22fd517dedd8e0406f21df3dbf746d..e8c5589d7d4834cacc23d8399a0f49fe66d49c91 100644 --- a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C +++ b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C @@ -77,6 +77,8 @@ Foam::fileName Foam::ensightSurfaceWriter::write const bool verbose ) const { + const ensight::FileName surfName(surfaceName); + if (!isDir(outputDir)) { mkDir(outputDir); @@ -85,10 +87,11 @@ Foam::fileName Foam::ensightSurfaceWriter::write // const scalar timeValue = Foam::name(this->mesh().time().timeValue()); const scalar timeValue = 0.0; - OFstream osCase(outputDir/surfaceName + ".case"); + OFstream osCase(outputDir/surfName + ".case"); ensightGeoFile osGeom ( - outputDir/surfaceName + ".0000.mesh", + outputDir, + surfName + ".0000.mesh", writeFormat_ ); diff --git a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C index 1d14ab01966abd70849a6ffd7a2b743122ee9b65..b564b5c8e596cda596d07fd293257ca120760d32 100644 --- a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C +++ b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd. + \\/ M anipulation | Copyright (C) 2015-2016 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -47,23 +47,43 @@ Foam::fileName Foam::ensightSurfaceWriter::writeUncollated const bool verbose ) const { - if (!isDir(outputDir/fieldName)) + const ensight::FileName surfName(surfaceName); + const ensight::VarName varName(fieldName); + + // use variable name as sub-directory for results + // eg, something like this: + // - VAR1/SURF1.case + // - VAR1/SURF1.0000.mesh + // - VAR1/SURF1.0001.VAR1 + // - VAR1/SURF2.case + // - VAR1/SURF2.0000.mesh + // - VAR1/SURF2.0001.VAR1 + // and + // - VAR2/SURF1.case + // - VAR2/SURF1.0000.mesh + // - VAR2/SURF1.0001.VAR2 + + const fileName baseDir = outputDir/varName; + + if (!isDir(baseDir)) { - mkDir(outputDir/fieldName); + mkDir(baseDir); } // const scalar timeValue = Foam::name(this->mesh().time().timeValue()); const scalar timeValue = 0.0; - OFstream osCase(outputDir/fieldName/surfaceName + ".case"); + OFstream osCase(baseDir/surfName + ".case"); ensightGeoFile osGeom ( - outputDir/fieldName/surfaceName + ".0000.mesh", + baseDir, + surfName + ".0000.mesh", writeFormat_ ); ensightFile osField ( - outputDir/fieldName/surfaceName + ".0000." + fieldName, + baseDir, + surfName + ".0000." + varName, writeFormat_ ); @@ -82,8 +102,8 @@ Foam::fileName Foam::ensightSurfaceWriter::writeUncollated << "VARIABLE" << nl << ensightPTraits<Type>::typeName << " per " << word(isNodeValues ? "node:" : "element:") << setw(10) << 1 - << " " << fieldName - << " " << surfaceName.c_str() << ".****." << fieldName << nl + << " " << varName + << " " << surfName.c_str() << ".****." << varName << nl << nl << "TIME" << nl << "time set: 1" << nl @@ -118,8 +138,22 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated const bool verbose ) const { - - const fileName baseDir = outputDir.path()/surfaceName; + const ensight::FileName surfName(surfaceName); + const ensight::VarName varName(fieldName); + + // use surface name as sub-directory for results + // eg, something like this: + // - SURF1/SURF1.case + // - SURF1/SURF1.0000.mesh + // - SURF1/SURF1.0001.VAR1 + // - SURF1/SURF1.0001.VAR2 + // and + // - SURF2/SURF2.case + // - SURF2/SURF2.0000.mesh + // - SURF2/SURF2.0001.VAR1 + // - SURF2/SURF2.0001.VAR2 + + const fileName baseDir = outputDir.path()/surfName; const fileName timeDir = outputDir.name(); if (!isDir(baseDir)) @@ -127,7 +161,8 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated mkDir(baseDir); } - const fileName meshFile(baseDir/surfaceName + ".0000.mesh"); + // surfName already validated + const fileName meshFile(baseDir/surfName + ".0000.mesh"); const scalar timeValue = readScalar(IStringStream(timeDir)()); label timeIndex = 0; @@ -171,6 +206,8 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated { dictionary fieldDict; fieldDict.set("type", ensightPTraits<Type>::typeName); + fieldDict.set("name", varName); // ensight variable name + fieldsDict.set(fieldName, fieldDict); stateChanged = true; @@ -180,6 +217,7 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated { dictionary fieldDict; fieldDict.set("type", ensightPTraits<Type>::typeName); + fieldDict.set("name", varName); // ensight variable name dictionary fieldsDict; fieldsDict.set(fieldName, fieldDict); @@ -201,7 +239,7 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated os << dict; - OFstream osCase(baseDir/surfaceName + ".case"); + OFstream osCase(baseDir/surfName + ".case"); if (verbose) { @@ -216,18 +254,24 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated << "model: 1 " << meshFile.name() << nl << nl << "VARIABLE" << nl; + const dictionary& fieldsDict = dict.subDict("fields"); forAllConstIter(dictionary, fieldsDict, iter) { - const word& fieldName = iter().keyword(); - const word fieldType(iter().dict().lookup("type")); + const dictionary& subDict = iter().dict(); + const word fieldType(subDict.lookup("type")); + const word varName = subDict.lookupOrDefault + ( + "name", + iter().keyword() // fieldName as fallback + ); osCase << fieldType << " per " << word(isNodeValues ? "node:" : "element:") << setw(10) << 1 - << setw(15) << fieldName - << " " << surfaceName.c_str() << ".****." << fieldName + << setw(15) << varName + << " " << surfName.c_str() << ".****." << varName << nl; } osCase << nl; @@ -261,7 +305,8 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated { Info<< "Writing mesh file to " << meshFile.name() << endl; } - ensightGeoFile osGeom(meshFile, writeFormat_); + // use two-argument form for path-name to avoid validating the base-dir + ensightGeoFile osGeom(meshFile.path(), meshFile.name(), writeFormat_); osGeom << ensPart; } @@ -278,7 +323,8 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated // Write field ensightFile osField ( - baseDir/surfaceName + "." + timeString + "." + fieldName, + baseDir, + surfName + "." + timeString + "." + varName, writeFormat_ ); if (verbose) @@ -288,7 +334,7 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated osField.writeKeyword(ensightPTraits<Type>::typeName); ensPart.writeField(osField, values, isNodeValues); - return baseDir/surfaceName + ".case"; + return baseDir/surfName + ".case"; }