36void Foam::pairPatchAgglomeration::compactLevels(
const label nCreatedLevels)
44bool Foam::pairPatchAgglomeration::continueAgglomerating
56 label nGlobalOld =
returnReduce(nLocalOld, sumOp<label>());
60 returnReduce(nLocal > nFacesInCoarsestLevel_, orOp<bool>())
61 || nGlobal > nGlobalFacesInCoarsestLevel_
63 && nGlobal != nGlobalOld;
67void 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]),
120void 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]),
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();
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];
292void Foam::pairPatchAgglomeration::mapBaseToTopAgglom
294 const label fineLevelIndex
297 const labelList& fineToCoarse = restrictAddressing_[fineLevelIndex];
298 forAll(restrictTopBottomAddressing_, i)
300 restrictTopBottomAddressing_[i] =
301 fineToCoarse[restrictTopBottomAddressing_[i]];
306bool 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();
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;
575void 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));
void setSize(const label n)
Alias for resize()
A list of faces which address into the list of points.
void size(const label n)
Older name for setAddressableSize.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Primitive patch pair agglomerate method.
~pairPatchAgglomeration()
PtrList< bPatch > patchLevels_
Hierarchy of patch addressing.
labelList nFaces_
The number of faces in each level.
const bPatch & patchLevel(const label leveli) const
Return primitivePatch of given level.
void agglomerate()
Agglomerate patch.
PtrList< labelField > restrictAddressing_
Cell restriction addressing array.
PrimitivePatch< List< face >, const pointField > bPatch
A class for managing temporary objects.
runTime controlDict().readEntry("adjustTimeStep"
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const std::string patch
OpenFOAM patch number as a std::string.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
List< label > labelList
A List of labels.
IntListType renumber(const labelUList &oldToNew, const IntListType &input)
Renumber the values (not the indices) of a list.
Ostream & endl(Ostream &os)
Add newline and flush stream.
constexpr scalar degToRad() noexcept
Multiplication factor for degrees to radians conversion.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
List< labelList > labelListList
A List of labelList.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
errorManip< error > abort(error &err)
Field< label > labelField
Specialisation of Field<T> for label.
HashSet< edge, Hash< edge > > edgeHashSet
A HashSet with edge for its key.
PrimitivePatch<::Foam::List< face >, const pointField > bPatch
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce (copy) and return value.
labelListList invertOneToMany(const label len, const labelUList &map)
Invert one-to-many map. Unmapped elements will be size 0.
PrimitivePatch< IndirectList< face >, const pointField & > indirectPrimitivePatch
A PrimitivePatch with an IndirectList for the faces, const reference for the point field.
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensionedScalar cos(const dimensionedScalar &ds)
#define forAll(list, i)
Loop across all elements in list.
#define forAllConstIters(container, iter)
Iterate across all elements of the container object with const access.
Unit conversion functions.