44 static constexpr Foam::label
BLOCKED = -2;
53 template<
class Container>
56 const label len =
input.size();
60 for (label i = 0; i < len; ++i)
73 void Foam::regionSplit::checkBoundaryFaceSync
78 if (blockedFace.size())
81 boolList syncBlockedFace(blockedFace);
84 forAll(syncBlockedFace, facei)
88 blockedFace.test(facei)
89 != syncBlockedFace.test(facei)
93 <<
"Face " << facei <<
" not synchronised. My value:"
94 << blockedFace.test(facei) <<
" coupled value:"
95 << syncBlockedFace.test(facei) <<
nl
103 void Foam::regionSplit::updateFacePair
109 DynamicList<label>& facesChanged
114 if (faceRegion[face1] >= 0)
116 faceRegion[face0] = faceRegion[face1];
117 facesChanged.append(face0);
119 else if (faceRegion[face1] ==
BLOCKED)
125 else if (faceRegion[face0] >= 0)
129 faceRegion[face1] = faceRegion[face0];
130 facesChanged.append(face1);
132 else if (faceRegion[face1] ==
BLOCKED)
137 else if (faceRegion[face1] != faceRegion[face0])
140 <<
"Problem : coupled face " << face0
142 <<
" has region " << faceRegion[face0]
143 <<
" but coupled face " << face1
144 <<
" has region " << faceRegion[face1] <<
nl
145 <<
"Is your blocked faces specification"
146 <<
" synchronized across coupled boundaries?" <<
endl
153 void Foam::regionSplit::fillSeedMask
155 const UList<labelPair>& explicitConnections,
156 const label seedCellId,
157 const label markValue,
163 cellRegion[seedCellId] = markValue;
166 changedFaces_.clear();
167 for (
const label facei :
mesh().
cells()[seedCellId])
171 faceRegion[facei] = markValue;
172 changedFaces_.append(facei);
180 while (changedFaces_.size())
182 changedCells_.
clear();
184 for (
const label facei : changedFaces_)
190 cellRegion[own] = markValue;
191 changedCells_.
append(own);
194 if (
mesh().isInternalFace(facei))
200 cellRegion[nei] = markValue;
201 changedCells_.
append(nei);
208 Pout<<
" Changed cells / faces : "
209 << changedCells_.size() <<
" / " << changedFaces_.size()
210 <<
" before sync" <<
endl;
214 changedFaces_.clear();
215 for (
const label celli : changedCells_)
217 for (
const label facei :
mesh().
cells()[celli])
221 faceRegion[facei] = markValue;
222 changedFaces_.append(facei);
231 for (
const polyPatch& pp :
patches)
233 const cyclicPolyPatch* cpp = isA<cyclicPolyPatch>(pp);
235 if (cpp && cpp->owner())
238 const auto& cycPatch = *cpp;
240 label face0 = cycPatch.start();
244 const label face1 = cycPatch.transformGlobalFace(face0);
259 for (
const labelPair& pr : explicitConnections)
272 Pout<<
" Changed faces : "
273 << changedFaces_.size()
274 <<
" after sync" <<
endl;
280 Foam::label Foam::regionSplit::localRegionSplit
282 const UList<labelPair>& explicitConnections,
288 clockValue timing(
debug);
290 changedCells_.reserve(mesh_.nCells());
291 changedFaces_.reserve(mesh_.nFaces());
298 label nLocalRegions = 0;
300 for (label seedCellId = 0; seedCellId < cellRegion.size(); ++seedCellId)
304 for (; seedCellId < cellRegion.size(); ++seedCellId)
312 if (seedCellId >= cellRegion.size())
330 changedCells_.clearStorage();
331 changedFaces_.clearStorage();
337 if (cellRegion[celli] < 0)
340 <<
"cell:" << celli <<
" region:" << cellRegion[celli]
350 <<
"face:" << facei <<
" region:" << faceRegion[facei]
356 DebugInfo <<
"regionSplit = " << double(timing.elapsed()) <<
"s\n";
358 return nLocalRegions;
367 const bool doGlobalRegions
383 const bitSet& blockedFace,
385 const bool doGlobalRegions
401 for (
const label facei : blockedFace)
406 const label numLocalRegions =
407 localRegionSplit(explicitConnections, cellRegion, faceRegion);
414 bitSetOrBoolList hasBlockedFace(blockedFace);
417 reduceRegionsImpl(numLocalRegions, hasBlockedFace, cellRegion);
432 const bool doGlobalRegions
441 checkBoundaryFaceSync(blockedFace);
448 forAll(blockedFace, facei)
450 if (blockedFace.test(facei))
457 const label numLocalRegions =
458 localRegionSplit(explicitConnections, cellRegion, faceRegion);
465 bitSetOrBoolList hasBlockedFace(blockedFace);
468 reduceRegionsImpl(numLocalRegions, hasBlockedFace, cellRegion);
480 Foam::regionSplit::reduceRegionsImpl
482 const label numLocalRegions,
483 const bitSetOrBoolList& blockedFace,
492 <<
"The cellRegion size " << cellRegion.size()
501 const label nLocalRegions =
510 const globalIndex globalRegions(nLocalRegions);
516 Map<label> localToGlobal(2*nLocalRegions);
517 for (
const label regioni : cellRegion)
519 localToGlobal.insert(regioni, globalRegions.toGlobal(regioni));
524 Map<label> updateLookup(2*nLocalRegions);
550 bool emitWarning =
true;
556 Pout<<
nl <<
"-- Starting Iteration --" <<
endl;
559 updateLookup.clear();
563 for (
const polyPatch& pp :
patches)
567 SubList<label> patchNbrRegion
575 forAll(faceCells, patchFacei)
577 const label celli = faceCells[patchFacei];
578 const label meshFacei = pp.start()+patchFacei;
580 if (!blockedFace.test(meshFacei))
583 const label orig = cellRegion[celli];
585 patchNbrRegion[patchFacei] = localToGlobal[orig];
593 for (
const polyPatch& pp :
patches)
597 SubList<label> patchNbrRegion
605 forAll(faceCells, patchFacei)
607 const label celli = faceCells[patchFacei];
608 const label meshFacei = pp.start()+patchFacei;
610 if (!blockedFace.test(meshFacei))
614 const label orig = cellRegion[celli];
616 const label sent = localToGlobal[orig];
617 const label recv = patchNbrRegion[patchFacei];
623 Pout<<
"Warning in regionSplit:"
624 " received unassigned on "
625 << pp.
name() <<
" at patchFace "
627 <<
". Check synchronisation in caller"
631 else if (recv < sent)
635 auto fnd = updateLookup.find(sent);
638 updateLookup.insert(sent, recv);
640 else if (recv < *fnd)
662 labelList keys(localToGlobal.sortedToc());
666 vals[i] = localToGlobal[keys[i]];
669 Pout<<
"Updated local regions:" <<
nl
675 Pout<<
"Updated " << localToGlobal.size()
676 <<
" local regions" <<
endl;
682 while (
returnReduce(!updateLookup.empty(), orOp<bool>()));
696 const label regioni = iter.val();
698 if (globalRegions.isLocal(regioni))
700 localRegion.insert(regioni);
704 nCompact = localRegion.size();
709 globalIndex globalCompact(nCompact);
719 updateLookup.clear();
731 nonLocal[proci].resize
741 const label regioni = iter.val();
743 if (globalRegions.isLocal(regioni))
748 globalCompact.toGlobal(updateLookup.size())
753 nonLocal[globalRegions.whichProcID(regioni)].insert(regioni);
759 Pout<<
" per processor nonLocal regions: "
765 forAll(sendNonLocal, proci)
767 sendNonLocal[proci] = nonLocal[proci].toc();
774 Pstream::exchange<labelList, label>
789 for (label& regioni : send)
791 regioni = updateLookup[regioni];
796 Pstream::exchange<labelList, label>
810 forAll(recvNonLocal, proci)
812 const labelList& send = sendNonLocal[proci];
813 const labelList& recv = recvNonLocal[proci];
817 updateLookup.insert(send[i], recv[i]);
830 cellRegion[celli] = localToGlobal[cellRegion[celli]];
834 <<
"regionSplit::reduceRegions = " << double(timing.elapsed()) <<
"s\n";
836 return globalCompact;
843 const label numLocalRegions,
844 const bitSet& blockedFace,
850 bitSetOrBoolList hasBlockedFace(blockedFace);
852 return reduceRegionsImpl(numLocalRegions, hasBlockedFace, cellRegion);