41 Foam::label Foam::meshToMesh::calcDistribution
53 UPstream::listGatherValues<bool>
55 src.nCells() > 0 || tgt.nCells() > 0
59 const auto nHaveMesh = hasMesh.count();
63 proci = hasMesh.find_first();
65 <<
"Meshes local to processor" << proci <<
endl;
67 else if (nHaveMesh > 1)
71 <<
"Meshes split across multiple processors" <<
endl;
81 Foam::label Foam::meshToMesh::calcOverlappingProcs
83 const List<treeBoundBoxList>& procBb,
96 for (
const treeBoundBox&
b : bbp)
100 overlaps[proci] =
true;
117 switch (procMapMethod_)
119 case procMapMethod::pmLOD:
121 Info<<
"meshToMesh: Using processorLOD method" <<
endl;
126 const label nGlobalSrcCells = src.globalData().nTotalCells();
129 const label cellsPerBox =
max(16, 0.001*nGlobalSrcCells);
130 typename processorLODs::cellBox boxLOD
147 Info<<
"meshToMesh: Using AABBTree method" <<
endl;
152 if (src.nCells() > 0)
172 <<
"Determining extent of src mesh per processor:" <<
nl 173 <<
"\tproc\tbb" <<
endl;
176 Info<<
'\t' << proci <<
'\t' << procBb[proci] <<
endl;
191 dynSendMap[proci].setCapacity(iniSize);
198 for (label celli = 0; celli < tgt.nCells(); ++celli)
201 boundBox cellBb(tgt.cellBb(celli));
204 (void)calcOverlappingProcs(procBb, cellBb, procBbOverlaps);
206 forAll(procBbOverlaps, proci)
208 if (procBbOverlaps[proci])
210 dynSendMap[proci].append(celli);
218 sendMap[proci].transfer(dynSendMap[proci]);
224 Pout<<
"Of my " << tgt.nCells()
225 <<
" target cells I need to send to:" <<
nl 226 <<
"\tproc\tcells" <<
endl;
229 Pout<<
'\t' << proci <<
'\t' 230 << sendMap[proci].size() <<
endl;
242 void Foam::meshToMesh::distributeCells
244 const mapDistribute& map,
245 const polyMesh& tgtMesh,
246 const globalIndex& globalI,
248 List<label>& nInternalFaces,
249 List<faceList>& faces,
250 List<labelList>& faceOwner,
251 List<labelList>& faceNeighbour,
253 List<labelList>& nbrProcIDs,
254 List<labelList>& procLocalFaceIDs
272 const labelList& sendElems = map.subMap()[domain];
274 if (sendElems.size())
277 labelList reverseCellMap(tgtMesh.nCells(), -1);
278 forAll(sendElems, subCelli)
280 reverseCellMap[sendElems[subCelli]] = subCelli;
283 DynamicList<face> subFaces(tgtMesh.nFaces());
284 DynamicList<label> subFaceOwner(tgtMesh.nFaces());
285 DynamicList<label> subFaceNeighbour(tgtMesh.nFaces());
287 DynamicList<label> subNbrProcIDs(tgtMesh.nFaces());
288 DynamicList<label> subProcLocalFaceIDs(tgtMesh.nFaces());
293 forAll(tgtMesh.faceNeighbour(), facei)
295 label own = tgtMesh.faceOwner()[facei];
296 label nbr = tgtMesh.faceNeighbour()[facei];
297 label subOwn = reverseCellMap[own];
298 label subNbr = reverseCellMap[nbr];
300 if (subOwn != -1 && subNbr != -1)
306 subFaces.append(tgtMesh.faces()[facei]);
307 subFaceOwner.append(subOwn);
308 subFaceNeighbour.append(subNbr);
309 subNbrProcIDs.append(-1);
310 subProcLocalFaceIDs.append(-1);
314 subFaces.append(tgtMesh.faces()[facei].reverseFace());
315 subFaceOwner.append(subNbr);
316 subFaceNeighbour.append(subOwn);
317 subNbrProcIDs.append(-1);
318 subProcLocalFaceIDs.append(-1);
324 forAll(tgtMesh.faceNeighbour(), facei)
326 label own = tgtMesh.faceOwner()[facei];
327 label nbr = tgtMesh.faceNeighbour()[facei];
328 label subOwn = reverseCellMap[own];
329 label subNbr = reverseCellMap[nbr];
331 if (subOwn != -1 && subNbr == -1)
333 subFaces.append(tgtMesh.faces()[facei]);
334 subFaceOwner.append(subOwn);
335 subFaceNeighbour.append(subNbr);
336 subNbrProcIDs.append(-1);
337 subProcLocalFaceIDs.append(-1);
339 else if (subOwn == -1 && subNbr != -1)
341 subFaces.append(tgtMesh.faces()[facei].reverseFace());
342 subFaceOwner.append(subNbr);
343 subFaceNeighbour.append(subOwn);
344 subNbrProcIDs.append(-1);
345 subProcLocalFaceIDs.append(-1);
350 forAll(tgtMesh.boundaryMesh(), patchi)
352 const polyPatch&
pp = tgtMesh.boundaryMesh()[patchi];
353 const auto* procPatch = isA<processorPolyPatch>(
pp);
356 const label nbrProci =
357 (procPatch ? procPatch->neighbProcNo() : -1);
361 label facei =
pp.start() + i;
362 label own = tgtMesh.faceOwner()[facei];
364 if (reverseCellMap[own] != -1)
366 subFaces.append(tgtMesh.faces()[facei]);
367 subFaceOwner.append(reverseCellMap[own]);
368 subFaceNeighbour.append(-1);
369 subNbrProcIDs.append(nbrProci);
370 subProcLocalFaceIDs.append(i);
376 labelList reversePointMap(tgtMesh.nPoints(), -1);
377 DynamicList<point> subPoints(tgtMesh.nPoints());
378 forAll(subFaces, subFacei)
380 face&
f = subFaces[subFacei];
383 label pointi =
f[fp];
384 if (reversePointMap[pointi] == -1)
386 reversePointMap[pointi] = subPoints.
size();
387 subPoints.append(tgtMesh.points()[pointi]);
390 f[fp] = reversePointMap[pointi];
395 labelList globalElems(globalI.toGlobal(sendElems));
402 <<
" sending tgt cell " << sendElems[i]
403 <<
"[" << globalElems[i] <<
"]" 404 <<
" to srcProc " << domain <<
endl;
424 UOPstream toDomain(domain, pBufs);
434 << subProcLocalFaceIDs;
440 pBufs.finishedSends();
445 const labelList& recvElems = map.constructMap()[domain];
449 UIPstream str(domain, pBufs);
452 >> nInternalFaces[domain]
455 >> faceNeighbour[domain]
457 >> nbrProcIDs[domain]
458 >> procLocalFaceIDs[domain];
463 Pout<<
"Target mesh send sizes[" << domain <<
"]" 465 <<
", faces=" << faces[domain].size()
466 <<
", nInternalFaces=" << nInternalFaces[domain]
467 <<
", faceOwn=" << faceOwner[domain].size()
468 <<
", faceNbr=" << faceNeighbour[domain].size()
475 void Foam::meshToMesh::distributeAndMergeCells
477 const mapDistribute& map,
479 const globalIndex& globalI,
489 List<label> allNInternalFaces;
490 List<faceList> allFaces;
491 List<labelList> allFaceOwners;
492 List<labelList> allFaceNeighbours;
493 List<labelList> allTgtCellIDs;
497 List<labelList> allNbrProcIDs;
498 List<labelList> allProcLocalFaceIDs;
537 labelList allNIntCoupledFaces(allNInternalFaces);
551 forAll(allTgtCellIDs, proci)
553 cellOffset[proci] = nCells;
554 nCells += allTgtCellIDs[proci].size();
558 typedef FixedList<label, 3> label3;
559 typedef HashTable<label, label3> procCoupleInfo;
560 procCoupleInfo procFaceToGlobalCell;
562 forAll(allNbrProcIDs, proci)
564 const labelList& nbrProci = allNbrProcIDs[proci];
565 const labelList& localFacei = allProcLocalFaceIDs[proci];
569 if (nbrProci[i] != -1 && localFacei[i] != -1)
572 key[0] =
min(proci, nbrProci[i]);
573 key[1] =
max(proci, nbrProci[i]);
574 key[2] = localFacei[i];
576 const auto fnd = procFaceToGlobalCell.cfind(
key);
580 procFaceToGlobalCell.insert(
key, -1);
586 Pout<<
"Additional internal face between procs:" 587 <<
key[0] <<
" and " <<
key[1]
588 <<
" across local face " <<
key[2] <<
endl;
591 allNIntCoupledFaces[proci]++;
600 label nFacesTotal = 0;
602 forAll(allNIntCoupledFaces, proci)
604 label nCoupledFaces =
605 allNIntCoupledFaces[proci] - allNInternalFaces[proci];
607 internalFaceOffset[proci] = nIntFaces;
608 nIntFaces += allNIntCoupledFaces[proci];
609 nFacesTotal += allFaceOwners[proci].size() - nCoupledFaces;
613 tgtFaces.setSize(nFacesTotal);
614 tgtFaceOwners.setSize(nFacesTotal);
615 tgtFaceNeighbours.setSize(nFacesTotal);
616 tgtCellIDs.setSize(nCells);
622 SubList<point>(tgtPoints,
pts.
size(), pointOffset[proci]) =
pts;
626 forAll(allTgtCellIDs, proci)
636 const faceList& fcs = allFaces[proci];
637 const labelList& faceOs = allFaceOwners[proci];
638 const labelList& faceNs = allFaceNeighbours[proci];
643 allNInternalFaces[proci],
644 internalFaceOffset[proci]
646 slice = SubList<face>(fcs, allNInternalFaces[proci]);
649 add(slice[i], pointOffset[proci]);
652 SubField<label> ownSlice
655 allNInternalFaces[proci],
656 internalFaceOffset[proci]
658 ownSlice = SubField<label>(faceOs, allNInternalFaces[proci]);
659 add(ownSlice, cellOffset[proci]);
661 SubField<label> nbrSlice
664 allNInternalFaces[proci],
665 internalFaceOffset[proci]
667 nbrSlice = SubField<label>(faceNs, allNInternalFaces[proci]);
668 add(nbrSlice, cellOffset[proci]);
670 internalFaceOffset[proci] += allNInternalFaces[proci];
675 forAll(allNbrProcIDs, proci)
677 const labelList& nbrProci = allNbrProcIDs[proci];
678 const labelList& localFacei = allProcLocalFaceIDs[proci];
679 const labelList& faceOs = allFaceOwners[proci];
680 const faceList& fcs = allFaces[proci];
684 if (nbrProci[i] != -1 && localFacei[i] != -1)
687 key[0] =
min(proci, nbrProci[i]);
688 key[1] =
max(proci, nbrProci[i]);
689 key[2] = localFacei[i];
691 auto fnd = procFaceToGlobalCell.find(
key);
695 label tgtFacei = fnd();
699 fnd() = cellOffset[proci] + faceOs[i];
704 label newOwn = cellOffset[proci] + faceOs[i];
705 label newNbr = fnd();
706 label tgtFacei = internalFaceOffset[proci]++;
710 Pout<<
" proc " << proci
711 <<
"\tinserting face:" << tgtFacei
712 <<
" connection between owner " << newOwn
713 <<
" and neighbour " << newNbr
720 tgtFaces[tgtFacei] = fcs[i];
721 tgtFaceOwners[tgtFacei] = newOwn;
722 tgtFaceNeighbours[tgtFacei] = newNbr;
727 tgtFaces[tgtFacei] = fcs[i].reverseFace();
728 tgtFaceOwners[tgtFacei] = newNbr;
729 tgtFaceNeighbours[tgtFacei] = newOwn;
732 add(tgtFaces[tgtFacei], pointOffset[proci]);
743 forAll(allNbrProcIDs, proci)
745 const labelList& nbrProci = allNbrProcIDs[proci];
746 const labelList& localFacei = allProcLocalFaceIDs[proci];
747 const labelList& faceOs = allFaceOwners[proci];
748 const labelList& faceNs = allFaceNeighbours[proci];
749 const faceList& fcs = allFaces[proci];
754 if (nbrProci[i] != -1 && localFacei[i] != -1)
757 key[0] =
min(proci, nbrProci[i]);
758 key[1] =
max(proci, nbrProci[i]);
759 key[2] = localFacei[i];
761 label tgtFacei = procFaceToGlobalCell[
key];
766 <<
"Unvisited " <<
key 769 else if (tgtFacei != -2)
771 label newOwn = cellOffset[proci] + faceOs[i];
772 label tgtFacei = nIntFaces++;
776 Pout<<
" proc " << proci
777 <<
"\tinserting boundary face:" << tgtFacei
778 <<
" from coupled face " <<
key 782 tgtFaces[tgtFacei] = fcs[i];
783 add(tgtFaces[tgtFacei], pointOffset[proci]);
785 tgtFaceOwners[tgtFacei] = newOwn;
786 tgtFaceNeighbours[tgtFacei] = -1;
792 label own = faceOs[i];
793 label nbr = faceNs[i];
794 if ((own != -1) && (nbr == -1))
796 label newOwn = cellOffset[proci] + faceOs[i];
797 label tgtFacei = nIntFaces++;
799 tgtFaces[tgtFacei] = fcs[i];
800 add(tgtFaces[tgtFacei], pointOffset[proci]);
802 tgtFaceOwners[tgtFacei] = newOwn;
803 tgtFaceNeighbours[tgtFacei] = -1;
825 Pout<<
"Merged from " << oldToNew.size()
826 <<
" down to " << tgtPoints.size() <<
" points" <<
endl;
828 for (
auto&
f : tgtFaces)
void size(const label n)
Older name for setAddressableSize.
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.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
static rangeType allProcs(const label communicator=worldComm)
Range of process indices for all processes.
constexpr char nl
The newline '\n' character (0x0a)
Ostream & endl(Ostream &os)
Add newline and flush stream.
static bool & parRun() noexcept
Test if this a parallel run.
List< treeBoundBox > treeBoundBoxList
A List of treeBoundBox.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
List< labelList > labelListList
List of labelList.
static void broadcast(Type &value, const label comm=UPstream::worldComm)
Broadcast content (contiguous or non-contiguous) to all processes in communicator.
#define forAll(list, i)
Loop across all elements in list.
static void allGatherList(List< T > &values, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Gather data, but keep individual values separate. Uses linear/tree communication. ...
List< face > faceList
List of faces.
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
vectorField pointField
pointField is a vectorField.
void setSize(const label n)
Alias for resize()
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
#define DebugInFunction
Report an information message using Foam::Info.
label inplaceMergePoints(PointList &points, const scalar mergeTol, const bool verbose, labelList &pointToUnique)
Inplace merge points, preserving the original point order. All points closer/equal mergeTol are to be...
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
errorManip< error > abort(error &err)
void add(FieldField< Field1, typename typeOfSum< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
int debug
Static debugging option.
Geometric merging of points. See below.
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values (not the indices) of a list.
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
"nonBlocking" : (MPI_Isend, MPI_Irecv)
messageStream Info
Information stream (stdout output on master, null elsewhere)
List< label > labelList
A List of labels.
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
List< bool > boolList
A List of bools.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
#define InfoInFunction
Report an information message using Foam::Info.
static constexpr const zero Zero
Global zero (0)