diff --git a/src/fileFormats/ensight/file/ensightCase.C b/src/fileFormats/ensight/file/ensightCase.C index 1d7ff6fc31eba39f131593ff99b20ed12dcb3541..2338cfbf0de51a9c45f299ecfc34837fb11c40e6 100644 --- a/src/fileFormats/ensight/file/ensightCase.C +++ b/src/fileFormats/ensight/file/ensightCase.C @@ -138,7 +138,7 @@ Foam::scalar Foam::ensightCase::writeTimeset() const { const label ts = 1; - const labelList indices = timesUsed_.sortedToc(); + const labelList indices(timesUsed_.sortedToc()); label count = indices.size(); // correct for negative starting values diff --git a/src/fileFormats/ensight/file/ensightCase.H b/src/fileFormats/ensight/file/ensightCase.H index 67835f2e7d693ee7248185270e3af957d72e603c..1b516eed0ac218917da8966528164fd93078a1b9 100644 --- a/src/fileFormats/ensight/file/ensightCase.H +++ b/src/fileFormats/ensight/file/ensightCase.H @@ -106,7 +106,7 @@ private: //- Record time indices when geometry is written. // These values will be used to decide if timeset 1 // or a separate timeset are used. - // The special index '-1' is used static geometry. + // The special index '-1' is used for static geometry. mutable labelHashSet geomTimes_; //- Record time indices when clouds are written. diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C index c1fcbe4adf138e16aeb44ea635a55372da686c55..721b684b6ce44a950a08224f2c79bc2e087186a7 100644 --- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C +++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C @@ -135,6 +135,7 @@ Foam::sampledSurfaces::sampledSurfaces sampleFaceScheme_(word::null), sampleNodeScheme_(word::null), mergedList_(), + changedGeom_(), formatter_(nullptr) { if (Pstream::parRun()) @@ -168,6 +169,7 @@ Foam::sampledSurfaces::sampledSurfaces sampleFaceScheme_(word::null), sampleNodeScheme_(word::null), mergedList_(), + changedGeom_(), formatter_(nullptr) { read(dict); @@ -219,11 +221,12 @@ bool Foam::sampledSurfaces::write() const label nFields = classifyFields(); - // write geometry first if required, + // Write geometry first if required, // or when no fields would otherwise be written - if (nFields == 0 || formatter_->separateGeometry()) + if (formatter_->separateGeometry() || !nFields) { writeGeometry(); + changedGeom_ = false; } const IOobjectList objects(obr_, obr_.time().timeName()); @@ -246,9 +249,7 @@ bool Foam::sampledSurfaces::write() bool Foam::sampledSurfaces::read(const dictionary& dict) { - bool surfacesFound = dict.found("surfaces"); - - if (surfacesFound) + if (dict.found("surfaces")) { sampleFaceScheme_ = dict.lookupOrDefault<word>("sampleScheme", "cell"); @@ -304,6 +305,10 @@ bool Foam::sampledSurfaces::read(const dictionary& dict) Pout<< ")" << endl; } + // New geometry + changedGeom_.resize(size()); + changedGeom_ = true; + return true; } @@ -369,6 +374,8 @@ bool Foam::sampledSurfaces::expire() } } + changedGeom_ = true; + // true if any surfaces just expired return justExpired; } @@ -388,9 +395,12 @@ bool Foam::sampledSurfaces::update() { forAll(*this, surfi) { - if (operator[](surfi).update()) + sampledSurface& s = operator[](surfi); + + if (s.update()) { updated = true; + changedGeom_[surfi] = true; } } @@ -414,6 +424,7 @@ bool Foam::sampledSurfaces::update() if (s.update()) { updated = true; + changedGeom_[surfi] = true; mergedList_[surfi].merge(s, mergeDim); } } diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H index 590da3ed4b92eb84403525e4f21488a1bcc6c73a..16432d71653ff9b2d905f82f7da951c3f9ee356f 100644 --- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H +++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H @@ -151,6 +151,9 @@ class sampledSurfaces //- Merged meshed surfaces (parallel only) List<mergedSurf> mergedList_; + //- Track which surfaces have changed + List<bool> changedGeom_; + // Calculated diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C index f314d9381877918bb40a2cbdf9906fac27098bde..19ccc258a663dacdc46d1b100f24f389a0c7bb0d 100644 --- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C +++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C @@ -42,6 +42,13 @@ void Foam::sampledSurfaces::writeSurface { const sampledSurface& s = operator[](surfi); + if (changedGeom_[surfi]) + { + // Trigger any changes + formatter_->updateMesh(outputDir, s.name()); + changedGeom_[surfi] = false; + } + if (Pstream::parRun()) { // Collect values from all processors diff --git a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C index 77cdd19687ed66dcf49e8db5098f28ee3ff24422..ef6575a29d60d18687741b1b05ef4752e0d1e980 100644 --- a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C +++ b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2015-2016 OpenCFD Ltd. + \\/ M anipulation | Copyright (C) 2015-2018 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -36,6 +36,61 @@ namespace Foam } +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +void Foam::ensightSurfaceWriter::printTimeset +( + OSstream& os, + const label ts, + const scalar& timeValue +) +{ + os + << "time set: " << ts << nl + << "number of steps: " << 1 << nl; + + // Assume to be contiguous numbering + os << "filename start number: 0" << nl + << "filename increment: 1" << nl + << "time values:" << nl; + + os << " " << timeValue + << nl << nl; +} + + +void Foam::ensightSurfaceWriter::printTimeset +( + OSstream& os, + const label ts, + const UList<scalar>& values +) +{ + label count = values.size(); + os + << "time set: " << ts << nl + << "number of steps: " << count << nl; + + // Assume to be contiguous numbering + os << "filename start number: 0" << nl + << "filename increment: 1" << nl + << "time values:" << nl; + + count = 0; + for (const scalar& t : values) + { + os << ' ' << setw(12) << t; + + if (++count % 6 == 0) + { + os << nl; + } + } + os << nl << nl; +} + + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::ensightSurfaceWriter::ensightSurfaceWriter() @@ -75,6 +130,47 @@ bool Foam::ensightSurfaceWriter::separateGeometry() const } +void Foam::ensightSurfaceWriter::updateMesh +( + const fileName& outputDir, + const fileName& surfaceName +) const +{ + if (collateTimes_ && Pstream::master()) + { + const ensight::FileName surfName(surfaceName); + + const fileName baseDir = outputDir.path()/surfName; + const fileName timeDir = outputDir.name(); + const scalar timeValue = readScalar(timeDir); + + if (!isDir(baseDir)) + { + mkDir(baseDir); + } + + dictionary dict; + + if (isFile(baseDir/"fieldsDict")) + { + IFstream is(baseDir/"fieldsDict"); + if (is.good() && dict.read(is)) + { + dict.read(is); + } + } + + dict.set("updateMesh", timeValue); + + { + OFstream os(baseDir/"fieldsDict"); + os << "// Summary of Ensight fields, times" << nl << nl; + dict.write(os, false); + } + } +} + + Foam::fileName Foam::ensightSurfaceWriter::write ( const fileName& outputDir, @@ -92,8 +188,6 @@ Foam::fileName Foam::ensightSurfaceWriter::write mkDir(outputDir); } - const scalar timeValue = 0.0; - OFstream osCase(outputDir/surfName + ".case"); ensightGeoFile osGeom ( @@ -114,14 +208,9 @@ Foam::fileName Foam::ensightSurfaceWriter::write << "GEOMETRY" << nl << "model: 1 " << osGeom.name().name() << nl << nl - << "TIME" << nl - << "time set: 1" << nl - << "number of steps: 1" << nl - << "filename start number: 0" << nl - << "filename increment: 1" << nl - << "time values:" << nl - << " " << timeValue << nl - << nl; + << "TIME" << nl; + + printTimeset(osCase, 1, 0.0); ensightPartFaces ensPart(0, osGeom.name().name(), points, faces, true); osGeom << ensPart; diff --git a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.H b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.H index 4086a1875d08e8ae61014dd687c1286f67b4bfb4..db5ef7adb7a163c8c9819ef254c2eceefd263eac 100644 --- a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.H +++ b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2015-2016 OpenCFD Ltd. + \\/ M anipulation | Copyright (C) 2015-2018 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -79,6 +79,23 @@ class ensightSurfaceWriter // Private Member Functions + //- Print time-set for ensight case file + static void printTimeset + ( + OSstream& os, + const label ts, + const scalar& timeValue + ); + + //- Print time-set for ensight case file + static void printTimeset + ( + OSstream& os, + const label ts, + const UList<scalar>& times + ); + + //- Templated write operation - one file per timestep template<class Type> fileName writeCollated @@ -144,6 +161,13 @@ public: // False if geometry and field must be in a single file virtual bool separateGeometry() const; + //- Trigger for geometry changes. + // \note this is a stop-gap solution + virtual void updateMesh + ( + const fileName& outputDir, + const fileName& surfaceName + ) const; // override //- Write single surface geometry to file. virtual fileName write diff --git a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C index c1fe9ae7fad83f888a22f067c7920abe767ed3c1..f04011fe01df8ec2262f107535a219b810f77380 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-2016 OpenCFD Ltd. + \\/ M anipulation | Copyright (C) 2015-2018 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -29,7 +29,6 @@ License #include "ensightPartFaces.H" #include "ensightSerialOutput.H" #include "ensightPTraits.H" -#include "StringStream.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -63,15 +62,13 @@ Foam::fileName Foam::ensightSurfaceWriter::writeUncollated const fileName baseDir = outputDir/varName; const fileName timeDir = outputDir.name(); + const scalar timeValue = readScalar(timeDir); if (!isDir(baseDir)) { mkDir(baseDir); } - // const scalar timeValue = Foam::name(this->mesh().time().timeValue()); - const scalar timeValue = readScalar(timeDir); - OFstream osCase(baseDir/surfName + ".case"); ensightGeoFile osGeom ( @@ -109,14 +106,10 @@ Foam::fileName Foam::ensightSurfaceWriter::writeUncollated << setw(15) << varName << " " << surfName.c_str() << ".********." << varName << nl << nl - << "TIME" << nl - << "time set: 1" << nl - << "number of steps: 1" << nl - << "filename start number: 0" << nl - << "filename increment: 1" << nl - << "time values:" << nl - << " " << timeValue - << nl << nl << "# end" << nl; + << "TIME" << nl; + + printTimeset(osCase, 1, timeValue); + osCase << "# end" << nl; ensightPartFaces ensPart ( @@ -171,20 +164,22 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated const fileName baseDir = outputDir.path()/surfName; const fileName timeDir = outputDir.name(); + const scalar timeValue = readScalar(timeDir); + scalar meshValue = 0; if (!isDir(baseDir)) { mkDir(baseDir); } - // surfName already validated - const fileName meshFile(baseDir/surfName + ".000000.mesh"); - const scalar timeValue = readScalar(timeDir); - label timeIndex = 0; + label meshIndex = 0, timeIndex = 0; + + fileName meshFile; // Do case file { dictionary dict; + scalarList meshes; scalarList times; bool stateChanged = false; @@ -193,26 +188,56 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated IFstream is(baseDir/"fieldsDict"); if (is.good() && dict.read(is)) { - dict.lookup("times") >> times; - const scalar timeValue = readScalar(timeDir); - label index = findLower(times, timeValue); - timeIndex = index+1; + dict.readIfPresent("meshes", meshes); + dict.readIfPresent("times", times); + + timeIndex = 1+findLower(times, timeValue); + + if (dict.readIfPresent("updateMesh", meshValue)) + { + meshIndex = 1+findLower(meshes, meshValue); + + dict.remove("updateMesh"); + stateChanged = true; + } + else if (meshes.size()) + { + meshIndex = meshes.size()-1; + meshValue = meshes.last(); + } + else + { + meshIndex = 0; + } } } - // Update stored times list - times.setSize(timeIndex+1, -1); + meshes.resize(meshIndex+1, -1); + times.resize(timeIndex+1, -1); + if (meshes[meshIndex] != meshValue) + { + stateChanged = true; + } if (times[timeIndex] != timeValue) { stateChanged = true; } + + meshes[meshIndex] = meshValue; times[timeIndex] = timeValue; + // surfName already validated + meshFile = + ( + baseDir/"data"/word::printf("%06d", meshIndex)/"geometry" + ); + // Add my information to dictionary { + dict.set("meshes", meshes); dict.set("times", times); if (dict.found("fields")) { @@ -252,7 +277,7 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated } { OFstream os(baseDir/"fieldsDict"); - os << "// summary of ensight times/fields" << nl << nl; + os << "// Summary of Ensight fields, times" << nl << nl; dict.write(os, false); } @@ -268,7 +293,8 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated << "type: ensight gold" << nl << nl << "GEOMETRY" << nl - << "model: 1 " << meshFile.name() << nl + << "model: 2 " // time-set 2 + << " data/******/geometry" << nl << nl << "VARIABLE" << nl; @@ -298,24 +324,12 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated osCase << nl; osCase - << "TIME" << nl - << "time set: 1" << nl - << "number of steps: " << timeIndex+1 << nl - << "filename start number: 0" << nl - << "filename increment: 1" << nl - << "time values:" << nl; - - label count = 0; - forAll(times, timei) - { - osCase << ' ' << setw(12) << times[timei]; + << "TIME" << nl; - if (!(++count % 6)) - { - osCase << nl; - } - } - osCase << nl << nl << "# end" << nl; + printTimeset(osCase, 1, times); + printTimeset(osCase, 2, meshes); + + osCase << "# end" << nl; } } @@ -341,16 +355,8 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated } - // Get string representation - string timeString; - { - OStringStream os; - os.stdStream().fill('0'); - os << setw(6) << timeIndex; - timeString = os.str(); - } - - fileName dataDir = baseDir/"data"/timeString; + // Location for data + fileName dataDir = baseDir/"data"/word::printf("%06d", timeIndex); // As per mkdir -p "data/000000" mkDir(dataDir); diff --git a/src/sampling/sampledSurface/writers/surfaceWriter.H b/src/sampling/sampledSurface/writers/surfaceWriter.H index 2b9b9315238d59417d3b31a84cea4706181a14d1..e22fca297735fc38461717b96feb7fc43f720af4 100644 --- a/src/sampling/sampledSurface/writers/surfaceWriter.H +++ b/src/sampling/sampledSurface/writers/surfaceWriter.H @@ -113,6 +113,16 @@ public: return false; } + //- Trigger for geometry changes. + // \note this is a stop-gap solution until the writing infrastructure + // is improved. + virtual void updateMesh + ( + const fileName& outputDir, + const fileName& surfaceName + ) const + {} + //- Write single surface geometry to file. virtual fileName write ( diff --git a/tutorials/compressible/rhoSimpleFoam/squareBend/system/controlDict b/tutorials/compressible/rhoSimpleFoam/squareBend/system/controlDict index b95b2cb2d2863fa1354e7f836db33c11a204d276..74ccb50c5a6f64c548fe6b612698394da1deea18 100644 --- a/tutorials/compressible/rhoSimpleFoam/squareBend/system/controlDict +++ b/tutorials/compressible/rhoSimpleFoam/squareBend/system/controlDict @@ -52,6 +52,7 @@ runTimeModifiable true; functions { #include "sampling" + // #include "samplingDebug" } diff --git a/tutorials/compressible/rhoSimpleFoam/squareBend/system/samplingDebug b/tutorials/compressible/rhoSimpleFoam/squareBend/system/samplingDebug index 796b038f1aeb99407fc6e8ca05c2bed11804f5da..19c0f2d5c6dd093c338dd6e516842864e96c5b55 100644 --- a/tutorials/compressible/rhoSimpleFoam/squareBend/system/samplingDebug +++ b/tutorials/compressible/rhoSimpleFoam/squareBend/system/samplingDebug @@ -21,6 +21,7 @@ debug ensight { collateTimes true; + // collateTimes false; } }