51 bool Foam::polyBoundaryMesh::hasGroupIDs()
const 56 return !groupIDsPtr_->empty();
63 if (!
p.inGroups().empty())
73 void 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);
100 <<
"' which clashes with patch " << patchi
101 <<
" of the same name." 108 void Foam::polyBoundaryMesh::populate(PtrList<entry>&& entries)
110 clearLocalAddressing();
125 entries[patchi].keyword(),
126 entries[patchi].
dict(),
137 bool Foam::polyBoundaryMesh::readIOcontents(
const bool allowOptionalRead)
139 bool updated =
false;
140 PtrList<entry> entries;
144 this->isReadRequired()
145 || (allowOptionalRead && this->isReadOptional() && this->headerOk())
149 warnNoRereading<polyBoundaryMesh>();
152 Istream& is = readStream(typeName);
164 populate(std::move(entries));
183 readIOcontents(
false);
224 if (!readIOcontents(
true))
242 PtrList<entry>&& entries
249 if (!readIOcontents(
true))
251 populate(std::move(entries));
278 void Foam::polyBoundaryMesh::clearLocalAddressing()
280 neighbourEdgesPtr_.reset(
nullptr);
281 patchIDPtr_.reset(
nullptr);
282 groupIDsPtr_.reset(
nullptr);
288 clearLocalAddressing();
301 void Foam::polyBoundaryMesh::calcGeometry()
313 operator[](patchi).initGeometry(pBufs);
316 pBufs.finishedSends();
320 operator[](patchi).calcGeometry(pBufs);
328 pBufs.finishedSends();
330 for (
const auto& schedEval : patchSchedule)
332 const label patchi = schedEval.patch;
336 operator[](patchi).initGeometry(pBufs);
340 operator[](patchi).calcGeometry(pBufs);
352 mesh_.nBoundaryFaces(),
353 mesh_.nInternalFaces()
363 mesh_.nBoundaryFaces(),
364 mesh_.nInternalFaces()
397 <<
"Neighbour edge addressing not correct across parallel" 398 <<
" boundaries." <<
endl;
401 if (!neighbourEdgesPtr_)
403 neighbourEdgesPtr_.emplace(size());
404 auto& neighbourEdges = *neighbourEdgesPtr_;
407 label nEdgePairs = 0;
410 const polyPatch&
pp = operator[](patchi);
414 for (
labelPair& edgeInfo : neighbourEdges[patchi])
425 EdgeMap<labelPair> pointsToEdge(nEdgePairs);
429 const polyPatch&
pp = operator[](patchi);
436 edgei < edges.size();
441 const edge&
e = edges[edgei];
446 auto fnd = pointsToEdge.find(meshEdge);
470 neighbourEdges[edgeInfo[0]][edgeInfo[1]]
476 pointsToEdge.erase(meshEdge);
481 if (pointsToEdge.size())
484 <<
"Not all boundary edges of patches match up." <<
nl 485 <<
"Is the outside of your mesh multiply connected?" 491 const polyPatch&
pp = operator[](patchi);
499 if (edgeInfo[0] == -1 || edgeInfo[1] == -1)
505 <<
"Not all boundary edges of patches match up." <<
nl 506 <<
"Edge " << edgei <<
" on patch " <<
pp.name()
509 <<
" edge on any other patch." <<
nl 510 <<
"Is the outside of your mesh multiply connected?" 517 return *neighbourEdgesPtr_;
525 patchIDPtr_.emplace(mesh_.nBoundaryFaces());
526 auto& list = *patchIDPtr_;
547 const label bndFacei = (meshFacei - mesh_.nInternalFaces());
551 (bndFacei >= 0 && bndFacei < mesh_.nBoundaryFaces())
562 forAll(meshFaceIndices, i)
578 return *groupIDsPtr_;
584 const word& groupName,
588 groupIDsPtr_.reset(
nullptr);
597 if (pending.test(patchi))
599 pending.
unset(patchi);
600 patches[patchi].addGroup(groupName);
607 if (pending.test(patchi))
609 patches[patchi].removeGroup(groupName);
623 if (isA<processorPolyPatch>(
p))
643 if (isA<processorPolyPatch>(
p))
668 PtrListOps::get<word>
671 [](
const polyPatch&
p) {
return p.physicalType(); }
679 PtrListOps::get<label>
690 PtrListOps::get<label>
701 PtrListOps::get<labelRange>
711 return this->groupPatchIDs().sortedToc();
717 return mesh_.nInternalFaces();
723 return mesh_.nBoundaryFaces();
729 return labelRange(mesh_.nInternalFaces(), mesh_.nBoundaryFaces());
741 return (*
this)[patchi].range();
757 const bool checkGroups = (useGroups && this->hasGroupIDs());
765 const auto& groupLookup = groupPatchIDs();
768 if (matcher(iter.key()))
771 ids.insert(iter.val());
796 else if (checkGroups)
798 const auto iter = groupPatchIDs().cfind(matcher);
803 ids.insert(iter.val());
808 return ids.sortedToc();
814 const wordRes& matcher,
822 else if (matcher.size() == 1)
824 return this->indices(matcher.front(), useGroups);
830 if (useGroups && this->hasGroupIDs())
832 ids.reserve(this->size());
834 const auto& groupLookup = groupPatchIDs();
837 if (matcher(iter.key()))
840 ids.insert(iter.val());
854 return ids.sortedToc();
861 const wordRes& ignore,
867 return this->indices(
select, useGroups);
870 const wordRes::filter matcher(
select, ignore);
875 if (useGroups && this->hasGroupIDs())
877 ids.reserve(this->size());
879 const auto& groupLookup = groupPatchIDs();
882 if (matcher(iter.key()))
885 ids.insert(iter.val());
899 return ids.sortedToc();
915 const word& patchName,
919 if (patchName.empty())
934 <<
"Patch '" << patchName <<
"' not found. " 935 <<
"Available patch names";
940 <<
" in region '" << mesh_.name() <<
"'";
951 Pout<<
"label polyBoundaryMesh::findPatchID(const word&) const" 952 <<
"Patch named " << patchName <<
" not found. " 953 <<
"Available patch names: " <<
names() <<
endl;
964 if (meshFacei <
mesh().nInternalFaces())
969 else if (meshFacei >=
mesh().nFaces())
973 <<
"Face " << meshFacei
974 <<
" out of bounds. Number of geometric faces " <<
mesh().
nFaces()
997 [](
const polyPatch&
p, label val) {
return (
p.start() <= val); }
1000 if (patchi < 0 || !
patches[patchi].
range().contains(meshFacei))
1004 <<
"Face " << meshFacei <<
" not found in any of the patches " 1006 <<
"The patches appear to be inconsistent with the mesh :" 1008 <<
" total number of faces:" <<
mesh().
nFaces()
1023 forAll(meshFaceIndices, i)
1025 output[i] = whichPatchFace(meshFaceIndices[i]);
1033 const UList<wordRe>&
select,
1034 const bool warnNotFound,
1035 const bool useGroups
1051 const bool checkGroups = (useGroups && this->hasGroupIDs());
1053 for (
const wordRe& matcher :
select)
1057 for (label i = 0; i < len; ++i)
1066 if (missed && checkGroups)
1069 if (matcher.isPattern())
1073 if (matcher.match(iter.key()))
1076 ids.insert(iter.val());
1083 const auto iter = groupPatchIDs().cfind(matcher);
1088 ids.insert(iter.val());
1094 if (missed && warnNotFound)
1099 <<
"Cannot find any patch or group names matching " 1105 <<
"Cannot find any patch names matching " 1123 DynamicList<word> matchedGroups(1);
1128 const HashTable<labelList>& groupLookup = this->groupPatchIDs();
1138 label nMatch = nonGroupPatches.
erase(groupPatchSet);
1140 if (nMatch == groupPatchSet.size())
1142 matchedGroups.push_back(iter.key());
1144 else if (nMatch != 0)
1147 nonGroupPatches.transfer(oldNonGroupPatches);
1151 groups.transfer(matchedGroups);
1162 const polyBoundaryMesh& bm = *
this;
1164 bool hasError =
false;
1174 if (!isA<processorPolyPatch>(bm[patchi]))
1176 if (nonProci != patchi)
1181 if (
debug || report)
1183 Pout<<
" ***Problem with boundary patch " << patchi
1184 <<
" name:" << bm[patchi].
name()
1185 <<
" type:" << bm[patchi].
type()
1186 <<
" - seems to be preceeded by processor patches." 1187 <<
" This is usually a problem." <<
endl;
1192 localNames[nonProci] = bm[patchi].
name();
1193 localTypes[nonProci] = bm[patchi].
type();
1198 localNames.resize(nonProci);
1199 localTypes.resize(nonProci);
1204 const globalIndex
procAddr(globalIndex::gatherNonLocal{}, nonProci);
1212 const auto procNames(allNames.slice(
procAddr.
range(proci)));
1213 const auto procTypes(allTypes.slice(
procAddr.
range(proci)));
1215 if (procNames != localNames || procTypes != localTypes)
1219 if (
debug || report)
1221 Info<<
" ***Inconsistent patches across processors, " 1222 "processor0 has patch names:" << localNames
1223 <<
" patch types:" << localTypes
1224 <<
" processor" << proci
1225 <<
" has patch names:" << procNames
1226 <<
" patch types:" << procTypes
1240 const polyBoundaryMesh& bm = *
this;
1242 bool hasError =
false;
1248 if (bm[patchi].start() != nextPatchStart && !hasError)
1252 Info<<
" ****Problem with boundary patch " << patchi
1253 <<
" named " << bm[patchi].name()
1254 <<
" of type " << bm[patchi].type()
1255 <<
". The patch should start on face no " << nextPatchStart
1256 <<
" and the patch specifies " << bm[patchi].start()
1258 <<
"Possibly consecutive patches have this same problem." 1259 <<
" Suppressing future warnings." <<
endl;
1262 if (!
patchNames.insert(bm[patchi].name()) && !hasError)
1266 Info<<
" ****Duplicate boundary patch " << patchi
1267 <<
" named " << bm[patchi].name()
1268 <<
" of type " << bm[patchi].type()
1270 <<
"Suppressing future warnings." <<
endl;
1273 nextPatchStart += bm[patchi].size();
1278 if (
debug || report)
1282 Pout<<
" ***Boundary definition is in error." <<
endl;
1286 Info<<
" Boundary definition OK." <<
endl;
1306 operator[](patchi).initMovePoints(pBufs,
p);
1309 pBufs.finishedSends();
1313 operator[](patchi).movePoints(pBufs,
p);
1321 pBufs.finishedSends();
1323 for (
const auto& schedEval : patchSchedule)
1325 const label patchi = schedEval.patch;
1329 operator[](patchi).initMovePoints(pBufs,
p);
1333 operator[](patchi).movePoints(pBufs,
p);
1342 neighbourEdgesPtr_.reset(
nullptr);
1343 patchIDPtr_.reset(
nullptr);
1344 groupIDsPtr_.reset(
nullptr);
1356 operator[](patchi).initUpdateMesh(pBufs);
1359 pBufs.finishedSends();
1363 operator[](patchi).updateMesh(pBufs);
1371 pBufs.finishedSends();
1373 for (
const auto& schedEval : patchSchedule)
1375 const label patchi = schedEval.patch;
1379 operator[](patchi).initUpdateMesh(pBufs);
1383 operator[](patchi).updateMesh(pBufs);
1393 const bool validBoundary
1404 patches[patchi].index() = patchi;
1418 os << entries.size();
1420 if (entries.empty())
1429 for (
const auto&
pp : entries)
1443 const word& keyword,
1449 if (!keyword.empty())
1471 const bool writeOnProc
1483 const word& patchName
1486 const label patchi = findPatchID(patchName);
1491 <<
"Patch named " << patchName <<
" not found." <<
nl 1492 <<
"Available patch names: " <<
names() <<
endl 1496 return operator[](patchi);
1502 const word& patchName
1505 const label patchi = findPatchID(patchName);
1510 <<
"Patch named " << patchName <<
" not found." <<
nl 1511 <<
"Available patch names: " <<
names() <<
endl 1515 return operator[](patchi);
label findPatchID(const word &patchName, const bool allowNotFound=true) const
Find patch index given a name, return -1 if not found.
labelRange range(const label proci) const
Return start/size range of proci data.
const labelList patchIDs(pbm.indices(polyPatchNames, true))
const polyBoundaryMesh & pbm
labelList patchSizes() const
Return a list of patch sizes.
const List< labelPairList > & neighbourEdges() const
Per patch the edges on the neighbouring patch.
void size(const label n)
Older name for setAddressableSize.
autoPtr< IOobject > clone() const
Clone.
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type unset(const label i)
Unset the bool entry at specified position, always false for out-of-range access. ...
labelList findMatching(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
Extract list indices for all items with 'name()' that matches.
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< word > names(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
List of names generated by calling name() for each list item and filtered for matches.
virtual const fileName & name() const
The name of the stream.
errorManipArg< error, int > exit(error &err, const int errNo=1)
const Field< point_type > & localPoints() const
Return pointField of points in patch.
virtual Ostream & write(const char c) override
Write character.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
virtual bool check(const char *operation) const
Check IOstream status for given operation.
List< edge > edgeList
List of edge.
void setGroup(const word &groupName, const labelUList &patchIDs)
Set/add group with patches.
const word & name() const noexcept
Return the object name.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
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.
A range or interval of labels defined by a start and a size.
polyBoundaryMesh(const polyBoundaryMesh &)=delete
No copy construct.
List< bool > select(const label n, const labelUList &locations)
Construct a selection list of bools (all false) with the given pre-size, subsequently add specified l...
constexpr char nl
The newline '\n' character (0x0a)
label start() const noexcept
The start label of boundary faces in the polyMesh face list.
bool empty() const noexcept
True if List is empty (ie, size() is zero)
Type type(bool followLink=true, bool checkGzip=false) const
Return the directory entry type: UNDEFINED, FILE, DIRECTORY (or SYMLINK).
virtual bool writeData(Ostream &os) const
The writeData member function required by regIOobject.
void reorder(const labelUList &oldToNew, const bool validBoundary)
Reorders patches. Ordering does not have to be done in.
Ostream & endl(Ostream &os)
Add newline and flush stream.
labelPair whichPatchFace(const label meshFacei) const
Lookup mesh face index and return (patchi, patchFacei) tuple or (-1, meshFacei) for internal faces...
const labelList & patchID() const
Per boundary face label the patch index.
static bool & parRun() noexcept
Test if this a parallel run.
void reorder(const labelUList &oldToNew, const bool check=false)
Reorder elements. Reordering must be unique (ie, shuffle).
wordList groupNames() const
A list of the group names (if any)
label nInternalEdges() const
Number of internal edges.
void clearGeom()
Clear geometry at this level and at patches.
static void reduceOr(bool &value, const label communicator=worldComm)
Logical (or) reduction (MPI_AllReduce)
Begin list [isseparator].
labelRange range() const noexcept
The face range for all boundary faces.
List< lduScheduleEntry > lduSchedule
A List of lduSchedule entries.
List< labelPair > labelPairList
List of labelPair.
Functions to operate on Pointer Lists.
A simple container for options an IOstream can normally have.
SubList< face > subList
Declare type of subList.
virtual bool writeObject(IOstreamOption streamOpt, const bool writeOnProc) const
Write using stream options.
Smooth ATC in cells next to a set of patches supplied by type.
wordList types() const
Return a list of patch types.
label nFaces() const noexcept
Number of mesh faces.
virtual const fileName & name() const override
Get the name of the output serial stream. (eg, the name of the Fstream file name) ...
void movePoints(const pointField &p)
Correct polyBoundaryMesh after moving points.
UList< label > labelUList
A UList of labels.
const labelList & meshPoints() const
Return labelList of mesh points in patch.
Extract name (as a word) from an object, typically using its name() method.
label nProcessorPatches() const
The number of processorPolyPatch patches.
#define forAll(list, i)
Loop across all elements in list.
labelList indices(const wordRe &matcher, const bool useGroups=true) const
Return (sorted) patch indices for all matches.
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
PtrList< polyPatch > polyPatchList
Store lists of polyPatch as a PtrList.
void matchGroups(const labelUList &patchIDs, wordList &groups, labelHashSet &nonGroupPatches) const
Match the patches to groups.
void resize_null(const label newLen)
Set the addressed list to the given size, deleting all existing entries. Afterwards the list contains...
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
A List obtained as a section of another List.
UPtrList< const labelUList > faceCells() const
Return a list of faceCells for each patch.
vectorField pointField
pointField is a vectorField.
const dimensionedScalar e
Elementary charge.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
"scheduled" (MPI standard) : (MPI_Send, MPI_Recv)
A class for handling words, derived from Foam::string.
static word defaultRegion
Return the default region name.
bool checkDefinition(const bool report=false) const
Check boundary definition.
wordList names() const
Return a list of patch names.
label size() const noexcept
The number of entries in the list.
virtual Ostream & endBlock()
Write end block group.
wordList patchNames(nPatches)
const globalMeshData & globalData() const
Return parallel info (demand-driven)
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
label nInternalFaces() const noexcept
Number of internal faces.
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
wordList physicalTypes() const
Return a list of physical types.
friend Ostream & operator(Ostream &os, const UPtrList< T > &list)
Write UPtrList to Ostream.
A HashTable similar to std::unordered_map.
const HashTable< labelList > & groupPatchIDs() const
The patch indices per patch group.
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
errorManip< error > abort(error &err)
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings...
const faceList::subList faces() const
Return mesh faces for the entire boundary.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
void clear()
Clear the patch list and all demand-driven data.
bool checkParallelSync(const bool report=false) const
Check whether all procs have all patches and in same order.
label nEdges() const
Number of edges in patch.
void writeEntry(Ostream &os) const
Write as a plain list of entries.
int debug
Static debugging option.
void updateMesh()
Correct polyBoundaryMesh after topology update.
Pair< label > labelPair
A pair of labels.
OBJstream os(runTime.globalPath()/outputName)
defineTypeNameAndDebug(combustionModel, 0)
compressionType compression() const noexcept
Get the stream compression.
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
labelList patchStarts() const
Return a list of patch start face indices.
labelRange subProcs() const noexcept
Range of process indices for addressed sub-offsets (processes)
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
List< word > wordList
List of word.
label nFaces() const noexcept
The number of boundary faces in the underlying mesh.
static commsTypes defaultCommsType
Default commsType.
#define WarningInFunction
Report a warning using Foam::Warning.
globalIndex procAddr(aMesh.nFaces())
List< labelRange > patchRanges() const
Return a list of patch ranges.
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
void clearAddressing()
Clear addressing at this level and at patches.
bool good() const noexcept
True if next operation might succeed.
const lduSchedule & patchSchedule() const noexcept
Order in which the patches should be initialised/evaluated corresponding to the schedule.
const polyBoundaryMesh & patches
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
void clear()
Clear the PtrList. Delete allocated entries and set size to zero.
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
messageStream Info
Information stream (stdout output on master, null elsewhere)
virtual Ostream & beginBlock(const keyType &kw)
Write begin block group with the given name.
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
static Ostream & output(Ostream &os, const IntRange< T > &range)
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.
Mesh consisting of general polyhedral cells.
static void gather(const labelUList &offsets, const label comm, const ProcIDsContainer &procIDs, const UList< Type > &fld, List< Type > &allFld, const int tag=UPstream::msgType(), const UPstream::commsTypes=UPstream::commsTypes::nonBlocking)
Collect data in processor order on master (== procIDs[0]).
List< label > labelList
A List of labels.
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
virtual bool writeObject(IOstreamOption streamOpt, const bool writeOnProc=true) const
Write using stream options, but always UNCOMPRESSED.
virtual Ostream & endEntry()
Write end entry (';') followed by newline.
"buffered" : (MPI_Bsend, MPI_Recv)
A patch is a list of labels that address the faces in the global face list.
label nNonProcessor() const
The number of patches before the first processor patch.
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Defines the attributes of an object for which implicit objectRegistry management is supported...
List< bool > boolList
A List of bools.
bool isPattern() const noexcept
The wordRe is a pattern, not a literal string.
label findIndex(const wordRe &key) const
Return patch index for the first match, return -1 if not found.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Extract type (as a word) from an object, typically using its type() method.
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
forAllConstIters(mixture.phases(), phase)
label firstMatching(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
Find first list item with 'name()' that matches, -1 on failure.
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
const labelList::subList faceOwner() const
Return face owner for the entire boundary.