41Foam::label Foam::meshToMesh::calcDistribution
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;
81Foam::label Foam::meshToMesh::calcOverlappingProcs
100 overlaps[proci] =
true;
111Foam::autoPtr<Foam::mapDistribute> Foam::meshToMesh::calcProcMap
122 switch (procMapMethod_)
124 case procMapMethod::pmLOD:
126 Info<<
"meshToMesh: Using processorLOD method" <<
endl;
131 const label nGlobalSrcCells = src.globalData().nTotalCells();
134 const label cellsPerBox =
max(16, 0.001*nGlobalSrcCells);
147 return boxLOD.map(constructLayout);
152 Info<<
"meshToMesh: Using AABBTree method" <<
endl;
157 if (src.nCells() > 0)
177 <<
"Determining extent of src mesh per processor:" <<
nl
178 <<
"\tproc\tbb" <<
endl;
181 Info<<
'\t' << proci <<
'\t' << procBb[proci] <<
endl;
196 dynSendMap[proci].setCapacity(iniSize);
203 for (label celli = 0; celli < tgt.nCells(); ++celli)
209 (void)calcOverlappingProcs(procBb, cellBb, procBbOverlaps);
211 forAll(procBbOverlaps, proci)
213 if (procBbOverlaps[proci])
215 dynSendMap[proci].append(celli);
222 Pout<<
"Of my " << tgt.nCells()
223 <<
" target cells I need to send to:" <<
nl
224 <<
"\tproc\tcells" <<
endl;
227 Pout<<
'\t' << proci <<
'\t'
228 << dynSendMap[proci].size() <<
endl;
235 sendMap[proci].transfer(dynSendMap[proci]);
251void Foam::meshToMesh::distributeCells
281 const labelList& sendElems = map.subMap()[domain];
283 if (sendElems.size())
286 labelList reverseCellMap(tgtMesh.nCells(), -1);
287 forAll(sendElems, subCelli)
289 reverseCellMap[sendElems[subCelli]] = subCelli;
302 forAll(tgtMesh.faceNeighbour(), facei)
304 label own = tgtMesh.faceOwner()[facei];
305 label nbr = tgtMesh.faceNeighbour()[facei];
306 label subOwn = reverseCellMap[own];
307 label subNbr = reverseCellMap[nbr];
309 if (subOwn != -1 && subNbr != -1)
315 subFaces.append(tgtMesh.faces()[facei]);
316 subFaceOwner.append(subOwn);
317 subFaceNeighbour.append(subNbr);
318 subNbrProcIDs.append(-1);
319 subProcLocalFaceIDs.append(-1);
323 subFaces.append(tgtMesh.faces()[facei].reverseFace());
324 subFaceOwner.append(subNbr);
325 subFaceNeighbour.append(subOwn);
326 subNbrProcIDs.append(-1);
327 subProcLocalFaceIDs.append(-1);
333 forAll(tgtMesh.faceNeighbour(), facei)
335 label own = tgtMesh.faceOwner()[facei];
336 label nbr = tgtMesh.faceNeighbour()[facei];
337 label subOwn = reverseCellMap[own];
338 label subNbr = reverseCellMap[nbr];
340 if (subOwn != -1 && subNbr == -1)
342 subFaces.append(tgtMesh.faces()[facei]);
343 subFaceOwner.append(subOwn);
344 subFaceNeighbour.append(subNbr);
345 subNbrProcIDs.append(-1);
346 subProcLocalFaceIDs.append(-1);
348 else if (subOwn == -1 && subNbr != -1)
350 subFaces.append(tgtMesh.faces()[facei].reverseFace());
351 subFaceOwner.append(subNbr);
352 subFaceNeighbour.append(subOwn);
353 subNbrProcIDs.append(-1);
354 subProcLocalFaceIDs.append(-1);
359 forAll(tgtMesh.boundaryMesh(), patchi)
361 const polyPatch&
pp = tgtMesh.boundaryMesh()[patchi];
365 const label nbrProci =
366 (procPatch ? procPatch->neighbProcNo() : -1);
370 label facei =
pp.start() + i;
371 label own = tgtMesh.faceOwner()[facei];
373 if (reverseCellMap[own] != -1)
375 subFaces.append(tgtMesh.faces()[facei]);
376 subFaceOwner.append(reverseCellMap[own]);
377 subFaceNeighbour.append(-1);
378 subNbrProcIDs.append(nbrProci);
379 subProcLocalFaceIDs.append(i);
385 labelList reversePointMap(tgtMesh.nPoints(), -1);
387 forAll(subFaces, subFacei)
389 face&
f = subFaces[subFacei];
392 label pointi =
f[fp];
393 if (reversePointMap[pointi] == -1)
395 reversePointMap[pointi] = subPoints.size();
396 subPoints.append(tgtMesh.points()[pointi]);
399 f[fp] = reversePointMap[pointi];
404 labelList globalElems(globalI.toGlobal(sendElems));
411 <<
" sending tgt cell " << sendElems[i]
412 <<
"[" << globalElems[i] <<
"]"
413 <<
" to srcProc " << domain <<
endl;
443 << subProcLocalFaceIDs;
449 pBufs.finishedSends();
454 const labelList& recvElems = map.constructMap()[domain];
461 >> nInternalFaces[domain]
464 >> faceNeighbour[domain]
466 >> nbrProcIDs[domain]
467 >> procLocalFaceIDs[domain];
472 Pout<<
"Target mesh send sizes[" << domain <<
"]"
474 <<
", faces=" << faces[domain].size()
475 <<
", nInternalFaces=" << nInternalFaces[domain]
476 <<
", faceOwn=" << faceOwner[domain].size()
477 <<
", faceNbr=" << faceNeighbour[domain].size()
478 <<
", cellIDs=" << cellIDs[domain].size() <<
endl;
484void Foam::meshToMesh::distributeAndMergeCells
546 labelList allNIntCoupledFaces(allNInternalFaces);
560 forAll(allTgtCellIDs, proci)
562 cellOffset[proci] = nCells;
563 nCells += allTgtCellIDs[proci].size();
569 procCoupleInfo procFaceToGlobalCell;
571 forAll(allNbrProcIDs, proci)
573 const labelList& nbrProci = allNbrProcIDs[proci];
574 const labelList& localFacei = allProcLocalFaceIDs[proci];
578 if (nbrProci[i] != -1 && localFacei[i] != -1)
581 key[0] =
min(proci, nbrProci[i]);
582 key[1] =
max(proci, nbrProci[i]);
583 key[2] = localFacei[i];
585 const auto fnd = procFaceToGlobalCell.cfind(key);
589 procFaceToGlobalCell.insert(key, -1);
595 Pout<<
"Additional internal face between procs:"
596 <<
key[0] <<
" and " <<
key[1]
597 <<
" across local face " <<
key[2] <<
endl;
600 allNIntCoupledFaces[proci]++;
609 label nFacesTotal = 0;
611 forAll(allNIntCoupledFaces, proci)
613 label nCoupledFaces =
614 allNIntCoupledFaces[proci] - allNInternalFaces[proci];
616 internalFaceOffset[proci] = nIntFaces;
617 nIntFaces += allNIntCoupledFaces[proci];
618 nFacesTotal += allFaceOwners[proci].size() - nCoupledFaces;
622 tgtFaces.setSize(nFacesTotal);
623 tgtFaceOwners.setSize(nFacesTotal);
624 tgtFaceNeighbours.setSize(nFacesTotal);
625 tgtCellIDs.setSize(nCells);
635 forAll(allTgtCellIDs, proci)
637 const labelList& cellIDs = allTgtCellIDs[proci];
638 SubList<label>(tgtCellIDs, cellIDs.size(), cellOffset[proci]) = cellIDs;
645 const faceList& fcs = allFaces[proci];
646 const labelList& faceOs = allFaceOwners[proci];
647 const labelList& faceNs = allFaceNeighbours[proci];
652 allNInternalFaces[proci],
653 internalFaceOffset[proci]
658 add(slice[i], pointOffset[proci]);
664 allNInternalFaces[proci],
665 internalFaceOffset[proci]
668 add(ownSlice, cellOffset[proci]);
673 allNInternalFaces[proci],
674 internalFaceOffset[proci]
677 add(nbrSlice, cellOffset[proci]);
679 internalFaceOffset[proci] += allNInternalFaces[proci];
684 forAll(allNbrProcIDs, proci)
686 const labelList& nbrProci = allNbrProcIDs[proci];
687 const labelList& localFacei = allProcLocalFaceIDs[proci];
688 const labelList& faceOs = allFaceOwners[proci];
689 const faceList& fcs = allFaces[proci];
693 if (nbrProci[i] != -1 && localFacei[i] != -1)
696 key[0] =
min(proci, nbrProci[i]);
697 key[1] =
max(proci, nbrProci[i]);
698 key[2] = localFacei[i];
700 auto fnd = procFaceToGlobalCell.find(key);
704 label tgtFacei = fnd();
708 fnd() = cellOffset[proci] + faceOs[i];
713 label newOwn = cellOffset[proci] + faceOs[i];
714 label newNbr = fnd();
715 label tgtFacei = internalFaceOffset[proci]++;
719 Pout<<
" proc " << proci
720 <<
"\tinserting face:" << tgtFacei
721 <<
" connection between owner " << newOwn
722 <<
" and neighbour " << newNbr
729 tgtFaces[tgtFacei] = fcs[i];
730 tgtFaceOwners[tgtFacei] = newOwn;
731 tgtFaceNeighbours[tgtFacei] = newNbr;
736 tgtFaces[tgtFacei] = fcs[i].reverseFace();
737 tgtFaceOwners[tgtFacei] = newNbr;
738 tgtFaceNeighbours[tgtFacei] = newOwn;
741 add(tgtFaces[tgtFacei], pointOffset[proci]);
752 forAll(allNbrProcIDs, proci)
754 const labelList& nbrProci = allNbrProcIDs[proci];
755 const labelList& localFacei = allProcLocalFaceIDs[proci];
756 const labelList& faceOs = allFaceOwners[proci];
757 const labelList& faceNs = allFaceNeighbours[proci];
758 const faceList& fcs = allFaces[proci];
763 if (nbrProci[i] != -1 && localFacei[i] != -1)
766 key[0] =
min(proci, nbrProci[i]);
767 key[1] =
max(proci, nbrProci[i]);
768 key[2] = localFacei[i];
770 label tgtFacei = procFaceToGlobalCell[
key];
775 <<
"Unvisited " <<
key
778 else if (tgtFacei != -2)
780 label newOwn = cellOffset[proci] + faceOs[i];
781 label tgtFacei = nIntFaces++;
785 Pout<<
" proc " << proci
786 <<
"\tinserting boundary face:" << tgtFacei
787 <<
" from coupled face " <<
key
791 tgtFaces[tgtFacei] = fcs[i];
792 add(tgtFaces[tgtFacei], pointOffset[proci]);
794 tgtFaceOwners[tgtFacei] = newOwn;
795 tgtFaceNeighbours[tgtFacei] = -1;
801 label own = faceOs[i];
802 label nbr = faceNs[i];
803 if ((own != -1) && (nbr == -1))
805 label newOwn = cellOffset[proci] + faceOs[i];
806 label tgtFacei = nIntFaces++;
808 tgtFaces[tgtFacei] = fcs[i];
809 add(tgtFaces[tgtFacei], pointOffset[proci]);
811 tgtFaceOwners[tgtFacei] = newOwn;
812 tgtFaceNeighbours[tgtFacei] = -1;
834 Pout<<
"Merged from " << oldToNew.size()
835 <<
" down to " << tgtPoints.size() <<
" points" <<
endl;
837 for (
auto&
f : tgtFaces)
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
Templated tree of axis-aligned bounding boxes (AABB).
const List< treeBoundBox > & boundBoxes() const noexcept
Return the bounding boxes making up the tree.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
A 1D vector of objects of type <T> with a fixed length <N>.
A HashTable similar to std::unordered_map.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
void setSize(label n)
Alias for resize().
Buffers for inter-processor communications streams (UOPstream, UIPstream).
static void allGatherList(UList< T > &values, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Gather data, but keep individual values separate. Uses MPI_Allgather or manual communication.
SubField is a Field obtained as a section of another Field, without its own allocation....
A non-owning sub-view of a List (allocated or unallocated storage).
Input inter-processor communications stream using MPI send/recv etc. - operating on external buffer.
void size(const label n)
Older name for setAddressableSize.
Output inter-processor communications stream using MPI send/recv etc. - operating on external buffer.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
static List< T > listGatherValues(const T &localValue, const int communicator=UPstream::worldComm)
Gather individual values into list locations.
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run.
static rangeType allProcs(const label communicator=worldComm)
Range of process indices for all processes.
@ broadcast
broadcast [MPI]
static bool & parRun() noexcept
Test if this a parallel run.
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
A bounding box defined in terms of min/max extrema points.
A face is a list of labels corresponding to mesh vertices.
Calculates a non-overlapping list of offsets based on an input size (eg, number of cells) from differ...
layoutTypes
The map layout (eg, of the constructMap).
@ linear
In processor-order.
Class containing processor-to-processor mapping information.
Mesh consisting of general polyhedral cells.
A patch is a list of labels that address the faces in the global face list.
Creates the parallel distribution map by describing the source and target objects using box shapes.
Standard boundBox with extra functionality for use in octree.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Geometric merging of points. See below.
#define DebugInFunction
Report an information message using Foam::Info.
#define InfoInFunction
Report an information message using Foam::Info.
Namespace for handling debugging switches.
constexpr auto key(const Type &t) noexcept
Helper function to return the enum value.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values within a list.
List< labelList > labelListList
List of labelList.
List< label > labelList
A List of labels.
List< treeBoundBox > treeBoundBoxList
A List of treeBoundBox.
messageStream Info
Information stream (stdout output on master, null elsewhere).
List< face > faceList
List of faces.
Ostream & endl(Ostream &os)
Add newline and flush stream.
void add(DimensionedField< scalar, GeoMesh > &result, const dimensioned< scalar > &dt1, const DimensionedField< scalar, GeoMesh > &f2)
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
errorManip< error > abort(error &err)
List< bool > boolList
A List of bools.
static constexpr const zero Zero
Global zero (0).
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
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...
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
vectorField pointField
pointField is a vectorField.
constexpr char nl
The newline '\n' character (0x0a).
#define forAll(list, i)
Loop across all elements in list.