From c5bd5393df6f12dbc2dbfa260c1b9b788c2e3784 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Tue, 4 Jul 2017 11:57:54 +0200 Subject: [PATCH] ENH: lazier field loading in foamToVTK - avoid loading surface fields if there are no faceZones - avoid pointMesh if there are no appropriate point fields --- .../dataConversion/foamToVTK/foamToVTK.C | 146 ++++++++++++++---- .../dataConversion/foamToVTK/readFields.C | 21 +-- .../dataConversion/foamToVTK/readFields.H | 4 +- 3 files changed, 134 insertions(+), 37 deletions(-) diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK.C index ccc00ba5d4..7896889cb0 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK.C +++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamToVTK.C @@ -55,7 +55,7 @@ Usage - \par -fields \ Convert selected fields only. For example, \verbatim - -fields "( p T U )" + -fields '( p T U )' \endverbatim The quoting is required to avoid shell expansions and to pass the information as a single argument. @@ -231,10 +231,49 @@ labelList getSelectedPatches Info<< " patch " << patchi << " " << pp.name() << endl; } } + return patchIDs.shrink(); } +HashTable candidateObjects +( + const IOobjectList& objects, + const wordHashSet& supportedTypes, + const bool specifiedFields, + const wordHashSet& selectedFields +) +{ + // Special case = no fields + if (specifiedFields && selectedFields.empty()) + { + return HashTable(); + } + + HashTable usable = objects.classes(); + + // Limited to types that we explicitly handle + usable.retain(supportedTypes); + + // If specified, further limit to selected fields + if (specifiedFields) + { + forAllIters(usable, iter) + { + iter.object().retain(selectedFields); + } + + // Prune entries without any fields + usable.filterValues + ( + [](const wordHashSet& vals){ return !vals.empty(); } + ); + } + + return usable; +} + + // // Process args for output options // Default from foamVtkOutputOptions is inline ASCII xml @@ -527,9 +566,39 @@ int main(int argc, char *argv[]) #include "findClouds.H" - forAll(timeDirs, timeI) + // Supported volume field types + const wordHashSet vFieldTypes { - runTime.setTime(timeDirs[timeI], timeI); + volScalarField::typeName, + volVectorField::typeName, + volSphericalTensorField::typeName, + volSymmTensorField::typeName, + volTensorField::typeName + }; + + // Supported dimensioned field types + const wordHashSet dFieldTypes + { + volScalarField::Internal::typeName, + volVectorField::Internal::typeName, + volSphericalTensorField::Internal::typeName, + volSymmTensorField::Internal::typeName, + volTensorField::Internal::typeName + }; + + // Supported point field types + const wordHashSet pFieldTypes + { + pointScalarField::typeName, + pointVectorField::typeName, + pointSphericalTensorField::typeName, + pointSymmTensorField::typeName, + pointTensorField::typeName + }; + + forAll(timeDirs, timei) + { + runTime.setTime(timeDirs[timei], timei); Info<< "Time: " << runTime.timeName() << endl; @@ -611,14 +680,15 @@ int main(int argc, char *argv[]) // Search for list of objects for this time IOobjectList objects(mesh, runTime.timeName()); - HashSet selectedFields; + wordHashSet selectedFields; const bool specifiedFields = args.optionReadIfPresent ( "fields", selectedFields ); - // Construct the vol fields (on the original mesh if subsetted) + // Construct the vol fields + // References the original mesh, but uses subsetted portion only. PtrList vScalarFld; PtrList vVectorFld; @@ -626,7 +696,16 @@ int main(int argc, char *argv[]) PtrList vSymTensorFld; PtrList vTensorFld; - if (!specifiedFields || selectedFields.size()) + if + ( + candidateObjects + ( + objects, + vFieldTypes, + specifiedFields, + selectedFields + ).size() + ) { readFields ( @@ -696,7 +775,16 @@ int main(int argc, char *argv[]) PtrList dSymTensorFld; PtrList dTensorFld; - if (!specifiedFields || selectedFields.size()) + if + ( + candidateObjects + ( + objects, + dFieldTypes, + specifiedFields, + selectedFields + ).size() + ) { readFields ( @@ -767,12 +855,24 @@ int main(int argc, char *argv[]) // Construct pointMesh only if necessary since it constructs edge // addressing (expensive on polyhedral meshes) - if (!noPointValues && !(specifiedFields && selectedFields.empty())) + if + ( + !noPointValues + && candidateObjects + ( + objects, + pFieldTypes, + specifiedFields, + selectedFields + ).size() + ) { + const pointMesh& ptMesh = pointMesh::New(meshRef.baseMesh()); + readFields ( meshRef, - pointMesh::New(meshRef.baseMesh()), + ptMesh, objects, selectedFields, pScalarFld @@ -782,7 +882,7 @@ int main(int argc, char *argv[]) readFields ( meshRef, - pointMesh::New(meshRef.baseMesh()), + ptMesh, objects, selectedFields, pVectorFld @@ -792,7 +892,7 @@ int main(int argc, char *argv[]) readFields ( meshRef, - pointMesh::New(meshRef.baseMesh()), + ptMesh, objects, selectedFields, pSphTensorFld @@ -802,7 +902,7 @@ int main(int argc, char *argv[]) readFields ( meshRef, - pointMesh::New(meshRef.baseMesh()), + ptMesh, objects, selectedFields, pSymTensorFld @@ -812,7 +912,7 @@ int main(int argc, char *argv[]) readFields ( meshRef, - pointMesh::New(meshRef.baseMesh()), + ptMesh, objects, selectedFields, pTensorFld @@ -1138,7 +1238,7 @@ int main(int argc, char *argv[]) // //--------------------------------------------------------------------- - if (doFaceZones) + if (doFaceZones && !mesh.faceZones().empty()) { PtrList sScalarFld; readFields @@ -1162,12 +1262,8 @@ int main(int argc, char *argv[]) ); print(" surfVector :", Info, sVectorFld); - const faceZoneMesh& zones = mesh.faceZones(); - - forAll(zones, zoneI) + for (const faceZone& fz : mesh.faceZones()) { - const faceZone& fz = zones[zoneI]; - mkDir(fvPath/fz.name()); fileName outputName = @@ -1213,10 +1309,8 @@ int main(int argc, char *argv[]) // //--------------------------------------------------------------------- - forAll(cloudNames, cloudNo) + for (const fileName& cloudName : cloudNames) { - const fileName& cloudName = cloudNames[cloudNo]; - // Always create the cloud directory. mkDir(fvPath/cloud::prefix/cloudName); @@ -1358,13 +1452,13 @@ int main(int argc, char *argv[]) dirs.setSize(sz+1); dirs[sz] = "."; - forAll(dirs, i) + for (const fileName& subDir : dirs) { - fileNameList subFiles(readDir(procVTK/dirs[i], fileName::FILE)); + fileNameList subFiles(readDir(procVTK/subDir, fileName::FILE)); - forAll(subFiles, j) + for (const fileName& subFile : subFiles) { - fileName procFile(procVTK/dirs[i]/subFiles[j]); + fileName procFile(procVTK/subDir/subFile); if (exists(procFile)) { diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/readFields.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/readFields.C index 172a83cf23..1db40528a1 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/readFields.C +++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/readFields.C @@ -34,7 +34,7 @@ namespace Foam // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // template -void readFields +label readFields ( const meshSubsetHelper& helper, const typename GeoField::Mesh& mesh, @@ -43,29 +43,32 @@ void readFields PtrList& fields ) { - // Search list of objects for fields of type GeomField - IOobjectList fieldObjects(objects.lookupClass(GeoField::typeName)); - - // Construct the fields - fields.setSize(fieldObjects.size()); label nFields = 0; - forAllConstIter(IOobjectList, fieldObjects, iter) + // Available fields of type GeomField + const wordList fieldNames = objects.sortedNames(GeoField::typeName); + + fields.setSize(fieldNames.size()); + + // Construct the fields + for (const word& fieldName : fieldNames) { - if (selectedFields.empty() || selectedFields.found(iter()->name())) + if (selectedFields.empty() || selectedFields.found(fieldName)) { fields.set ( nFields++, helper.interpolate ( - GeoField(*iter(), mesh) + GeoField(*(objects[fieldName]), mesh) ).ptr() ); } } fields.setSize(nFields); + + return nFields; } diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/readFields.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/readFields.H index 085570d685..7021385255 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToVTK/readFields.H +++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/readFields.H @@ -44,9 +44,9 @@ SourceFiles namespace Foam { -// Read the fields and optionally subset and put on the pointer list +// Read the fields, optionally subset, and place on the pointer list template -void readFields +label readFields ( const meshSubsetHelper& helper, const typename GeoField::Mesh& mesh,