Commit 42bf91f3 authored by mattijs's avatar mattijs
Browse files

Merge branch 'develop' of develop.openfoam.com:Development/OpenFOAM-plus into develop

parents c55dc325 e62e34f0
......@@ -55,7 +55,7 @@ Usage
- \par -fields \<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.
......@@ -64,10 +64,12 @@ Usage
Write surfaceScalarFields (e.g., phi)
- \par -cellSet \<name\>
- \par -faceSet \<name\>
- \par -cellZone \<name\>
Restrict conversion to either the cellSet or the cellZone.
- \par -faceSet \<name\>
- \par -pointSet \<name\>
Restrict conversion to the cellSet, faceSet or pointSet.
Restrict conversion to the faceSet or pointSet.
- \par -nearCellValue
Output cell value on patches instead of patch value itself
......@@ -231,10 +233,49 @@ labelList getSelectedPatches
Info<< " patch " << patchi << " " << pp.name() << endl;
}
}
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
// Default from foamVtkOutputOptions is inline ASCII xml
......@@ -320,6 +361,12 @@ int main(int argc, char *argv[])
"convert a mesh subset corresponding to the specified cellSet"
);
argList::addOption
(
"cellZone",
"name",
"convert a mesh subset corresponding to the specified cellZone"
);
argList::addOption
(
"faceSet",
"name",
......@@ -451,10 +498,17 @@ int main(int argc, char *argv[])
string vtkName = runTime.caseName();
word cellSetName;
if (args.optionReadIfPresent("cellSet", cellSetName))
meshSubsetHelper::subsetType cellSubsetType = meshSubsetHelper::NONE;
word cellSubsetName;
if (args.optionReadIfPresent("cellSet", cellSubsetName))
{
vtkName = cellSubsetName;
cellSubsetType = meshSubsetHelper::SET;
}
else if (args.optionReadIfPresent("cellZone", cellSubsetName))
{
vtkName = cellSetName;
vtkName = cellSubsetName;
cellSubsetType = meshSubsetHelper::ZONE;
}
else if (Pstream::parRun())
{
......@@ -495,7 +549,7 @@ int main(int argc, char *argv[])
(
args.optionFound("time")
|| args.optionFound("latestTime")
|| cellSetName.size()
|| cellSubsetName.size()
|| faceSetName.size()
|| pointSetName.size()
|| regionName != polyMesh::defaultRegion
......@@ -516,7 +570,7 @@ int main(int argc, char *argv[])
instantList timeDirs = timeSelector::select0(runTime, args);
// Mesh wrapper: does subsetting and decomposition
meshSubsetHelper meshRef(mesh, meshSubsetHelper::SET, cellSetName);
meshSubsetHelper meshRef(mesh, cellSubsetType, cellSubsetName);
// Collect decomposition information etc.
vtk::vtuCells vtuMeshCells(fmtType, decomposePoly);
......@@ -527,9 +581,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 +695,15 @@ int main(int argc, char *argv[])
// Search for list of objects for this time
IOobjectList objects(mesh, runTime.timeName());
HashSet<word> 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<const volScalarField> vScalarFld;
PtrList<const volVectorField> vVectorFld;
......@@ -626,7 +711,16 @@ int main(int argc, char *argv[])
PtrList<const volSymmTensorField> vSymTensorFld;
PtrList<const volTensorField> vTensorFld;
if (!specifiedFields || selectedFields.size())
if
(
candidateObjects
(
objects,
vFieldTypes,
specifiedFields,
selectedFields
).size()
)
{
readFields
(
......@@ -636,7 +730,7 @@ int main(int argc, char *argv[])
selectedFields,
vScalarFld
);
print(" volScalar :", Info, vScalarFld);
print(" volScalar :", Info, vScalarFld);
readFields
(
......@@ -646,7 +740,7 @@ int main(int argc, char *argv[])
selectedFields,
vVectorFld
);
print(" volVector :", Info, vVectorFld);
print(" volVector :", Info, vVectorFld);
readFields
(
......@@ -656,7 +750,7 @@ int main(int argc, char *argv[])
selectedFields,
vSphTensorf
);
print(" volSphericalTensor :", Info, vSphTensorf);
print(" volSphTensor :", Info, vSphTensorf);
readFields
(
......@@ -666,7 +760,7 @@ int main(int argc, char *argv[])
selectedFields,
vSymTensorFld
);
print(" volSymmTensor :", Info, vSymTensorFld);
print(" volSymmTensor :", Info, vSymTensorFld);
readFields
(
......@@ -676,7 +770,7 @@ int main(int argc, char *argv[])
selectedFields,
vTensorFld
);
print(" volTensor :", Info, vTensorFld);
print(" volTensor :", Info, vTensorFld);
}
const label nVolFields =
......@@ -696,7 +790,16 @@ int main(int argc, char *argv[])
PtrList<const volSymmTensorField::Internal> dSymTensorFld;
PtrList<const volTensorField::Internal> dTensorFld;
if (!specifiedFields || selectedFields.size())
if
(
candidateObjects
(
objects,
dFieldTypes,
specifiedFields,
selectedFields
).size()
)
{
readFields
(
......@@ -706,7 +809,7 @@ int main(int argc, char *argv[])
selectedFields,
dScalarFld
);
print(" volScalar::Internal :", Info, dScalarFld);
print(" volScalar::Internal :", Info, dScalarFld);
readFields
(
......@@ -716,7 +819,7 @@ int main(int argc, char *argv[])
selectedFields,
dVectorFld
);
print(" volVector::Internal :", Info, dVectorFld);
print(" volVector::Internal :", Info, dVectorFld);
readFields
(
......@@ -726,7 +829,7 @@ int main(int argc, char *argv[])
selectedFields,
dSphTensorFld
);
print(" volSphericalTensor::Internal :", Info, dSphTensorFld);
print(" volSphTensor::Internal :", Info, dSphTensorFld);
readFields
(
......@@ -736,7 +839,7 @@ int main(int argc, char *argv[])
selectedFields,
dSymTensorFld
);
print(" volSymmTensor::Internal :", Info, dSymTensorFld);
print(" volSymmTensor::Internal :", Info, dSymTensorFld);
readFields
(
......@@ -746,7 +849,7 @@ int main(int argc, char *argv[])
selectedFields,
dTensorFld
);
print(" volTensor::Internal :", Info, dTensorFld);
print(" volTensor::Internal :", Info, dTensorFld);
}
const label nDimFields =
......@@ -767,57 +870,69 @@ 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
);
print(" pointScalar :", Info, pScalarFld);
print(" pointScalar :", Info, pScalarFld);
readFields
(
meshRef,
pointMesh::New(meshRef.baseMesh()),
ptMesh,
objects,
selectedFields,
pVectorFld
);
print(" pointVector :", Info, pVectorFld);
print(" pointVector :", Info, pVectorFld);
readFields
(
meshRef,
pointMesh::New(meshRef.baseMesh()),
ptMesh,
objects,
selectedFields,
pSphTensorFld
);
print(" pointSphTensor : ", Info, pSphTensorFld);
print(" pointSphTensor : ", Info, pSphTensorFld);
readFields
(
meshRef,
pointMesh::New(meshRef.baseMesh()),
ptMesh,
objects,
selectedFields,
pSymTensorFld
);
print(" pointSymmTensor :", Info, pSymTensorFld);
print(" pointSymmTensor :", Info, pSymTensorFld);
readFields
(
meshRef,
pointMesh::New(meshRef.baseMesh()),
ptMesh,
objects,
selectedFields,
pTensorFld
);
print(" pointTensor :", Info, pTensorFld);
print(" pointTensor :", Info, pTensorFld);
}
const label nPointFields =
......@@ -831,16 +946,8 @@ int main(int argc, char *argv[])
{
if (vtuMeshCells.empty())
{
// subMesh or baseMesh
vtuMeshCells.reset(meshRef.mesh());
// Convert cellMap, addPointCellLabels to global cell ids
if (meshRef.useSubMesh())
{
vtuMeshCells.renumberCells
(
meshRef.subsetter().cellMap()
);
}
}
// Create file and write header
......@@ -856,7 +963,7 @@ int main(int argc, char *argv[])
// Write mesh
vtk::internalWriter writer
(
meshRef.baseMesh(),
meshRef.mesh(),
vtuMeshCells,
outputName,
fmtType
......@@ -936,7 +1043,7 @@ int main(int argc, char *argv[])
selectedFields,
sScalarFld
);
print(" surfScalar :", Info, sScalarFld);
print(" surfScalar :", Info, sScalarFld);
PtrList<const surfaceVectorField> sVectorFld;
readFields
......@@ -947,7 +1054,7 @@ int main(int argc, char *argv[])
selectedFields,
sVectorFld
);
print(" surfVector :", Info, sVectorFld);
print(" surfVector :", Info, sVectorFld);
if (sScalarFld.size())
{
......@@ -1006,11 +1113,11 @@ int main(int argc, char *argv[])
fileName outputName
(
fvPath/"allPatches"
/ (meshRef.useSubMesh() ? cellSetName : "allPatches")
/ (meshRef.useSubMesh() ? cellSubsetName : "allPatches")
+ "_"
+ timeDesc
);
Info<< " Combined patches : "
Info<< " Combined patches : "
<< relativeName(runTime, outputName) << nl;
vtk::patchWriter writer
......@@ -1076,7 +1183,7 @@ int main(int argc, char *argv[])
fileName outputName
(
fvPath/pp.name()
/ (meshRef.useSubMesh() ? cellSetName : pp.name())
/ (meshRef.useSubMesh() ? cellSubsetName : pp.name())
+ "_"
+ timeDesc
);
......@@ -1095,7 +1202,7 @@ int main(int argc, char *argv[])
if (!isA<emptyPolyPatch>(pp))
{
// VolFields + patchID
writer.beginCellData(1+nVolFields);
writer.beginCellData(1 + nVolFields);
// Write patchID field
writer.writePatchIDs();
......@@ -1146,7 +1253,7 @@ int main(int argc, char *argv[])
//
//---------------------------------------------------------------------
if (doFaceZones)
if (doFaceZones && !mesh.faceZones().empty())
{
PtrList<const surfaceScalarField> sScalarFld;
readFields
......@@ -1157,7 +1264,7 @@ int main(int argc, char *argv[])
selectedFields,
sScalarFld
);
print(" surfScalar :", Info, sScalarFld);
print(" surfScalar :", Info, sScalarFld);
PtrList<const surfaceVectorField> sVectorFld;
readFields
......@@ -1168,20 +1275,16 @@ int main(int argc, char *argv[])
selectedFields,
sVectorFld
);
print(" surfVector :", Info, sVectorFld);
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 =
(
fvPath/fz.name()
/ (meshRef.useSubMesh() ? cellSetName : fz.name())
/ (meshRef.useSubMesh() ? cellSubsetName : fz.name())
+ "_"
+ timeDesc
);
......@@ -1221,10 +1324,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);
......@@ -1246,15 +1347,15 @@ int main(int argc, char *argv[])
if (sprayObjs.found("positions"))
{
wordList labelNames(sprayObjs.names(labelIOField::typeName));
Info<< " labels :";
Info<< " labels :";
print(Info, labelNames);
wordList scalarNames(sprayObjs.names(scalarIOField::typeName));
Info<< " scalars :";
Info<< " scalars :";
print(Info, scalarNames);
wordList vectorNames(sprayObjs.names(vectorIOField::typeName));
Info<< " vectors :";
Info<< " vectors :";
print(Info, vectorNames);
wordList sphereNames
......@@ -1264,7 +1365,7 @@ int main(int argc, char *argv[])
sphericalTensorIOField::typeName
)
);
Info<< " spherical tensors :";
Info<< " sphTensors :";
print(Info, sphereNames);
wordList symmNames
......@@ -1274,11 +1375,11 @@ int main(int argc, char *argv[])
symmTensorIOField::typeName
)
);
Info<< " symm tensors :";
Info<< " symmTensors :";
print(Info, symmNames);
wordList tensorNames(sprayObjs.names(tensorIOField::typeName));
Info<< " tensors :";
Info<< " tensors :";
print(Info, tensorNames);
vtk::lagrangianWriter writer
......@@ -1366,13 +1467,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))
{
......
......@@ -34,7 +34,7 @@ namespace Foam
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
template<class GeoField>
void readFields
label readFields
(
const meshSubsetHelper& helper,
const typename GeoField::Mesh& mesh,
......@@ -43,29 +43,32 @@ void readFields
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;
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
(