From d9ab5d54efb584a09831d7accf86dcf144be9b1b Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Fri, 18 Nov 2022 15:28:14 +0100 Subject: [PATCH] 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 --- .../utilities/ensightWrite/ensightWrite.C | 36 +++++- .../utilities/ensightWrite/ensightWrite.H | 12 +- .../utilities/ensightWrite/ensightWriteImpl.C | 17 ++- .../ensightWrite/ensightWriteUpdate.C | 4 + .../utilities/vtkWrite/vtkWrite.C | 121 +++++++++++------- .../utilities/vtkWrite/vtkWrite.H | 39 +++--- .../{vtkWriteTemplates.C => vtkWriteImpl.C} | 42 +++--- .../utilities/vtkWrite/vtkWriteUpdate.C | 16 ++- .../simpleFoam/motorBike/system/ensightWrite | 5 + .../windAroundBuildings/system/vtkWrite | 18 ++- 10 files changed, 192 insertions(+), 118 deletions(-) rename src/functionObjects/utilities/vtkWrite/{vtkWriteTemplates.C => vtkWriteImpl.C} (82%) diff --git a/src/functionObjects/utilities/ensightWrite/ensightWrite.C b/src/functionObjects/utilities/ensightWrite/ensightWrite.C index 92f6575d89..c25755e45b 100644 --- a/src/functionObjects/utilities/ensightWrite/ensightWrite.C +++ b/src/functionObjects/utilities/ensightWrite/ensightWrite.C @@ -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(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(filter); + } + else + { + // With 'allow' filter only + candidateNames = mesh_.names(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; diff --git a/src/functionObjects/utilities/ensightWrite/ensightWrite.H b/src/functionObjects/utilities/ensightWrite/ensightWrite.H index 9e049823cd..c8dc1e3a5d 100644 --- a/src/functionObjects/utilities/ensightWrite/ensightWrite.H +++ b/src/functionObjects/utilities/ensightWrite/ensightWrite.H @@ -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 diff --git a/src/functionObjects/utilities/ensightWrite/ensightWriteImpl.C b/src/functionObjects/utilities/ensightWrite/ensightWriteImpl.C index 3fb5204b2e..1a7096b1a9 100644 --- a/src/functionObjects/utilities/ensightWrite/ensightWriteImpl.C +++ b/src/functionObjects/utilities/ensightWrite/ensightWriteImpl.C @@ -34,7 +34,7 @@ Foam::label Foam::functionObjects::ensightWrite::writeVolFieldsImpl ( ensightOutput::floatBufferType& scratch, const fvMeshSubset& proxy, - const wordHashSet& acceptField + const wordHashSet& candidateNames ) { typedef GeometricField GeoField; @@ -43,16 +43,15 @@ Foam::label Foam::functionObjects::ensightWrite::writeVolFieldsImpl label count = 0; - for (const word& fieldName : baseMesh.sortedNames(acceptField)) + for + ( + const GeoField& origField + : baseMesh.sorted(candidateNames) + ) { - const auto* fieldptr = baseMesh.findObject(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 os = ensCase().newData(fieldName); diff --git a/src/functionObjects/utilities/ensightWrite/ensightWriteUpdate.C b/src/functionObjects/utilities/ensightWrite/ensightWriteUpdate.C index 84b51823ed..62084a8998 100644 --- a/src/functionObjects/utilities/ensightWrite/ensightWriteUpdate.C +++ b/src/functionObjects/utilities/ensightWrite/ensightWriteUpdate.C @@ -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"); diff --git a/src/functionObjects/utilities/vtkWrite/vtkWrite.C b/src/functionObjects/utilities/vtkWrite/vtkWrite.C index 84e49ab664..0b38881561 100644 --- a/src/functionObjects/utilities/vtkWrite/vtkWrite.C +++ b/src/functionObjects/utilities/vtkWrite/vtkWrite.C @@ -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& internalWriter, UPtrList& patchWriters, const fvMeshSubset& proxy, - const wordHashSet& acceptField + const wordHashSet& candidateNames ) const { - #undef vtkWrite_WRITE_FIELD - #define vtkWrite_WRITE_FIELD(FieldType) \ - writeVolFields \ - ( \ - 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 \ + ( \ + 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& patchWriters, const UPtrList>& patchInterps, const fvMeshSubset& proxy, - const wordHashSet& acceptField + const wordHashSet& candidateNames ) const { - #undef vtkWrite_WRITE_FIELD - #define vtkWrite_WRITE_FIELD(FieldType) \ - writeVolFields \ - ( \ - 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 \ + ( \ + 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(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(filter); + } + else + { + // With 'allow' filter only + candidateNames = baseMesh.names(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(fieldTypes::volume), - acceptField + candidateNames ) : 0 ); @@ -316,7 +347,7 @@ bool Foam::functionObjects::vtkWrite::write() // ? baseMesh.count // ( // stringListOps::foundOp(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 diff --git a/src/functionObjects/utilities/vtkWrite/vtkWrite.H b/src/functionObjects/utilities/vtkWrite/vtkWrite.H index 8053845acd..68f1f40caf 100644 --- a/src/functionObjects/utilities/vtkWrite/vtkWrite.H +++ b/src/functionObjects/utilities/vtkWrite/vtkWrite.H @@ -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& internalWriter, UPtrList& 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 >& patchInterps, const fvMeshSubset& proxy, - const wordHashSet& acceptField + const wordHashSet& candidateNames ) const; //- Write selected GeoField fields. template - label writeVolFields + label writeVolFieldsImpl ( autoPtr& internalWriter, UPtrList& patchWriters, const fvMeshSubset& proxy, - const wordHashSet& acceptField + const wordHashSet& candidateNames ) const; //- Write selected GeoField fields with point interpolation template - label writeVolFields + label writeVolFieldsImpl ( autoPtr& internalWriter, const autoPtr& pInterp, @@ -281,7 +290,7 @@ class vtkWrite PrimitivePatchInterpolation >& patchInterps, const fvMeshSubset& proxy, - const wordHashSet& acceptField + const wordHashSet& candidateNames ) const; @@ -342,12 +351,6 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -#ifdef NoRepository - #include "vtkWriteTemplates.C" -#endif - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - #endif // ************************************************************************* // diff --git a/src/functionObjects/utilities/vtkWrite/vtkWriteTemplates.C b/src/functionObjects/utilities/vtkWrite/vtkWriteImpl.C similarity index 82% rename from src/functionObjects/utilities/vtkWrite/vtkWriteTemplates.C rename to src/functionObjects/utilities/vtkWrite/vtkWriteImpl.C index b46a302462..450cd6fcef 100644 --- a/src/functionObjects/utilities/vtkWrite/vtkWriteTemplates.C +++ b/src/functionObjects/utilities/vtkWrite/vtkWriteImpl.C @@ -28,29 +28,26 @@ License // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // template -Foam::label Foam::functionObjects::vtkWrite::writeVolFields +Foam::label Foam::functionObjects::vtkWrite::writeVolFieldsImpl ( autoPtr& internalWriter, UPtrList& 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(acceptField)) + for + ( + const GeoField& origField + : baseMesh.sorted(candidateNames) + ) { bool ok = false; - const auto* fieldptr = baseMesh.findObject(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 -Foam::label Foam::functionObjects::vtkWrite::writeVolFields +Foam::label Foam::functionObjects::vtkWrite::writeVolFieldsImpl ( autoPtr& internalWriter, const autoPtr& pInterp, UPtrList& patchWriters, const UPtrList>& 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(acceptField)) + for + ( + const GeoField& origField + : baseMesh.sorted(candidateNames) + ) { bool ok = false; - const auto* fieldptr = baseMesh.findObject(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(); } } } diff --git a/src/functionObjects/utilities/vtkWrite/vtkWriteUpdate.C b/src/functionObjects/utilities/vtkWrite/vtkWriteUpdate.C index bfa32ec4a5..bcf6fcf90b 100644 --- a/src/functionObjects/utilities/vtkWrite/vtkWriteUpdate.C +++ b/src/functionObjects/utilities/vtkWrite/vtkWriteUpdate.C @@ -59,6 +59,8 @@ Foam::labelList Foam::functionObjects::vtkWrite::getSelectedPatches { DynamicList