67 doRenumber_(
controlDict.getOrDefault<bool>(
"renumber", false)),
68 forceConnected_(
controlDict.getOrDefault<bool>(
"forceConnected", true)),
76 clusterSize_(decomposerPtr_().nDomains()),
99 doRenumber_(
controlDict.getOrDefault<bool>(
"renumber", false)),
100 forceConnected_(
controlDict.getOrDefault<bool>(
"forceConnected", true)),
108 clusterSize_(decomposerPtr_().nDomains()),
123bool Foam::decompositionGAMGAgglomeration::checkRestriction
127 const lduAddressing& fineAddressing,
138 if (fineAddressing.size() != restriction.size())
141 <<
"nCells:" << fineAddressing.size()
142 <<
" agglom:" << restriction.size()
162 const label own =
lower[facei];
163 const label nei =
upper[facei];
165 if (restriction[own] == restriction[nei])
169 if (master[own] < master[nei])
171 master[nei] = master[own];
174 else if (master[own] > master[nei])
176 master[own] = master[nei];
191 labelList oldToNewRegion(restriction.size(), -1);
192 labelList masterToRegion(restriction.size(), -1);
194 forAll(restriction, celli)
196 if (master[celli] == celli)
199 masterToRegion[celli] = nNewCoarse++;
200 const label oldRegion = restriction[celli];
201 oldToNewRegion[oldRegion] = masterToRegion[celli];
204 if (nNewCoarse != nCoarse)
214Foam::bitSet Foam::decompositionGAMGAgglomeration::blockedFaces
226 isBlockedFace[facei] = (region[own[facei]] != region[nbr[facei]]);
234 const lduAddressing& addr,
236 CompactListList<label>& cellCells
255 cellCells.resize_nocopy(nNbrs);
257 auto&
values = cellCells.values();
258 auto& offsets = cellCells.offsets();
266 const label
n = nbr[facei];
267 const label o = own[facei];
268 values[offsets[
n]+(nNbrs[
n]++)] = o;
269 values[offsets[o]+(nNbrs[o]++)] =
n;
286 if (regions.size() != addr.size())
296 if (regions[i] == regioni)
298 oldToNew[i] = nCells++;
305 const label
n = oldToNew[nbr[facei]];
306 const label o = oldToNew[own[facei]];
307 if (
n != -1 && o != -1)
315 cellCells.resize_nocopy(nNbrs);
317 auto&
values = cellCells.values();
318 const auto& offsets = cellCells.offsets();
324 const label
n = oldToNew[nbr[facei]];
325 const label o = oldToNew[own[facei]];
326 if (
n != -1 && o != -1)
328 values[offsets[
n]+(nNbrs[
n]++)] = o;
329 values[offsets[o]+(nNbrs[o]++)] =
n;
336void Foam::decompositionGAMGAgglomeration::coarseCellCells
346 const label nCoarse =
max(regions)+1;
351 const label
n = regions[nbr[facei]];
352 const label o = regions[own[facei]];
360 cellCells.resize_nocopy(nNbrs);
362 auto&
values = cellCells.values();
363 const auto& offsets = cellCells.offsets();
369 const label
n = regions[nbr[facei]];
370 const label o = regions[own[facei]];
373 values[offsets[
n]+(nNbrs[
n]++)] = o;
374 values[offsets[o]+(nNbrs[o]++)] =
n;
380Foam::tmp<Foam::labelField> Foam::decompositionGAMGAgglomeration::agglomerate
382 const bool partByPart,
383 const label nCoarseCells,
400 const label nRegions =
max(region) + 1;
403 auto& agglom = tagglom.ref();
411 for (label regioni = 0; regioni < nRegions; regioni++)
425 auto cc(avg(cellCentres, cellCells.size(), oldToNew));
426 decomposer.nDomains(nCoarseCells);
428 const label nRegionCells = cellCells.size();
430 if (nRegionCells >= 2*nCoarseCells)
432 cellToProc = decomposer.decompose(cellCells, cc);
441 static label fallBackCell = 0;
442 cellToProc.resize_nocopy(nRegionCells);
443 cellToProc = fallBackCell;
444 fallBackCell = ((fallBackCell +1) % nCoarseCells);
451 const label compactCelli = oldToNew[celli];
452 if (compactCelli != -1)
455 regioni*nCoarseCells + cellToProc[compactCelli];
468 decomposer.nDomains(nCoarseCells);
470 agglom = decomposer.decompose
480 label nAgglom =
max(agglom)+1;
484 const bool ok = checkRestriction
496 <<
"Extending agglomeration from:" << nAgglom <<
" to:"
497 << nNewAgglom <<
endl;
498 agglom = std::move(newAgglom);
503 if (nNewAgglom > nAgglom)
509 <<
"When splitting coarse mesh into " << nAgglom
510 <<
" cells created " << nNewAgglom
511 <<
" disconnected domains." <<
nl
512 <<
" This might give numerical problems. Either choose"
513 <<
" a decomposition method that guarantees a single domain"
514 <<
" or keep the result of the decomposition by setting"
515 <<
" 'forceConnected' to false" <<
nl
516 <<
" Disabling further warnings."
527 coarseCellCells(addr, agglom, cellCells);
532 agglom[celli] = oldToNew[agglom[celli]];
540void Foam::decompositionGAMGAgglomeration::agglomerate
542 const label nCellsInCoarsestLevel,
543 const label startLevel,
547 const bool doProcessorAgglomerate
553 if (nCells_.size() < maxLevels_)
556 nCells_.resize(maxLevels_);
557 restrictAddressing_.resize(maxLevels_);
558 nFaces_.resize(maxLevels_);
559 faceRestrictAddressing_.resize(maxLevels_);
560 faceFlipMap_.resize(maxLevels_);
561 nPatchFaces_.resize(maxLevels_);
562 patchFaceRestrictAddressing_.resize(maxLevels_);
563 meshLevels_.resize(maxLevels_);
566 procCommunicator_.resize(maxLevels_ + 1, -1);
567 if (processorAgglomerate())
569 procAgglomMap_.resize(maxLevels_);
570 agglomProcIDs_.resize(maxLevels_);
571 procCommunicator_.resize(maxLevels_);
572 procCellOffsets_.resize(maxLevels_);
573 procFaceMap_.resize(maxLevels_);
574 procBoundaryMap_.resize(maxLevels_);
575 procBoundaryFaceMap_.resize(maxLevels_);
579 const auto& startMesh = meshLevel(startLevel);
592 cellCentres = startMeshPtr->cellCentres();
593 cellWeights = startMeshPtr->cellVolumes();
606 label nCoarsestCells = startAddr.size();
607 while (nCoarsestCells/clusterSize_ >= nCellsInCoarsestLevel)
609 nCoarsestCells /= clusterSize_;
612 <<
"Doing coarsest:" << nCoarsestCells
613 <<
" instead of:" << startAddr.size()
642 startAgglomeration.append(std::move(fineToCoarsest));
645 while (startAgglomeration.size() < maxLevels_)
647 const label nFineCells =
max(startAgglomeration.last())+1;
655 nFineCells >= startAddr.size()/(2*clusterSize_),
678 startAgglomeration.last()
692 startAgglomeration.append(fineToCoarse);
701 label nCreatedLevels = startLevel;
703 forAll(startAgglomeration, i)
705 if (!hasMeshLevel(nCreatedLevels))
712 const auto& fineMesh = meshLevel(nCreatedLevels);
717 const auto& startToCoarse = startAgglomeration[i];
718 const label nCoarseCells =
max(startToCoarse)+1;
720 auto& finalAgglom = tfinalAgglomPtr.ref();
723 finalAgglom = startToCoarse;
729 const auto& startToPrev = startAgglomeration[i-1];
732 nCells_[nCreatedLevels] = nCoarseCells;
733 restrictAddressing_.set(nCreatedLevels, tfinalAgglomPtr);
736 agglomerateLduAddressing(nCreatedLevels);
760 compactLevels(nCreatedLevels, doProcessorAgglomerate);
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
The bandCompression function renumbers the addressing such that the band of the matrix is reduced....
A packed storage of objects of type <T> using an offset table for access.
void resize_nocopy(const label mRows, const label nVals)
Redimension without preserving existing content.
const labelList & offsets() const noexcept
Return the offset table (= size()+1).
const List< T > & values() const noexcept
Return the packed values.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
void append(const T &val)
Copy append an element to the end of this list.
Geometric agglomerated algebraic multigrid agglomeration class.
bool processorAgglomerate() const
Whether to agglomerate across processors.
static const GAMGAgglomeration & New(const lduMesh &mesh, const dictionary &controlDict)
Return the selected geometric agglomerator.
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.
label nCellsInCoarsestLevel_
Number of cells in coarsest level.
labelList nFaces_
The number of (coarse) faces in each level.
PtrList< lduPrimitiveMesh > meshLevels_
Hierarchy of mesh addressing.
GAMGAgglomeration(const GAMGAgglomeration &)=delete
No copy construct.
labelList nCells_
The number of cells in each level.
labelList procCommunicator_
Communicator for given level.
PtrList< labelList > agglomProcIDs_
Per level the set of processors to agglomerate. Element 0 is.
PtrList< labelList > procAgglomMap_
Per level, per processor the processor it agglomerates into.
PtrList< labelListList > procBoundaryMap_
Mapping from processor to procMeshLevel boundary.
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?
label nCells(const label leveli) const
Return number of coarse cells (before processor agglomeration).
const lduMesh & meshLevel(const label leveli) const
Return LDU mesh of given level.
PtrList< labelListListList > procBoundaryFaceMap_
Mapping from processor to procMeshLevel boundary face.
const lduMesh & mesh() const noexcept
A List with indirect addressing. Like IndirectList but does not store addressing.
void size(const label n)
Older name for setAddressableSize.
T & last()
Access last element of the list, position [size()-1].
static bool parRun(const bool on) noexcept
Set as parallel run on/off.
static int & msgType() noexcept
Message tag of standard messages.
static bool & parRun() noexcept
Test if this a parallel run.
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Agglomerate using the decomposition algorithm.
decompositionGAMGAgglomeration(const lduMesh &mesh, const dictionary &controlDict)
Construct given mesh and controls.
static void localCellCells(const lduAddressing &addr, const bitSet &isBlockedFace, CompactListList< label > &cellCells)
Abstract base class for domain decomposition.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
virtual const lduAddressing & lduAddr() const
Return ldu addressing.
virtual label comm() const
Return communicator used for parallel communication.
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.
Abstract base class for meshes which provide LDU addressing for the construction of lduMatrix and LDU...
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
runTime controlDict().readEntry("adjustTimeStep"
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const bitSet isBlockedFace(intersectedFaces())
#define DebugInfo
Report an information message using Foam::Info.
#define WarningInFunction
Report a warning using Foam::Warning.
#define DebugPout
Report an information message using Foam::Pout.
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
string upper(const std::string &s)
Return string copy transformed with std::toupper on each character.
string lower(const std::string &s)
Return string copy transformed with std::tolower on each character.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh > > &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
List< label > labelList
A List of labels.
void reverse(UList< T > &list, const label n)
Reverse the first n elements of the list.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Ostream & endl(Ostream &os)
Add newline and flush stream.
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
void reduce(T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce).
bool returnReduceAnd(const bool value, const int communicator=UPstream::worldComm)
Perform logical (and) MPI Allreduce on a copy. Uses UPstream::reduceAnd.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
errorManip< error > abort(error &err)
Field< vector > vectorField
Specialisation of Field<T> for vector.
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...
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
vectorField pointField
pointField is a vectorField.
errorManipArg< error, int > exit(error &err, const int errNo=1)
UList< label > labelUList
A UList of labels.
constexpr char nl
The newline '\n' character (0x0a).
#define forAll(list, i)
Loop across all elements in list.