64 return decompDict.
get<label>(
"numberOfSubdomains");
74 const label nDomainsGlobal = nDomains(decompDict);
79 if (regionDict.
readIfPresent(
"numberOfSubdomains", nDomainsRegion))
81 if (nDomainsRegion >= 1 && nDomainsRegion <= nDomainsGlobal)
83 return nDomainsRegion;
87 <<
"ignoring out of range numberOfSubdomains "
88 << nDomainsRegion <<
" for region " <<
regionName
93 return nDomainsGlobal;
103 auto finder = decompDict.
csearch(
"regions");
111 return finder.dict();
121 bool Foam::decompositionMethod::constraintCompat(
const word& modelType)
const
123 bool usable = decompDict_.found(modelType);
129 for (
const auto& item : constraints_)
131 if (modelType == item.type())
141 <<
nl <<
" Using '" << modelType
142 <<
"' constraint specification." <<
nl;
147 <<
nl <<
" Ignoring '" << modelType
148 <<
"' constraint specification - was already specified." <<
nl;
158 void Foam::decompositionMethod::readConstraints()
160 constraints_.clear();
162 const dictionary* dictptr = decompDict_.findDict(
"constraints");
166 for (
const entry& dEntry : *dictptr)
168 if (!dEntry.isDict())
174 const dictionary&
dict = dEntry.dict();
184 if (constraintCompat(
"preserveBaffles"))
188 new decompositionConstraints::preserveBaffles()
192 if (constraintCompat(
"preservePatches"))
196 new decompositionConstraints::preservePatches
198 decompDict_.get<wordRes>(
"preservePatches")
203 if (constraintCompat(
"preserveFaceZones"))
207 new decompositionConstraints::preserveFaceZones
209 decompDict_.get<wordRes>(
"preserveFaceZones")
214 if (constraintCompat(
"singleProcessorFaceSets"))
218 new decompositionConstraints::singleProcessorFaceSets
220 decompDict_.lookup(
"singleProcessorFaceSets")
231 const word& coeffsName,
242 !(select & selectionType::EXACT)
251 if (select & selectionType::MANDATORY)
254 <<
"'" << coeffsName <<
"' dictionary not found in dictionary "
259 if (select & selectionType::NULL_DICT)
270 const word& coeffsName,
278 !decompRegionDict_.empty()
281 (fnd = decompRegionDict_.csearch(coeffsName)).isDict()
284 !(select & selectionType::EXACT)
285 && (fnd = decompRegionDict_.csearch(
defaultName)).isDict()
295 (fnd = decompDict_.csearch(coeffsName)).isDict()
298 !(select & selectionType::EXACT)
299 && (fnd = decompDict_.csearch(
defaultName)).isDict()
307 if (select & selectionType::MANDATORY)
310 <<
"'" << coeffsName <<
"' dictionary not found in dictionary "
311 << decompDict_.name() <<
endl
315 if (select & selectionType::NULL_DICT)
326 Foam::decompositionMethod::decompositionMethod
331 decompDict_(decompDict),
333 nDomains_(nDomains(decompDict))
339 Foam::decompositionMethod::decompositionMethod
345 decompDict_(decompDict),
363 const word methodType(decompDict.
get<
word>(
"method"));
365 auto cstrIter = dictionaryConstructorTablePtr_->cfind(methodType);
367 if (!cstrIter.found())
372 "decompositionMethod",
374 *dictionaryConstructorTablePtr_
380 Info<<
"Selecting decompositionMethod " << methodType
381 <<
" [" << (nDomains(decompDict)) <<
"]" <<
endl;
396 if (regionDict.empty())
405 auto cstrIter = dictionaryRegionConstructorTablePtr_->cfind(methodType);
407 if (!cstrIter.found())
411 <<
"Unknown region decompositionMethod "
412 << methodType <<
nl <<
nl
413 <<
"Valid decompositionMethods : " <<
endl
414 << dictionaryRegionConstructorTablePtr_->sortedToc() <<
nl
415 <<
"Reverting to non-region version" <<
nl
423 Info<<
"Selecting decompositionMethod " << methodType
424 <<
" [" << (nDomains(decompDict,
regionName)) <<
"] (region "
474 labelList fineDistribution(fineToCoarse.size());
476 forAll(fineDistribution, i)
478 fineDistribution[i] = coarseDistribution[fineToCoarse[i]];
481 return fineDistribution;
492 scalarField weights(coarsePoints.size(), scalar(1));
512 return decompose(globalCellCells, cc, weights);
520 const label nLocalCoarse,
549 if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp)))
551 label facei = pp.start();
556 globalNeighbour[bFacei] = globalAgglom.
toGlobal
558 agglom[faceOwner[facei]]
579 const label own = agglom[faceOwner[facei]];
580 const label nei = agglom[faceNeighbour[facei]];
582 nFacesPerCell[own]++;
583 nFacesPerCell[nei]++;
588 if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp)))
590 label facei = pp.start();
595 const label own = agglom[faceOwner[facei]];
596 const label globalNei = globalNeighbour[bFacei];
600 !globalAgglom.
isLocal(globalNei)
601 || globalAgglom.
toLocal(globalNei) != own
604 nFacesPerCell[own]++;
617 cellCells.
setSize(nFacesPerCell);
627 const label own = agglom[faceOwner[facei]];
628 const label nei = agglom[faceNeighbour[facei]];
630 m[offsets[own] + nFacesPerCell[own]++] = globalAgglom.
toGlobal(nei);
631 m[offsets[nei] + nFacesPerCell[nei]++] = globalAgglom.
toGlobal(own);
637 if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp)))
639 label facei = pp.start();
644 const label own = agglom[faceOwner[facei]];
645 const label globalNei = globalNeighbour[bFacei];
649 !globalAgglom.
isLocal(globalNei)
650 || globalAgglom.
toLocal(globalNei) != own
653 m[offsets[own] + nFacesPerCell[own]++] = globalNei;
667 if (cellCells.
size() == 0)
675 label startIndex = cellCells.
offsets()[0];
682 const label endIndex = cellCells.
offsets()[celli+1];
684 for (label i = startIndex; i < endIndex; ++i)
686 if (nbrCells.
insert(cellCells.
m()[i]))
688 cellCells.
m()[newIndex++] = cellCells.
m()[i];
691 startIndex = endIndex;
692 cellCells.
offsets()[celli+1] = newIndex;
718 const label nLocalCoarse,
748 if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp)))
750 label facei = pp.start();
755 globalNeighbour[bFacei] = globalAgglom.
toGlobal
757 agglom[faceOwner[facei]]
778 const label own = agglom[faceOwner[facei]];
779 const label nei = agglom[faceNeighbour[facei]];
781 nFacesPerCell[own]++;
782 nFacesPerCell[nei]++;
787 if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp)))
789 label facei = pp.start();
794 const label own = agglom[faceOwner[facei]];
795 const label globalNei = globalNeighbour[bFacei];
799 !globalAgglom.
isLocal(globalNei)
800 || globalAgglom.
toLocal(globalNei) != own
803 nFacesPerCell[own]++;
816 cellCells.
setSize(nFacesPerCell);
817 cellCellWeights.
setSize(nFacesPerCell);
828 const label own = agglom[faceOwner[facei]];
829 const label nei = agglom[faceNeighbour[facei]];
831 const label ownIndex = offsets[own] + nFacesPerCell[own]++;
832 const label neiIndex = offsets[nei] + nFacesPerCell[nei]++;
834 m[ownIndex] = globalAgglom.
toGlobal(nei);
836 m[neiIndex] = globalAgglom.
toGlobal(own);
843 if (pp.coupled() && (parallel || !isA<processorPolyPatch>(pp)))
845 label facei = pp.start();
850 const label own = agglom[faceOwner[facei]];
851 const label globalNei = globalNeighbour[bFacei];
855 !globalAgglom.
isLocal(globalNei)
856 || globalAgglom.
toLocal(globalNei) != own
859 const label ownIndex = offsets[own] + nFacesPerCell[own]++;
860 m[ownIndex] = globalNei;
875 if (cellCells.
size() == 0)
883 label startIndex = cellCells.
offsets()[0];
890 const label endIndex = cellCells.
offsets()[celli+1];
892 for (label i = startIndex; i < endIndex; ++i)
894 if (nbrCells.
insert(cellCells.
m()[i]))
896 cellCells.
m()[newIndex] = cellCells.
m()[i];
897 cellCellWeights.
m()[newIndex] = cellCellWeights.
m()[i];
901 startIndex = endIndex;
902 cellCells.
offsets()[celli+1] = newIndex;
903 cellCellWeights.
offsets()[celli+1] = newIndex;
907 cellCellWeights.
m().
setSize(newIndex);
936 if (hasWeights && cellWeights.size() !=
mesh.
nCells())
939 <<
"Number of weights " << cellWeights.size()
940 <<
" differs from number of cells " <<
mesh.
nCells()
945 const bool hasUnblocked =
948 (!blockedFace.empty() && !
BitOps::all(blockedFace)),
956 explicitConnections.size(),
963 for (
const labelList& procset : specifiedProcessorFaces)
965 nProcSets += procset.size();
972 if (!hasUnblocked && !nConnections && !nProcSets)
990 regionSplit localRegion(
mesh, blockedFace, explicitConnections,
false);
995 const label nUnblocked =
1006 Info<<
"Constrained decomposition:" <<
nl
1007 <<
" faces with same owner and neighbour processor : "
1009 <<
" baffle faces with same owner processor : "
1010 << nConnections <<
nl
1011 <<
" faces all on same processor : "
1032 forAll(localRegion, celli)
1034 const label regioni = localRegion[celli];
1036 regionWeights[regioni] += cellWeights[celli];
1046 forAll(localRegion, celli)
1048 const label regioni = localRegion[celli];
1050 regionWeights[regioni] += 1.0;
1073 for (
const labelPair& baffle : explicitConnections)
1075 const label f0 = baffle.first();
1076 const label f1 = baffle.second();
1078 if (!blockedFace[f0] && !blockedFace[f1])
1092 else if (blockedFace[f0] != blockedFace[f1])
1095 <<
"On explicit connection between faces " << f0
1097 <<
" the two blockedFace status are not equal : "
1098 << blockedFace[f0] <<
" and " << blockedFace[f1]
1121 label nUnblocked = 0;
1122 forAll(blockedFace, facei)
1124 if (blockedFace[facei])
1126 faceData[facei] =
minData(-123);
1139 forAll(blockedFace, facei)
1141 if (!blockedFace[facei])
1144 seedFaces[nUnblocked] = facei;
1145 seedData[nUnblocked] =
minData(finalDecomp[own]);
1163 forAll(finalDecomp, celli)
1165 if (cellData[celli].valid(deltaCalc.data()))
1167 finalDecomp[celli] = cellData[celli].data();
1186 forAll(specifiedProcessorFaces, seti)
1188 const labelList& set = specifiedProcessorFaces[seti];
1190 label proci = specifiedProcessor[seti];
1205 for (
const label facei : set)
1208 for (
const label pointi :
f)
1211 for (
const label pFacei :
pFaces)
1236 const label facei = pp.start()+i;
1240 if (!blockedFace[facei])
1242 const label ownProc = finalDecomp[own];
1243 const label nbrProc = nbrDecomp[bFacei];
1245 if (ownProc != nbrProc)
1248 <<
"patch:" << pp.name()
1249 <<
" face:" << facei
1251 <<
" ownProc:" << ownProc
1252 <<
" nbrProc:" << nbrProc
1277 specifiedProcessorFaces.
clear();
1278 explicitConnections.
clear();
1282 decompConstraint.add
1286 specifiedProcessorFaces,
1306 decompConstraint.apply
1310 specifiedProcessorFaces,
1312 explicitConnections,
1335 specifiedProcessorFaces,
1349 specifiedProcessorFaces,
1361 specifiedProcessorFaces,
1363 explicitConnections,