51bool Foam::polyBoundaryMesh::hasGroupIDs()
const
56 return !groupIDsPtr_->empty();
63 if (!
p.inGroups().empty())
73void Foam::polyBoundaryMesh::calcGroupIDs()
const
80 groupIDsPtr_.emplace(16);
81 auto& groupLookup = *groupIDsPtr_;
87 for (
const word& groupName :
patches[patchi].inGroups())
89 groupLookup(groupName).push_back(patchi);
96 if (groupLookup.empty())
100 else if (groupLookup.erase(
patches[patchi].
name()))
104 <<
"' which clashes with patch " << patchi
105 <<
" of the same name."
114 clearLocalAddressing();
129 entries[patchi].keyword(),
130 entries[patchi].
dict(),
141bool Foam::polyBoundaryMesh::readIOcontents(
const bool allowOptionalRead)
143 bool updated =
false;
148 this->isReadRequired()
149 || (allowOptionalRead && this->isReadOptional() && this->headerOk())
153 warnNoRereading<polyBoundaryMesh>();
168 populate(std::move(entries));
187 readIOcontents(
false);
228 if (!readIOcontents(
true))
253 if (!readIOcontents(
true))
255 populate(std::move(entries));
282void Foam::polyBoundaryMesh::clearLocalAddressing()
284 neighbourEdgesPtr_.reset(
nullptr);
285 patchIDPtr_.reset(
nullptr);
286 groupIDsPtr_.reset(
nullptr);
292 clearLocalAddressing();
305void Foam::polyBoundaryMesh::calcGeometry()
320 operator[](patchi).initGeometry(pBufs);
323 pBufs.finishedSends();
327 operator[](patchi).calcGeometry(pBufs);
335 pBufs.finishedSends();
337 for (
const auto& schedEval : patchSchedule)
339 const label patchi = schedEval.patch;
343 operator[](patchi).initGeometry(pBufs);
347 operator[](patchi).calcGeometry(pBufs);
362 mesh_.nBoundaryFaces(),
363 mesh_.nInternalFaces()
373 mesh_.nBoundaryFaces(),
374 mesh_.nInternalFaces()
407 <<
"Neighbour edge addressing not correct across parallel"
408 <<
" boundaries." <<
endl;
411 if (!neighbourEdgesPtr_)
413 neighbourEdgesPtr_.emplace(size());
414 auto& neighbourEdges = *neighbourEdgesPtr_;
417 label nEdgePairs = 0;
424 for (
labelPair& edgeInfo : neighbourEdges[patchi])
446 edgei < edges.size();
451 const edge&
e = edges[edgei];
456 auto fnd = pointsToEdge.find(meshEdge);
480 neighbourEdges[edgeInfo[0]][edgeInfo[1]]
486 pointsToEdge.erase(meshEdge);
491 if (pointsToEdge.size())
494 <<
"Not all boundary edges of patches match up." <<
nl
495 <<
"Is the outside of your mesh multiply connected?"
509 if (edgeInfo[0] == -1 || edgeInfo[1] == -1)
515 <<
"Not all boundary edges of patches match up." <<
nl
516 <<
"Edge " << edgei <<
" on patch " <<
pp.name()
519 <<
" edge on any other patch." <<
nl
520 <<
"Is the outside of your mesh multiply connected?"
527 return *neighbourEdgesPtr_;
535 patchIDPtr_.emplace(mesh_.nBoundaryFaces());
536 auto& list = *patchIDPtr_;
546 (
patches[patchi].start() - mesh_.nInternalFaces())
557 const label bndFacei = (meshFacei - mesh_.nInternalFaces());
561 (bndFacei >= 0 && bndFacei < mesh_.nBoundaryFaces())
562 ? this->patchID()[bndFacei]
572 forAll(meshFaceIndices, i)
588 return *groupIDsPtr_;
594 const word& groupName,
598 groupIDsPtr_.reset(
nullptr);
607 if (pending.test(patchi))
609 pending.unset(patchi);
610 patches[patchi].addGroup(groupName);
617 if (pending.test(patchi))
701 [](
const polyPatch&
p) {
return p.physicalType(); }
747 return mesh_.nInternalFaces();
753 return mesh_.nBoundaryFaces();
759 return labelRange(mesh_.nInternalFaces(), mesh_.nBoundaryFaces());
771 return (*
this)[patchi].range();
777 const wordRe& matcher,
787 const bool checkGroups = (useGroups && this->hasGroupIDs());
791 if (matcher.isPattern())
795 const auto& groupLookup = groupPatchIDs();
798 if (matcher(iter.key()))
801 ids.insert(iter.val());
826 else if (checkGroups)
828 const auto iter = groupPatchIDs().cfind(matcher);
833 ids.insert(iter.val());
838 return ids.sortedToc();
852 else if (matcher.size() == 1)
854 return this->indices(matcher.front(), useGroups);
860 if (useGroups && this->hasGroupIDs())
862 ids.reserve(this->size());
864 const auto& groupLookup = groupPatchIDs();
867 if (matcher(iter.key()))
870 ids.insert(iter.val());
884 return ids.sortedToc();
890 const wordRes& allow,
895 if (allow.empty() && deny.empty())
906 if (useGroups && this->hasGroupIDs())
908 ids.reserve(this->size());
910 const auto& groupLookup = groupPatchIDs();
913 if (matcher(iter.key()))
916 ids.insert(iter.val());
930 return ids.sortedToc();
946 const word& patchName,
950 if (patchName.empty())
965 <<
"Patch '" << patchName <<
"' not found. "
966 <<
"Available patch names";
971 <<
" in region '" << mesh_.name() <<
"'";
982 Pout<<
"label polyBoundaryMesh::findPatchID(const word&) const"
983 <<
"Patch named " << patchName <<
" not found. "
984 <<
"Available patch names: " <<
names() <<
endl;
997 if (!patchName.empty())
1010 if (meshFacei <
mesh().nInternalFaces())
1015 else if (meshFacei >=
mesh().nFaces())
1019 <<
"Face " << meshFacei
1020 <<
" out of bounds. Number of geometric faces " <<
mesh().
nFaces()
1032 const label patchi =
1044 const label patchi =
1051 [](
const polyPatch&
p, label val) {
return (
p.start() <= val); }
1054 if (patchi < 0 || !
patches[patchi].
range().contains(meshFacei))
1058 <<
"Face " << meshFacei <<
" not found in any of the patches "
1060 <<
"The patches appear to be inconsistent with the mesh :"
1062 <<
" total number of faces:" <<
mesh().
nFaces()
1077 forAll(meshFaceIndices, i)
1087 const UList<wordRe>& select,
1088 const bool warnNotFound,
1089 const bool useGroups
1105 const bool checkGroups = (useGroups && this->hasGroupIDs());
1107 for (
const wordRe& matcher : select)
1111 for (label i = 0; i < len; ++i)
1120 if (missed && checkGroups)
1123 if (matcher.isPattern())
1127 if (matcher.match(iter.key()))
1130 ids.insert(iter.val());
1137 const auto iter = groupPatchIDs().cfind(matcher);
1142 ids.insert(iter.val());
1148 if (missed && warnNotFound)
1153 <<
"Cannot find any patch or group names matching "
1159 <<
"Cannot find any patch names matching "
1192 label nMatch = nonGroupPatches.erase(groupPatchSet);
1194 if (nMatch == groupPatchSet.size())
1196 matchedGroups.push_back(iter.key());
1198 else if (nMatch != 0)
1201 nonGroupPatches.transfer(oldNonGroupPatches);
1205 groups.transfer(matchedGroups);
1218 bool hasError =
false;
1230 if (nonProci != patchi)
1235 if (
debug || report)
1237 Pout<<
" ***Problem with boundary patch " << patchi
1238 <<
" name:" << bm[patchi].name()
1239 <<
" type:" << bm[patchi].type()
1240 <<
" - seems to be preceeded by processor patches."
1241 <<
" This is usually a problem." <<
endl;
1246 localNames[nonProci] = bm[patchi].name();
1247 localTypes[nonProci] = bm[patchi].type();
1252 localNames.resize(nonProci);
1253 localTypes.resize(nonProci);
1260 const wordList allNames(procAddr.gather(localNames));
1261 const wordList allTypes(procAddr.gather(localTypes));
1264 for (
const int proci : procAddr.subProcs())
1266 const auto procNames(allNames.slice(procAddr.range(proci)));
1267 const auto procTypes(allTypes.slice(procAddr.range(proci)));
1269 if (procNames != localNames || procTypes != localTypes)
1273 if (
debug || report)
1275 Info<<
" ***Inconsistent patches across processors, "
1276 "processor0 has patch names:" << localNames
1277 <<
" patch types:" << localTypes
1278 <<
" processor" << proci
1279 <<
" has patch names:" << procNames
1280 <<
" patch types:" << procTypes
1294 const polyBoundaryMesh& bm = *
this;
1296 bool hasError =
false;
1302 if (bm[patchi].start() != nextPatchStart && !hasError)
1306 Info<<
" ****Problem with boundary patch " << patchi
1307 <<
" named " << bm[patchi].name()
1308 <<
" of type " << bm[patchi].type()
1309 <<
". The patch should start on face no " << nextPatchStart
1310 <<
" and the patch specifies " << bm[patchi].start()
1312 <<
"Possibly consecutive patches have this same problem."
1313 <<
" Suppressing future warnings." <<
endl;
1316 if (!
patchNames.insert(bm[patchi].name()) && !hasError)
1320 Info<<
" ****Duplicate boundary patch " << patchi
1321 <<
" named " << bm[patchi].name()
1322 <<
" of type " << bm[patchi].type()
1324 <<
"Suppressing future warnings." <<
endl;
1327 nextPatchStart += bm[patchi].size();
1332 if (
debug || report)
1336 Pout<<
" ***Boundary definition is in error." <<
endl;
1340 Info<<
" Boundary definition OK." <<
endl;
1360 operator[](patchi).initMovePoints(pBufs,
p);
1363 pBufs.finishedSends();
1367 operator[](patchi).movePoints(pBufs,
p);
1375 pBufs.finishedSends();
1377 for (
const auto& schedEval : patchSchedule)
1379 const label patchi = schedEval.patch;
1383 operator[](patchi).initMovePoints(pBufs,
p);
1396 neighbourEdgesPtr_.reset(
nullptr);
1397 patchIDPtr_.reset(
nullptr);
1398 groupIDsPtr_.reset(
nullptr);
1410 operator[](patchi).initUpdateMesh(pBufs);
1413 pBufs.finishedSends();
1417 operator[](patchi).updateMesh(pBufs);
1425 pBufs.finishedSends();
1427 for (
const auto& schedEval : patchSchedule)
1429 const label patchi = schedEval.patch;
1433 operator[](patchi).initUpdateMesh(pBufs);
1447 const bool validBoundary
1458 patches[patchi].index() = patchi;
1462 groupIDsPtr_.reset(
nullptr);
1475 os << entries.size();
1477 if (entries.empty())
1486 for (
const auto&
pp : entries)
1500 const word& keyword,
1506 if (!keyword.empty())
1514 if (!keyword.empty())
os.endEntry();
1528 const bool writeOnProc
1540 const word& patchName
1543 const label patchi = findPatchID(patchName);
1548 <<
"Patch named " << patchName <<
" not found." <<
nl
1549 <<
"Available patch names: " <<
names() <<
endl
1553 return operator[](patchi);
1559 const word& patchName
1562 const label patchi = findPatchID(patchName);
1567 <<
"Patch named " << patchName <<
" not found." <<
nl
1568 <<
"Available patch names: " <<
names() <<
endl
1572 return operator[](patchi);
Functions to operate on Pointer Lists.
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
const polyBoundaryMesh & pbm
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
void push_back(const T &val)
Copy append an element to the end of this list.
Map from edge (expressed as its endpoints) to value. Hashing (and ==) on an edge is symmetric.
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
A HashTable similar to std::unordered_map.
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Foam::label erase(InputIter first, InputIter last)
bool empty() const noexcept
True if the hash table is empty.
void reserve(label numEntries)
Reserve space for at least the specified number of elements (not the number of buckets) and regenerat...
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
void transfer(HashTable< T, Key, Hash > &rhs)
Transfer contents into this table.
iterator find(const Key &key)
Find and return an iterator set at the hashed entry.
label size() const noexcept
The number of elements in table.
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
Defines the attributes of an object for which implicit objectRegistry management is supported,...
const word & name() const noexcept
Return the object name.
static word groupName(StringType base, const word &group)
Create dot-delimited name.group string.
autoPtr< IOobject > clone() const
Clone.
A simple container for options an IOstream can normally have.
compressionType compression() const noexcept
Get the stream compression.
@ UNCOMPRESSED
compression = false
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
void resize(const label len)
Adjust allocated size of list.
virtual Ostream & write(const char c) override
Write character.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
virtual Ostream & endBlock()
Write end block group.
virtual Ostream & beginBlock(const keyType &kw)
Write begin block group with the given name.
label nEdges() const
Number of edges in patch.
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
label nInternalEdges() const
Number of internal edges.
const labelList & meshPoints() const
Return labelList of mesh points in patch.
const Field< point_type > & localPoints() const
Return pointField of points in patch.
Buffers for inter-processor communications streams (UOPstream, UIPstream).
UPstream::commsTypes commsType() const noexcept
The communications type of the stream.
void finishedSends(const bool wait=true)
Mark the send phase as being finished.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie,...
void resize_null(const label newLen)
Set the addressed list to the given size, deleting all existing entries. Afterwards the list contains...
constexpr PtrList() noexcept
A non-owning sub-view of a List (allocated or unallocated storage).
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
bool test(const label i) const
Test bool value at specified position, always false for out-of-range access.
bool empty() const noexcept
True if List is empty (ie, size() is zero).
SubList< T > slice(const label pos, label len=-1)
Return SubList slice (non-const access) - no range checking.
T & front()
Access first element of the list, position [0].
bool unset(const label i)
Unset the bool entry at specified position, always false for out-of-range access.
void size(const label n)
Older name for setAddressableSize.
@ scheduled
"scheduled" (MPI standard) : (MPI_Send, MPI_Recv)
@ nonBlocking
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
@ buffered
"buffered" : (MPI_Bsend, MPI_Recv)
static bool parRun(const bool on) noexcept
Set as parallel run on/off.
static int & msgType() noexcept
Message tag of standard messages.
static void reduceOr(bool &value, const int communicator=worldComm)
Logical (or) reduction (MPI_AllReduce).
static int incrMsgType(int val=1) noexcept
Increment the message tag for standard messages.
static commsTypes defaultCommsType
Default commsType.
static bool & parRun() noexcept
Test if this a parallel run.
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie,...
void reorder(const labelUList &oldToNew, const bool check=false)
Reorder elements. Reordering must be unique (ie, shuffle).
bool empty() const noexcept
True if the list is empty (ie, size() is zero).
label size() const noexcept
The number of entries in the list.
label count() const noexcept
The number of non-nullptr entries in the list.
An edge is a list of two vertex labels. This can correspond to a directed graph edge or an edge on a ...
Calculates a non-overlapping list of offsets based on an input size (eg, number of cells) from differ...
const lduSchedule & patchSchedule() const noexcept
Order in which the patches should be initialised/evaluated corresponding to the schedule.
A range or interval of labels defined by a start and a size.
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
A polyBoundaryMesh is a polyPatch list with registered IO, a reference to the associated polyMesh,...
bool checkDefinition(const bool report=false) const
Check boundary definition.
label nNonProcessorFaces() const
The number of boundary faces before the first processor patch.
label nNonProcessor() const
The number of patches before the first processor patch.
wordList physicalTypes() const
Return a list of physical types.
const HashTable< labelList > & groupPatchIDs() const
The patch indices per patch group.
labelList patchStarts() const
Return a list of patch start face indices.
virtual bool writeObject(IOstreamOption streamOpt, const bool writeOnProc=true) const
Write using stream options, but always UNCOMPRESSED.
const List< labelPairList > & neighbourEdges() const
Per patch the edges on the neighbouring patch.
void reorder(const labelUList &oldToNew, const bool validBoundary)
Reorders patches. Ordering does not have to be done in.
wordList types() const
Return a list of patch types.
void clearGeom()
Clear geometry at this level and at patches.
label findPatchID(const word &patchName, const bool allowNotFound=true) const
Find patch index given a name, return -1 if not found.
UPtrList< const labelUList > faceCells() const
Return a list of faceCells for each patch.
virtual bool writeData(Ostream &os) const
The writeData member function required by regIOobject.
labelHashSet patchSet(const UList< wordRe > &select, const bool warnNotFound=true, const bool useGroups=true) const
Return the set of patch IDs corresponding to the given names.
const polyPatch & operator[](const word &patchName) const
Return const reference to polyPatch by name.
const faceList::subList faces() const
Return mesh faces for the entire boundary.
void setGroup(const word &groupName, const labelUList &patchIDs)
Set/add group with patches.
labelRange range() const noexcept
The face range for all boundary faces.
void movePoints(const pointField &p)
Correct polyBoundaryMesh after moving points.
List< labelRange > patchRanges() const
Return a list of patch ranges.
void matchGroups(const labelUList &patchIDs, wordList &groups, labelHashSet &nonGroupPatches) const
Match the patches to groups.
void clearAddressing()
Clear addressing at this level and at patches.
label nFaces() const noexcept
The number of boundary faces in the underlying mesh.
friend class polyMesh
Declare friendship with polyMesh.
label start() const noexcept
The start label of boundary faces in the polyMesh face list.
void writeEntry(Ostream &os) const
Write as a plain list of entries.
const labelList & patchID() const
Per boundary face label the patch index.
const polyMesh & mesh() const noexcept
Return the mesh reference.
labelList patchSizes() const
Return a list of patch sizes.
void clear()
Clear the patch list and all demand-driven data.
wordList groupNames() const
A list of the group names (if any).
wordList names() const
Return a list of patch names.
bool checkParallelSync(const bool report=false) const
Check whether all procs have all patches and in same order.
void updateMesh()
Correct polyBoundaryMesh after topology update.
const polyPatch * cfindPatch(const word &patchName) const
Find patch by name and return const pointer.
const labelList::subList faceOwner() const
Return face owner for the entire boundary.
label nProcessorPatches() const
The number of processorPolyPatch patches.
polyBoundaryMesh(const polyBoundaryMesh &)=delete
No copy construct.
labelList indices(const wordRe &matcher, const bool useGroups=true) const
The (sorted) patch indices for all matches, optionally matching patch groups.
label findIndex(const wordRe &key) const
Return patch index for the first match, return -1 if not found.
labelPair whichPatchFace(const label meshFacei) const
Lookup mesh face index and return (patchi, patchFacei) tuple or (-1, meshFacei) for internal faces.
Mesh consisting of general polyhedral cells.
static word defaultRegion
Return the default region name.
const globalMeshData & globalData() const
Return parallel info (demand-driven).
A patch is a list of labels that address the faces in the global face list.
static autoPtr< polyPatch > New(const word &patchType, const word &name, const label size, const label start, const label index, const polyBoundaryMesh &bm)
Return pointer to a new patch created on freestore from components.
label nInternalFaces() const noexcept
Number of internal faces.
label nFaces() const noexcept
Number of mesh faces.
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
virtual bool writeObject(IOstreamOption streamOpt, const bool writeOnProc) const
Write using stream options.
regIOobject(const IOobject &io, const bool isTimeObject=false)
Construct from IOobject. The optional flag adds special handling if the object is the top-level regIO...
@ BEGIN_LIST
Begin list [isseparator].
@ END_LIST
End list [isseparator].
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings.
bool isPattern() const noexcept
The wordRe is a pattern, not a literal string.
A List of wordRe with additional matching capabilities.
A class for handling words, derived from Foam::string.
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
const polyBoundaryMesh & patches
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
OBJstream os(runTime.globalPath()/outputName)
#define WarningInFunction
Report a warning using Foam::Warning.
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
labelList findMatching(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
Extract list indices for all items with 'name()' that matches.
label firstMatching(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
Find first list item with 'name()' that matches, -1 on failure.
Namespace for handling debugging switches.
List< edge > edgeList
List of edge.
Pair< label > labelPair
A pair of labels.
PtrList< polyPatch > polyPatchList
Store lists of polyPatch as a PtrList.
List< word > wordList
List of word.
bool returnReduceOr(const bool value, const int communicator=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
List< labelPair > labelPairList
List of labelPair.
List< label > labelList
A List of labels.
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
messageStream Info
Information stream (stdout output on master, null elsewhere).
label findLower(const ListType &input, const T &val, const label start, const ComparePredicate &comp)
Binary search to find the index of the last element in a sorted list that is less than value.
List< lduScheduleEntry > lduSchedule
A List of lduSchedule entries.
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces).
Ostream & incrIndent(Ostream &os)
Increment the indent level.
const word GlobalIOList< Tuple2< scalar, vector > >::typeName("scalarVectorTable")
Ostream & endl(Ostream &os)
Add newline and flush stream.
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
errorManip< error > abort(error &err)
List< bool > boolList
A List of bools.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
vectorField pointField
pointField is a vectorField.
errorManipArg< error, int > exit(error &err, const int errNo=1)
UList< label > labelUList
A UList of labels.
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
constexpr char nl
The newline '\n' character (0x0a).
wordList patchNames(nPatches)
#define forAll(list, i)
Loop across all elements in list.
#define forAllConstIters(container, iter)
Iterate across all elements of the container object with const access.
Dispatch tag: Construct 'one-sided' from the non-master local sizes using gather but no broadcast.
Extract name (as a word) from an object, typically using its name() method.
Extract type (as a word) from an object, typically using its type() method.
Functor wrapper of allow/deny lists of wordRe for filtering.