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(),
394 patchFineToCoarse[inti] = refCast<const GAMGInterface>
396 coarseInterfaces[inti]
404 lduPrimitiveMesh::nonBlockingSchedule<processorGAMGInterface>
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 421 <<
" lower:" <<
flatOutput(coarseAddr.lowerAddr()) <<
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]
507 const CompactListList<label> data
509 CompactListList<label>::pack<labelList>
511 procBoundaryMap_[levelIndex]
514 const labelList localSizes = data.localSizes();
515 const labelList& localStarts = data.offsets();
518 procBoundaryMap_[levelIndex].
setSize(procIDs.size());
525 data.values().cdata(),
528 ConstPrecisionAdaptor<int, label, List>(localSizes).cref(),
529 ConstPrecisionAdaptor<int, label, List>(localStarts).cref(),
541 procAgglomerateRestrictAddressing
550 clearLevel(levelIndex);
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)
639 SubList<label> procSlot
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))
736 GAMGInterface& prevInt = refCast<GAMGInterface>
738 const_cast<lduInterface&
> 743 const GAMGInterface& curInt = refCast<const GAMGInterface>
747 prevInt.combine(curInt);
753 meshLevels_.set(prevLevel, meshLevels_.set(curLevel,
nullptr));
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);
783 masterProcs.
setSize(agglomToMaster.size());
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]);
const labelList & faceRestrictAddressing(const label leveli) const
Return face restrict addressing of given level.
const labelList & nPatchFaces(const label leveli) const
Return number of coarse patch faces (before processor agglomeration)
void size(const label n)
Older name for setAddressableSize.
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.
const boolList & faceFlipMap(const label leveli) const
Return face flip map of given level.
PtrList< labelListList > patchFaceRestrictAddressing_
Patch-local face restriction addressing array.
errorManipArg< error, int > exit(error &err, const int errNo=1)
void resize(const label len)
Adjust allocated size of list.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const lduMesh & meshLevel(const label leveli) const
Return LDU mesh of given level.
static label nRequests() noexcept
Number of outstanding requests (on the internal list of requests)
constexpr char nl
The newline '\n' character (0x0a)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Abstract base class for meshes which provide LDU addressing for the construction of lduMatrix and LDU...
labelList findIndices(const ListType &input, typename ListType::const_reference val, label start=0)
Linear search to find all occurrences of given element.
static int & msgType() noexcept
Message tag of standard messages.
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]).
virtual label comm() const =0
Return communicator used for parallel communication.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
void procAgglomerateLduAddressing(const label comm, const labelList &procAgglomMap, const labelList &procIDs, const label allMeshComm, const label levelIndex)
Collect and combine processor meshes into allMesh:
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.
static void waitRequests()
Wait for all requests to finish.
#define forAll(list, i)
Loop across all elements in list.
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]).
void setSize(const label n)
Alias for resize()
label size() const noexcept
Return number of equations.
"scheduled" (MPI standard) : (MPI_Send, MPI_Recv)
PtrList< lduPrimitiveMesh > meshLevels_
Hierarchy of mesh addressing.
void clear()
Clear the list, i.e. set size to zero.
virtual const labelUList & upperAddr() const =0
Return upper addressing.
label size() const noexcept
The number of entries in the list.
UPtrList< const lduInterface > lduInterfacePtrsList
Store lists of lduInterface as a UPtrList.
virtual const labelUList & patchAddr(const label patchNo) const =0
Return patch to internal addressing given patch number.
Simplest concrete lduMesh that stores the addressing needed by lduMatrix.
virtual const lduAddressing & lduAddr() const =0
Return ldu addressing.
labelList nCells_
The number of cells in each level.
List< labelListList > labelListListList
List of labelListList.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
errorManip< error > abort(error &err)
labelList nFaces_
The number of (coarse) faces in each level.
label find(const T &val) const
Find index of the first occurrence of the value.
void agglomerateLduAddressing(const label fineLevelIndex)
Assemble coarse mesh addressing.
static void gather(const label agglomComm, const lduMesh &mesh, PtrList< lduPrimitiveMesh > &otherMeshes)
Gather meshes from other processors using agglomComm.
int debug
Static debugging option.
Pair< label > labelPair
A pair of labels.
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.
void procAgglomerateRestrictAddressing(const label comm, const labelList &procIDs, const label levelIndex)
Collect and combine basic restriction addressing:
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.
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
std::enable_if_t< std::is_same_v< bool, TypeT >, bool > set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
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.
#define forAllReverse(list, i)
Reverse loop across all elements in list.
List< label > labelList
A List of labels.
A class for managing temporary objects.
List< bool > boolList
A List of bools.
static void calculateRegionMaster(const label comm, const labelList &procAgglomMap, labelList &masterProcs, List< label > &agglomProcIDs)
Given fine to coarse processor map determine:
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
void combineLevels(const label curLevel)
Combine a level with the previous one.
forAllConstIters(mixture.phases(), phase)
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
static constexpr const zero Zero
Global zero (0)