36 void Foam::pairPatchAgglomeration::compactLevels(
const label nCreatedLevels)
44 bool Foam::pairPatchAgglomeration::continueAgglomerating
56 label nGlobalOld =
returnReduce(nLocalOld, sumOp<label>());
60 returnReduce(nLocal > nFacesInCoarsestLevel_, orOp<bool>())
61 || nGlobal > nGlobalFacesInCoarsestLevel_
63 && nGlobal != nGlobalOld;
67 void Foam::pairPatchAgglomeration::setLevel0EdgeWeights()
69 const bPatch& coarsePatch = patchLevels_[0];
70 forAll(coarsePatch.edges(), i)
72 if (coarsePatch.isInternalEdge(i))
75 coarsePatch.edges()[i].mag(coarsePatch.localPoints());
77 const labelList& eFaces = coarsePatch.edgeFaces()[i];
79 if (eFaces.size() == 2)
82 coarsePatch.faceNormals()[eFaces[0]]
83 & coarsePatch.faceNormals()[eFaces[1]];
85 const edge edgeCommon = edge(eFaces[0], eFaces[1]);
87 if (facePairWeight_.found(edgeCommon))
89 facePairWeight_[edgeCommon] += edgeLength;
93 facePairWeight_.insert(edgeCommon, edgeLength);
98 facePairWeight_[edgeCommon] = -1.0;
105 for (label
k = j+1;
k<eFaces.size();
k++)
107 facePairWeight_.insert
109 edge(eFaces[j], eFaces[
k]),
120 void Foam::pairPatchAgglomeration::setEdgeWeights
122 const label fineLevelIndex
125 const bPatch& coarsePatch = patchLevels_[fineLevelIndex];
126 const labelList& fineToCoarse = restrictAddressing_[fineLevelIndex];
127 const label nCoarseI =
max(fineToCoarse) + 1;
130 edgeHashSet fineFeaturedFaces(coarsePatch.nEdges()/10);
137 const edge
e = iter.key();
138 const edge edgeFeatured
143 fineFeaturedFaces.insert(edgeFeatured);
148 facePairWeight_.clear();
149 facePairWeight_.resize(coarsePatch.nEdges());
151 forAll(coarsePatch.edges(), i)
153 if (coarsePatch.isInternalEdge(i))
156 coarsePatch.edges()[i].mag(coarsePatch.localPoints());
158 const labelList& eFaces = coarsePatch.edgeFaces()[i];
160 if (eFaces.size() == 2)
162 const edge edgeCommon = edge(eFaces[0], eFaces[1]);
163 if (facePairWeight_.found(edgeCommon))
165 facePairWeight_[edgeCommon] += edgeLength;
169 facePairWeight_.insert(edgeCommon, edgeLength);
173 if (fineFeaturedFaces.found(edgeCommon))
175 facePairWeight_[edgeCommon] = -1.0;
183 for (label
k = j+1;
k<eFaces.size();
k++)
185 facePairWeight_.insert
187 edge(eFaces[j], eFaces[
k]),
200 Foam::pairPatchAgglomeration::pairPatchAgglomeration
212 nFacesInCoarsestLevel_
216 nGlobalFacesInCoarsestLevel_(
labelMax),
222 controlDict.getOrDefault<scalar>(
"featureAngle", 0)
225 restrictAddressing_(maxLevels_),
226 restrictTopBottomAddressing_(
identity(faces.size())),
227 patchLevels_(maxLevels_),
228 facePairWeight_(faces.size())
237 setLevel0EdgeWeights();
241 Foam::pairPatchAgglomeration::pairPatchAgglomeration
245 const label mergeLevels,
246 const label maxLevels,
247 const label nFacesInCoarsestLevel,
248 const label nGlobalFacesInCoarsestLevel,
249 const scalar featureAngle
252 mergeLevels_(mergeLevels),
253 maxLevels_(maxLevels),
254 nFacesInCoarsestLevel_(nFacesInCoarsestLevel),
255 nGlobalFacesInCoarsestLevel_(nGlobalFacesInCoarsestLevel),
256 featureAngle_(featureAngle),
258 restrictAddressing_(maxLevels_),
259 restrictTopBottomAddressing_(
identity(faces.size())),
260 patchLevels_(maxLevels_),
261 facePairWeight_(faces.size())
270 setLevel0EdgeWeights();
288 return patchLevels_[i];
292 void Foam::pairPatchAgglomeration::mapBaseToTopAgglom
294 const label fineLevelIndex
297 const labelList& fineToCoarse = restrictAddressing_[fineLevelIndex];
298 forAll(restrictTopBottomAddressing_, i)
300 restrictTopBottomAddressing_[i] =
301 fineToCoarse[restrictTopBottomAddressing_[i]];
306 bool Foam::pairPatchAgglomeration::agglomeratePatch
310 const label fineLevelIndex
313 if (
min(fineToCoarse) == -1)
319 if (fineToCoarse.size() == 0)
324 if (fineToCoarse.size() !=
patch.size())
327 <<
"restrict map does not correspond to fine level. " <<
endl
328 <<
" Sizes: restrictMap: " << fineToCoarse.size()
329 <<
" nEqns: " <<
patch.size()
333 const label nCoarseI =
max(fineToCoarse) + 1;
334 List<face> patchFaces(nCoarseI);
340 for (label coarseI = 0; coarseI < nCoarseI; coarseI++)
342 const labelList& fineFaces = coarseToFine[coarseI];
347 IndirectList<face>(
patch, fineFaces),
351 if (upp.edgeLoops().size() != 1)
353 if (fineFaces.size() == 2)
355 const edge
e(fineFaces[0], fineFaces[1]);
356 facePairWeight_[
e] = -1.0;
358 else if (fineFaces.size() == 3)
360 const edge
e(fineFaces[0], fineFaces[1]);
361 const edge e1(fineFaces[0], fineFaces[2]);
362 const edge e2(fineFaces[2], fineFaces[1]);
363 facePairWeight_[
e] = -1.0;
364 facePairWeight_[e1] = -1.0;
365 facePairWeight_[e2] = -1.0;
370 patchFaces[coarseI] = face
385 SubList<face>(patchFaces, nCoarseI, 0),
396 label nPairLevels = 0;
397 label nCreatedLevels = 1;
399 label nCoarseFaces = 0;
400 label nCoarseFacesOld = 0;
402 while (nCreatedLevels < maxLevels_)
404 const bPatch&
patch = patchLevels_[nCreatedLevels - 1];
409 bool createdLevel =
false;
410 while (!createdLevel)
414 tfinalAgglom = agglomerateOneLevel(nCoarseFaces,
patch);
416 if (nCoarseFaces == 0)
425 createdLevel = agglomeratePatch
436 restrictAddressing_.set(nCreatedLevels, tfinalAgglom);
438 mapBaseToTopAgglom(nCreatedLevels);
440 setEdgeWeights(nCreatedLevels);
442 if (nPairLevels % mergeLevels_)
444 combineLevels(nCreatedLevels);
453 nFaces_[nCreatedLevels] = nCoarseFaces;
458 if (!continueAgglomerating(nCoarseFaces, nCoarseFacesOld))
463 nCoarseFacesOld = nCoarseFaces;
466 compactLevels(nCreatedLevels);
476 const label nFineFaces =
patch.size();
478 tmp<labelField> tcoarseCellMap(
new labelField(nFineFaces, -1));
479 labelField& coarseCellMap = tcoarseCellMap.ref();
487 const labelList& fFaces = faceFaces[facei];
489 if (coarseCellMap[facei] < 0)
491 label matchFaceNo = -1;
492 label matchFaceNeibNo = -1;
493 scalar maxFaceWeight = -GREAT;
498 label faceNeig = fFaces[i];
499 const edge edgeCommon = edge(facei, faceNeig);
502 facePairWeight_[edgeCommon] > maxFaceWeight
503 && coarseCellMap[faceNeig] < 0
504 && facePairWeight_[edgeCommon] != -1.0
509 matchFaceNeibNo = faceNeig;
510 maxFaceWeight = facePairWeight_[edgeCommon];
514 if (matchFaceNo >= 0)
517 coarseCellMap[matchFaceNo] = nCoarseFaces;
518 coarseCellMap[matchFaceNeibNo] = nCoarseFaces;
525 label clusterMatchFaceNo = -1;
526 scalar clusterMaxFaceCoeff = -GREAT;
530 label faceNeig = fFaces[i];
531 const edge edgeCommon = edge(facei, faceNeig);
534 facePairWeight_[edgeCommon] > clusterMaxFaceCoeff
535 && facePairWeight_[edgeCommon] != -1.0
536 && coarseCellMap[faceNeig] >= 0
539 clusterMatchFaceNo = faceNeig;
540 clusterMaxFaceCoeff = facePairWeight_[edgeCommon];
544 if (clusterMatchFaceNo > 0)
547 coarseCellMap[facei] = coarseCellMap[clusterMatchFaceNo];
552 coarseCellMap[facei] = nCoarseFaces;
560 for (label facei=0; facei<nFineFaces; facei++)
562 if (coarseCellMap[facei] < 0)
566 <<
" is not part of a cluster"
571 return tcoarseCellMap;
575 void Foam::pairPatchAgglomeration::combineLevels(
const label curLevel)
577 label prevLevel = curLevel - 1;
580 nFaces_[prevLevel] = nFaces_[curLevel];
585 const labelList& curResAddr = restrictAddressing_[curLevel];
586 labelList& prevResAddr = restrictAddressing_[prevLevel];
590 prevResAddr[i] = curResAddr[prevResAddr[i]];
594 restrictAddressing_.set(curLevel,
nullptr);
596 patchLevels_.set(prevLevel, patchLevels_.set(curLevel,
nullptr));