ENH: lazier field loading in foamToVTK

- avoid loading surface fields if there are no faceZones

- avoid pointMesh if there are no appropriate point fields
This commit is contained in:
Mark Olesen
2017-07-04 11:57:54 +02:00
parent 6dd5a5f35f
commit c5bd5393df
3 changed files with 134 additions and 37 deletions

View File

@ -55,7 +55,7 @@ Usage
- \par -fields \<fields\> - \par -fields \<fields\>
Convert selected fields only. For example, Convert selected fields only. For example,
\verbatim \verbatim
-fields "( p T U )" -fields '( p T U )'
\endverbatim \endverbatim
The quoting is required to avoid shell expansions and to pass the The quoting is required to avoid shell expansions and to pass the
information as a single argument. information as a single argument.
@ -231,10 +231,49 @@ labelList getSelectedPatches
Info<< " patch " << patchi << " " << pp.name() << endl; Info<< " patch " << patchi << " " << pp.name() << endl;
} }
} }
return patchIDs.shrink(); return patchIDs.shrink();
} }
HashTable<wordHashSet> candidateObjects
(
const IOobjectList& objects,
const wordHashSet& supportedTypes,
const bool specifiedFields,
const wordHashSet& selectedFields
)
{
// Special case = no fields
if (specifiedFields && selectedFields.empty())
{
return HashTable<wordHashSet>();
}
HashTable<wordHashSet> 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 // Process args for output options
// Default from foamVtkOutputOptions is inline ASCII xml // Default from foamVtkOutputOptions is inline ASCII xml
@ -527,9 +566,39 @@ int main(int argc, char *argv[])
#include "findClouds.H" #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; Info<< "Time: " << runTime.timeName() << endl;
@ -611,14 +680,15 @@ int main(int argc, char *argv[])
// Search for list of objects for this time // Search for list of objects for this time
IOobjectList objects(mesh, runTime.timeName()); IOobjectList objects(mesh, runTime.timeName());
HashSet<word> selectedFields; wordHashSet selectedFields;
const bool specifiedFields = args.optionReadIfPresent const bool specifiedFields = args.optionReadIfPresent
( (
"fields", "fields",
selectedFields 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<const volScalarField> vScalarFld; PtrList<const volScalarField> vScalarFld;
PtrList<const volVectorField> vVectorFld; PtrList<const volVectorField> vVectorFld;
@ -626,7 +696,16 @@ int main(int argc, char *argv[])
PtrList<const volSymmTensorField> vSymTensorFld; PtrList<const volSymmTensorField> vSymTensorFld;
PtrList<const volTensorField> vTensorFld; PtrList<const volTensorField> vTensorFld;
if (!specifiedFields || selectedFields.size()) if
(
candidateObjects
(
objects,
vFieldTypes,
specifiedFields,
selectedFields
).size()
)
{ {
readFields readFields
( (
@ -696,7 +775,16 @@ int main(int argc, char *argv[])
PtrList<const volSymmTensorField::Internal> dSymTensorFld; PtrList<const volSymmTensorField::Internal> dSymTensorFld;
PtrList<const volTensorField::Internal> dTensorFld; PtrList<const volTensorField::Internal> dTensorFld;
if (!specifiedFields || selectedFields.size()) if
(
candidateObjects
(
objects,
dFieldTypes,
specifiedFields,
selectedFields
).size()
)
{ {
readFields readFields
( (
@ -767,12 +855,24 @@ int main(int argc, char *argv[])
// Construct pointMesh only if necessary since it constructs edge // Construct pointMesh only if necessary since it constructs edge
// addressing (expensive on polyhedral meshes) // 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 readFields
( (
meshRef, meshRef,
pointMesh::New(meshRef.baseMesh()), ptMesh,
objects, objects,
selectedFields, selectedFields,
pScalarFld pScalarFld
@ -782,7 +882,7 @@ int main(int argc, char *argv[])
readFields readFields
( (
meshRef, meshRef,
pointMesh::New(meshRef.baseMesh()), ptMesh,
objects, objects,
selectedFields, selectedFields,
pVectorFld pVectorFld
@ -792,7 +892,7 @@ int main(int argc, char *argv[])
readFields readFields
( (
meshRef, meshRef,
pointMesh::New(meshRef.baseMesh()), ptMesh,
objects, objects,
selectedFields, selectedFields,
pSphTensorFld pSphTensorFld
@ -802,7 +902,7 @@ int main(int argc, char *argv[])
readFields readFields
( (
meshRef, meshRef,
pointMesh::New(meshRef.baseMesh()), ptMesh,
objects, objects,
selectedFields, selectedFields,
pSymTensorFld pSymTensorFld
@ -812,7 +912,7 @@ int main(int argc, char *argv[])
readFields readFields
( (
meshRef, meshRef,
pointMesh::New(meshRef.baseMesh()), ptMesh,
objects, objects,
selectedFields, selectedFields,
pTensorFld pTensorFld
@ -1138,7 +1238,7 @@ int main(int argc, char *argv[])
// //
//--------------------------------------------------------------------- //---------------------------------------------------------------------
if (doFaceZones) if (doFaceZones && !mesh.faceZones().empty())
{ {
PtrList<const surfaceScalarField> sScalarFld; PtrList<const surfaceScalarField> sScalarFld;
readFields readFields
@ -1162,12 +1262,8 @@ int main(int argc, char *argv[])
); );
print(" surfVector :", Info, sVectorFld); print(" surfVector :", Info, sVectorFld);
const faceZoneMesh& zones = mesh.faceZones(); for (const faceZone& fz : mesh.faceZones())
forAll(zones, zoneI)
{ {
const faceZone& fz = zones[zoneI];
mkDir(fvPath/fz.name()); mkDir(fvPath/fz.name());
fileName outputName = 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. // Always create the cloud directory.
mkDir(fvPath/cloud::prefix/cloudName); mkDir(fvPath/cloud::prefix/cloudName);
@ -1358,13 +1452,13 @@ int main(int argc, char *argv[])
dirs.setSize(sz+1); dirs.setSize(sz+1);
dirs[sz] = "."; 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)) if (exists(procFile))
{ {

View File

@ -34,7 +34,7 @@ namespace Foam
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
template<class GeoField> template<class GeoField>
void readFields label readFields
( (
const meshSubsetHelper& helper, const meshSubsetHelper& helper,
const typename GeoField::Mesh& mesh, const typename GeoField::Mesh& mesh,
@ -43,29 +43,32 @@ void readFields
PtrList<const GeoField>& fields PtrList<const GeoField>& 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; 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 fields.set
( (
nFields++, nFields++,
helper.interpolate helper.interpolate
( (
GeoField(*iter(), mesh) GeoField(*(objects[fieldName]), mesh)
).ptr() ).ptr()
); );
} }
} }
fields.setSize(nFields); fields.setSize(nFields);
return nFields;
} }

View File

@ -44,9 +44,9 @@ SourceFiles
namespace Foam 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<class GeoField> template<class GeoField>
void readFields label readFields
( (
const meshSubsetHelper& helper, const meshSubsetHelper& helper,
const typename GeoField::Mesh& mesh, const typename GeoField::Mesh& mesh,