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;
246 MeshObject_type(
mesh),
250 updateInterval_(
controlDict.getOrDefault<label>(
"updateInterval", 1)),
251 requireUpdate_(false),
253 nCellsInCoarsestLevel_
255 controlDict.getOrDefault<label>(
"nCellsInCoarsestLevel", 10)
257 meshInterfaces_(
mesh.interfaces()),
261 (UPstream::nProcs(
mesh.comm()) > 1)
264 ? GAMGProcAgglomeration::
New 270 : autoPtr<GAMGProcAgglomeration>()
274 restrictAddressing_(maxLevels_),
276 faceRestrictAddressing_(maxLevels_),
277 faceFlipMap_(maxLevels_),
278 nPatchFaces_(maxLevels_),
279 patchFaceRestrictAddressing_(maxLevels_),
281 meshLevels_(maxLevels_)
311 const GAMGAgglomeration* agglomPtr =
314 GAMGAgglomeration::typeName
319 if (agglomPtr->requireUpdate_)
329 const word agglomeratorType
331 controlDict.getOrDefault<word>(
"agglomerator",
"faceAreaPair")
337 "geometricGAMGAgglomerationLibs",
338 lduMeshConstructorTablePtr_
341 auto* ctorPtr = lduMeshConstructorTable(agglomeratorType);
346 <<
"Unknown GAMGAgglomeration type " 347 << agglomeratorType <<
".\n" 348 <<
"Valid matrix GAMGAgglomeration types :" 349 << lduMatrixConstructorTablePtr_->sortedToc() <<
endl 350 <<
"Valid geometric GAMGAgglomeration types :" 351 << lduMeshConstructorTablePtr_->sortedToc()
358 agglomPtr().printLevels();
367 const lduMatrix& matrix,
371 const lduMesh&
mesh = matrix.mesh();
373 const GAMGAgglomeration* agglomPtr =
376 GAMGAgglomeration::typeName
381 if (agglomPtr->requireUpdate_)
391 const word agglomeratorType
393 controlDict.getOrDefault<word>(
"agglomerator",
"faceAreaPair")
399 "algebraicGAMGAgglomerationLibs",
400 lduMatrixConstructorTablePtr_
403 auto* ctorPtr = lduMatrixConstructorTable(agglomeratorType);
414 agglomPtr().printLevels();
431 const GAMGAgglomeration* agglomPtr =
434 GAMGAgglomeration::typeName
439 if (agglomPtr->requireUpdate_)
449 const word agglomeratorType
451 controlDict.getOrDefault<word>(
"agglomerator",
"faceAreaPair")
457 "geometricGAMGAgglomerationLibs",
458 geometryConstructorTablePtr_
461 auto* ctorPtr = geometryConstructorTable(agglomeratorType);
466 <<
"Unknown GAMGAgglomeration type " 467 << agglomeratorType <<
".\n" 468 <<
"Valid geometric GAMGAgglomeration types :" 469 << geometryConstructorTablePtr_->sortedToc()
485 agglomPtr().printLevels();
503 (updateInterval_ > 0)
504 && ((mesh_.thisDb().time().timeIndex() % updateInterval_) == 0);
510 if (requiresUpdate())
512 requireUpdate_ =
true;
515 return requireUpdate_;
530 return meshLevels_[i - 1];
543 return meshLevels_.set(i - 1);
555 return meshInterfaces_;
559 return meshLevels_[i - 1].rawInterfaces();
568 meshLevels_.set(i - 1,
nullptr);
570 if (i < nCells_.size())
573 restrictAddressing_.set(i,
nullptr);
575 faceRestrictAddressing_.set(i,
nullptr);
576 faceFlipMap_.set(i,
nullptr);
577 nPatchFaces_.set(i,
nullptr);
578 patchFaceRestrictAddressing_.set(i,
nullptr);
589 return procAgglomMap_[leveli];
598 return agglomProcIDs_[leveli];
604 return procCommunicator_[leveli] != -1;
610 return procCommunicator_[leveli];
616 return procAgglomCommunicator_[leveli];
625 return procCellOffsets_[leveli];
634 return procFaceMap_[leveli];
643 return procBoundaryMap_[leveli];
652 return procBoundaryFaceMap_[leveli];
665 if (fineAddressing.
size() != restriction.
size())
668 <<
"nCells:" << fineAddressing.
size()
669 <<
" agglom:" << restriction.
size()
686 const label own =
lower[facei];
687 const label nei =
upper[facei];
689 if (restriction[own] == restriction[nei])
693 if (master[own] < master[nei])
695 master[nei] = master[own];
698 else if (master[own] > master[nei])
700 master[own] = master[nei];
706 reduce(nChanged, sumOp<label>());
718 forAll(restriction, celli)
720 labelList& masters = coarseToMasters[restriction[celli]];
722 if (!masters.found(master[celli]))
724 masters.
append(master[celli]);
729 if (nNewCoarse > nCoarse)
740 nNewCoarse = nCoarse;
742 forAll(coarseToMasters, coarseI)
744 const labelList& masters = coarseToMasters[coarseI];
746 labelList& newCoarse = coarseToNewCoarse[coarseI];
747 newCoarse.
setSize(masters.size());
748 newCoarse[0] = coarseI;
749 for (label i=1; i<newCoarse.size(); i++)
751 newCoarse[i] = nNewCoarse++;
756 forAll(restriction, celli)
758 const label coarseI = restriction[celli];
760 const label index = coarseToMasters[coarseI].find(master[celli]);
761 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.
string upper(const std::string &s)
Return string copy transformed with std::toupper on each character.
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.
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
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.
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.
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.
OSstream & stream(OSstream *alternative=nullptr)
Return OSstream for output operations.
Istream and Ostream manipulators taking arguments.
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
int debug
Static debugging option.
defineTypeNameAndDebug(combustionModel, 0)
const label maxLevels_
Max number of levels.
const labelList & cellOffsets(const label fineLeveli) const
Mapping from processor to procMesh cells.
string lower(const std::string &s)
Return string copy transformed with std::tolower on each character.
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.
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?
void reduce(T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce) using linear/tree communication schedule.
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.