36 const label nCellsInCoarsestLevel,
37 const label startLevel,
39 const bool doProcessorAgglomerate
75 label nPairLevels = 0;
76 label nCreatedLevels = startLevel;
87 const auto& fineMesh =
meshLevel(nCreatedLevels);
90 label nCoarseCells = -1;
103 nCellsInCoarsestLevel,
104 finalAgglomPtr().
size(),
110 nCells_[nCreatedLevels] = nCoarseCells;
136 faceWeights = std::move(aggFaceWeights);
139 if (nPairLevels % mergeLevels_)
165 const label nFineCells = fineMatrixAddressing.
size();
172 labelList cellFaceOffsets(nFineCells + 1);
180 nNbrs[upperAddr[facei]]++;
185 nNbrs[lowerAddr[facei]]++;
188 cellFaceOffsets[0] = 0;
191 cellFaceOffsets[celli+1] = cellFaceOffsets[celli] + nNbrs[celli];
201 cellFaceOffsets[upperAddr[facei]] + nNbrs[upperAddr[facei]]
204 nNbrs[upperAddr[facei]]++;
211 cellFaceOffsets[lowerAddr[facei]] + nNbrs[lowerAddr[facei]]
214 nNbrs[lowerAddr[facei]]++;
222 auto& coarseCellMap = tcoarseCellMap.ref();
227 for (label cellfi=0; cellfi<nFineCells; cellfi++)
230 celli = forward_ ? cellfi : nFineCells - cellfi - 1;
232 if (coarseCellMap[celli] < 0)
234 label matchFaceNo = -1;
235 scalar maxFaceWeight = -GREAT;
240 label faceOs=cellFaceOffsets[celli];
241 faceOs<cellFaceOffsets[celli+1];
245 label facei = cellFaces[faceOs];
251 coarseCellMap[upperAddr[facei]] < 0
252 && coarseCellMap[lowerAddr[facei]] < 0
253 && faceWeights[facei] > maxFaceWeight
258 maxFaceWeight = faceWeights[facei];
262 if (matchFaceNo >= 0)
265 coarseCellMap[upperAddr[matchFaceNo]] = nCoarseCells;
266 coarseCellMap[lowerAddr[matchFaceNo]] = nCoarseCells;
273 label clusterMatchFaceNo = -1;
274 scalar clusterMaxFaceCoeff = -GREAT;
278 label faceOs=cellFaceOffsets[celli];
279 faceOs<cellFaceOffsets[celli+1];
283 label facei = cellFaces[faceOs];
285 if (faceWeights[facei] > clusterMaxFaceCoeff)
287 clusterMatchFaceNo = facei;
288 clusterMaxFaceCoeff = faceWeights[facei];
292 if (clusterMatchFaceNo >= 0)
295 coarseCellMap[celli] =
max 297 coarseCellMap[upperAddr[clusterMatchFaceNo]],
298 coarseCellMap[lowerAddr[clusterMatchFaceNo]]
307 for (label cellfi=0; cellfi<nFineCells; cellfi++)
310 celli = forward_ ? cellfi : nFineCells - cellfi - 1;
312 if (coarseCellMap[celli] < 0)
314 coarseCellMap[celli] = nCoarseCells;
323 forAll(coarseCellMap, celli)
325 coarseCellMap[celli] = nCoarseCells - coarseCellMap[celli];
333 forward_ = !forward_;
335 return tcoarseCellMap;
PtrList< labelListList > procBoundaryMap_
Mapping from processor to procMeshLevel boundary.
void size(const label n)
Older name for setAddressableSize.
bool continueAgglomerating(const label nCellsInCoarsestLevel, const label nCells, const label nCoarseCells, const label comm) const
Check the need for further agglomeration.
PtrList< labelListList > procFaceMap_
Mapping from processor to procMeshLevel face.
PtrList< labelListList > patchFaceRestrictAddressing_
Patch-local face restriction addressing array.
errorManipArg< error, int > exit(error &err, const int errNo=1)
void resize(const label len)
Adjust allocated size of list.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
PtrList< labelListListList > procBoundaryFaceMap_
Mapping from processor to procMeshLevel boundary face.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const lduMesh & meshLevel(const label leveli) const
Return LDU mesh of given level.
PtrList< labelList > procCellOffsets_
Mapping from processor to procMeshLevel cells.
void restrictFaceField(Field< Type > &cf, const Field< Type > &ff, const label fineLevelIndex) const
Restrict (integrate by summation) face field.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
PtrList< labelList > faceRestrictAddressing_
Face restriction addressing array.
PtrList< labelList > nPatchFaces_
The number of (coarse) patch faces in each level.
virtual const labelUList & lowerAddr() const =0
Return lower addressing.
PtrList< labelList > agglomProcIDs_
Per level the set of processors to agglomerate. Element 0 is.
#define forAll(list, i)
Loop across all elements in list.
static tmp< labelField > agglomerate(label &nCoarseCells, const lduAddressing &fineMatrixAddressing, const scalarField &faceWeights)
Calculate and return agglomeration.
labelList procCommunicator_
Communicator for given level.
label size() const noexcept
Return number of equations.
bool processorAgglomerate() const
Whether to agglomerate across processors.
PtrList< lduPrimitiveMesh > meshLevels_
Hierarchy of mesh addressing.
virtual const labelUList & upperAddr() const =0
Return upper addressing.
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
labelList nCells_
The number of cells in each level.
labelList nFaces_
The number of (coarse) faces in each level.
PtrList< labelField > restrictAddressing_
Cell restriction addressing array.
void agglomerateLduAddressing(const label fineLevelIndex)
Assemble coarse mesh addressing.
const label maxLevels_
Max number of levels.
PtrList< labelList > procAgglomMap_
Per level, per processor the processor it agglomerates into.
The class contains the addressing required by the lduMatrix: upper, lower and losort.
PtrList< boolList > faceFlipMap_
Face flip: for faces mapped to internal faces stores whether.
A class for managing temporary objects.
bool hasMeshLevel(const label leveli) const
Do we have mesh for given level?
void combineLevels(const label curLevel)
Combine a level with the previous one.
void compactLevels(const label nCreatedLevels, const bool doProcessorAgglomerate)
Shrink the number of levels to that specified. Optionally do.
static constexpr const zero Zero
Global zero (0)