43 template<
class PatchType>
54 for (
const label patchEdgei : edgeIds)
56 const edge e(
p.meshEdge(patchEdgei));
59 <<
p.points()[
e.first()] <<
' '
60 <<
p.points()[
e.second()] <<
nl;
63 if (maxOutput > 0 && nOutput >= maxOutput)
65 os <<
" ... suppressing further output" <<
nl;
77 Foam::faMesh::getBoundaryEdgeConnections()
const
101 label patchEdgei_ = -1;
102 label meshFacei_ = -1;
115 <<
"Determining required boundary edge connections, "
116 <<
"resolving locally attached boundary edges." <<
endl;
126 edgeToBoundaryIndex.insert
135 if (edgeFaces.size() != 1)
137 badEdges.insert(patchEdgei);
141 const label patchFacei = edgeFaces[0];
142 const label meshFacei = faceLabels_[patchFacei];
146 const label
patchId = pbm.patchID()[bndFacei];
150 auto& tuple = bndEdgeConnections[bndEdgei].first();
154 tuple.patchEdgei(patchEdgei);
155 tuple.meshFacei(meshFacei);
160 auto& pairing = patchPairings[bndEdgei];
164 pairing.patchEdgei_ = patchEdgei;
165 pairing.meshFacei_ = meshFacei;
169 if ((nBadEdges =
returnReduce(badEdges.size(), sumOp<label>())) > 0)
175 patch().localPoints(),
180 / (
"faMesh-construct.nonManifoldEdges")
191 <<
"Boundary edges not singly connected: "
202 <<
"(debug) wrote " <<
writer.output().name() <<
nl;
213 label nMissing = patchPairings.size();
217 if (!nMissing)
break;
219 const polyPatch& pp = pbm[patchi];
224 label patchEdgei = pp.nInternalEdges();
225 patchEdgei < pp.nEdges();
229 const label bndEdgei =
230 edgeToBoundaryIndex.lookup(pp.meshEdge(patchEdgei), -1);
236 auto& pairing = patchPairings[bndEdgei];
241 if (pairing.insert(patchi))
244 const labelList& edgeFaces = pp.edgeFaces()[patchEdgei];
246 if (edgeFaces.size() != 1)
248 pairing.erase(patchi);
249 badEdges.insert(badEdges.size());
253 const label patchFacei = edgeFaces[0];
254 const label meshFacei = patchFacei + pp.start();
257 pairing.patchEdgei_ = patchEdgei;
258 pairing.meshFacei_ = meshFacei;
261 if (!nMissing)
break;
267 if ((nBadEdges =
returnReduce(badEdges.size(), sumOp<label>())) > 0)
270 <<
"Had " << nBadEdges
271 <<
" boundary edges with missing or multiple edge connections"
279 const auto& pairing = patchPairings[bndEdgei];
280 const label nbrPatchi = pairing.second();
281 const label nbrPatchEdgei = pairing.patchEdgei_;
282 const label nbrMeshFacei = pairing.meshFacei_;
284 if (nbrMeshFacei >= 0)
287 auto& tuple = bndEdgeConnections[bndEdgei].second();
290 tuple.patchi(nbrPatchi);
291 tuple.patchEdgei(nbrPatchEdgei);
292 tuple.meshFacei(nbrMeshFacei);
309 nBadEdges = badEdges.size();
316 patch().localPoints(),
321 / (
"faMesh-construct.invalidEdges")
332 <<
"Boundary edges with missing/invalid neighbours: "
343 <<
"(debug) wrote " <<
writer.output().name() <<
nl;
350 return bndEdgeConnections;
359 <<
"Creating global coupling data" <<
endl;
363 const mapDistribute& map =
globalData.globalEdgeSlavesMap();
364 const label nCoupledEdges = cpp.nEdges();
367 List<bool> coupledEdgesUsed(map.constructSize(),
false);
370 for (label cppEdgei = 0; cppEdgei < nCoupledEdges; ++cppEdgei)
372 coupledEdgesUsed[cppEdgei] =
373 edgeToBoundaryIndex.found(cpp.meshEdge(cppEdgei));
377 <<
"Starting sync of boundary edge topology" <<
endl;
391 for (label cppEdgei = 0; cppEdgei < nCoupledEdges; ++cppEdgei)
393 if (coupledEdgesUsed[cppEdgei])
402 <<
" connected boundary edges (total, some duplicates)" <<
endl;
408 List<DynamicList<patchTuple, 2>> gatheredConnections(map.constructSize());
411 EdgeMap<label> edgeToCoupledIndex(2*nCoupledEdges);
418 for (label cppEdgei = 0; cppEdgei < nCoupledEdges; ++cppEdgei)
420 if (coupledEdgesUsed[cppEdgei])
422 const edge meshEdge(cpp.meshEdge(cppEdgei));
424 const label bndEdgei =
425 edgeToBoundaryIndex.lookup(meshEdge, -1);
431 auto& gathered = gatheredConnections[cppEdgei];
432 gathered.setCapacity(2);
434 auto& tuple = gathered.last();
436 tuple = bndEdgeConnections[bndEdgei].first();
443 edgeToCoupledIndex.insert(meshEdge, cppEdgei);
455 if (edgeToCoupledIndex.empty())
break;
457 const polyPatch& pp = pbm[patchi];
462 label patchEdgei = pp.nInternalEdges();
463 patchEdgei < pp.nEdges();
467 const edge meshEdge(pp.meshEdge(patchEdgei));
469 const label cppEdgei =
470 edgeToCoupledIndex.lookup(meshEdge, -1);
477 const labelList& edgeFaces = pp.edgeFaces()[patchEdgei];
479 if (edgeFaces.size() != 1)
481 badEdges.insert(cppEdgei);
485 const label patchFacei = edgeFaces[0];
486 const label meshFacei = patchFacei + pp.start();
488 auto& gathered = gatheredConnections[cppEdgei];
489 gathered.setCapacity(2);
491 auto& tuple = gathered.last();
494 tuple.patchi(patchi);
495 tuple.patchEdgei(patchEdgei);
496 tuple.meshFacei(meshFacei);
499 edgeToCoupledIndex.erase(meshEdge);
501 if (edgeToCoupledIndex.empty())
break;
506 if ((nBadEdges =
returnReduce(badEdges.size(), sumOp<label>())) > 0)
509 <<
"Had " << nBadEdges <<
" coupled boundary edges"
510 <<
" with missing or multiple edge connections"
515 <<
"Starting sync of boundary edge information" <<
endl;
523 ListOps::appendEqOp<patchTuple>()
528 <<
"Collating sync information" <<
endl;
531 for (label cppEdgei = 0; cppEdgei < nCoupledEdges; ++cppEdgei)
533 const auto& gathered = gatheredConnections[cppEdgei];
535 const label bndEdgei =
536 edgeToBoundaryIndex.lookup(cpp.meshEdge(cppEdgei), -1);
544 && gathered.size() == 2
547 const auto& a = gathered[0];
548 const auto&
b = gathered[1];
551 auto& connection = bndEdgeConnections[bndEdgei];
553 connection.second() = (connection.first() ==
b) ? a :
b;
561 const auto& connection = bndEdgeConnections[bndEdgei];
563 if (!connection.second().valid())
576 patch().localPoints(),
577 patch().boundaryEdges(),
581 / (
"faMesh-construct.boundaryEdges")
596 const auto& connection = bndEdgeConnections[bndEdgei];
598 neighProc[bndEdgei] = connection.second().procNo();
599 neighPatch[bndEdgei] = connection.second().patchi();
602 writer.write(
"neighProc", neighProc);
603 writer.write(
"neighPatch", neighPatch);
614 / (
"faMesh-construct.faPatch")
627 if ((nBadEdges =
returnReduce(badEdges.size(), sumOp<label>())) > 0)
633 patch().localPoints(),
638 / (
"faMesh-construct.invalidEdges")
649 <<
"Boundary edges with missing/invalid neighbours: "
660 <<
"(debug) wrote " <<
writer.output().name() <<
nl;
670 <<
"Return sorted list of boundary connections" <<
endl;
672 return bndEdgeConnections;
676 void Foam::faMesh::setBoundaryConnections
678 const List<Pair<patchTuple>>& bndEdgeConnections
681 const label nInternalEdges =
patch().nInternalEdges();
682 const label nBoundaryEdges =
patch().nBoundaryEdges();
684 if (bndEdgeConnections.size() != nBoundaryEdges)
687 <<
"Sizing mismatch. Expected " << nBoundaryEdges
688 <<
" boundary edge connections, but had "
689 << bndEdgeConnections.size() <<
nl
695 new List<labelPair>(nBoundaryEdges,
labelPair(-1,-1))
697 auto& bndConnect = *bndConnectPtr_;
699 for (
const auto& connection : bndEdgeConnections)
701 const auto& a = connection.first();
702 const auto&
b = connection.second();
704 if (a.is_finiteArea() && a.is_localProc())
706 const label bndEdgei = (a.patchEdgei() - nInternalEdges);
708 bndConnect[bndEdgei].first() =
b.procNo();
709 bndConnect[bndEdgei].second() =
b.meshFacei();
711 else if (
b.is_finiteArea() &&
b.is_localProc())
713 const label bndEdgei = (
b.patchEdgei() - nInternalEdges);
715 bndConnect[bndEdgei].first() = a.procNo();
716 bndConnect[bndEdgei].second() = a.meshFacei();
721 <<
"Unexpected pairing input " << connection
722 <<
" ... programming error" <<
nl
728 for (
const auto& connection : bndConnect)
730 if (connection.first() < 0 || connection.second() < 0)
738 reduce(nInvalid, sumOp<label>());
744 <<
"Did not properly match " << nInvalid
745 <<
" boundary edges" <<
nl
751 void Foam::faMesh::calcBoundaryConnections()
const
753 setBoundaryConnections(this->getBoundaryEdgeConnections());
761 const auto& connections = this->boundaryConnections();
765 for (
const labelPair& tuple : connections)
767 procsUsed.insert(tuple.first());
773 return procsUsed.sortedToc();
779 const auto& connections = this->boundaryConnections();
783 for (
const labelPair& tuple : connections)
785 ++procCount(tuple.first());
791 List<labelPair>
output(procCount.size());
793 for (
const label proci : procCount.sortedToc())
808 haloMapPtr_.
reset(
new faMeshBoundaryHalo(*
this));
815 void Foam::faMesh::calcHaloFaceGeometry()
const
817 if (haloFaceCentresPtr_ || haloFaceNormalsPtr_)
820 <<
"Halo centres/normals already calculated"
825 <<
"Calculating halo face centres/normals" <<
endl;
830 const faMeshBoundaryHalo& halo = boundaryHaloMap();
832 const labelList& inputFaceIds = halo.inputMeshFaces();
837 auto& centres = *haloFaceCentresPtr_;
838 auto& normals = *haloFaceNormalsPtr_;
840 centres.
resize(inputFaceIds.size());
841 normals.resize(inputFaceIds.size());
846 const face&
f = faces[inputFaceIds[i]];
849 normals[i] =
f.unitNormal(
points);
853 halo.distributeSparse(centres);
854 halo.distributeSparse(normals);
860 if (!haloFaceCentresPtr_ || !haloFaceNormalsPtr_)
862 calcHaloFaceGeometry();
865 return *haloFaceCentresPtr_;
871 if (!haloFaceCentresPtr_ || !haloFaceNormalsPtr_)
873 calcHaloFaceGeometry();
876 return *haloFaceNormalsPtr_;
883 if (patchi < 0 || patchi >=
boundary().size())
886 <<
"Patch " << patchi <<
" is out-of-range 0.."
897 this->haloFaceCentres(),
908 if (patchi < 0 || patchi >=
boundary().size())
911 <<
"Patch " << patchi <<
" is out-of-range 0.."
922 this->haloFaceNormals(),