53 const label nCreatedLevels,
54 const bool doProcessorAgglomerate
85 Info<<
"GAMGAgglomeration:" <<
nl 86 <<
" local agglomerator : " <<
type() <<
nl;
87 if (processorAgglomerate())
89 Info<<
" processor agglomerator : " 90 << procAgglomeratorPtr_().type() <<
nl 95 <<
setw(20) <<
"nFaces/nCells" 96 <<
setw(20) <<
"nInterfaces" 97 <<
setw(20) <<
"nIntFaces/nCells" 98 <<
setw(12) <<
"profile" 100 <<
setw(8) <<
"Level" 101 <<
setw(8) <<
"nProcs" 117 <<
setw(8) <<
"-----" 118 <<
setw(8) <<
"------" 136 const label maxSize =
returnReduce(size(), maxOp<label>());
138 for (label levelI = 0; levelI <= maxSize; levelI++)
142 scalar faceCellRatio = 0;
143 label nInterfaces = 0;
146 scalar profile = 0.0;
148 if (hasMeshLevel(levelI))
152 const lduMesh& fineMesh = meshLevel(levelI);
153 nCells = fineMesh.lduAddr().size();
155 scalar(fineMesh.lduAddr().lowerAddr().size())/nCells;
158 fineMesh.interfaces();
161 if (interfaces.set(i))
164 nIntFaces += interfaces[i].faceCells().size();
167 ratio = scalar(nIntFaces)/nCells;
169 profile = fineMesh.lduAddr().band().second();
177 scalar maxFaceCellRatio =
179 scalar totFaceCellRatio =
182 label maxNInt =
returnReduce(nInterfaces, maxOp<label>());
183 label totNInt =
returnReduce(nInterfaces, sumOp<label>());
188 scalar totProfile =
returnReduce(profile, sumOp<scalar>());
193 <<
setw(8) << totNprocs
195 <<
setw(8) << totNCells/totNprocs
196 <<
setw(8) << maxNCells
198 <<
setw(8) << totFaceCellRatio/totNprocs
199 <<
setw(8) << maxFaceCellRatio
201 <<
setw(8) << scalar(totNInt)/totNprocs
202 <<
setw(8) << maxNInt
204 <<
setw(8) << totRatio/totNprocs
205 <<
setw(8) << maxRatio
206 <<
setw(12) << totProfile/totNprocs
217 const label nCellsInCoarsestLevel,
218 const label nFineCells,
219 const label nCoarseCells,
223 const label nTotalCoarseCells =
231 const label nTotalFineCells =
233 return nTotalCoarseCells < nTotalFineCells;
251 GAMGAgglomeration::typeName
258 updateInterval_(
controlDict.getOrDefault<label>(
"updateInterval", 1)),
259 requireUpdate_(false),
261 nCellsInCoarsestLevel_
263 controlDict.getOrDefault<label>(
"nCellsInCoarsestLevel", 10)
265 meshInterfaces_(
mesh.interfaces()),
269 (UPstream::nProcs(
mesh.comm()) > 1)
272 ? GAMGProcAgglomeration::
New 278 : autoPtr<GAMGProcAgglomeration>()
282 restrictAddressing_(maxLevels_),
284 faceRestrictAddressing_(maxLevels_),
285 faceFlipMap_(maxLevels_),
286 nPatchFaces_(maxLevels_),
287 patchFaceRestrictAddressing_(maxLevels_),
289 meshLevels_(maxLevels_)
322 const GAMGAgglomeration* agglomPtr =
328 GAMGAgglomeration::typeName
334 if (agglomPtr->requireUpdate_)
344 const word agglomeratorType
346 controlDict.getOrDefault<word>(
"agglomerator",
"faceAreaPair")
352 "geometricGAMGAgglomerationLibs",
353 lduMeshConstructorTablePtr_
356 auto* ctorPtr = lduMeshConstructorTable(agglomeratorType);
361 <<
"Unknown GAMGAgglomeration type " 362 << agglomeratorType <<
".\n" 363 <<
"Valid matrix GAMGAgglomeration types :" 364 << lduMatrixConstructorTablePtr_->sortedToc() <<
endl 365 <<
"Valid geometric GAMGAgglomeration types :" 366 << lduMeshConstructorTablePtr_->sortedToc()
373 agglomPtr().printLevels();
382 const lduMatrix& matrix,
386 const lduMesh&
mesh = matrix.mesh();
388 const GAMGAgglomeration* agglomPtr =
394 GAMGAgglomeration::typeName
400 if (agglomPtr->requireUpdate_)
410 const word agglomeratorType
412 controlDict.getOrDefault<word>(
"agglomerator",
"faceAreaPair")
418 "algebraicGAMGAgglomerationLibs",
419 lduMatrixConstructorTablePtr_
422 auto* ctorPtr = lduMatrixConstructorTable(agglomeratorType);
433 agglomPtr().printLevels();
450 const GAMGAgglomeration* agglomPtr =
456 GAMGAgglomeration::typeName
462 if (agglomPtr->requireUpdate_)
472 const word agglomeratorType
474 controlDict.getOrDefault<word>(
"agglomerator",
"faceAreaPair")
480 "geometricGAMGAgglomerationLibs",
481 geometryConstructorTablePtr_
484 auto* ctorPtr = geometryConstructorTable(agglomeratorType);
489 <<
"Unknown GAMGAgglomeration type " 490 << agglomeratorType <<
".\n" 491 <<
"Valid geometric GAMGAgglomeration types :" 492 << geometryConstructorTablePtr_->sortedToc()
508 agglomPtr().printLevels();
526 (updateInterval_ > 0)
527 && ((mesh_.thisDb().time().timeIndex() % updateInterval_) == 0);
533 if (requiresUpdate())
535 requireUpdate_ =
true;
538 return requireUpdate_;
553 return meshLevels_[i - 1];
566 return meshLevels_.set(i - 1);
578 return meshInterfaces_;
582 return meshLevels_[i - 1].rawInterfaces();
591 meshLevels_.set(i - 1,
nullptr);
593 if (i < nCells_.size())
596 restrictAddressing_.set(i,
nullptr);
598 faceRestrictAddressing_.set(i,
nullptr);
599 faceFlipMap_.set(i,
nullptr);
600 nPatchFaces_.set(i,
nullptr);
601 patchFaceRestrictAddressing_.set(i,
nullptr);
612 return procAgglomMap_[leveli];
621 return agglomProcIDs_[leveli];
627 return procCommunicator_[leveli] != -1;
633 return procCommunicator_[leveli];
639 return procAgglomCommunicator_[leveli];
648 return procCellOffsets_[leveli];
657 return procFaceMap_[leveli];
666 return procBoundaryMap_[leveli];
675 return procBoundaryFaceMap_[leveli];
688 if (fineAddressing.
size() != restriction.
size())
691 <<
"nCells:" << fineAddressing.
size()
692 <<
" agglom:" << restriction.
size()
709 const label own =
lower[facei];
710 const label nei =
upper[facei];
712 if (restriction[own] == restriction[nei])
716 if (master[own] < master[nei])
718 master[nei] = master[own];
721 else if (master[own] > master[nei])
723 master[own] = master[nei];
729 reduce(nChanged, sumOp<label>());
741 forAll(restriction, celli)
743 labelList& masters = coarseToMasters[restriction[celli]];
745 if (!masters.found(master[celli]))
747 masters.
append(master[celli]);
752 if (nNewCoarse > nCoarse)
763 nNewCoarse = nCoarse;
765 forAll(coarseToMasters, coarseI)
767 const labelList& masters = coarseToMasters[coarseI];
769 labelList& newCoarse = coarseToNewCoarse[coarseI];
770 newCoarse.
setSize(masters.size());
771 newCoarse[0] = coarseI;
772 for (label i=1; i<newCoarse.size(); i++)
774 newCoarse[i] = nNewCoarse++;
779 forAll(restriction, celli)
781 const label coarseI = restriction[celli];
783 const label index = coarseToMasters[coarseI].find(master[celli]);
784 newRestrict[celli] = coarseToNewCoarse[coarseI][index];
autoPtr< GAMGProcAgglomeration > procAgglomeratorPtr_
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
PtrList< labelListList > procBoundaryMap_
Mapping from processor to procMeshLevel boundary.
bool hasProcMesh(const label fineLeveli) const
Check that level has combined mesh.
static bool checkRestriction(labelList &newRestrict, label &nNewCoarse, const lduAddressing &fineAddressing, const labelUList &restriction, const label nCoarse)
Given restriction determines if coarse cells are connected.
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.
dlLibraryTable & libs() const noexcept
Mutable access to the loaded dynamic libraries.
PtrList< labelListList > patchFaceRestrictAddressing_
Patch-local face restriction addressing array.
errorManipArg< error, int > exit(error &err, const int errNo=1)
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.
GAMGAgglomeration(const GAMGAgglomeration &)=delete
No copy construct.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
label agglomCommunicator(const label fineLeveli) const
Communicator for collecting contributions.
void append(const T &val)
Append an element at the end of the list.
const lduMesh & meshLevel(const label leveli) const
Return LDU mesh of given level.
PtrList< labelList > procCellOffsets_
Mapping from processor to procMeshLevel cells.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
constexpr char nl
The newline '\n' character (0x0a)
const labelListList & boundaryMap(const label fineLeveli) const
Mapping from processor to procMesh boundary.
Ostream & endl(Ostream &os)
Add newline and flush stream.
~GAMGAgglomeration()
Destructor.
Abstract base class for meshes which provide LDU addressing for the construction of lduMatrix and LDU...
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.
static const GAMGAgglomeration & New(const lduMesh &mesh, const dictionary &controlDict)
Return the selected geometric agglomerator.
bool store()
Register object with its registry and transfer ownership to the registry.
static int & msgType() noexcept
Message tag of standard messages.
bool checkOut(regIOobject *io) const
Remove a regIOobject from registry and free memory if the object is ownedByRegistry. A nullptr is ignored.
const Type * cfindObject(const word &name, const bool recursive=false) const
Return const pointer to the object of the given Type.
PtrList< labelList > faceRestrictAddressing_
Face restriction addressing array.
List< labelList > labelListList
List of labelList.
PtrList< labelList > nPatchFaces_
The number of (coarse) patch faces in each level.
virtual const labelUList & lowerAddr() const =0
Return lower addressing.
void clearLevel(const label leveli)
UList< label > labelUList
A UList of labels.
void reduce(T &value, [[maybe_unused]] BinaryOp bop, [[maybe_unused]] const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce)
PtrList< labelList > agglomProcIDs_
Per level the set of processors to agglomerate. Element 0 is.
virtual const objectRegistry & thisDb() const
Return the object registry - resolve conflict polyMesh/lduMesh.
#define forAll(list, i)
Loop across all elements in list.
label procCommunicator(const label fineLeveli) const
Communicator for current level or -1.
labelList procCommunicator_
Communicator for given level.
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
bool requiresUpdate() const
Does the agglomeration need to be fully updated?
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
virtual bool movePoints()
Update when the mesh moves.
void setSize(const label n)
Alias for resize()
label size() const noexcept
Return number of equations.
bool processorAgglomerate() const
Whether to agglomerate across processors.
PtrList< lduPrimitiveMesh > meshLevels_
Hierarchy of mesh addressing.
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...
const lduMesh & mesh() const noexcept
Reference to the mesh.
virtual int precision() const override
Get precision of output field.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
const Time & time() const noexcept
Return time registry.
virtual const labelUList & upperAddr() const =0
Return upper addressing.
PtrList< UPstream::communicator > procAgglomCommunicator_
Communicator for collecting contributions. Note self-contained.
UPtrList< const lduInterface > lduInterfacePtrsList
Store lists of lduInterface as a UPtrList.
const labelList & agglomProcIDs(const label fineLeveli) const
Set of processors to agglomerate. Element 0 is the master processor. (local, same only on those proce...
void printLevels() const
Print level overview.
virtual const lduAddressing & lduAddr() const =0
Return ldu addressing.
T returnReduce(const T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
OSstream & stream(OSstream *alternative=nullptr, int communicator=-1)
Return OSstream for output operations.
labelList nCells_
The number of cells in each level.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
runTime controlDict().readEntry("adjustTimeStep"
The central control dictionary, the contents of which are either taken directly from the FOAM_CONTROL...
errorManip< error > abort(error &err)
labelList nFaces_
The number of (coarse) faces in each level.
PtrList< labelField > restrictAddressing_
Cell restriction addressing array.
Istream and Ostream manipulators taking arguments.
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
int debug
Static debugging option.
defineTypeNameAndDebug(combustionModel, 0)
const label maxLevels_
Max number of levels.
string upper(const std::string &s)
Return string copy transformed with std::toupper on each character.
const labelList & cellOffsets(const label fineLeveli) const
Mapping from processor to procMesh cells.
const labelListListList & boundaryFaceMap(const label fineLeveli) const
Mapping from processor to procMesh boundary face.
const labelList & procAgglomMap(const label fineLeveli) const
Mapping from processor to agglomerated processor (global, all processors have the same information)...
PtrList< labelList > procAgglomMap_
Per level, per processor the processor it agglomerates into.
const lduInterfacePtrsList & interfaceLevel(const label leveli) const
Return LDU interface addressing of given level.
string lower(const std::string &s)
Return string copy transformed with std::tolower on each character.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Field< vector > vectorField
Specialisation of Field<T> for vector.
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.
Omanip< int > setw(const int i)
List< label > labelList
A List of labels.
bool open(bool verbose=true)
Open named, but unopened libraries. These names will normally have been added with push_back()...
Geometric agglomerated algebraic multigrid agglomeration class.
bool hasMeshLevel(const label leveli) const
Do we have mesh for given level?
label nCellsInCoarsestLevel_
Number of cells in coarsest level.
void compactLevels(const label nCreatedLevels, const bool doProcessorAgglomerate)
Shrink the number of levels to that specified. Optionally do.
const labelListList & faceMap(const label fineLeveli) const
Mapping from processor to procMesh face.