diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkData.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkData.H index 8116fcbe2490fa0c88dba529f0d91336a89a1f96..50e78e781c8ef9a70ae7e8553d9d272a91793df4 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkData.H +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkData.H @@ -11,7 +11,7 @@ if (!fieldsToUse.found(fieldName)) { variableGood = ( - fieldName.size() > 2 && fieldName(fieldName.size() - 2, 2) == "_0" + fieldName.size() > 2 && fieldName(fieldName.size()-2, 2) == "_0" ? false : IOobject ( diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkMeshMoving.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkMeshMoving.H index 455fa33c6604ddbe14c884b51218813aef71de8e..bda9220acbddf7feca356febe22a9724f7f27ce9 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkMeshMoving.H +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/checkMeshMoving.H @@ -12,14 +12,16 @@ if (timeDirs.size() > 1 && Pstream::master()) Info<< "Search for moving mesh ... " << flush; forAll(timeDirs, timeI) { + const word& timeName = timeDirs[timeI].name(); + meshMoving = ( - timeDirs[timeI].name() != mesh.pointsInstance() - && isDir(baseDir/timeDirs[timeI].name()/polyMesh::meshSubDir) + timeName != mesh.pointsInstance() + && isDir(baseDir/timeName/polyMesh::meshSubDir) && IOobject ( "points", - timeDirs[timeI].name(), + timeName, polyMesh::meshSubDir, mesh, IOobject::NO_READ, diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/findCloudFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/findCloudFields.H new file mode 100644 index 0000000000000000000000000000000000000000..0f228f723fe1b355c109ba7220a2f64b07df9f27 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/findCloudFields.H @@ -0,0 +1,93 @@ +// check all time directories for the following: + +// The fields for each cloud: +HashTable<HashTable<word>> cloudFields; + +// Identify if lagrangian data exist at any time step. +if (timeDirs.size() && !noLagrangian) +{ + const fileName& baseDir = mesh.time().path(); + const fileName& cloudPrefix = regionPrefix/cloud::prefix; + + Info<< "Searching for lagrangian ... " << flush; + + forAll(timeDirs, timeI) + { + const word& timeName = timeDirs[timeI].name(); + + // DO NOT USE -->> runTime.setTime(timeDirs[timeI], timeI); <<-- + // It incurs a large overhead when done so frequently. + + fileNameList cloudDirs = readDir + ( + baseDir/timeName/cloudPrefix, + fileName::DIRECTORY + ); + + forAll(cloudDirs, cloudI) + { + const word& cloudName = cloudDirs[cloudI]; + + IOobjectList cloudObjs + ( + mesh, + timeName, + cloudPrefix/cloudName + ); + + // clouds always require "positions" + if (cloudObjs.found("positions")) + { + HashTable<HashTable<word>>::iterator cloudIter = + cloudFields.find(cloudName); + + if (cloudIter == cloudFields.end()) + { + // A newly discovered cloud + cloudFields.insert(cloudName, HashTable<word>()); + cloudIter = cloudFields.find(cloudName); + } + + forAllConstIter(IOobjectList, cloudObjs, fieldIter) + { + const IOobject obj = *fieldIter(); + + // Add field and field type + cloudIter().insert + ( + obj.name(), + obj.headerClassName() + ); + } + } + } + } + + // prune out "positions" again since it gets treated specially + forAllIter(HashTable<HashTable<word>>, cloudFields, cloudIter) + { + cloudIter().erase("positions"); + } + + if (cloudFields.empty()) + { + Info<< "none detected." << endl; + } +} + + +// sorted list of cloud names +const wordList cloudNames(cloudFields.sortedToc()); + +if (cloudNames.size()) +{ + // complete the echo information + Info<< "("; + forAll(cloudNames, cloudNo) + { + Info<< ' ' << cloudNames[cloudNo]; + } + Info<< " ) " << endl; +} + +// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C b/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C index eaf75778156cd7786b6c62a0d5ba87e8f34535da..07000c7f7546801353ee116fd70e8caa03475e7d 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/foamToEnsight.C @@ -42,13 +42,16 @@ Usage \param -noZero \n Exclude the often incomplete initial conditions. - \param -patches patchList \n - Specify particular patches to write. - Specifying an empty list suppresses writing the internalMesh. + \param -noLagrangian \n + Suppress writing lagrangian positions and fields. \param -noPatches \n Suppress writing any patches. + \param -patches patchList \n + Specify particular patches to write. + Specifying an empty list suppresses writing the internalMesh. + \param -faceZones zoneList \n Specify faceZones to write, with wildcards @@ -126,6 +129,11 @@ int main(int argc, char *argv[]) "write values in nodes" ); argList::addBoolOption + ( + "noLagrangian", + "suppress writing lagrangian positions and fields" + ); + argList::addBoolOption ( "noPatches", "suppress writing any patches" @@ -298,6 +306,8 @@ int main(int argc, char *argv[]) fieldPatterns = wordReList(args.optionLookup("fields")()); } + const bool noLagrangian = args.optionFound("noLagrangian"); + word cellZoneName; const bool doCellZone = args.optionReadIfPresent("cellZone", cellZoneName); @@ -334,6 +344,7 @@ int main(int argc, char *argv[]) IOobjectList objects(mesh, runTime.timeName()); #include "checkMeshMoving.H" + #include "findCloudFields.H" if (Pstream::master()) { @@ -356,99 +367,19 @@ int main(int argc, char *argv[]) << setw(16) << "model:" << ensightMesh::geometryName << nl; } - } - - // Identify if lagrangian data exists any time step, and add clouds - // to the 'cloudNames' (sorted list) - wordList cloudNames; - { - wordHashSet allCloudNames; - - forAll(timeDirs, timeI) - { - runTime.setTime(timeDirs[timeI], timeI); - - fileNameList cloudDirs = readDir - ( - runTime.timePath()/regionPrefix/cloud::prefix, - fileName::DIRECTORY - ); - - forAll(cloudDirs, cloudI) - { - IOobjectList cloudObjs - ( - mesh, - runTime.timeName(), - cloud::prefix/cloudDirs[cloudI] - ); - - IOobject* positionsPtr = cloudObjs.lookup(word("positions")); - - if (positionsPtr) - { - allCloudNames.insert(cloudDirs[cloudI]); - } - } - } - - // sorted for consistency - cloudNames = allCloudNames.sortedToc(); - } - - // ignore special fields (_0 fields), - // ignore fields we don't handle, - // ignore fields that are not available for all time-steps - HashTable<bool> fieldsToUse; - HashTable<HashTable<word>> allCloudFields; - forAll(cloudNames, cloudNo) - { - const word& cloudName = cloudNames[cloudNo]; // Add the name of the cloud(s) to the case file header - if (Pstream::master()) + forAll(cloudNames, cloudNo) { + const word& cloudName = cloudNames[cloudNo]; + ensightCaseFile << setw(16) << "measured: 1" - << fileName(dataMask/cloud::prefix/cloudName/"positions").c_str() - << nl; - } - - // Create a new hash table for each cloud - allCloudFields.insert(cloudName, HashTable<word>()); - - // Identify the new cloud in the hash table - HashTable<HashTable<word>>::iterator newCloudIter = - allCloudFields.find(cloudName); - - // Loop over all times to build list of fields and field types - // for each cloud - forAll(timeDirs, timeI) - { - runTime.setTime(timeDirs[timeI], timeI); - - IOobjectList cloudObjs - ( - mesh, - runTime.timeName(), - cloud::prefix/cloudName - ); - - forAllConstIter(IOobjectList, cloudObjs, fieldIter) - { - const IOobject obj = *fieldIter(); - - if (obj.name() != "positions") - { - // Add field and field type - newCloudIter().insert - ( - obj.name(), - obj.headerClassName() - ); - } - } + << fileName + ( + dataMask/cloud::prefix/cloudName/"positions" + ).c_str() << nl; } } @@ -456,6 +387,11 @@ int main(int argc, char *argv[]) << timer.cpuTimeIncrement() << " s, " << mem.update().size() << " kB" << nl << endl; + // ignore special fields (_0 fields), + // ignore fields we don't handle, + // ignore fields that are not available for all time-steps + HashTable<bool> fieldsToUse; + label nTimeSteps = 0; forAll(timeDirs, timeIndex) { @@ -740,13 +676,7 @@ int main(int argc, char *argv[]) forAll(cloudNames, cloudNo) { const word& cloudName = cloudNames[cloudNo]; - if (!allCloudFields.found(cloudName)) - { - // extra safety - continue; - } - - const HashTable<word>& cloudFields = allCloudFields[cloudName]; + const HashTable<word>& theseCloudFields = cloudFields[cloudName]; fileNameList currentCloudDirs = readDir ( @@ -769,7 +699,7 @@ int main(int argc, char *argv[]) format ); - forAllConstIter(HashTable<word>, cloudFields, fieldIter) + forAllConstIter(HashTable<word>, theseCloudFields, fieldIter) { const word& fieldName = fieldIter.key(); const word& fieldType = fieldIter(); diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/findFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/findFields.H index 077490f1ecdaaa2116db06ced0bf4823aa0e4ec8..721ba05101adb48013b947fc89fb5fb52e2e4e2f 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/findFields.H +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/findFields.H @@ -8,7 +8,10 @@ HashTable<HashTable<word>> cloudFields; if (timeDirs.size()) { - IOobjectList objs(mesh, timeDirs.last().name()); + const fileName& cloudPrefix = regionPrefix/cloud::prefix; + const word& lastTimeName = timeDirs.last().name(); + + IOobjectList objs(mesh, lastTimeName); forAllConstIter(IOobjectList, objs, fieldIter) { @@ -31,14 +34,17 @@ if (timeDirs.size()) // // now check for lagrangian/<cloudName> // - fileNameList cloudDirs = readDir - ( - runTime.path() - / timeDirs.last().name() - / regionPrefix - / cloud::prefix, - fileName::DIRECTORY - ); + fileNameList cloudDirs; + if (!noLagrangian) + { + cloudDirs = readDir + ( + runTime.path() + / lastTimeName + / cloudPrefix, + fileName::DIRECTORY + ); + } forAll(cloudDirs, cloudI) { @@ -54,8 +60,8 @@ if (timeDirs.size()) IOobjectList objs ( mesh, - timeDirs.last().name(), - cloud::prefix/cloudName + lastTimeName, + cloudPrefix/cloudName ); bool hasPositions = false; @@ -89,17 +95,27 @@ if (timeDirs.size()) // for (label i=0; volumeFields.size() && i < timeDirs.size(); ++i) { - IOobjectList objs(mesh, timeDirs[i].name()); + const word& timeName = timeDirs[i].name(); - forAllIter(HashTable<word>, volumeFields, fieldIter) - { - const word& fieldName = fieldIter.key(); + // Everything is potentially missing, unless we discover otherwise + wordHashSet missing(volumeFields); - if (!objs.found(fieldName)) - { - volumeFields.erase(fieldIter); - } + // Avoid -->> IOobjectList objs(mesh, timeName); <<-- + // Too much overhead when done so frequently. + + fileNameList contents = readDir + ( + runTime.path() + / timeName, + fileName::FILE + ); + + forAll(contents, fileI) + { + missing.erase(contents[fileI].name()); } + + volumeFields.erase(missing); } } diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C index 8f00f0128c7453668bada4637404b7c3a419132f..34bce4adea4c4d393ce4fd60023718958c3b51d9 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C @@ -44,6 +44,9 @@ Usage \param -noZero \n Exclude the often incomplete initial conditions. + \param -noLagrangian \n + Suppress writing lagrangian positions and fields. + \param -index \<start\>\n Ignore the time index contained in the time file and use a simple indexing when creating the \c Ensight/data/######## files. @@ -101,6 +104,11 @@ int main(int argc, char *argv[]) "and use simple indexing when creating the files" ); argList::addBoolOption + ( + "noLagrangian", + "suppress writing lagrangian positions and fields" + ); + argList::addBoolOption ( "noMesh", "suppress writing the geometry. " @@ -158,7 +166,8 @@ int main(int argc, char *argv[]) // control for renumbering iterations label indexingNumber = 0; - bool optIndex = args.optionReadIfPresent("index", indexingNumber); + const bool optIndex = args.optionReadIfPresent("index", indexingNumber); + const bool noLagrangian = args.optionFound("noLagrangian"); // always write the geometry, unless the -noMesh option is specified bool optNoMesh = args.optionFound("noMesh"); @@ -389,15 +398,9 @@ int main(int argc, char *argv[]) forAllConstIter(HashTable<HashTable<word>>, cloudFields, cloudIter) { const word& cloudName = cloudIter.key(); + const fileName& cloudPrefix = regionPrefix/cloud::prefix; - if - ( - !isDir - ( - runTime.timePath()/regionPrefix/ - cloud::prefix/cloudName - ) - ) + if (!isDir(runTime.timePath()/cloudPrefix/cloudName)) { continue; } @@ -406,27 +409,24 @@ int main(int argc, char *argv[]) ( mesh, runTime.timeName(), - cloud::prefix/cloudName + cloudPrefix/cloudName ); // check that the positions field is present for this time - IOobject* positionPtr = cloudObjs.lookup(word("positions")); - if (positionPtr != NULL) - { - ensightParticlePositions - ( - mesh, - dataDir, - subDir, - cloudName, - format - ); - } - else + if (!cloudObjs.found("positions")) { continue; } + ensightParticlePositions + ( + mesh, + dataDir, + subDir, + cloudName, + format + ); + Info<< "write " << cloudName << " (" << flush; forAllConstIter(HashTable<word>, cloudIter(), fieldIter) @@ -439,7 +439,7 @@ int main(int argc, char *argv[]) if (!fieldObject) { Info<< "missing " - << runTime.timeName()/cloud::prefix/cloudName + << runTime.timeName()/cloudPrefix/cloudName / fieldName << endl; continue;