39 const label fineLevelIndex
48 const label nFineFaces = upperAddr.
size();
53 if (
min(restrictMap) == -1)
59 if (restrictMap.
size() != fineMeshAddr.
size())
62 <<
"restrict map does not correspond to fine level. " <<
endl
63 <<
" Sizes: restrictMap: " << restrictMap.
size()
64 <<
" nEqns: " << fineMeshAddr.
size()
70 const label nCoarseCells =
nCells_[fineLevelIndex];
81 labelList cCellFaces(maxNnbrs*nCoarseCells);
91 label& nCoarseFaces =
nFaces_[fineLevelIndex];
95 forAll(upperAddr, fineFacei)
97 label rmUpperAddr = restrictMap[upperAddr[fineFacei]];
98 label rmLowerAddr = restrictMap[lowerAddr[fineFacei]];
100 if (rmUpperAddr == rmLowerAddr)
105 faceRestrictAddr[fineFacei] = -(rmUpperAddr + 1);
111 label cOwn = rmUpperAddr;
112 label cNei = rmLowerAddr;
115 if (rmUpperAddr > rmLowerAddr)
122 label* ccFaces = &cCellFaces[maxNnbrs*cOwn];
124 bool nbrFound =
false;
125 label& ccnFaces = cCellnFaces[cOwn];
127 for (
int i=0; i<ccnFaces; i++)
129 if (initCoarseNeighb[ccFaces[i]] == cNei)
132 faceRestrictAddr[fineFacei] = ccFaces[i];
139 if (ccnFaces >= maxNnbrs)
141 label oldMaxNnbrs = maxNnbrs;
144 cCellFaces.
setSize(maxNnbrs*nCoarseCells);
148 label* oldCcNbrs = &cCellFaces[oldMaxNnbrs*i];
149 label* newCcNbrs = &cCellFaces[maxNnbrs*i];
151 for (
int j=0; j<cCellnFaces[i]; j++)
153 newCcNbrs[j] = oldCcNbrs[j];
157 ccFaces = &cCellFaces[maxNnbrs*cOwn];
160 ccFaces[ccnFaces] = nCoarseFaces;
161 initCoarseNeighb[nCoarseFaces] = cNei;
162 faceRestrictAddr[fineFacei] = nCoarseFaces;
179 label coarseFacei = 0;
183 label* cFaces = &cCellFaces[maxNnbrs*cci];
184 label ccnFaces = cCellnFaces[cci];
186 for (
int i=0; i<ccnFaces; i++)
188 coarseOwner[coarseFacei] = cci;
189 coarseNeighbour[coarseFacei] = initCoarseNeighb[cFaces[i]];
190 coarseFaceMap[cFaces[i]] = coarseFacei;
195 forAll(faceRestrictAddr, fineFacei)
197 if (faceRestrictAddr[fineFacei] >= 0)
199 faceRestrictAddr[fineFacei] =
200 coarseFaceMap[faceRestrictAddr[fineFacei]];
210 forAll(faceRestrictAddr, fineFacei)
212 label coarseFacei = faceRestrictAddr[fineFacei];
214 if (coarseFacei >= 0)
217 label cOwn = coarseOwner[coarseFacei];
218 label cNei = coarseNeighbour[coarseFacei];
220 label rmUpperAddr = restrictMap[upperAddr[fineFacei]];
221 label rmLowerAddr = restrictMap[lowerAddr[fineFacei]];
223 if (cOwn == rmUpperAddr && cNei == rmLowerAddr)
227 else if (cOwn == rmLowerAddr && cNei == rmUpperAddr)
235 <<
" fineFacei:" << fineFacei
236 <<
" rmUpperAddr:" << rmUpperAddr
237 <<
" rmLowerAddr:" << rmLowerAddr
238 <<
" coarseFacei:" << coarseFacei
251 initCoarseNeighb.
clear();
252 coarseFaceMap.
clear();
281 forAll(fineInterfaces, inti)
283 if (fineInterfaces.
set(inti))
285 if (fineLevelIndex == 0)
287 fineInterfaces[inti].initInternalFieldTransfer
296 fineInterfaces[inti].initInternalFieldTransfer
324 forAll(fineInterfaces, inti)
326 if (fineInterfaces.
set(inti))
332 if (fineLevelIndex == 0)
334 restrictMapInternalField =
335 fineInterfaces[inti].interfaceInternalField
343 restrictMapInternalField =
344 fineInterfaces[inti].interfaceInternalField
351 fineInterfaces[inti].internalFieldTransfer
364 fineInterfaces[inti],
365 restrictMapInternalField(),
366 nbrRestrictMapInternalField(),
396 coarseInterfaces[inti]
397 ).faceRestrictAddressing();
413 const auto& coarseAddr =
meshLevels_[fineLevelIndex].lduAddr();
415 Pout<<
"GAMGAgglomeration :"
416 <<
" agglomerated level " << fineLevelIndex
417 <<
" from nCells:" << fineMeshAddr.
size()
418 <<
" nFaces:" << upperAddr.
size()
419 <<
" to nCells:" << nCoarseCells
420 <<
" nFaces:" << nCoarseFaces <<
nl
422 <<
" upper:" <<
flatOutput(coarseAddr.upperAddr()) <<
nl
430 const label meshComm,
433 const label allMeshComm,
435 const label levelIndex
443 const lduMesh& myMesh = meshLevels_[levelIndex-1];
444 const label nOldInterfaces = myMesh.interfaces().size();
446 procAgglomMap_.set(levelIndex,
new labelList(procAgglomMap));
447 agglomProcIDs_.set(levelIndex,
new labelList(procIDs));
448 procCommunicator_[levelIndex] = allMeshComm;
450 procAgglomCommunicator_.set
453 new UPstream::communicator
459 const label comm = agglomCommunicator(levelIndex);
463 procCellOffsets_.set(levelIndex,
new labelList(0));
470 PtrList<lduPrimitiveMesh> otherMeshes;
490 procCellOffsets_[levelIndex],
492 procFaceMap_[levelIndex],
493 procBoundaryMap_[levelIndex],
494 procBoundaryFaceMap_[levelIndex]
511 procBoundaryMap_[levelIndex]
514 const labelList localSizes = data.localSizes();
515 const labelList& localStarts = data.offsets();
518 procBoundaryMap_[levelIndex].setSize(procIDs.size());
520 bMap.setSize(nOldInterfaces);
525 data.values().cdata(),
541 procAgglomerateRestrictAddressing
559 const label levelIndex
579 restrictAddressing_[levelIndex].size(),
589 if (master && !sizes.empty())
591 const label len = sizes.size();
593 fineOffsets.resize(len+1);
594 coarseOffsets.resize(len+1);
597 label coarseCount = 0;
599 for (label i = 0; i < len; ++i)
601 fineOffsets[i] = fineCount;
602 fineCount += sizes[i].first();
604 coarseOffsets[i] = coarseCount;
605 coarseCount += sizes[i].second();
608 fineOffsets[len] = fineCount;
609 coarseOffsets[len] = coarseCount;
619 procRestrictAddressing.resize(fineOffsets.back());
626 restrictAddressing_[levelIndex],
627 procRestrictAddressing,
634 nCells_[levelIndex] = coarseOffsets.back();
637 for (label proci = 1; proci < procIDs.size(); ++proci)
641 procRestrictAddressing,
642 fineOffsets[proci+1]-fineOffsets[proci],
649 procSlot[i] += coarseOffsets[proci];
653 restrictAddressing_[levelIndex].transfer(procRestrictAddressing);
660 label prevLevel = curLevel - 1;
663 nCells_[prevLevel] = nCells_[curLevel];
664 nFaces_[prevLevel] = nFaces_[curLevel];
669 const labelList& curResAddr = restrictAddressing_[curLevel];
670 labelList& prevResAddr = restrictAddressing_[prevLevel];
672 const labelList& curFaceResAddr = faceRestrictAddressing_[curLevel];
673 labelList& prevFaceResAddr = faceRestrictAddressing_[prevLevel];
674 const boolList& curFaceFlipMap = faceFlipMap_[curLevel];
675 boolList& prevFaceFlipMap = faceFlipMap_[prevLevel];
677 forAll(prevFaceResAddr, i)
679 if (prevFaceResAddr[i] >= 0)
681 label fineFacei = prevFaceResAddr[i];
682 prevFaceResAddr[i] = curFaceResAddr[fineFacei];
683 prevFaceFlipMap[i] = curFaceFlipMap[fineFacei];
687 label fineFacei = -prevFaceResAddr[i] - 1;
688 prevFaceResAddr[i] = -curResAddr[fineFacei] - 1;
689 prevFaceFlipMap[i] = curFaceFlipMap[fineFacei];
694 faceRestrictAddressing_.set(curLevel,
nullptr);
695 faceFlipMap_.set(curLevel,
nullptr);
699 prevResAddr[i] = curResAddr[prevResAddr[i]];
703 patchFaceRestrictAddressing_[curLevel];
705 patchFaceRestrictAddressing_[prevLevel];
707 forAll(prevPatchFaceResAddr, inti)
709 const labelList& curResAddr = curPatchFaceResAddr[inti];
710 labelList& prevResAddr = prevPatchFaceResAddr[inti];
713 label fineFacei = prevResAddr[i];
714 prevResAddr[i] = curResAddr[fineFacei];
719 restrictAddressing_.set(curLevel,
nullptr);
722 nPatchFaces_[prevLevel] = nPatchFaces_[curLevel];
728 meshLevels_[curLevel].rawInterfaces();
730 meshLevels_[prevLevel].rawInterfaces();
732 forAll(prevInterLevel, inti)
734 if (prevInterLevel.set(inti))
747 prevInt.combine(curInt);
768 forAll(procAgglomMap, proci)
770 const label coarsei = procAgglomMap[proci];
772 auto iter = agglomToMaster.
find(coarsei);
775 iter.val() =
min(iter.val(), proci);
779 agglomToMaster.
insert(coarsei, proci);
786 masterProcs[iter.key()] = iter.val();
792 label myAgglom = procAgglomMap[myProcID];
796 agglomProcIDs =
findIndices(procAgglomMap, myAgglom);
800 agglomProcIDs.
find(agglomToMaster[myAgglom]);
802 std::swap(agglomProcIDs[0], agglomProcIDs[index]);
A packed storage of objects of type <T> using an offset table for access.
const labelList & offsets() const noexcept
Return the offset table (= size()+1).
const List< T > & values() const noexcept
Return the packed values.
static CompactListList< T > pack(const UList< SubListType > &lists, const bool checkOverflow=false)
Construct by packing together the list of lists.
labelList localSizes() const
The local row sizes.
A const Field/List wrapper with possible data conversion.
const labelList & nPatchFaces(const label leveli) const
Return number of coarse patch faces (before processor agglomeration).
void procAgglomerateRestrictAddressing(const label comm, const labelList &procIDs, const label levelIndex)
Collect and combine basic restriction addressing:
void clearLevel(const label leveli)
label agglomCommunicator(const label fineLeveli) const
Communicator for collecting contributions.
void agglomerateLduAddressing(const label fineLevelIndex)
Assemble coarse mesh addressing.
static void calculateRegionMaster(const label comm, const labelList &procAgglomMap, labelList &masterProcs, List< label > &agglomProcIDs)
Given fine to coarse processor map determine:
PtrList< labelListList > patchFaceRestrictAddressing_
Patch-local face restriction addressing array.
PtrList< boolList > faceFlipMap_
Face flip: for faces mapped to internal faces stores whether.
PtrList< UPstream::communicator > procAgglomCommunicator_
Communicator for collecting contributions. Note self-contained.
PtrList< labelList > nPatchFaces_
The number of (coarse) patch faces in each level.
void procAgglomerateLduAddressing(const label comm, const labelList &procAgglomMap, const labelList &procIDs, const label allMeshComm, const label levelIndex)
Collect and combine processor meshes into allMesh:
const labelList & procAgglomMap(const label fineLeveli) const
Mapping from processor to agglomerated processor (global, all processors have the same information)....
labelList nFaces_
The number of (coarse) faces in each level.
const boolList & faceFlipMap(const label leveli) const
Return face flip map of given level.
PtrList< lduPrimitiveMesh > meshLevels_
Hierarchy of mesh addressing.
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.
void combineLevels(const label curLevel)
Combine a level with the previous one.
const labelList & agglomProcIDs(const label fineLeveli) const
Set of processors to agglomerate. Element 0 is the master processor. (local, same only on those proce...
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.
const lduInterfacePtrsList & interfaceLevel(const label leveli) const
Return LDU interface addressing of given level.
const labelField & restrictAddressing(const label leveli) const
Return cell restrict addressing of 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.
Abstract base class for GAMG agglomerated interfaces.
void combine(const GAMGInterface &)
Merge the next level with this level.
static autoPtr< GAMGInterface > New(const label index, const lduInterfacePtrsList &coarseInterfaces, const lduInterface &fineInterface, const labelField &localRestrictAddressing, const labelField &neighbourRestrictAddressing, const label fineLevelIndex, const label coarseComm)
Return a pointer to a new interface created on freestore given.
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
iterator find(const Key &key)
Find and return an iterator set at the hashed entry.
label size() const noexcept
The number of elements in table.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
bool set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
void setSize(label n)
Alias for resize().
void resize(const label len)
Adjust allocated size of list.
void clear()
Clear the list, i.e. set size to zero.
A HashTable to objects of type <T> with a label key.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
A non-owning sub-view of a List (allocated or unallocated storage).
T & first()
Access first element of the list, position [0].
bool empty() const noexcept
True if List is empty (ie, size() is zero).
T & back()
Access last element of the list, position [size()-1].
T * data() noexcept
Return pointer to the underlying array serving as data storage.
void size(const label n)
Older name for setAddressableSize.
label find(const T &val) const
Find index of the first occurrence of the value.
Wrapper for internally indexed communicator label. Always invokes UPstream::allocateCommunicatorCompo...
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
static label nRequests() noexcept
Number of outstanding requests (on the internal list of requests).
@ scheduled
"scheduled" (MPI standard) : (MPI_Send, MPI_Recv)
@ nonBlocking
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
static int & msgType() noexcept
Message tag of standard messages.
static void mpiScatterv(const Type *sendData, const UList< int > &sendCounts, const UList< int > &sendOffsets, Type *recvData, int recvCount, const int communicator=UPstream::worldComm)
Send variable length data to all ranks.
static void waitRequests()
Wait for all requests to finish.
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie,...
label size() const noexcept
The number of entries in the list.
static void gather(const labelUList &offsets, const label comm, const ProcIDsContainer &procIDs, const UList< Type > &fld, UList< Type > &allFld, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking)
Collect data in processor order on master (== procIDs[0]).
static List< Type > listGatherValues(const label comm, const ProcIDsContainer &procIDs, const Type &localValue, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking)
Collect single values in processor order on master (== procIDs[0]).
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.
virtual const labelUList & patchAddr(const label patchNo) const =0
Return patch to internal addressing given patch number.
label size() const noexcept
Return number of equations.
An abstract base class for implicitly-coupled interfaces e.g. processor and cyclic patches.
Abstract base class for meshes which provide LDU addressing for the construction of lduMatrix and LDU...
virtual label comm() const =0
Return communicator used for parallel communication.
virtual const lduAddressing & lduAddr() const =0
Return ldu addressing.
virtual lduInterfacePtrsList interfaces() const =0
Return a list of pointers for each patch with only those pointing to interfaces being set.
Simplest concrete lduMesh that stores the addressing needed by lduMatrix.
static void gather(const label agglomComm, const lduMesh &mesh, PtrList< lduPrimitiveMesh > &otherMeshes)
Gather meshes from other processors using agglomComm.
static lduSchedule nonBlockingSchedule(const lduInterfacePtrsList &)
Get non-scheduled send/receive schedule.
const T & cref() const
Return const reference to the object or to the contents of a (non-null) managed pointer.
A class for managing temporary objects.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Namespace for handling debugging switches.
Type & refCast(U &obj)
A dynamic_cast (for references) to Type reference.
Pair< label > labelPair
A pair of labels.
List< labelList > labelListList
List of labelList.
List< label > labelList
A List of labels.
List< labelListList > labelListListList
List of labelListList.
UPtrList< const lduInterface > lduInterfacePtrsList
Store lists of lduInterface as a UPtrList.
Ostream & endl(Ostream &os)
Add newline and flush stream.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
errorManip< error > abort(error &err)
Field< label > labelField
Specialisation of Field<T> for label.
List< bool > boolList
A List of bools.
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...
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
labelList findIndices(const ListType &input, typename ListType::const_reference val, label start=0)
Linear search to find all occurrences of given element.
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.
#define forAllReverse(list, i)
Reverse loop across all elements in list.
#define forAllConstIters(container, iter)
Iterate across all elements of the container object with const access.