ENH: patch/zone indices with select/ignore combination

STYLE: prefer indices() to patchSet() with warn=false
This commit is contained in:
Mark Olesen 2023-08-01 18:19:53 +02:00
parent db39f196cc
commit 14f7d44ca0
15 changed files with 328 additions and 127 deletions

View File

@ -30,12 +30,7 @@ Input
const labelList patchIDs
(
pbm.patchSet
(
polyPatchNames,
false, // warnNotFound
true // useGroups
).sortedToc()
pbm.indices(polyPatchNames, true) // useGroups
);
label nFaceLabels = 0;

View File

@ -357,7 +357,7 @@ int main(int argc, char *argv[])
dict.subDict("merge").get<wordRes>("patches")
).sortedToc();
Info<< "Detecting baffles on " << mergePatchIDs.size()
Info<< "Merge baffles on " << mergePatchIDs.size()
<< " patches with "
<< returnReduce(patchSize(mesh, mergePatchIDs), sumOp<label>())
<< " faces" << endl;
@ -369,7 +369,7 @@ int main(int argc, char *argv[])
dict.subDict("split").get<wordRes>("patches")
).sortedToc();
Info<< "Detecting baffles on " << splitPatchIDs.size()
Info<< "Split baffles on " << splitPatchIDs.size()
<< " patches with "
<< returnReduce(patchSize(mesh, splitPatchIDs), sumOp<label>())
<< " faces" << endl;

View File

@ -34,28 +34,35 @@ License
#include "lduSchedule.H"
#include "globalMeshData.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::pointBoundaryMesh::addPatches(const polyBoundaryMesh& pbm)
{
// Set boundary patches
pointPatchList& patches = *this;
patches.resize_null(pbm.size());
forAll(patches, patchi)
{
// NB: needs ptr() to get *pointPatch instead of *facePointPatch
patches.set(patchi, facePointPatch::New(pbm[patchi], *this).ptr());
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::pointBoundaryMesh::pointBoundaryMesh
(
const pointMesh& m,
const polyBoundaryMesh& basicBdry
const polyBoundaryMesh& pbm
)
:
pointPatchList(basicBdry.size()),
pointPatchList(),
mesh_(m)
{
// Set boundary patches
pointPatchList& Patches = *this;
forAll(Patches, patchi)
{
Patches.set
(
patchi,
facePointPatch::New(basicBdry[patchi], *this).ptr()
);
}
addPatches(pbm);
}
@ -81,6 +88,17 @@ Foam::labelList Foam::pointBoundaryMesh::indices
}
Foam::labelList Foam::pointBoundaryMesh::indices
(
const wordRes& select,
const wordRes& ignore,
const bool useGroups
) const
{
return mesh().boundaryMesh().indices(select, ignore, useGroups);
}
Foam::label Foam::pointBoundaryMesh::findPatchID(const word& patchName) const
{
return mesh().boundaryMesh().findPatchID(patchName);

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2013 OpenFOAM Foundation
Copyright (C) 2018-2021 OpenCFD Ltd.
Copyright (C) 2018-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -69,6 +69,9 @@ class pointBoundaryMesh
//- Calculate geometry for the patches (transformation tensors etc.)
void calcGeometry();
//- Assign facePointPatches corresponding to the given polyBoundaryMesh
void addPatches(const polyBoundaryMesh& pbm);
//- No copy construct
pointBoundaryMesh(const pointBoundaryMesh&) = delete;
@ -85,11 +88,7 @@ public:
// Constructors
//- Construct from polyBoundaryMesh
pointBoundaryMesh
(
const pointMesh&,
const polyBoundaryMesh&
);
pointBoundaryMesh(const pointMesh&, const polyBoundaryMesh&);
// Member Functions
@ -108,6 +107,18 @@ public:
// A no-op (returns empty list) for an empty matcher
labelList indices(const wordRes& matcher, const bool useGroups) const;
//- Return (sorted) patch indices for all selected matches that
//- are not ignored.
//- The selection logic as per Foam::wordRes::filter.
// Optionally matches patch groups.
// A no-op (returns empty list) for an empty select matcher
labelList indices
(
const wordRes& select,
const wordRes& ignore,
const bool useGroups
) const;
//- Find patch index given a name
// A no-op (returns -1) for an empty patchName
label findPatchID(const word& patchName) const;

View File

@ -33,7 +33,7 @@ License
#include "PstreamBuffers.H"
#include "lduSchedule.H"
#include "globalMeshData.H"
#include "stringListOps.H"
#include "wordRes.H"
#include "DynamicList.H"
#include "PtrListOps.H"
#include "edgeHashes.H"
@ -77,7 +77,7 @@ void Foam::polyBoundaryMesh::calcGroupIDs() const
return; // Or FatalError
}
groupIDsPtr_.reset(new HashTable<labelList>(16));
groupIDsPtr_.emplace(16);
auto& groupLookup = *groupIDsPtr_;
const polyPatchList& patches = *this;
@ -88,7 +88,7 @@ void Foam::polyBoundaryMesh::calcGroupIDs() const
for (const word& groupName : groups)
{
groupLookup(groupName).append(patchi);
groupLookup(groupName).push_back(patchi);
}
}
@ -315,7 +315,7 @@ Foam::polyBoundaryMesh::neighbourEdges() const
if (!neighbourEdgesPtr_)
{
neighbourEdgesPtr_.reset(new List<labelPairList>(size()));
neighbourEdgesPtr_.emplace(size());
auto& neighbourEdges = *neighbourEdgesPtr_;
// Initialize.
@ -437,8 +437,8 @@ const Foam::labelList& Foam::polyBoundaryMesh::patchID() const
{
if (!patchIDPtr_)
{
patchIDPtr_.reset(new labelList(mesh_.nBoundaryFaces()));
labelList& list = *patchIDPtr_;
patchIDPtr_.emplace(mesh_.nBoundaryFaces());
auto& list = *patchIDPtr_;
const polyPatchList& patches = *this;
@ -509,7 +509,7 @@ void Foam::polyBoundaryMesh::setGroup
// Add to specified patches
for (const label patchi : patchIDs)
{
patches[patchi].inGroups().appendUniq(groupName);
patches[patchi].inGroups().push_uniq(groupName);
donePatch[patchi] = true;
}
@ -681,7 +681,7 @@ Foam::labelList Foam::polyBoundaryMesh::indices
// Only check groups if requested and they exist
const bool checkGroups = (useGroups && this->hasGroupIDs());
labelHashSet ids;
labelHashSet ids(0);
if (matcher.isPattern())
{
@ -690,9 +690,9 @@ Foam::labelList Foam::polyBoundaryMesh::indices
const auto& groupLookup = groupPatchIDs();
forAllConstIters(groupLookup, iter)
{
if (matcher.match(iter.key()))
if (matcher(iter.key()))
{
// Hash ids associated with the group
// Add patch ids associated with the group
ids.insert(iter.val());
}
}
@ -746,10 +746,10 @@ Foam::labelList Foam::polyBoundaryMesh::indices
}
else if (matcher.size() == 1)
{
return this->indices(matcher.first(), useGroups);
return this->indices(matcher.front(), useGroups);
}
labelHashSet ids;
labelHashSet ids(0);
// Only check groups if requested and they exist
if (useGroups && this->hasGroupIDs())
@ -759,9 +759,54 @@ Foam::labelList Foam::polyBoundaryMesh::indices
const auto& groupLookup = groupPatchIDs();
forAllConstIters(groupLookup, iter)
{
if (matcher.match(iter.key()))
if (matcher(iter.key()))
{
// Hash ids associated with the group
// Add patch ids associated with the group
ids.insert(iter.val());
}
}
}
if (ids.empty())
{
return PtrListOps::findMatching(*this, matcher);
}
else
{
ids.insert(PtrListOps::findMatching(*this, matcher));
}
return ids.sortedToc();
}
Foam::labelList Foam::polyBoundaryMesh::indices
(
const wordRes& select,
const wordRes& ignore,
const bool useGroups
) const
{
if (ignore.empty())
{
return this->indices(select, useGroups);
}
const wordRes::filter matcher(select, ignore);
labelHashSet ids(0);
// Only check groups if requested and they exist
if (useGroups && this->hasGroupIDs())
{
ids.resize(2*this->size());
const auto& groupLookup = groupPatchIDs();
forAllConstIters(groupLookup, iter)
{
if (matcher(iter.key()))
{
// Add patch ids associated with the group
ids.insert(iter.val());
}
}
@ -910,23 +955,38 @@ Foam::polyBoundaryMesh::whichPatchFace(const labelUList& meshFaceIndices) const
Foam::labelHashSet Foam::polyBoundaryMesh::patchSet
(
const UList<wordRe>& patchNames,
const UList<wordRe>& select,
const bool warnNotFound,
const bool useGroups
) const
{
const wordList allPatchNames(this->names());
labelHashSet ids(2*this->size());
labelHashSet ids(0);
if (select.empty())
{
return ids;
}
const polyPatchList& patches = *this;
const label len = patches.size();
ids.resize(2*len);
// Only check groups if requested and they exist
const bool checkGroups = (useGroups && this->hasGroupIDs());
for (const wordRe& matcher : patchNames)
for (const wordRe& matcher : select)
{
labelList matchIndices = findMatchingStrings(matcher, allPatchNames);
ids.insert(matchIndices);
bool missed = true;
bool missed = matchIndices.empty();
for (label i = 0; i < len; ++i)
{
if (matcher(patches[i].name()))
{
ids.insert(i);
missed = false;
}
}
if (missed && checkGroups)
{
@ -1004,7 +1064,7 @@ void Foam::polyBoundaryMesh::matchGroups
if (nMatch == groupPatchSet.size())
{
matchedGroups.append(iter.key());
matchedGroups.push_back(iter.key());
}
else if (nMatch != 0)
{

View File

@ -235,6 +235,18 @@ public:
const bool useGroups = true
) const;
//- Return (sorted) patch indices for all selected matches that
//- are not ignored.
//- The selection logic as per Foam::wordRes::filter.
// Optionally matches patch groups.
// A no-op (returns empty list) for an empty select matcher
labelList indices
(
const wordRes& select,
const wordRes& ignore,
const bool useGroups = true
) const;
//- Return patch index for the first match, return -1 if not found
// A no-op (returns -1) for an empty key
label findIndex(const wordRe& key) const;
@ -289,7 +301,7 @@ public:
// Optionally matches to patchGroups as well as patchNames.
labelHashSet patchSet
(
const UList<wordRe>& patchNames,
const UList<wordRe>& select,
const bool warnNotFound = true,
const bool useGroups = true
) const;

View File

@ -68,7 +68,7 @@ void Foam::ZoneMesh<ZoneType, MeshType>::calcZoneMap() const
nObjects += zn.size();
}
zoneMapPtr_.reset(new Map<label>(2*nObjects));
zoneMapPtr_.emplace(2*nObjects);
auto& zm = *zoneMapPtr_;
// Fill in objects of all zones into the map.
@ -122,7 +122,7 @@ void Foam::ZoneMesh<ZoneType, MeshType>::calcGroupIDs() const
return; // Or FatalError
}
groupIDsPtr_.reset(new HashTable<labelList>(16));
groupIDsPtr_.emplace(16);
auto& groupLookup = *groupIDsPtr_;
const PtrList<ZoneType>& zones = *this;
@ -382,7 +382,7 @@ Foam::labelList Foam::ZoneMesh<ZoneType, MeshType>::indices
// Only check groups if requested and they exist
const bool checkGroups = (useGroups && this->hasGroupIDs());
labelHashSet ids;
labelHashSet ids(0);
if (checkGroups)
{
@ -396,7 +396,7 @@ Foam::labelList Foam::ZoneMesh<ZoneType, MeshType>::indices
const auto& groupLookup = groupZoneIDs();
forAllConstIters(groupLookup, iter)
{
if (matcher.match(iter.key()))
if (matcher(iter.key()))
{
// Hash ids associated with the group
ids.insert(iter.val());
@ -453,10 +453,10 @@ Foam::labelList Foam::ZoneMesh<ZoneType, MeshType>::indices
}
else if (matcher.size() == 1)
{
return this->indices(matcher.first(), useGroups);
return this->indices(matcher.front(), useGroups);
}
labelHashSet ids;
labelHashSet ids(0);
// Only check groups if requested and they exist
if (useGroups && this->hasGroupIDs())
@ -466,7 +466,7 @@ Foam::labelList Foam::ZoneMesh<ZoneType, MeshType>::indices
const auto& groupLookup = groupZoneIDs();
forAllConstIters(groupLookup, iter)
{
if (matcher.match(iter.key()))
if (matcher(iter.key()))
{
// Hash the ids associated with the group
ids.insert(iter.val());
@ -487,6 +487,52 @@ Foam::labelList Foam::ZoneMesh<ZoneType, MeshType>::indices
}
template<class ZoneType, class MeshType>
Foam::labelList Foam::ZoneMesh<ZoneType, MeshType>::indices
(
const wordRes& select,
const wordRes& ignore,
const bool useGroups
) const
{
if (ignore.empty())
{
return this->indices(select, useGroups);
}
const wordRes::filter matcher(select, ignore);
labelHashSet ids(0);
// Only check groups if requested and they exist
if (useGroups && this->hasGroupIDs())
{
ids.resize(2*this->size());
const auto& groupLookup = groupZoneIDs();
forAllConstIters(groupLookup, iter)
{
if (matcher(iter.key()))
{
// Add patch ids associated with the group
ids.insert(iter.val());
}
}
}
if (ids.empty())
{
return PtrListOps::findMatching(*this, matcher);
}
else
{
ids.insert(PtrListOps::findMatching(*this, matcher));
}
return ids.sortedToc();
}
template<class ZoneType, class MeshType>
Foam::label Foam::ZoneMesh<ZoneType, MeshType>::findIndex
(

View File

@ -196,6 +196,18 @@ public:
const bool useGroups = true
) const;
//- Return (sorted) zone indices for all selected matches that
//- are not ignored.
//- The selection logic as per Foam::wordRes::filter.
// Optionally matches patch groups.
// A no-op (returns empty list) for an empty select matcher
labelList indices
(
const wordRes& select,
const wordRes& ignore,
const bool useGroups = true
) const;
//- Zone index for the first match, return -1 if not found
// A no-op (returns -1) for an empty key
label findIndex(const wordRe& key) const;

View File

@ -31,6 +31,7 @@ License
#include "globalIndex.H"
#include "primitiveMesh.H"
#include "processorFaPatch.H"
#include "wordRes.H"
#include "PtrListOps.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -72,7 +73,7 @@ void Foam::faBoundaryMesh::calcGroupIDs() const
return; // Or FatalError
}
groupIDsPtr_.reset(new HashTable<labelList>(16));
groupIDsPtr_.emplace(16);
auto& groupLookup = *groupIDsPtr_;
const faPatchList& patches = *this;
@ -83,7 +84,7 @@ void Foam::faBoundaryMesh::calcGroupIDs() const
for (const word& groupName : groups)
{
groupLookup(groupName).append(patchi);
groupLookup(groupName).push_back(patchi);
}
}
@ -370,7 +371,7 @@ void Foam::faBoundaryMesh::setGroup
// Add to specified patches
for (const label patchi : patchIDs)
{
patches[patchi].inGroups().appendUniq(groupName);
patches[patchi].inGroups().push_uniq(groupName);
donePatch[patchi] = true;
}
@ -495,18 +496,20 @@ Foam::labelList Foam::faBoundaryMesh::indices
// Only check groups if requested and they exist
const bool checkGroups = (useGroups && this->hasGroupIDs());
labelHashSet ids;
labelHashSet ids(0);
if (matcher.isPattern())
{
if (checkGroups)
{
ids.resize(2*this->size());
const auto& groupLookup = groupPatchIDs();
forAllConstIters(groupLookup, iter)
{
if (matcher.match(iter.key()))
if (matcher(iter.key()))
{
// Hash ids associated with the group
// Add patch ids associated with the group
ids.insert(iter.val());
}
}
@ -538,7 +541,7 @@ Foam::labelList Foam::faBoundaryMesh::indices
if (iter.good())
{
// Hash ids associated with the group
// Add patch ids associated with the group
ids.insert(iter.val());
}
}
@ -560,10 +563,10 @@ Foam::labelList Foam::faBoundaryMesh::indices
}
else if (matcher.size() == 1)
{
return this->indices(matcher.first(), useGroups);
return this->indices(matcher.front(), useGroups);
}
labelHashSet ids;
labelHashSet ids(0);
// Only check groups if requested and they exist
if (useGroups && this->hasGroupIDs())
@ -573,9 +576,54 @@ Foam::labelList Foam::faBoundaryMesh::indices
const auto& groupLookup = groupPatchIDs();
forAllConstIters(groupLookup, iter)
{
if (matcher.match(iter.key()))
if (matcher(iter.key()))
{
// Hash ids associated with the group
// Add patch ids associated with the group
ids.insert(iter.val());
}
}
}
if (ids.empty())
{
return PtrListOps::findMatching(*this, matcher);
}
else
{
ids.insert(PtrListOps::findMatching(*this, matcher));
}
return ids.sortedToc();
}
Foam::labelList Foam::faBoundaryMesh::indices
(
const wordRes& select,
const wordRes& ignore,
const bool useGroups
) const
{
if (ignore.empty())
{
return this->indices(select, useGroups);
}
const wordRes::filter matcher(select, ignore);
labelHashSet ids(0);
// Only check groups if requested and they exist
if (useGroups && this->hasGroupIDs())
{
ids.resize(2*this->size());
const auto& groupLookup = groupPatchIDs();
forAllConstIters(groupLookup, iter)
{
if (matcher(iter.key()))
{
// Add patch ids associated with the group
ids.insert(iter.val());
}
}

View File

@ -204,6 +204,18 @@ public:
const bool useGroups = true
) const;
//- Return (sorted) patch indices for all selected matches that
//- are not ignored.
//- The selection logic as per Foam::wordRes::filter.
// Optionally matches patch groups.
// A no-op (returns empty list) for an empty select matcher
labelList indices
(
const wordRes& select,
const wordRes& ignore,
const bool useGroups = true
) const;
//- Return patch index for the first match, return -1 if not found
// A no-op (returns -1) for an empty key
label findIndex(const wordRe& key) const;

View File

@ -82,12 +82,7 @@ static labelList selectPatchFaces
{
const labelList patchIDs
(
pbm.patchSet
(
polyPatchNames,
false, // warnNotFound
true // useGroups
).sortedToc()
pbm.indices(polyPatchNames, true) // useGroups
);
if (patchIDs.empty())

View File

@ -87,13 +87,11 @@ void Foam::MRFZone::setMRFFaces()
}
labelHashSet excludedPatches(excludedPatchLabels_);
forAll(patches, patchi)
{
const polyPatch& pp = patches[patchi];
if (pp.coupled() || excludedPatches.found(patchi))
if (pp.coupled() || excludedPatchLabels_.contains(patchi))
{
forAll(pp, i)
{
@ -250,7 +248,7 @@ Foam::MRFZone::MRFZone
active_(true),
cellZoneName_(cellZoneName),
cellZoneID_(-1),
excludedPatchNames_(wordRes()),
excludedPatchNames_(),
origin_(Zero),
axis_(Zero),
omega_(nullptr)
@ -580,18 +578,8 @@ bool Foam::MRFZone::read(const dictionary& dict)
{
cellZoneID_ = mesh_.cellZones().findZoneID(cellZoneName_);
const labelHashSet excludedPatchSet
(
mesh_.boundaryMesh().patchSet(excludedPatchNames_)
);
excludedPatchLabels_.setSize(excludedPatchSet.size());
label i = 0;
for (const label patchi : excludedPatchSet)
{
excludedPatchLabels_[i++] = patchi;
}
excludedPatchLabels_ =
mesh_.boundaryMesh().indices(excludedPatchNames_);
if (!returnReduceOr(cellZoneID_ != -1))
{

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2021 OpenCFD Ltd.
Copyright (C) 2018-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -32,16 +32,16 @@ License
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::fvBoundaryMesh::addPatches(const polyBoundaryMesh& basicBdry)
void Foam::fvBoundaryMesh::addPatches(const polyBoundaryMesh& pbm)
{
setSize(basicBdry.size());
// Set boundary patches
fvPatchList& Patches = *this;
fvPatchList& patches = *this;
forAll(Patches, patchi)
patches.resize_null(pbm.size());
forAll(patches, patchi)
{
Patches.set(patchi, fvPatch::New(basicBdry[patchi], *this));
patches.set(patchi, fvPatch::New(pbm[patchi], *this));
}
}
@ -61,13 +61,13 @@ Foam::fvBoundaryMesh::fvBoundaryMesh
Foam::fvBoundaryMesh::fvBoundaryMesh
(
const fvMesh& m,
const polyBoundaryMesh& basicBdry
const polyBoundaryMesh& pbm
)
:
fvPatchList(basicBdry.size()),
fvPatchList(),
mesh_(m)
{
addPatches(basicBdry);
addPatches(pbm);
}
@ -93,27 +93,24 @@ Foam::labelList Foam::fvBoundaryMesh::indices
}
Foam::labelList Foam::fvBoundaryMesh::indices
(
const wordRes& select,
const wordRes& ignore,
const bool useGroups
) const
{
return mesh().boundaryMesh().indices(select, ignore, useGroups);
}
Foam::label Foam::fvBoundaryMesh::findPatchID(const word& patchName) const
{
if (patchName.empty())
{
return -1;
}
// OR: return PtrListOps::firstMatching(*this, patchName);
const fvPatchList& patches = *this;
forAll(patches, patchi)
{
if (patches[patchi].name() == patchName)
{
return patchi;
}
}
// Not found, return -1
return -1;
return PtrListOps::firstMatching(*this, patchName);
}
@ -171,10 +168,9 @@ Foam::lduInterfacePtrsList Foam::fvBoundaryMesh::interfaces() const
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::fvBoundaryMesh::readUpdate(const polyBoundaryMesh& basicBdry)
void Foam::fvBoundaryMesh::readUpdate(const polyBoundaryMesh& pbm)
{
clear();
addPatches(basicBdry);
addPatches(pbm);
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2021 OpenCFD Ltd.
Copyright (C) 2018-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -67,8 +67,8 @@ class fvBoundaryMesh
// Private Member Functions
//- Add fvPatches corresponding to the given polyBoundaryMesh
void addPatches(const polyBoundaryMesh&);
//- Assign fvPatches corresponding to the given polyBoundaryMesh
void addPatches(const polyBoundaryMesh& pbm);
//- No copy construct
@ -121,6 +121,18 @@ public:
// A no-op (returns empty list) for an empty matcher
labelList indices(const wordRes& matcher, const bool useGroups) const;
//- Return (sorted) patch indices for all selected matches that
//- are not ignored.
//- The selection logic as per Foam::wordRes::filter.
// Optionally matches patch groups.
// A no-op (returns empty list) for an empty select matcher
labelList indices
(
const wordRes& select,
const wordRes& ignore,
const bool useGroups
) const;
//- Find patch index given a name
// A no-op (returns -1) for an empty patchName
label findPatchID(const word& patchName) const;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2017-2022 OpenCFD Ltd.
Copyright (C) 2017-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -237,11 +237,7 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::setPatchFaces()
labelList selected
(
mesh_.boundaryMesh().patchSet
(
selectionNames_,
false // warnNotFound - we do that ourselves
).sortedToc()
mesh_.boundaryMesh().indices(selectionNames_, true) // useGroup
);
DynamicList<label> bad;