ENH: revise patch group selection to ensightMesh

- supports inGroup while also respecting allow/deny semantics

- support inGroup for cellZone/faceZone selection
This commit is contained in:
Mark Olesen
2025-06-12 16:56:26 +02:00
parent 93f980834b
commit be278abcc0
4 changed files with 109 additions and 149 deletions

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2024 OpenCFD Ltd.
Copyright (C) 2016-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,36 +31,13 @@ License
#include "polyMesh.H"
#include "emptyPolyPatch.H"
#include "processorPolyPatch.H"
#include "stringListOps.H" // For stringListOps::findMatching()
#include "ListOps.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const Foam::label Foam::ensightMesh::internalZone = -1;
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Patch names without processor patches
static wordList nonProcessorPatchNames(const polyBoundaryMesh& bmesh)
{
#ifdef FULLDEBUG
// Patches are output. Check that they are synced.
bmesh.checkParallelSync(true);
#endif
wordList patchNames(bmesh.names());
patchNames.resize(bmesh.nNonProcessor());
return patchNames;
}
} // End namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::ensightMesh::clear()
@ -141,63 +118,69 @@ void Foam::ensightMesh::correct()
{
clear();
const wordRes& czMatcher = option().cellZoneSelection();
const wordRes& fzMatcher = option().faceZoneSelection();
const auto& pbm = mesh_.boundaryMesh();
// Possible cellZones
const wordList czNames =
(
// Selected patch indices
labelList patchIds;
if (option().useBoundaryMesh())
{
patchIds = pbm.indices
(
option().useCellZones()
&& (!czMatcher.empty() || option().useInternalMesh())
)
? mesh_.cellZones().names()
: wordList()
);
const labelList czoneIds =
(
czMatcher.empty()
? identity(czNames.size()) // All
: czMatcher.matching(czNames) // Selected names
);
// Possible faceZones
const wordList fzNames =
(
option().useFaceZones()
? mesh_.faceZones().names()
: wordList()
);
const labelList fzoneIds =
(
fzMatcher.empty()
? identity(fzNames.size()) // All
: fzMatcher.matching(fzNames) // Selected names
);
// Possible patchNames
const wordList patchNames =
(
option().useBoundaryMesh()
? nonProcessorPatchNames(mesh_.boundaryMesh())
: wordList()
);
const labelList patchIds =
(
option().useBoundaryMesh()
? stringListOps::findMatching
(
patchNames,
option().patchSelection(),
option().patchExclude()
)
: labelList()
);
);
// Prune undesirable patches - empty and processor patches
label count = 0;
for (const label patchi : patchIds)
{
const auto& pp = pbm[patchi];
if (isType<emptyPolyPatch>(pp))
{
continue;
}
else if (isA<processorPolyPatch>(pp))
{
break; // No processor patches
}
patchIds[count] = patchi;
++count;
}
patchIds.resize(count);
}
// Selection of cellZones
const auto& czMatcher = option().cellZoneSelection();
// Selected cell zone indices
labelList czoneIds;
if (option().useCellZones())
{
// Use allow/deny to have desired behaviour with empty selection
czoneIds = mesh_.cellZones().indices
(
option().cellZoneSelection(),
option().cellZoneExclude()
);
}
// Selected face zone indices
labelList fzoneIds;
if (option().useFaceZones())
{
// Use allow/deny to have desired behaviour with empty selection
fzoneIds = mesh_.faceZones().indices
(
option().faceZoneSelection(),
option().faceZoneExclude()
);
}
// Track which cells are in a zone or not
@ -210,8 +193,8 @@ void Foam::ensightMesh::correct()
// cellZones first
for (const label zoneId : czoneIds)
{
const word& zoneName = czNames[zoneId];
const cellZone& zn = mesh_.cellZones()[zoneId];
const auto& zn = mesh_.cellZones()[zoneId];
const auto& zoneName = zn.name();
if (returnReduceOr(!zn.empty()))
{
@ -323,7 +306,7 @@ void Foam::ensightMesh::correct()
// Ensure full mesh coverage
excludeFace.resize(mesh_.nFaces());
for (const polyPatch& p : mesh_.boundaryMesh())
for (const polyPatch& p : pbm)
{
const auto* cpp = isA<coupledPolyPatch>(p);
@ -344,8 +327,8 @@ void Foam::ensightMesh::correct()
// Patches
for (const label patchId : patchIds)
{
const word& patchName = patchNames[patchId];
const polyPatch& p = mesh_.boundaryMesh()[patchId];
const auto& p = pbm[patchId];
const auto& patchName = p.name();
if (isA<emptyPolyPatch>(p))
{
@ -386,11 +369,10 @@ void Foam::ensightMesh::correct()
// Face zones
for (const label zoneId : fzoneIds)
{
const word& zoneName = fzNames[zoneId];
const faceZone& zn = mesh_.faceZones()[zoneId];
const auto& zn = mesh_.faceZones()[zoneId];
const auto& zoneName = zn.name();
ensightFaces& part = faceZoneParts_(zoneId);

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2024 OpenCFD Ltd.
Copyright (C) 2016-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -292,34 +292,46 @@ public:
//- Using boundary?
bool useBoundaryMesh() const noexcept;
//- Using faceZones?
bool useFaceZones() const noexcept;
//- Using cellZones?
bool useCellZones() const noexcept;
//- Using faceZones?
bool useFaceZones() const noexcept;
//- Selection of patches. Empty if unspecified.
const wordRes& patchSelection() const noexcept
{
return patchInclude_;
}
//- Selection of black listed patches. Empty if unspecified.
//- Excluded patches. Empty if unspecified.
const wordRes& patchExclude() const noexcept
{
return patchExclude_;
}
//- Selection of faceZones. Empty if unspecified.
//- Selection of cell zones. Empty if unspecified.
const wordRes& cellZoneSelection() const noexcept
{
return cellZoneInclude_;
}
//- Excluded cell zones. Future use
const wordRes& cellZoneExclude() const noexcept
{
return wordRes::null();
}
//- Selection of face zones. Empty if unspecified.
const wordRes& faceZoneSelection() const noexcept
{
return faceZoneInclude_;
}
//- Selection of faceZones. Empty if unspecified.
const wordRes& cellZoneSelection() const noexcept
//- Excluded face zones. Future use
const wordRes& faceZoneExclude() const noexcept
{
return cellZoneInclude_;
return wordRes::null();
}
@ -356,18 +368,18 @@ public:
//- Define patch selection to exclude
void patchExclude(List<wordRe>&& patterns);
//- Define faceZone selection matcher
void faceZoneSelection(const UList<wordRe>& patterns);
//- Define faceZone selection matcher
void faceZoneSelection(List<wordRe>&& patterns);
//- Define cellZone selection matcher
void cellZoneSelection(const UList<wordRe>& patterns);
//- Define cellZone selection matcher
void cellZoneSelection(List<wordRe>&& patterns);
//- Define faceZone selection matcher
void faceZoneSelection(const UList<wordRe>& patterns);
//- Define faceZone selection matcher
void faceZoneSelection(List<wordRe>&& patterns);
// Output

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2023 OpenCFD Ltd.
Copyright (C) 2016-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -122,29 +122,6 @@ Foam::functionObjects::ensightWrite::ensightWrite
}
Foam::wordRes Foam::functionObjects::ensightWrite::patchNameSet
(
const UList<wordRe>& select
) const
{
const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
const labelList patchIDs
(
pbm.patchSet(select).sortedToc()
);
wordRes names(patchIDs.size());
for (const label patchi : patchIDs)
{
names[patchi] = mesh_.boundary()[patchi].name();
}
return names;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionObjects::ensightWrite::read(const dictionary& dict)
@ -175,27 +152,21 @@ bool Foam::functionObjects::ensightWrite::read(const dictionary& dict)
<< "conversion of the boundaries" << endl;
}
if (wordRes list; dict.readIfPresent("patches", list))
{
list.uniq(); // usually a no-op
writeOpts_.patchSelection(std::move(list));
}
if (wordRes list; dict.readIfPresent("excludePatches", list))
{
list.uniq(); // usually a no-op
writeOpts_.patchExclude(std::move(list));
}
if (dict.found("patches"))
if (wordRes list; dict.readIfPresent("faceZones", list))
{
writeOpts_.patchSelection
(
wordRes::uniq(patchNameSet(dict.get<wordRes>("patches")))
);
}
if (dict.found("excludePatches"))
{
writeOpts_.patchExclude
(
wordRes::uniq(patchNameSet(dict.get<wordRes>("excludePatches")))
);
}
if (dict.found("faceZones"))
{
writeOpts_.faceZoneSelection
(
wordRes::uniq(dict.get<wordRes>("faceZones"))
);
list.uniq(); // usually a no-op
writeOpts_.faceZoneSelection(std::move(list));
}

View File

@ -233,11 +233,6 @@ class ensightWrite
//- Update meshes, subMeshes etc.
bool update();
//- Return the set of names of available patches and patch groups
//- corresponding to the given names
// A convenience wrapper for \c polyBoundaryMesh::patchSet
wordRes patchNameSet(const UList<wordRe>& select) const;
// Write