Commit 9b856995 authored by Mark Olesen's avatar Mark Olesen

ENH: add a patches filter for volMesh conversion (issue #2)

- allows restriction of the output patches to specific names and hiding
  others.
parent 79639bce
...@@ -62,13 +62,17 @@ void Foam::catalyst::faMeshInput::update() ...@@ -62,13 +62,17 @@ void Foam::catalyst::faMeshInput::update()
forAllConstIters(meshes_, iter) forAllConstIters(meshes_, iter)
{ {
if (!backends_.found(iter.key())) const word& areaName(iter.key());
if (!backends_.found(areaName))
{ {
backends_.set auto backend =
( autoPtr<Foam::vtk::faMeshAdaptor>::New(*(iter.object()));
iter.key(),
new Foam::vtk::faMeshAdaptor(*(iter.object())) // Apply any configuration options
); // ...
backends_.set(areaName, backend);
} }
} }
} }
...@@ -215,7 +219,6 @@ bool Foam::catalyst::faMeshInput::convert ...@@ -215,7 +219,6 @@ bool Foam::catalyst::faMeshInput::convert
{ {
auto dataset = backends_[areaName]->output(selectFields_); auto dataset = backends_[areaName]->output(selectFields_);
// Existing or new // Existing or new
vtkSmartPointer<vtkMultiBlockDataSet> block = vtkSmartPointer<vtkMultiBlockDataSet> block =
outputs.lookup outputs.lookup
......
...@@ -38,6 +38,9 @@ catalyst ...@@ -38,6 +38,9 @@ catalyst
// Emit internal mesh/fields // Emit internal mesh/fields
internal true; internal true;
// Restrict boundary conversion to specific patches
patches (walls "*.top");
// Selected fields (words or regex) // Selected fields (words or regex)
fields (T U p); fields (T U p);
} }
......
...@@ -139,7 +139,6 @@ bool Foam::catalyst::cloudInput::convert ...@@ -139,7 +139,6 @@ bool Foam::catalyst::cloudInput::convert
auto dataset = auto dataset =
vtk::cloudAdaptor(fvm).getCloud(cloudName, selectFields_); vtk::cloudAdaptor(fvm).getCloud(cloudName, selectFields_);
// Existing or new // Existing or new
vtkSmartPointer<vtkMultiBlockDataSet> block = vtkSmartPointer<vtkMultiBlockDataSet> block =
outputs.lookup outputs.lookup
......
...@@ -60,13 +60,22 @@ void Foam::catalyst::fvMeshInput::update() ...@@ -60,13 +60,22 @@ void Foam::catalyst::fvMeshInput::update()
forAllConstIters(meshes_, iter) forAllConstIters(meshes_, iter)
{ {
if (!backends_.found(iter.key())) const word& regionName = iter.key();
if (!backends_.found(regionName))
{ {
backends_.set auto backend =
( autoPtr<Foam::vtk::fvMeshAdaptor>::New
iter.key(), (
new Foam::vtk::fvMeshAdaptor(*(iter.object()), decomposeOpt_) *(iter.object()),
); channelOpt_,
selectPatches_
);
// Special polyhedral treatment?
backend->setDecompose(decomposeOpt_);
backends_.set(regionName, backend);
} }
} }
} }
...@@ -86,6 +95,7 @@ Foam::catalyst::fvMeshInput::fvMeshInput ...@@ -86,6 +95,7 @@ Foam::catalyst::fvMeshInput::fvMeshInput
channelOpt_(channelType::DEFAULT), channelOpt_(channelType::DEFAULT),
decomposeOpt_(false), decomposeOpt_(false),
selectRegions_(), selectRegions_(),
selectPatches_(),
selectFields_(), selectFields_(),
meshes_(), meshes_(),
backends_() backends_()
...@@ -102,8 +112,9 @@ bool Foam::catalyst::fvMeshInput::read(const dictionary& dict) ...@@ -102,8 +112,9 @@ bool Foam::catalyst::fvMeshInput::read(const dictionary& dict)
meshes_.clear(); meshes_.clear();
backends_.clear(); backends_.clear();
selectFields_.clear();
selectRegions_.clear(); selectRegions_.clear();
selectPatches_.clear();
selectFields_.clear();
decomposeOpt_ = dict.lookupOrDefault("decompose", false); decomposeOpt_ = dict.lookupOrDefault("decompose", false);
unsigned selected(channelType::NONE); unsigned selected(channelType::NONE);
...@@ -132,6 +143,7 @@ bool Foam::catalyst::fvMeshInput::read(const dictionary& dict) ...@@ -132,6 +143,7 @@ bool Foam::catalyst::fvMeshInput::read(const dictionary& dict)
// All possible meshes // All possible meshes
meshes_ = time_.lookupClass<fvMesh>(); meshes_ = time_.lookupClass<fvMesh>();
dict.readIfPresent("patches", selectPatches_);
dict.readIfPresent("regions", selectRegions_); dict.readIfPresent("regions", selectRegions_);
if (selectRegions_.empty()) if (selectRegions_.empty())
...@@ -226,12 +238,8 @@ bool Foam::catalyst::fvMeshInput::convert ...@@ -226,12 +238,8 @@ bool Foam::catalyst::fvMeshInput::convert
for (const word& regionName : regionNames) for (const word& regionName : regionNames)
{ {
// Define/redefine output channels (caching)
backends_[regionName]->channels(channelOpt_);
auto dataset = backends_[regionName]->output(selectFields_); auto dataset = backends_[regionName]->output(selectFields_);
// Existing or new // Existing or new
vtkSmartPointer<vtkMultiBlockDataSet> block = vtkSmartPointer<vtkMultiBlockDataSet> block =
outputs.lookup outputs.lookup
......
...@@ -50,6 +50,7 @@ Usage ...@@ -50,6 +50,7 @@ Usage
type | input type: \c default | no | default type | input type: \c default | no | default
region | name for a single region | no | region0 region | name for a single region | no | region0
regions | wordRe list of regions | no | regions | wordRe list of regions | no |
patches | explicit wordRe list of patches | no |
fields | wordRe list of fields | yes | fields | wordRe list of fields | yes |
boundary | convert boundary fields | no | true boundary | convert boundary fields | no | true
internal | convert internal fields | no | true internal | convert internal fields | no | true
...@@ -83,6 +84,10 @@ Usage ...@@ -83,6 +84,10 @@ Usage
Note Note
The channel name is that of the defining dictionary. The channel name is that of the defining dictionary.
If the \c patches entry is missing or an empty list,
all non-processor patches will be used for the boundary.
When it is non-empty, only the explicitly specified (non-processor)
patch names will be used.
See also See also
Foam::vtk::fvMeshAdaptor Foam::vtk::fvMeshAdaptor
...@@ -135,6 +140,9 @@ protected: ...@@ -135,6 +140,9 @@ protected:
//- Requested names of regions to process //- Requested names of regions to process
wordRes selectRegions_; wordRes selectRegions_;
//- Requested names of patches to process
wordRes selectPatches_;
//- Names of fields to process //- Names of fields to process
wordRes selectFields_; wordRes selectFields_;
......
...@@ -59,26 +59,69 @@ Foam::vtk::fvMeshAdaptor::channelNames ...@@ -59,26 +59,69 @@ Foam::vtk::fvMeshAdaptor::channelNames
}; };
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::vtk::fvMeshAdaptor::definePatchIds()
{
// Generate or update the list of patchIds
patchIds_.clear();
if (!usingBoundary())
{
return;
}
// General patch information
// Restrict to non-processor patches.
// This value is invariant across all processors.
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
const label nNonProcessor = patches.nNonProcessor();
if (patchPatterns_.empty())
{
patchIds_ = identity(nNonProcessor);
}
else
{
labelHashSet ids(patches.patchSet(patchPatterns_, false, false));
// Restricted to non-processor patches
ids.filterKeys
(
[nNonProcessor](const label i){ return i < nNonProcessor; }
);
// MUST be sorted. Other internal logic relies upon this!
patchIds_ = ids.sortedToc();
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::vtk::fvMeshAdaptor::fvMeshAdaptor Foam::vtk::fvMeshAdaptor::fvMeshAdaptor
( (
const fvMesh& mesh, const fvMesh& mesh,
const bool decompose const channelType channelsOpt,
const wordRes& patchSelection
) )
: :
mesh_(mesh), mesh_(mesh),
channels_(ALL), patchPatterns_(patchSelection),
patchIds_(),
channels_(channelsOpt),
interpFields_(true), interpFields_(true),
extrapPatches_(false), extrapPatches_(false),
decomposePoly_(decompose), decomposePoly_(false),
meshState_(polyMesh::TOPO_CHANGE) meshState_(polyMesh::TOPO_CHANGE)
{} {}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::vtk::fvMeshAdaptor::channels(const wordList& chanNames) void Foam::vtk::fvMeshAdaptor::setChannels(const wordList& chanNames)
{ {
unsigned chanIds = 0; unsigned chanIds = 0;
for (const word& chan : chanNames) for (const word& chan : chanNames)
...@@ -89,11 +132,11 @@ void Foam::vtk::fvMeshAdaptor::channels(const wordList& chanNames) ...@@ -89,11 +132,11 @@ void Foam::vtk::fvMeshAdaptor::channels(const wordList& chanNames)
} }
} }
channels(chanIds); setChannels(chanIds);
} }
void Foam::vtk::fvMeshAdaptor::channels(enum channelType chanIds) void Foam::vtk::fvMeshAdaptor::setChannels(enum channelType chanIds)
{ {
channels_ = chanIds; channels_ = chanIds;
...@@ -105,11 +148,12 @@ void Foam::vtk::fvMeshAdaptor::channels(enum channelType chanIds) ...@@ -105,11 +148,12 @@ void Foam::vtk::fvMeshAdaptor::channels(enum channelType chanIds)
if (!usingBoundary()) if (!usingBoundary())
{ {
cachedVtp_.clear(); cachedVtp_.clear();
patchIds_.clear();
} }
} }
void Foam::vtk::fvMeshAdaptor::channels(unsigned chanIds) void Foam::vtk::fvMeshAdaptor::setChannels(unsigned chanIds)
{ {
channels_ = (chanIds & 0x3); channels_ = (chanIds & 0x3);
...@@ -121,6 +165,17 @@ void Foam::vtk::fvMeshAdaptor::channels(unsigned chanIds) ...@@ -121,6 +165,17 @@ void Foam::vtk::fvMeshAdaptor::channels(unsigned chanIds)
if (!usingBoundary()) if (!usingBoundary())
{ {
cachedVtp_.clear(); cachedVtp_.clear();
patchIds_.clear();
}
}
void Foam::vtk::fvMeshAdaptor::setDecompose(const bool val)
{
if (usingInternal() && val != decomposePoly_)
{
cachedVtu_.clear();
decomposePoly_ = val;
} }
} }
...@@ -143,17 +198,9 @@ bool Foam::vtk::fvMeshAdaptor::usingBoundary() const ...@@ -143,17 +198,9 @@ bool Foam::vtk::fvMeshAdaptor::usingBoundary() const
} }
Foam::label Foam::vtk::fvMeshAdaptor::nPatches() const const Foam::labelList& Foam::vtk::fvMeshAdaptor::patchIds() const
{ {
// Restrict to non-processor patches. return patchIds_;
// This value is invariant across all processors.
if (usingBoundary())
{
return mesh_.boundaryMesh().nNonProcessor();
}
return 0;
} }
...@@ -161,6 +208,14 @@ void Foam::vtk::fvMeshAdaptor::updateContent(const wordRes& selectFields) ...@@ -161,6 +208,14 @@ void Foam::vtk::fvMeshAdaptor::updateContent(const wordRes& selectFields)
{ {
const bool oldDecomp = decomposePoly_; const bool oldDecomp = decomposePoly_;
// General patch information
// Restrict to non-processor patches.
// This value is invariant across all processors.
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
const label nNonProcessor = patches.nNonProcessor();
// Update cached, saved, unneed values. // Update cached, saved, unneed values.
HashSet<string> nowActive; HashSet<string> nowActive;
...@@ -171,18 +226,15 @@ void Foam::vtk::fvMeshAdaptor::updateContent(const wordRes& selectFields) ...@@ -171,18 +226,15 @@ void Foam::vtk::fvMeshAdaptor::updateContent(const wordRes& selectFields)
nowActive.insert(internalName()); nowActive.insert(internalName());
} }
// BOUNDARY
// Restrict to non-processor patches.
// This value is invariant across all processors.
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
const label npatches = this->nPatches();
for (label patchId=0; patchId < npatches; ++patchId) // BOUNDARY
if (usingBoundary())
{ {
const polyPatch& pp = patches[patchId]; for (label patchId=0; patchId < nNonProcessor; ++patchId)
nowActive.insert(pp.name()); {
const polyPatch& pp = patches[patchId];
nowActive.insert(pp.name());
}
} }
// Dispose of unneeded components // Dispose of unneeded components
...@@ -206,6 +258,8 @@ void Foam::vtk::fvMeshAdaptor::updateContent(const wordRes& selectFields) ...@@ -206,6 +258,8 @@ void Foam::vtk::fvMeshAdaptor::updateContent(const wordRes& selectFields)
iter.object().clearGeom(); iter.object().clearGeom();
iter.object().clear(); iter.object().clear();
} }
definePatchIds();
} }
else if (oldDecomp != decomposePoly_) else if (oldDecomp != decomposePoly_)
{ {
...@@ -281,8 +335,7 @@ Foam::vtk::fvMeshAdaptor::output(const wordRes& select) ...@@ -281,8 +335,7 @@ Foam::vtk::fvMeshAdaptor::output(const wordRes& select)
} }
// BOUNDARY // BOUNDARY
const label npatches = this->nPatches(); if (!patchIds_.empty())
if (npatches)
{ {
unsigned int subBlockNo = 0; unsigned int subBlockNo = 0;
...@@ -290,7 +343,7 @@ Foam::vtk::fvMeshAdaptor::output(const wordRes& select) ...@@ -290,7 +343,7 @@ Foam::vtk::fvMeshAdaptor::output(const wordRes& select)
const polyBoundaryMesh& patches = mesh_.boundaryMesh(); const polyBoundaryMesh& patches = mesh_.boundaryMesh();
for (label patchId=0; patchId < npatches; ++patchId) for (const label patchId : patchIds_)
{ {
const polyPatch& pp = patches[patchId]; const polyPatch& pp = patches[patchId];
const word& longName = pp.name(); const word& longName = pp.name();
......
...@@ -170,6 +170,12 @@ private: ...@@ -170,6 +170,12 @@ private:
//- OpenFOAM mesh //- OpenFOAM mesh
const fvMesh& mesh_; const fvMesh& mesh_;
//- In non-empty, restrict to these selected patches only
wordRes patchPatterns_;
//- Cached values for selected patches. *Always* in sorted order.
labelList patchIds_;
//- Selected output channels //- Selected output channels
unsigned channels_; unsigned channels_;
...@@ -195,6 +201,9 @@ private: ...@@ -195,6 +201,9 @@ private:
// Mesh Conversion // Mesh Conversion
//- Define patch ids
void definePatchIds();
//- Convert internal //- Convert internal
void convertGeometryInternal(); void convertGeometryInternal();
...@@ -293,7 +302,12 @@ public: ...@@ -293,7 +302,12 @@ public:
// Constructors // Constructors
//- Construct from components //- Construct from components
fvMeshAdaptor(const fvMesh& mesh, const bool decompose=false); fvMeshAdaptor
(
const fvMesh& mesh,
const channelType channelsOpt = channelType::DEFAULT,
const wordRes& patchSelection = wordRes()
);
//- Destructor //- Destructor
...@@ -303,13 +317,17 @@ public: ...@@ -303,13 +317,17 @@ public:
// Member Functions // Member Functions
//- Define the output channels by name //- Define the output channels by name
void channels(const wordList& chanNames); void setChannels(const wordList& chanNames);
//- Define the output channels by enum //- Define the output channels by enum
void channels(enum channelType chanIds); void setChannels(enum channelType chanIds);
//- Define the output channels by value //- Define the output channels by value
void channels(unsigned chanIds); void setChannels(unsigned chanIds);
//- Define polyhedral decomposition treatment
void setDecompose(const bool on);
//- Return the selected output channel ids //- Return the selected output channel ids
label channels() const; label channels() const;
...@@ -320,9 +338,9 @@ public: ...@@ -320,9 +338,9 @@ public:
//- True if BOUNDARY channel is being used //- True if BOUNDARY channel is being used
bool usingBoundary() const; bool usingBoundary() const;
//- Number of non-processor patches, when the BOUNDARY channel is being //- Selected (non-processor) patch ids, when the BOUNDARY channel
//- used - otherwise 0. //- is being used. Empty otherwise.
label nPatches() const; const labelList& patchIds() const;
//- Return the names of known (supported) fields //- Return the names of known (supported) fields
wordHashSet knownFields(const wordRes& selectFields) const; wordHashSet knownFields(const wordRes& selectFields) const;
......
...@@ -69,9 +69,7 @@ void Foam::vtk::fvMeshAdaptor::convertVolField ...@@ -69,9 +69,7 @@ void Foam::vtk::fvMeshAdaptor::convertVolField
convertVolFieldInternal(fld, ptfPtr); convertVolFieldInternal(fld, ptfPtr);
// BOUNDARY // BOUNDARY
const label npatches = this->nPatches(); for (const label patchId : patchIds_)
for (label patchId=0; patchId < npatches; ++patchId)
{ {
const polyPatch& pp = patches[patchId]; const polyPatch& pp = patches[patchId];
const word& longName = pp.name(); const word& longName = pp.name();
...@@ -125,7 +123,11 @@ void Foam::vtk::fvMeshAdaptor::convertVolField ...@@ -125,7 +123,11 @@ void Foam::vtk::fvMeshAdaptor::convertVolField
transcribeFloatData(cdata, tpptf()); transcribeFloatData(cdata, tpptf());
if (interpFields_ && patchId < patchInterpList.size()) if
(
patchId < patchInterpList.size()
&& patchInterpList.set(patchId)
)
{ {
pdata = vtk::Tools::convertFieldToVTK pdata = vtk::Tools::convertFieldToVTK
( (
...@@ -138,7 +140,11 @@ void Foam::vtk::fvMeshAdaptor::convertVolField ...@@ -138,7 +140,11 @@ void Foam::vtk::fvMeshAdaptor::convertVolField
{ {
transcribeFloatData(cdata, ptf); transcribeFloatData(cdata, ptf);
if (interpFields_ && patchId < patchInterpList.size()) if
(
patchId < patchInterpList.size()
&& patchInterpList.set(patchId)
)
{ {
pdata = vtk::Tools::convertFieldToVTK pdata = vtk::Tools::convertFieldToVTK
( (
......
...@@ -105,21 +105,23 @@ void Foam::vtk::fvMeshAdaptor::convertVolFields ...@@ -105,21 +105,23 @@ void Foam::vtk::fvMeshAdaptor::convertVolFields
PtrList<patchInterpolator> interpLst; PtrList<patchInterpolator> interpLst;
if (interpFields_) if (interpFields_ && patchIds_.size())
{ {
// NOTE: this will be broken with processor patches, but // NOTE: this would be broken with processor patches,
// for the catalyst adaptor we explicitly restrict ourselves // but we don't allow them for the catalyst adaptor anyhow
// to non-processor patches
interpLst.setSize(this->nPatches());