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;
251 forAll(constructMap, proci)
256 constructMap[proci].setSize(nRecv);
258 for (label i = 0; i < nRecv; i++)
260 constructMap[proci][i] = segmentI++;
268 std::move(constructMap)
277 void Foam::meshToMesh::distributeCells
279 const mapDistribute& map,
280 const polyMesh& tgtMesh,
281 const globalIndex& globalI,
283 List<label>& nInternalFaces,
284 List<faceList>& faces,
285 List<labelList>& faceOwner,
286 List<labelList>& faceNeighbour,
288 List<labelList>& nbrProcIDs,
289 List<labelList>& procLocalFaceIDs
307 const labelList& sendElems = map.subMap()[domain];
309 if (sendElems.size())
312 labelList reverseCellMap(tgtMesh.nCells(), -1);
313 forAll(sendElems, subCelli)
315 reverseCellMap[sendElems[subCelli]] = subCelli;
318 DynamicList<face> subFaces(tgtMesh.nFaces());
319 DynamicList<label> subFaceOwner(tgtMesh.nFaces());
320 DynamicList<label> subFaceNeighbour(tgtMesh.nFaces());
322 DynamicList<label> subNbrProcIDs(tgtMesh.nFaces());
323 DynamicList<label> subProcLocalFaceIDs(tgtMesh.nFaces());
328 forAll(tgtMesh.faceNeighbour(), facei)
330 label own = tgtMesh.faceOwner()[facei];
331 label nbr = tgtMesh.faceNeighbour()[facei];
332 label subOwn = reverseCellMap[own];
333 label subNbr = reverseCellMap[nbr];
335 if (subOwn != -1 && subNbr != -1)
341 subFaces.append(tgtMesh.faces()[facei]);
342 subFaceOwner.append(subOwn);
343 subFaceNeighbour.append(subNbr);
344 subNbrProcIDs.append(-1);
345 subProcLocalFaceIDs.append(-1);
349 subFaces.append(tgtMesh.faces()[facei].reverseFace());
350 subFaceOwner.append(subNbr);
351 subFaceNeighbour.append(subOwn);
352 subNbrProcIDs.append(-1);
353 subProcLocalFaceIDs.append(-1);
359 forAll(tgtMesh.faceNeighbour(), facei)
361 label own = tgtMesh.faceOwner()[facei];
362 label nbr = tgtMesh.faceNeighbour()[facei];
363 label subOwn = reverseCellMap[own];
364 label subNbr = reverseCellMap[nbr];
366 if (subOwn != -1 && subNbr == -1)
368 subFaces.append(tgtMesh.faces()[facei]);
369 subFaceOwner.append(subOwn);
370 subFaceNeighbour.append(subNbr);
371 subNbrProcIDs.append(-1);
372 subProcLocalFaceIDs.append(-1);
374 else if (subOwn == -1 && subNbr != -1)
376 subFaces.append(tgtMesh.faces()[facei].reverseFace());
377 subFaceOwner.append(subNbr);
378 subFaceNeighbour.append(subOwn);
379 subNbrProcIDs.append(-1);
380 subProcLocalFaceIDs.append(-1);
385 forAll(tgtMesh.boundaryMesh(), patchi)
387 const polyPatch& pp = tgtMesh.boundaryMesh()[patchi];
388 const auto* procPatch = isA<processorPolyPatch>(pp);
391 const label nbrProci =
392 (procPatch ? procPatch->neighbProcNo() : -1);
396 label facei = pp.start() + i;
397 label own = tgtMesh.faceOwner()[facei];
399 if (reverseCellMap[own] != -1)
401 subFaces.append(tgtMesh.faces()[facei]);
402 subFaceOwner.append(reverseCellMap[own]);
403 subFaceNeighbour.append(-1);
404 subNbrProcIDs.append(nbrProci);
405 subProcLocalFaceIDs.append(i);
411 labelList reversePointMap(tgtMesh.nPoints(), -1);
412 DynamicList<point> subPoints(tgtMesh.nPoints());
413 forAll(subFaces, subFacei)
415 face&
f = subFaces[subFacei];
418 label pointi =
f[fp];
419 if (reversePointMap[pointi] == -1)
421 reversePointMap[pointi] = subPoints.
size();
422 subPoints.append(tgtMesh.points()[pointi]);
425 f[fp] = reversePointMap[pointi];
430 labelList globalElems(globalI.toGlobal(sendElems));
437 <<
" sending tgt cell " << sendElems[i]
438 <<
"[" << globalElems[i] <<
"]" 439 <<
" to srcProc " << domain <<
endl;
459 UOPstream toDomain(domain, pBufs);
469 << subProcLocalFaceIDs;
475 pBufs.finishedSends();
480 const labelList& recvElems = map.constructMap()[domain];
484 UIPstream str(domain, pBufs);
487 >> nInternalFaces[domain]
490 >> faceNeighbour[domain]
492 >> nbrProcIDs[domain]
493 >> procLocalFaceIDs[domain];
498 Pout<<
"Target mesh send sizes[" << domain <<
"]" 500 <<
", faces=" << faces[domain].size()
501 <<
", nInternalFaces=" << nInternalFaces[domain]
502 <<
", faceOwn=" << faceOwner[domain].size()
503 <<
", faceNbr=" << faceNeighbour[domain].size()
510 void Foam::meshToMesh::distributeAndMergeCells
512 const mapDistribute& map,
514 const globalIndex& globalI,
524 List<label> allNInternalFaces;
525 List<faceList> allFaces;
526 List<labelList> allFaceOwners;
527 List<labelList> allFaceNeighbours;
528 List<labelList> allTgtCellIDs;
532 List<labelList> allNbrProcIDs;
533 List<labelList> allProcLocalFaceIDs;
572 labelList allNIntCoupledFaces(allNInternalFaces);
586 forAll(allTgtCellIDs, proci)
588 cellOffset[proci] = nCells;
589 nCells += allTgtCellIDs[proci].size();
593 typedef FixedList<label, 3> label3;
594 typedef HashTable<label, label3> procCoupleInfo;
595 procCoupleInfo procFaceToGlobalCell;
597 forAll(allNbrProcIDs, proci)
599 const labelList& nbrProci = allNbrProcIDs[proci];
600 const labelList& localFacei = allProcLocalFaceIDs[proci];
604 if (nbrProci[i] != -1 && localFacei[i] != -1)
607 key[0] =
min(proci, nbrProci[i]);
608 key[1] =
max(proci, nbrProci[i]);
609 key[2] = localFacei[i];
611 const auto fnd = procFaceToGlobalCell.cfind(
key);
615 procFaceToGlobalCell.insert(
key, -1);
621 Pout<<
"Additional internal face between procs:" 622 <<
key[0] <<
" and " <<
key[1]
623 <<
" across local face " <<
key[2] <<
endl;
626 allNIntCoupledFaces[proci]++;
635 label nFacesTotal = 0;
637 forAll(allNIntCoupledFaces, proci)
639 label nCoupledFaces =
640 allNIntCoupledFaces[proci] - allNInternalFaces[proci];
642 internalFaceOffset[proci] = nIntFaces;
643 nIntFaces += allNIntCoupledFaces[proci];
644 nFacesTotal += allFaceOwners[proci].size() - nCoupledFaces;
648 tgtFaces.setSize(nFacesTotal);
649 tgtFaceOwners.setSize(nFacesTotal);
650 tgtFaceNeighbours.setSize(nFacesTotal);
651 tgtCellIDs.setSize(nCells);
657 SubList<point>(tgtPoints,
pts.
size(), pointOffset[proci]) =
pts;
661 forAll(allTgtCellIDs, proci)
671 const faceList& fcs = allFaces[proci];
672 const labelList& faceOs = allFaceOwners[proci];
673 const labelList& faceNs = allFaceNeighbours[proci];
678 allNInternalFaces[proci],
679 internalFaceOffset[proci]
681 slice = SubList<face>(fcs, allNInternalFaces[proci]);
684 add(slice[i], pointOffset[proci]);
687 SubField<label> ownSlice
690 allNInternalFaces[proci],
691 internalFaceOffset[proci]
693 ownSlice = SubField<label>(faceOs, allNInternalFaces[proci]);
694 add(ownSlice, cellOffset[proci]);
696 SubField<label> nbrSlice
699 allNInternalFaces[proci],
700 internalFaceOffset[proci]
702 nbrSlice = SubField<label>(faceNs, allNInternalFaces[proci]);
703 add(nbrSlice, cellOffset[proci]);
705 internalFaceOffset[proci] += allNInternalFaces[proci];
710 forAll(allNbrProcIDs, proci)
712 const labelList& nbrProci = allNbrProcIDs[proci];
713 const labelList& localFacei = allProcLocalFaceIDs[proci];
714 const labelList& faceOs = allFaceOwners[proci];
715 const faceList& fcs = allFaces[proci];
719 if (nbrProci[i] != -1 && localFacei[i] != -1)
722 key[0] =
min(proci, nbrProci[i]);
723 key[1] =
max(proci, nbrProci[i]);
724 key[2] = localFacei[i];
726 auto fnd = procFaceToGlobalCell.find(
key);
730 label tgtFacei = fnd();
734 fnd() = cellOffset[proci] + faceOs[i];
739 label newOwn = cellOffset[proci] + faceOs[i];
740 label newNbr = fnd();
741 label tgtFacei = internalFaceOffset[proci]++;
745 Pout<<
" proc " << proci
746 <<
"\tinserting face:" << tgtFacei
747 <<
" connection between owner " << newOwn
748 <<
" and neighbour " << newNbr
755 tgtFaces[tgtFacei] = fcs[i];
756 tgtFaceOwners[tgtFacei] = newOwn;
757 tgtFaceNeighbours[tgtFacei] = newNbr;
762 tgtFaces[tgtFacei] = fcs[i].reverseFace();
763 tgtFaceOwners[tgtFacei] = newNbr;
764 tgtFaceNeighbours[tgtFacei] = newOwn;
767 add(tgtFaces[tgtFacei], pointOffset[proci]);
778 forAll(allNbrProcIDs, proci)
780 const labelList& nbrProci = allNbrProcIDs[proci];
781 const labelList& localFacei = allProcLocalFaceIDs[proci];
782 const labelList& faceOs = allFaceOwners[proci];
783 const labelList& faceNs = allFaceNeighbours[proci];
784 const faceList& fcs = allFaces[proci];
789 if (nbrProci[i] != -1 && localFacei[i] != -1)
792 key[0] =
min(proci, nbrProci[i]);
793 key[1] =
max(proci, nbrProci[i]);
794 key[2] = localFacei[i];
796 label tgtFacei = procFaceToGlobalCell[
key];
801 <<
"Unvisited " <<
key 804 else if (tgtFacei != -2)
806 label newOwn = cellOffset[proci] + faceOs[i];
807 label tgtFacei = nIntFaces++;
811 Pout<<
" proc " << proci
812 <<
"\tinserting boundary face:" << tgtFacei
813 <<
" from coupled face " <<
key 817 tgtFaces[tgtFacei] = fcs[i];
818 add(tgtFaces[tgtFacei], pointOffset[proci]);
820 tgtFaceOwners[tgtFacei] = newOwn;
821 tgtFaceNeighbours[tgtFacei] = -1;
827 label own = faceOs[i];
828 label nbr = faceNs[i];
829 if ((own != -1) && (nbr == -1))
831 label newOwn = cellOffset[proci] + faceOs[i];
832 label tgtFacei = nIntFaces++;
834 tgtFaces[tgtFacei] = fcs[i];
835 add(tgtFaces[tgtFacei], pointOffset[proci]);
837 tgtFaceOwners[tgtFacei] = newOwn;
838 tgtFaceNeighbours[tgtFacei] = -1;
860 Pout<<
"Merged from " << oldToNew.size()
861 <<
" down to " << tgtPoints.size() <<
" points" <<
endl;
863 for (
auto&
f : tgtFaces)
List< labelList > labelListList
A List of labelList.
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)
List< face > faceList
A List of faces.
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)
Number of this process (starting from masterNo() = 0)
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. ...
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator) 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.
#define InfoInFunction
Report an information message using Foam::Info.
static constexpr const zero Zero
Global zero (0)