ENH: ensightWrite, vtkWrite support for excluding fields and patches

- functionality similar to that provided by foamToEnsight, foamToVTK
  which allows blocking out patches (eg, outer walls, inlet/outlet)
  that are not particularly interesting to visualize
This commit is contained in:
Mark Olesen
2022-11-18 15:28:14 +01:00
parent ec1d66d640
commit d9ab5d54ef
10 changed files with 192 additions and 118 deletions

View File

@ -56,7 +56,7 @@ namespace functionObjects
Foam::label Foam::functionObjects::ensightWrite::writeAllVolFields
(
const fvMeshSubset& proxy,
const wordHashSet& acceptField
const wordHashSet& candidateNames
)
{
label count = 0;
@ -70,7 +70,7 @@ Foam::label Foam::functionObjects::ensightWrite::writeAllVolFields
( \
scratch, \
proxy, \
acceptField \
candidateNames \
);
doLocalCode(scalar);
@ -105,6 +105,7 @@ Foam::functionObjects::ensightWrite::ensightWrite
consecutive_(false),
meshState_(polyMesh::TOPO_CHANGE),
selectFields_(),
blockFields_(),
selection_(),
meshSubset_(mesh_),
ensCase_(nullptr),
@ -160,6 +161,11 @@ bool Foam::functionObjects::ensightWrite::read(const dictionary& dict)
list.uniq();
writeOpts_.patchSelection(list);
}
if (dict.readIfPresent("excludePatches", list))
{
list.uniq();
writeOpts_.patchExclude(list);
}
if (dict.readIfPresent("faceZones", list))
{
@ -234,19 +240,37 @@ bool Foam::functionObjects::ensightWrite::write()
ensMesh_().write(os);
}
// TBD: handle allow/deny filters
wordHashSet acceptField(mesh_.names<void>(selectFields_));
// Output fields MUST be specified to avoid accidentally
// writing everything. Can still use ".*" for everything
wordHashSet candidateNames(0);
if (!selectFields_.empty())
{
if (!blockFields_.empty())
{
// With 'allow' and 'deny' filters
wordRes::filter filter(selectFields_, blockFields_);
candidateNames = mesh_.names<void>(filter);
}
else
{
// With 'allow' filter only
candidateNames = mesh_.names<void>(selectFields_);
}
}
// Prune restart fields
acceptField.filterKeys
candidateNames.filterKeys
(
[](const word& k){ return k.ends_with("_0"); },
true // prune
);
Log << type() << " " << name() << " write: (";
writeAllVolFields(meshSubset_, acceptField);
writeAllVolFields(meshSubset_, candidateNames);
Log << " )" << nl;

View File

@ -46,6 +46,7 @@ Description
width 12;
fields (U p);
// excludeFields ("force.*");
selection
{
@ -85,6 +86,7 @@ Description
Property | Description | Required | Default
type | Type name: ensightWrite | yes |
fields | Fields to output | yes |
excludeFields | Exclude fields from output (wordRe list) | no |
boundary | Convert boundary fields | no | true
internal | Convert internal fields | no | true
nodeValues | Write values at nodes | no | false
@ -106,6 +108,7 @@ Description
region | Name for a single region | no | region0
faceZones | Select faceZones to write | no |
patches | Limit to listed patches (wordRe list) | no |
excludePatches | Exclude specified patches | no |
selection | Cell selection (topoSet actions) | no | empty dict
\endtable
@ -182,9 +185,12 @@ class ensightWrite
//- Track changes in mesh geometry
enum polyMesh::readUpdateState meshState_;
//- Requested names of fields to process
//- Requested selection of fields to process
wordRes selectFields_;
//- Requested selection of fields to block
wordRes blockFields_;
//- Dictionary of volume selections
dictionary selection_;
@ -231,14 +237,14 @@ class ensightWrite
(
ensightOutput::floatBufferType& scratch,
const fvMeshSubset& proxy,
const wordHashSet& acceptField
const wordHashSet& candidateNames
);
//- Write all volume fields
label writeAllVolFields
(
const fvMeshSubset& proxy,
const wordHashSet& acceptField
const wordHashSet& candidateNames
);
//- No copy construct

View File

@ -34,7 +34,7 @@ Foam::label Foam::functionObjects::ensightWrite::writeVolFieldsImpl
(
ensightOutput::floatBufferType& scratch,
const fvMeshSubset& proxy,
const wordHashSet& acceptField
const wordHashSet& candidateNames
)
{
typedef GeometricField<Type, fvPatchField, volMesh> GeoField;
@ -43,16 +43,15 @@ Foam::label Foam::functionObjects::ensightWrite::writeVolFieldsImpl
label count = 0;
for (const word& fieldName : baseMesh.sortedNames<GeoField>(acceptField))
for
(
const GeoField& origField
: baseMesh.sorted<GeoField>(candidateNames)
)
{
const auto* fieldptr = baseMesh.findObject<GeoField>(fieldName);
const word& fieldName = origField.name();
if (!fieldptr)
{
continue;
}
auto tfield = fvMeshSubsetProxy::interpolate(proxy, *fieldptr);
auto tfield = fvMeshSubsetProxy::interpolate(proxy, origField);
const auto& field = tfield();
autoPtr<ensightFile> os = ensCase().newData<Type>(fieldName);

View File

@ -102,6 +102,10 @@ bool Foam::functionObjects::ensightWrite::readSelection(const dictionary& dict)
dict.readEntry("fields", selectFields_);
selectFields_.uniq();
blockFields_.clear();
dict.readIfPresent("blockFields", blockFields_);
blockFields_.uniq();
// Actions to define selection
selection_ = dict.subOrEmptyDict("selection");

View File

@ -48,6 +48,9 @@ namespace functionObjects
}
// Implementation
#include "vtkWriteImpl.C"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::label Foam::functionObjects::vtkWrite::writeAllVolFields
@ -55,28 +58,31 @@ Foam::label Foam::functionObjects::vtkWrite::writeAllVolFields
autoPtr<vtk::internalWriter>& internalWriter,
UPtrList<vtk::patchWriter>& patchWriters,
const fvMeshSubset& proxy,
const wordHashSet& acceptField
const wordHashSet& candidateNames
) const
{
#undef vtkWrite_WRITE_FIELD
#define vtkWrite_WRITE_FIELD(FieldType) \
writeVolFields<FieldType> \
( \
internalWriter, \
patchWriters, \
proxy, \
acceptField \
)
label count = 0;
count += vtkWrite_WRITE_FIELD(volScalarField);
count += vtkWrite_WRITE_FIELD(volVectorField);
count += vtkWrite_WRITE_FIELD(volSphericalTensorField);
count += vtkWrite_WRITE_FIELD(volSymmTensorField);
count += vtkWrite_WRITE_FIELD(volTensorField);
#undef vtkWrite_WRITE_FIELD
{
#undef doLocalCode
#define doLocalCode(FieldType) \
count += writeVolFieldsImpl<FieldType> \
( \
internalWriter, \
patchWriters, \
proxy, \
candidateNames \
);
doLocalCode(volScalarField);
doLocalCode(volVectorField);
doLocalCode(volSphericalTensorField);
doLocalCode(volSymmTensorField);
doLocalCode(volTensorField);
#undef doLocalCode
}
return count;
}
@ -89,28 +95,31 @@ Foam::label Foam::functionObjects::vtkWrite::writeAllVolFields
UPtrList<vtk::patchWriter>& patchWriters,
const UPtrList<PrimitivePatchInterpolation<primitivePatch>>& patchInterps,
const fvMeshSubset& proxy,
const wordHashSet& acceptField
const wordHashSet& candidateNames
) const
{
#undef vtkWrite_WRITE_FIELD
#define vtkWrite_WRITE_FIELD(FieldType) \
writeVolFields<FieldType> \
( \
internalWriter, pInterp, \
patchWriters, patchInterps, \
proxy, \
acceptField \
)
label count = 0;
count += vtkWrite_WRITE_FIELD(volScalarField);
count += vtkWrite_WRITE_FIELD(volVectorField);
count += vtkWrite_WRITE_FIELD(volSphericalTensorField);
count += vtkWrite_WRITE_FIELD(volSymmTensorField);
count += vtkWrite_WRITE_FIELD(volTensorField);
#undef vtkWrite_WRITE_FIELD
{
#undef doLocalCode
#define doLocalCode(FieldType) \
count += writeVolFieldsImpl<FieldType> \
( \
internalWriter, pInterp, \
patchWriters, patchInterps, \
proxy, \
candidateNames \
);
doLocalCode(volScalarField);
doLocalCode(volVectorField);
doLocalCode(volSphericalTensorField);
doLocalCode(volSymmTensorField);
doLocalCode(volTensorField);
#undef doLocalCode
}
return count;
}
@ -138,7 +147,9 @@ Foam::functionObjects::vtkWrite::vtkWrite
meshState_(polyMesh::TOPO_CHANGE),
selectRegions_(),
selectPatches_(),
blockPatches_(),
selectFields_(),
blockFields_(),
selection_(),
meshes_(),
meshSubsets_(),
@ -288,10 +299,30 @@ bool Foam::functionObjects::vtkWrite::write()
const fvMesh& baseMesh = meshProxy.baseMesh();
wordHashSet acceptField(baseMesh.names<void>(selectFields_));
// Output fields MUST be specified to avoid accidentally
// writing everything. Can still use ".*" for everything
wordHashSet candidateNames(0);
if (!selectFields_.empty())
{
if (!blockFields_.empty())
{
// With 'allow' and 'deny' filters
wordRes::filter filter(selectFields_, blockFields_);
candidateNames = baseMesh.names<void>(filter);
}
else
{
// With 'allow' filter only
candidateNames = baseMesh.names<void>(selectFields_);
}
}
// Prune restart fields
acceptField.filterKeys
candidateNames.filterKeys
(
[](const word& k){ return k.ends_with("_0"); },
true // prune
@ -303,7 +334,7 @@ bool Foam::functionObjects::vtkWrite::write()
? baseMesh.count
(
stringListOps::foundOp<word>(fieldTypes::volume),
acceptField
candidateNames
)
: 0
);
@ -316,7 +347,7 @@ bool Foam::functionObjects::vtkWrite::write()
// ? baseMesh.count
// (
// stringListOps::foundOp<word>(fieldTypes::internal),
// acceptField
// candidateNames
// )
// : 0
// );
@ -564,14 +595,14 @@ bool Foam::functionObjects::vtkWrite::write()
internalWriter,
patchWriters,
meshProxy,
acceptField
candidateNames
);
// writeAllDimFields
// (
// internalWriter,
// meshProxy,
// acceptField
// candidateNames
// );
// End CellData is implicit
@ -612,14 +643,14 @@ bool Foam::functionObjects::vtkWrite::write()
internalWriter, pInterp,
patchWriters, patchInterps,
meshProxy,
acceptField
candidateNames
);
// writeAllDimFields
// (
// internalWriter, pInterp,
// meshProxy,
// acceptField
// candidateNames
// );
// writeAllPointFields
@ -627,7 +658,7 @@ bool Foam::functionObjects::vtkWrite::write()
// internalWriter,
// patchWriters,
// meshProxy,
// acceptField
// candidateNames
// );
// End PointData is implicit

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2020 OpenCFD Ltd.
Copyright (C) 2017-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -46,6 +46,7 @@ Description
decompose false;
...
fields (U p);
// excludeFields ("force.*");
selection
{
@ -84,7 +85,8 @@ Description
\table
Property | Description | Required | Default
type | Type name: vtkWrite | yes |
fields | Fields to output (wordRe list) | yes |
fields | Select fields to output (wordRe list) | yes |
excludeFields | Exclude fields from output (wordRe list) | no |
boundary | Convert boundary fields | no | true
internal | Convert internal fields | no | true
single | Combine patches into a single boundary | no | false
@ -109,6 +111,7 @@ Description
region | Name for a single region | no | region0
regions | List of regions (wordRe list) | no |
patches | Limit to listed patches (wordRe list) | no |
excludePatches | Exclude specified patches | no |
selection | Cell selection (topoSet actions) | no | empty dict
\endtable
@ -128,12 +131,12 @@ See also
SourceFiles
vtkWrite.C
vtkWriteTemplates.C
vtkWriteImpl.C
\*---------------------------------------------------------------------------*/
#ifndef functionObjects_vtkWrite_H
#define functionObjects_vtkWrite_H
#ifndef Foam_functionObjects_vtkWrite_H
#define Foam_functionObjects_vtkWrite_H
#include "timeFunctionObject.H"
#include "foamVtkInternalWriter.H"
@ -198,9 +201,15 @@ class vtkWrite
//- Requested names of patches to process
wordRes selectPatches_;
//- Requested names of fields to process
//- Selection of patches to block
wordRes blockPatches_;
//- Requested selection of fields to process
wordRes selectFields_;
//- Selection of fields to block
wordRes blockFields_;
//- Dictionary of volume selections
dictionary selection_;
@ -242,7 +251,7 @@ class vtkWrite
autoPtr<vtk::internalWriter>& internalWriter,
UPtrList<vtk::patchWriter>& patchWriters,
const fvMeshSubset& proxy,
const wordHashSet& acceptField
const wordHashSet& candidateNames
) const;
//- Write all volume fields with point interpolation
@ -256,22 +265,22 @@ class vtkWrite
PrimitivePatchInterpolation<primitivePatch>
>& patchInterps,
const fvMeshSubset& proxy,
const wordHashSet& acceptField
const wordHashSet& candidateNames
) const;
//- Write selected GeoField fields.
template<class GeoField>
label writeVolFields
label writeVolFieldsImpl
(
autoPtr<vtk::internalWriter>& internalWriter,
UPtrList<vtk::patchWriter>& patchWriters,
const fvMeshSubset& proxy,
const wordHashSet& acceptField
const wordHashSet& candidateNames
) const;
//- Write selected GeoField fields with point interpolation
template<class GeoField>
label writeVolFields
label writeVolFieldsImpl
(
autoPtr<vtk::internalWriter>& internalWriter,
const autoPtr<volPointInterpolation>& pInterp,
@ -281,7 +290,7 @@ class vtkWrite
PrimitivePatchInterpolation<primitivePatch>
>& patchInterps,
const fvMeshSubset& proxy,
const wordHashSet& acceptField
const wordHashSet& candidateNames
) const;
@ -342,12 +351,6 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "vtkWriteTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -28,29 +28,26 @@ License
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class GeoField>
Foam::label Foam::functionObjects::vtkWrite::writeVolFields
Foam::label Foam::functionObjects::vtkWrite::writeVolFieldsImpl
(
autoPtr<vtk::internalWriter>& internalWriter,
UPtrList<vtk::patchWriter>& patchWriters,
const fvMeshSubset& proxy,
const wordHashSet& acceptField
const wordHashSet& candidateNames
) const
{
const fvMesh& baseMesh = proxy.baseMesh();
label count = 0;
for (const word& fieldName : baseMesh.sortedNames<GeoField>(acceptField))
for
(
const GeoField& origField
: baseMesh.sorted<GeoField>(candidateNames)
)
{
bool ok = false;
const auto* fieldptr = baseMesh.findObject<GeoField>(fieldName);
if (!fieldptr)
{
continue;
}
auto tfield = fvMeshSubsetProxy::interpolate(proxy, *fieldptr);
auto tfield = fvMeshSubsetProxy::interpolate(proxy, origField);
const auto& field = tfield();
// Internal
@ -83,7 +80,7 @@ Foam::label Foam::functionObjects::vtkWrite::writeVolFields
{
Log << ' ';
}
Log << fieldName;
Log << origField.name();
}
}
}
@ -98,31 +95,28 @@ Foam::label Foam::functionObjects::vtkWrite::writeVolFields
template<class GeoField>
Foam::label Foam::functionObjects::vtkWrite::writeVolFields
Foam::label Foam::functionObjects::vtkWrite::writeVolFieldsImpl
(
autoPtr<vtk::internalWriter>& internalWriter,
const autoPtr<volPointInterpolation>& pInterp,
UPtrList<vtk::patchWriter>& patchWriters,
const UPtrList<PrimitivePatchInterpolation<primitivePatch>>& patchInterps,
const fvMeshSubset& proxy,
const wordHashSet& acceptField
const wordHashSet& candidateNames
) const
{
const fvMesh& baseMesh = proxy.baseMesh();
label count = 0;
for (const word& fieldName : baseMesh.sortedNames<GeoField>(acceptField))
for
(
const GeoField& origField
: baseMesh.sorted<GeoField>(candidateNames)
)
{
bool ok = false;
const auto* fieldptr = baseMesh.findObject<GeoField>(fieldName);
if (!fieldptr)
{
continue;
}
auto tfield = fvMeshSubsetProxy::interpolate(proxy, *fieldptr);
auto tfield = fvMeshSubsetProxy::interpolate(proxy, origField);
const auto& field = tfield();
// Internal
@ -158,7 +152,7 @@ Foam::label Foam::functionObjects::vtkWrite::writeVolFields
{
Log << ' ';
}
Log << fieldName;
Log << origField.name();
}
}
}

View File

@ -59,6 +59,8 @@ Foam::labelList Foam::functionObjects::vtkWrite::getSelectedPatches
{
DynamicList<label> patchIDs(patches.size());
wordRes::filter patchFilter(selectPatches_, blockPatches_);
for (const polyPatch& pp : patches)
{
if (isType<emptyPolyPatch>(pp))
@ -70,12 +72,7 @@ Foam::labelList Foam::functionObjects::vtkWrite::getSelectedPatches
break; // No processor patches
}
if
(
selectPatches_.size()
? selectPatches_.match(pp.name())
: true
)
if (patchFilter(pp.name()))
{
patchIDs.append(pp.index());
}
@ -180,9 +177,14 @@ bool Foam::functionObjects::vtkWrite::readSelection(const dictionary& dict)
selectPatches_.clear();
dict.readIfPresent("patches", selectPatches_);
blockPatches_.clear();
dict.readIfPresent("excludePatches", blockPatches_);
selectFields_.clear();
dict.readEntry("fields", selectFields_);
selectFields_.uniq();
blockFields_.clear();
dict.readIfPresent("excludeFields", blockFields_);
// Actions to define selection
selection_ = dict.subOrEmptyDict("selection");

View File

@ -12,6 +12,11 @@ ensightWrite
writeControl writeTime;
writeInterval 1;
//patches ( "motorBike.*" );
//- These patches are uninteresting
excludePatches ( inlet outlet frontAndBack ".*[Ww]all" );
}

View File

@ -6,6 +6,10 @@ vtkWrite
libs (utilityFunctionObjects);
log true;
//- Write more frequent than fields
writeControl timeStep;
writeInterval 25;
// Fields to output (words or regex)
fields (U p "(k|epsilon|omega)");
@ -21,9 +25,8 @@ vtkWrite
//- Write cell ids as field - Default=true
writeIds false;
//- Write more frequent than fields
writeControl timeStep;
writeInterval 25;
//- These patches are uninteresting
excludePatches ( inlet outlet frontAndBack );
}
subset
@ -32,6 +35,10 @@ subset
libs (utilityFunctionObjects);
log true;
//- Write more frequent than fields
writeControl timeStep;
writeInterval 25;
// boundary false;
interpolate true;
@ -42,9 +49,8 @@ subset
//- Write cell ids as field - Default=true
writeIds false;
//- Write more frequent than fields
writeControl timeStep;
writeInterval 25;
//- These patches are uninteresting
excludePatches ( inlet outlet frontAndBack );
// Region of interest
selection