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();
231 const scalar tol = 1E-10;
233 const scalar tol = 0;
238 for (label cellfi=0; cellfi<nFineCells; cellfi++)
241 celli = forward_ ? cellfi : nFineCells - cellfi - 1;
243 if (coarseCellMap[celli] < 0)
245 label matchFaceNo = -1;
246 scalar maxFaceWeight = -GREAT;
251 label faceOs=cellFaceOffsets[celli];
252 faceOs<cellFaceOffsets[celli+1];
256 label facei = cellFaces[faceOs];
262 coarseCellMap[upperAddr[facei]] < 0
263 && coarseCellMap[lowerAddr[facei]] < 0
264 && faceWeights[facei] > maxFaceWeight*(1.0 + tol)
269 maxFaceWeight = faceWeights[facei];
273 if (matchFaceNo >= 0)
276 coarseCellMap[upperAddr[matchFaceNo]] = nCoarseCells;
277 coarseCellMap[lowerAddr[matchFaceNo]] = nCoarseCells;
284 label clusterMatchFaceNo = -1;
285 scalar clusterMaxFaceCoeff = -GREAT;
289 label faceOs=cellFaceOffsets[celli];
290 faceOs<cellFaceOffsets[celli+1];
294 label facei = cellFaces[faceOs];
296 if (faceWeights[facei] > clusterMaxFaceCoeff*(1.0 + tol))
298 clusterMatchFaceNo = facei;
299 clusterMaxFaceCoeff = faceWeights[facei];
303 if (clusterMatchFaceNo >= 0)
306 coarseCellMap[celli] =
max
308 coarseCellMap[upperAddr[clusterMatchFaceNo]],
309 coarseCellMap[lowerAddr[clusterMatchFaceNo]]
318 for (label cellfi=0; cellfi<nFineCells; cellfi++)
321 celli = forward_ ? cellfi : nFineCells - cellfi - 1;
323 if (coarseCellMap[celli] < 0)
325 coarseCellMap[celli] = nCoarseCells;
334 forAll(coarseCellMap, celli)
336 coarseCellMap[celli] = nCoarseCells - coarseCellMap[celli];
344 forward_ = !forward_;
346 return tcoarseCellMap;
bool processorAgglomerate() const
Whether to agglomerate across processors.
void agglomerateLduAddressing(const label fineLevelIndex)
Assemble coarse mesh addressing.
PtrList< labelListList > patchFaceRestrictAddressing_
Patch-local face restriction addressing array.
PtrList< boolList > faceFlipMap_
Face flip: for faces mapped to internal faces stores whether.
PtrList< labelList > nPatchFaces_
The number of (coarse) patch faces in each level.
const label maxLevels_
Max number of levels.
void compactLevels(const label nCreatedLevels, const bool doProcessorAgglomerate)
Shrink the number of levels to that specified. Optionally do.
labelList nFaces_
The number of (coarse) faces in each level.
PtrList< lduPrimitiveMesh > meshLevels_
Hierarchy of mesh addressing.
labelList nCells_
The number of cells in each level.
bool continueAgglomerating(const label nCellsInCoarsestLevel, const label nCells, const label nCoarseCells, const label comm) const
Check the need for further agglomeration.
labelList procCommunicator_
Communicator for given level.
PtrList< labelList > agglomProcIDs_
Per level the set of processors to agglomerate. Element 0 is.
void restrictFaceField(Field< Type > &cf, const Field< Type > &ff, const label fineLevelIndex) const
Restrict (integrate by summation) face field.
PtrList< labelList > procAgglomMap_
Per level, per processor the processor it agglomerates into.
PtrList< labelListList > procBoundaryMap_
Mapping from processor to procMeshLevel boundary.
void combineLevels(const label curLevel)
Combine a level with the previous one.
PtrList< labelList > procCellOffsets_
Mapping from processor to procMeshLevel cells.
PtrList< labelField > restrictAddressing_
Cell restriction addressing array.
PtrList< labelListList > procFaceMap_
Mapping from processor to procMeshLevel face.
PtrList< labelList > faceRestrictAddressing_
Face restriction addressing array.
bool hasMeshLevel(const label leveli) const
Do we have mesh for given level?
const lduMesh & meshLevel(const label leveli) const
Return LDU mesh of given level.
PtrList< labelListListList > procBoundaryFaceMap_
Mapping from processor to procMeshLevel boundary face.
void size(const label n)
Older name for setAddressableSize.
The class contains the addressing required by the lduMatrix: upper, lower and losort.
virtual const labelUList & upperAddr() const =0
Return upper addressing.
virtual const labelUList & lowerAddr() const =0
Return lower addressing.
label size() const noexcept
Return number of equations.
static tmp< labelField > agglomerate(label &nCoarseCells, const lduAddressing &fineMatrixAddressing, const scalarField &faceWeights)
Calculate and return agglomeration.
A class for managing temporary objects.
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
List< label > labelList
A List of labels.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
static constexpr const zero Zero
Global zero (0).
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
errorManipArg< error, int > exit(error &err, const int errNo=1)
UList< label > labelUList
A UList of labels.
#define forAll(list, i)
Loop across all elements in list.