36 void Foam::domainDecomposition::mark
45 label pointi = zoneElems[i];
47 if (elementToZone[pointi] == -1)
50 elementToZone[pointi] = zoneI;
52 else if (elementToZone[pointi] >= 0)
55 elementToZone[pointi] = -2;
61 void Foam::domainDecomposition::addInterProcFace
64 const label ownerProc,
66 const label subPatchID,
67 List<Map<label>>& nbrToInterPatch,
68 List<DynamicList<DynamicList<label>>>& interPatchFaces,
69 List<labelListList>& subPatchIDs,
70 List<labelListList>& subPatchStarts
74 label toNbrProcPatchi = -1, toOwnerProcPatchi = -1;
75 if (!nbrToInterPatch[ownerProc].
found(nbrProc))
77 toNbrProcPatchi = nbrToInterPatch[ownerProc].size();
78 nbrToInterPatch[ownerProc].insert(nbrProc, toNbrProcPatchi);
79 interPatchFaces[ownerProc].append(DynamicList<label>());
80 subPatchIDs[ownerProc].append(
labelList(1, subPatchID));
83 if (facei != -1 && completeMesh().isInternalFace(facei))
85 toOwnerProcPatchi = nbrToInterPatch[nbrProc].size();
86 nbrToInterPatch[nbrProc].insert(ownerProc, toOwnerProcPatchi);
87 interPatchFaces[nbrProc].append(DynamicList<label>());
88 subPatchIDs[nbrProc].append(
labelList(1, subPatchID));
94 toNbrProcPatchi = nbrToInterPatch[ownerProc][nbrProc];
96 if (facei != -1 && completeMesh().isInternalFace(facei))
98 toOwnerProcPatchi = nbrToInterPatch[nbrProc][ownerProc];
103 if (subPatchIDs[ownerProc][toNbrProcPatchi].last() != subPatchID)
105 subPatchIDs[ownerProc][toNbrProcPatchi].append(subPatchID);
106 subPatchStarts[ownerProc][toNbrProcPatchi].append
108 interPatchFaces[ownerProc][toNbrProcPatchi].size()
111 if (facei != -1 && completeMesh().isInternalFace(facei))
113 subPatchIDs[nbrProc][toOwnerProcPatchi].append(subPatchID);
114 subPatchStarts[nbrProc][toOwnerProcPatchi].append
116 interPatchFaces[nbrProc][toOwnerProcPatchi].size()
124 interPatchFaces[ownerProc][toNbrProcPatchi].append(facei + 1);
126 if (completeMesh().isInternalFace(facei))
128 interPatchFaces[nbrProc][toOwnerProcPatchi].append(- facei - 1);
136 Info<<
"Calculating distribution of cells" <<
nl <<
endl;
138 cpuTime decompositionTime;
140 const dictionary decomposeParDict =
144 if (decomposeParDict.found(
"weightField"))
146 const word weightName = decomposeParDict.lookup(
"weightField");
153 completeMesh().time().
name(),
160 cellWeights = weights.primitiveField();
170 Info<<
nl <<
"Finished decomposition in "
171 << decompositionTime.elapsedCpuTime()
178 void Foam::domainDecomposition::processInterCyclics
181 const polyBoundaryMesh&
patches,
182 List<DynamicList<DynamicList<label>>>& interPatchFaces,
183 List<Map<label>>& procNbrToInterPatch,
184 List<labelListList>& subPatchIDs,
185 List<labelListList>& subPatchStarts,
195 const nonConformalCyclicPolyPatch& nccPp =
198 if (nccPp.owner() != owner)
continue;
200 const polyPatch& origPp = nccPp.origPatch();
201 const polyPatch& nbrOrigPp = nccPp.nbrPatch().origPatch();
203 const labelUList& origPatchFaceCells = origPp.faceCells();
204 const labelUList& nbrOrigPatchFaceCells = nbrOrigPp.faceCells();
208 forAll(origPatchFaceCells, origFacei)
210 const label ownerProc =
211 cellProc[origPatchFaceCells[origFacei]];
213 forAll(nbrOrigPatchFaceCells, nbrOrigFacei)
215 const label nbrProc =
216 cellProc[nbrOrigPatchFaceCells[nbrOrigFacei]];
220 (
first && ownerProc < nbrProc)
221 || (!
first && ownerProc > nbrProc)
241 const cyclicPolyPatch& cPp =
244 if (cPp.owner() != owner)
continue;
246 const labelUList& patchFaceCells = cPp.faceCells();
247 const labelUList& nbrPatchFaceCells = cPp.nbrPatch().faceCells();
250 forAll(patchFaceCells, facei)
252 const label ownerProc = cellProc[patchFaceCells[facei]];
253 const label nbrProc = cellProc[nbrPatchFaceCells[facei]];
257 (
first && ownerProc < nbrProc)
258 || (!
first && ownerProc > nbrProc)
279 void Foam::domainDecomposition::decompose()
282 cellProc_ = distributeCells();
288 Info<<
"Calculating original mesh data" <<
nl <<
endl;
291 const polyBoundaryMesh&
patches = completeMesh().boundaryMesh();
292 const faceList& fcs = completeMesh().faces();
293 const labelList& owner = completeMesh().faceOwner();
294 const labelList& neighbour = completeMesh().faceNeighbour();
299 Info<<
"Distributing cells to processors" <<
nl <<
endl;
304 Info<<
"Distributing faces to processors" <<
nl <<
endl;
310 List<DynamicList<label>> dynProcFaceAddressing(nProcs());
315 if (cellProc_[owner[facei]] == cellProc_[neighbour[facei]])
318 dynProcFaceAddressing[cellProc_[owner[facei]]].append(facei+1);
326 forAll(procPatchSize, proci)
329 procPatchStartIndex[proci].setSize(
patches.
size());
336 forAll(procPatchSize, proci)
338 procPatchSize[proci][
patchi] = 0;
339 procPatchStartIndex[proci][
patchi] =
340 dynProcFaceAddressing[proci].size();
352 forAll(patchFaceCells, facei)
354 const label curProc = cellProc_[patchFaceCells[facei]];
357 dynProcFaceAddressing[curProc].append(patchStart+facei+1);
360 procPatchSize[curProc][
patchi]++;
368 const cyclicPolyPatch& pp =
371 const labelUList& patchFaceCells = pp.faceCells();
372 const labelUList& nbrPatchFaceCells = pp.nbrPatch().faceCells();
374 forAll(patchFaceCells, facei)
376 const label curProc = cellProc_[patchFaceCells[facei]];
377 const label nbrProc = cellProc_[nbrPatchFaceCells[facei]];
379 if (curProc == nbrProc)
382 dynProcFaceAddressing[curProc].append(patchStart+facei+1);
385 procPatchSize[curProc][
patchi]++;
395 List<Map<label>> procNbrToInterPatch(nProcs());
398 List<DynamicList<DynamicList<label>>> interPatchFaces(nProcs());
401 List<labelListList> subPatchIDs(nProcs());
402 List<labelListList> subPatchStarts(nProcs());
407 const label ownerProc = cellProc_[owner[facei]];
408 const label nbrProc = cellProc_[neighbour[facei]];
410 if (ownerProc != nbrProc)
502 List<labelListList> procProcessorPatchSubPatchIDs(nProcs());
503 List<labelListList> procProcessorPatchSubPatchStarts(nProcs());
505 forAll(procNbrToInterPatch, proci)
507 label nInterfaces = procNbrToInterPatch[proci].size();
509 procNeighbourProcessors[proci].setSize(nInterfaces);
510 procProcessorPatchSize[proci].setSize(nInterfaces);
511 procProcessorPatchStartIndex[proci].setSize(nInterfaces);
512 procProcessorPatchSubPatchIDs[proci].setSize(nInterfaces);
513 procProcessorPatchSubPatchStarts[proci].setSize(nInterfaces);
516 const Map<label>& curNbrToInterPatch = procNbrToInterPatch[proci];
517 labelList nbrs = curNbrToInterPatch.toc();
521 DynamicList<DynamicList<label>>& curInterPatchFaces =
522 interPatchFaces[proci];
526 const label nbrProc = nbrs[i];
527 const label interPatch = curNbrToInterPatch[nbrProc];
529 procNeighbourProcessors[proci][i] = nbrProc;
530 procProcessorPatchSize[proci][i] =
531 curInterPatchFaces[interPatch].size();
532 procProcessorPatchStartIndex[proci][i] =
533 dynProcFaceAddressing[proci].size();
536 subPatchStarts[proci][interPatch].append
538 curInterPatchFaces[interPatch].size()
540 procProcessorPatchSubPatchIDs[proci][i].transfer
542 subPatchIDs[proci][interPatch]
544 procProcessorPatchSubPatchStarts[proci][i].transfer
546 subPatchStarts[proci][interPatch]
550 DynamicList<label>& interPatchFaces =
551 curInterPatchFaces[interPatch];
553 forAll(interPatchFaces, j)
555 dynProcFaceAddressing[proci].append(interPatchFaces[j]);
558 interPatchFaces.clearStorage();
561 curInterPatchFaces.clearStorage();
562 dynProcFaceAddressing[proci].shrink();
566 forAll(dynProcFaceAddressing, proci)
568 procFaceAddressing_[proci].transfer(dynProcFaceAddressing[proci]);
573 forAll(procPatchStartIndex, proci)
575 Info<<
"Processor:" << proci <<
endl;
576 Info<<
" total faces:" << procFaceAddressing_[proci].size()
579 const labelList& curProcPatchStartIndex =
580 procPatchStartIndex[proci];
585 <<
"\tstart:" << curProcPatchStartIndex[
patchi]
586 <<
"\tsize:" << procPatchSize[proci][
patchi]
592 forAll(procNeighbourProcessors, proci)
594 Info<<
"Processor " << proci <<
endl;
595 forAll(procNeighbourProcessors[proci], i)
597 Info<<
" nbr:" << procNeighbourProcessors[proci][i] <<
endl;
598 Info<<
" size:" << procProcessorPatchSize[proci][i] <<
endl;
599 Info<<
" start:" << procProcessorPatchStartIndex[proci][i]
608 forAll(procFaceAddressing_, proci)
610 Info<<
"Processor:" << proci <<
endl;
611 Info<<
" faces:" << procFaceAddressing_[proci] <<
endl;
615 Info<<
"Distributing points to processors" <<
nl <<
endl;
622 forAll(procPointAddressing_, proci)
627 const labelList& procFaceLabels = procFaceAddressing_[proci];
629 forAll(procFaceLabels, facei)
632 const labelList& facePoints = fcs[
mag(procFaceLabels[facei]) - 1];
634 forAll(facePoints, pointi)
642 labelList& procPointLabels = procPointAddressing_[proci];
646 label nUsedPoints = 0;
652 procPointLabels[nUsedPoints] = pointi;
659 procPointLabels.setSize(nUsedPoints);
662 Info<<
"Constructing processor meshes" <<
nl <<
endl;
674 forAll(completeMesh().pointZones(), zoneI)
676 mark(completeMesh().pointZones()[zoneI], zoneI, pointToZone);
680 labelList faceToZone(completeMesh().faces().size(), -1);
681 forAll(completeMesh().faceZones(), zoneI)
683 mark(completeMesh().faceZones()[zoneI], zoneI, faceToZone);
687 labelList cellToZone(completeMesh().nCells(), -1);
688 forAll(completeMesh().cellZones(), zoneI)
690 mark(completeMesh().cellZones()[zoneI], zoneI, cellToZone);
694 label maxProcCells = 0;
695 label totProcFaces = 0;
696 label maxProcPatches = 0;
697 label totProcPatches = 0;
698 label maxProcFaces = 0;
701 for (
label proci = 0; proci < nProcs(); proci++)
704 const labelList& curPointLabels = procPointAddressing_[proci];
705 const pointField& meshPoints = completeMesh().points();
708 forAll(curPointLabels, pointi)
710 procPoints[pointi] = meshPoints[curPointLabels[pointi]];
711 pointLookup[curPointLabels[pointi]] = pointi;
715 const labelList& curFaceLabels = procFaceAddressing_[proci];
716 const faceList& meshFaces = completeMesh().faces();
717 labelList faceLookup(completeMesh().nFaces(), -1);
718 faceList procFaces(curFaceLabels.size());
719 forAll(curFaceLabels, facei)
723 label curF =
mag(curFaceLabels[facei]) - 1;
725 faceLookup[curF] = facei;
730 if (curFaceLabels[facei] >= 0)
733 origFaceLabels = meshFaces[curF];
737 origFaceLabels = meshFaces[curF].reverseFace();
741 face& procFaceLabels = procFaces[facei];
743 procFaceLabels.setSize(origFaceLabels.size());
745 forAll(origFaceLabels, pointi)
747 procFaceLabels[pointi] = pointLookup[origFaceLabels[pointi]];
752 const labelList& curCellLabels = procCellAddressing_[proci];
753 const cellList& meshCells = completeMesh().cells();
754 cellList procCells(curCellLabels.size());
755 forAll(curCellLabels, celli)
757 const labelList& origCellLabels = meshCells[curCellLabels[celli]];
758 cell& curCell = procCells[celli];
759 curCell.setSize(origCellLabels.size());
760 forAll(origCellLabels, cellFacei)
762 curCell[cellFacei] = faceLookup[origCellLabels[cellFacei]];
775 completeMesh().facesInstance(),
777 runTimes_.procTimes()[proci]
784 fvMesh& procMesh = procMeshes_[proci];
785 procMesh.setPointsInstance(completeMesh().pointsInstance());
788 const labelList& curPatchSizes = procPatchSize[proci];
789 const labelList& curPatchStarts = procPatchStartIndex[proci];
790 const labelList& curNeighbourProcessors =
791 procNeighbourProcessors[proci];
792 const labelList& curProcessorPatchSizes =
793 procProcessorPatchSize[proci];
794 const labelList& curProcessorPatchStarts =
795 procProcessorPatchStartIndex[proci];
797 procProcessorPatchSubPatchIDs[proci];
799 procProcessorPatchSubPatchStarts[proci];
800 const polyPatchList& meshPatches = completeMesh().boundaryMesh();
803 label nInterProcPatches = 0;
804 forAll(curSubPatchIDs, procPatchi)
806 nInterProcPatches += curSubPatchIDs[procPatchi].size();
808 List<polyPatch*> procPatches
810 curPatchSizes.size() + nInterProcPatches,
819 const polyPatch& meshPatch = meshPatches[
patchi];
824 procMesh.boundaryMesh(),
834 forAll(curProcessorPatchSizes, procPatchi)
836 const labelList& subPatchID = curSubPatchIDs[procPatchi];
837 const labelList& subStarts = curSubStarts[procPatchi];
839 label curStart = curProcessorPatchStarts[procPatchi];
844 i < subPatchID.size() - 1
845 ? subStarts[i+1] - subStarts[i]
846 : curProcessorPatchSizes[procPatchi] - subStarts[i];
848 if (subPatchID[i] == -1)
852 new processorPolyPatch
857 procMesh.boundaryMesh(),
859 curNeighbourProcessors[procPatchi]
864 isA<nonConformalCyclicPolyPatch>
866 completeMesh().boundaryMesh()[subPatchID[i]]
872 const nonConformalCyclicPolyPatch& nccPp =
873 refCast<const nonConformalCyclicPolyPatch>
875 completeMesh().boundaryMesh()[subPatchID[i]]
879 new nonConformalProcessorCyclicPolyPatch
884 procMesh.boundaryMesh(),
886 curNeighbourProcessors[procPatchi],
888 nccPp.origPatch().name()
895 completeMesh().boundaryMesh()[subPatchID[i]]
900 const cyclicPolyPatch& cPp =
901 refCast<const cyclicPolyPatch>
903 completeMesh().boundaryMesh()[subPatchID[i]]
907 new processorCyclicPolyPatch
912 procMesh.boundaryMesh(),
914 curNeighbourProcessors[procPatchi],
921 <<
"Sub patch ID set for non-cyclic patch type"
932 procMesh.addFvPatches(procPatches);
939 const pointZoneList& pz = completeMesh().pointZones();
944 List<DynamicList<label>> zonePoints(pz.size());
949 zonePoints[zoneI].setCapacity(pz[zoneI].size()/nProcs());
954 forAll(curPointLabels, pointi)
956 label curPoint = curPointLabels[pointi];
958 label zoneI = pointToZone[curPoint];
963 zonePoints[zoneI].append(pointi);
965 else if (zoneI == -2)
970 label index = pz[zoneI].localIndex(curPoint);
974 zonePoints[zoneI].append(pointi);
980 procMesh.pointZones().setSize(zonePoints.size());
983 procMesh.pointZones().set
988 zonePoints[zoneI].shrink(),
989 procMesh.pointZones()
1003 const faceZoneList& fz = completeMesh().faceZones();
1008 List<DynamicList<label>> zoneFaces(fz.size());
1009 List<DynamicList<bool>> zoneFaceFlips(fz.size());
1014 label procSize = fz[zoneI].size()/nProcs();
1016 zoneFaces[zoneI].setCapacity(procSize);
1017 zoneFaceFlips[zoneI].setCapacity(procSize);
1023 forAll(curFaceLabels, facei)
1027 label curF =
mag(curFaceLabels[facei]) - 1;
1029 label zoneI = faceToZone[curF];
1034 zoneFaces[zoneI].append(facei);
1036 label index = fz[zoneI].localIndex(curF);
1038 if (fz[zoneI].oriented())
1040 bool flip = fz[zoneI].flipMap()[index];
1042 if (curFaceLabels[facei] < 0)
1047 zoneFaceFlips[zoneI].append(flip);
1050 else if (zoneI == -2)
1055 label index = fz[zoneI].localIndex(curF);
1059 zoneFaces[zoneI].append(facei);
1061 if (fz[zoneI].oriented())
1063 bool flip = fz[zoneI].flipMap()[index];
1065 if (curFaceLabels[facei] < 0)
1070 zoneFaceFlips[zoneI].append(flip);
1077 procMesh.faceZones().setSize(zoneFaces.size());
1080 if (fz[zoneI].oriented())
1082 procMesh.faceZones().set
1087 zoneFaces[zoneI].shrink(),
1088 zoneFaceFlips[zoneI].shrink(),
1089 procMesh.faceZones()
1095 procMesh.faceZones().set
1100 zoneFaces[zoneI].shrink(),
1101 procMesh.faceZones()
1116 const cellZoneList& cz = completeMesh().cellZones();
1121 List<DynamicList<label>> zoneCells(cz.size());
1126 zoneCells[zoneI].setCapacity(cz[zoneI].size()/nProcs());
1129 forAll(curCellLabels, celli)
1131 label curCelli = curCellLabels[celli];
1133 label zoneI = cellToZone[curCelli];
1138 zoneCells[zoneI].append(celli);
1140 else if (zoneI == -2)
1145 label index = cz[zoneI].localIndex(curCelli);
1149 zoneCells[zoneI].append(celli);
1155 procMesh.cellZones().setSize(zoneCells.size());
1158 procMesh.cellZones().set
1163 zoneCells[zoneI].shrink(),
1164 procMesh.cellZones()
1178 Info<<
"Processor " << proci <<
nl
1179 <<
" Number of cells = " << procMesh.nCells()
1182 maxProcCells =
max(maxProcCells, procMesh.nCells());
1184 label nBoundaryFaces = 0;
1185 label nProcPatches = 0;
1186 label nProcFaces = 0;
1190 if (isA<processorPolyPatch>(procMesh.boundaryMesh()[
patchi]))
1192 const processorPolyPatch& ppp =
1193 refCast<const processorPolyPatch>
1195 procMesh.boundaryMesh()[
patchi]
1198 Info<<
" Number of faces shared with processor "
1199 << ppp.neighbProcNo() <<
" = " << ppp.size() <<
endl;
1202 nProcFaces += ppp.size();
1206 nBoundaryFaces += procMesh.boundaryMesh()[
patchi].size();
1210 Info<<
" Number of processor patches = " << nProcPatches <<
nl
1211 <<
" Number of processor faces = " << nProcFaces <<
nl
1212 <<
" Number of boundary faces = " << nBoundaryFaces <<
nl
1215 totProcFaces += nProcFaces;
1216 totProcPatches += nProcPatches;
1217 maxProcPatches =
max(maxProcPatches, nProcPatches);
1218 maxProcFaces =
max(maxProcFaces, nProcFaces);
1223 scalar avgProcCells = scalar(completeMesh().nCells())/nProcs();
1224 scalar avgProcPatches = scalar(totProcPatches)/nProcs();
1225 scalar avgProcFaces = scalar(totProcFaces)/nProcs();
1228 if (totProcPatches == 0)
1232 if (totProcFaces == 0)
1237 Info<<
"Number of processor faces = " << totProcFaces/2 <<
nl
1238 <<
"Max number of cells = " << maxProcCells
1239 <<
" (" << 100.0*(maxProcCells-avgProcCells)/avgProcCells
1240 <<
"% above average " << avgProcCells <<
")" <<
nl
1241 <<
"Max number of processor patches = " << maxProcPatches
1242 <<
" (" << 100.0*(maxProcPatches-avgProcPatches)/avgProcPatches
1243 <<
"% above average " << avgProcPatches <<
")" <<
nl
1244 <<
"Max number of faces between processors = " << maxProcFaces
1245 <<
" (" << 100.0*(maxProcFaces-avgProcFaces)/avgProcFaces
1246 <<
"% above average " << avgProcFaces <<
")" <<
endl;
1249 procFaceAddressingBf_.clear();
1253 void Foam::domainDecomposition::decomposePoints()
1255 for (
label proci = 0; proci < nProcs(); proci++)
1257 fvMesh& procMesh = procMeshes_[proci];
1259 const label pointsCompare =
1262 completeMesh().pointsInstance(),
1263 procMeshes_[proci].pointsInstance()
1266 if (pointsCompare == -1)
1273 procPointAddressing_[proci]
#define forAll(list, i)
Loop across all elements in list.
void size(const label)
Override size to be inconsistent with allocated storage.
void setSize(const label)
Reset size of List.
label size() const
Return the number of elements in the UPtrList.
static IOdictionary decomposeParDict(const Time &time)
Read and return the decomposeParDict.
static autoPtr< decompositionMethod > NewDecomposer(const dictionary &decompositionDict)
Return a reference to the selected decomposition method.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const fvPatchList & patches
errorManipArg< error, int > exit(error &err, const int errNo=1)
List< label > labelList
A List of labels.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
List< cell > cellList
list of cells
Ostream & endl(Ostream &os)
Add newline and flush stream.
int order(const scalar s)
vectorField pointField
pointField is a vectorField.
labelListList invertOneToMany(const label len, const labelUList &)
Invert one-to-many map. Unmapped elements will be size 0.
List< bool > boolList
Bool container classes.
void mag(LagrangianPatchField< scalar > &f, const LagrangianPatchField< Type > &f1)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
labelList first(const UList< labelPair > &p)
List< labelList > labelListList
A List of labelList.
VolField< scalar > volScalarField
PtrList< polyPatch > polyPatchList
container classes for polyPatch
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
void sortedOrder(const UList< T > &, labelList &order)
Generate the (stable) sort order for the list.
UList< label > labelUList
labelList pointLabels(nPoints, -1)