21 const int NumDimensions,
const int interpolationOrder,
22 const int MyRank,
const int NumRanks,
23 const Array<GO> GFineNodesPerDir,
const Array<LO> LFineNodesPerDir,
24 const Array<LO> CoarseRate,
const Array<GO> MeshData)
25 :
IndexManager(comm, coupled, false, NumDimensions, interpolationOrder, GFineNodesPerDir, LFineNodesPerDir)
27 , numRanks(NumRanks) {
34 for (
int dim = 0; dim < 3; ++dim) {
36 if (CoarseRate.size() == 1) {
38 }
else if (CoarseRate.size() == this->numDimensions) {
47 for (
int rank = 0; rank <
numRanks; ++rank) {
49 for (
int entry = 0; entry < 10; ++entry) {
50 meshData[rank][entry] = MeshData[10 * rank + entry];
61 for (
int dim = 0; dim < 3; ++dim) {
81 Array<LO>& ghostedNodeCoarseLIDs,
82 Array<int>& ghostedNodeCoarsePIDs,
83 Array<GO>& ghostedNodeCoarseGIDs)
const {
85 ghostedNodeCoarseLIDs.resize(this->getNumLocalGhostedNodes());
86 ghostedNodeCoarsePIDs.resize(this->getNumLocalGhostedNodes());
87 ghostedNodeCoarseGIDs.resize(this->numGhostedNodes);
94 Array<LO> ghostedCoarseNodeCoarseIndices(3), ghostedCoarseNodeFineIndices(3);
95 Array<LO> lCoarseNodeCoarseIndices(3);
96 Array<GO> lCoarseNodeCoarseGIDs(this->lNumCoarseNodes);
97 LO currentIndex = -1, countCoarseNodes = 0;
98 for (
int k = 0; k < this->ghostedNodesPerDir[2]; ++k) {
99 for (
int j = 0; j < this->ghostedNodesPerDir[1]; ++j) {
100 for (
int i = 0; i < this->ghostedNodesPerDir[0]; ++i) {
101 currentIndex = k * this->numGhostedNodes10 + j * this->ghostedNodesPerDir[0] + i;
102 ghostedCoarseNodeCoarseIndices[0] = this->startGhostedCoarseNode[0] + i;
103 ghostedCoarseNodeFineIndices[0] = ghostedCoarseNodeCoarseIndices[0] * this->coarseRate[0];
104 if (ghostedCoarseNodeFineIndices[0] > this->gFineNodesPerDir[0] - 1) {
105 ghostedCoarseNodeFineIndices[0] = this->gFineNodesPerDir[0] - 1;
107 ghostedCoarseNodeCoarseIndices[1] = this->startGhostedCoarseNode[1] + j;
108 ghostedCoarseNodeFineIndices[1] = ghostedCoarseNodeCoarseIndices[1] * this->coarseRate[1];
109 if (ghostedCoarseNodeFineIndices[1] > this->gFineNodesPerDir[1] - 1) {
110 ghostedCoarseNodeFineIndices[1] = this->gFineNodesPerDir[1] - 1;
112 ghostedCoarseNodeCoarseIndices[2] = this->startGhostedCoarseNode[2] + k;
113 ghostedCoarseNodeFineIndices[2] = ghostedCoarseNodeCoarseIndices[2] * this->coarseRate[2];
114 if (ghostedCoarseNodeFineIndices[2] > this->gFineNodesPerDir[2] - 1) {
115 ghostedCoarseNodeFineIndices[2] = this->gFineNodesPerDir[2] - 1;
118 GO myGID = -1, myCoarseGID = -1;
119 LO myLID = -1, myPID = -1, myCoarseLID = -1;
120 getGIDLocalLexicographic(i, j, k, ghostedCoarseNodeFineIndices, myGID, myPID, myLID);
122 int rankIndex = rankIndices[myPID];
123 for (
int dim = 0; dim < 3; ++dim) {
124 if (dim < this->numDimensions) {
125 lCoarseNodeCoarseIndices[dim] = ghostedCoarseNodeCoarseIndices[dim] - coarseMeshData[rankIndex][3 + 2 * dim];
128 LO myRankIndexCoarseNodesInDir0 = coarseMeshData[rankIndex][4] - coarseMeshData[rankIndex][3] + 1;
129 LO myRankIndexCoarseNodes10 = (coarseMeshData[rankIndex][6] - coarseMeshData[rankIndex][5] + 1) * myRankIndexCoarseNodesInDir0;
130 myCoarseLID = lCoarseNodeCoarseIndices[2] * myRankIndexCoarseNodes10 + lCoarseNodeCoarseIndices[1] * myRankIndexCoarseNodesInDir0 + lCoarseNodeCoarseIndices[0];
131 myCoarseGID = myCoarseLID + coarseMeshData[rankIndex][9];
133 ghostedNodeCoarseLIDs[currentIndex] = myCoarseLID;
134 ghostedNodeCoarsePIDs[currentIndex] = myPID;
135 ghostedNodeCoarseGIDs[currentIndex] = myCoarseGID;
137 if (myPID == myRank) {
138 lCoarseNodeCoarseGIDs[countCoarseNodes] = myCoarseGID;
149 Array<GO>& coarseNodeCoarseGIDs,
150 Array<GO>& coarseNodeFineGIDs)
const {
152 coarseNodeCoarseGIDs.resize(this->getNumLocalCoarseNodes());
153 coarseNodeFineGIDs.resize(this->getNumLocalCoarseNodes());
156 ArrayView<const GO> fineNodeGIDs = fineCoordinatesMap->getLocalElementList();
158 Array<GO> coarseStartIndices(3);
159 for (
int dim = 0; dim < 3; ++dim) {
160 coarseStartIndices[dim] = this->coarseMeshData[myRankIndex][2 * dim + 3];
165 for (LO coarseLID = 0; coarseLID < this->getNumLocalCoarseNodes(); ++coarseLID) {
166 Array<LO> coarseIndices(3), fineIndices(3), gCoarseIndices(3);
167 this->getCoarseNodeLocalTuple(coarseLID,
171 getCoarseNodeFineLID(coarseIndices[0], coarseIndices[1], coarseIndices[2], fineLID);
172 coarseNodeFineGIDs[coarseLID] = fineNodeGIDs[fineLID];
174 LO myRankIndexCoarseNodesInDir0 = coarseMeshData[myRankIndex][4] - coarseMeshData[myRankIndex][3] + 1;
175 LO myRankIndexCoarseNodes10 = (coarseMeshData[myRankIndex][6] - coarseMeshData[myRankIndex][5] + 1) * myRankIndexCoarseNodesInDir0;
176 LO myCoarseLID = coarseIndices[2] * myRankIndexCoarseNodes10 + coarseIndices[1] * myRankIndexCoarseNodesInDir0 + coarseIndices[0];
177 GO myCoarseGID = myCoarseLID + coarseMeshData[myRankIndex][9];
178 coarseNodeCoarseGIDs[coarseLID] = myCoarseGID;
185 const Array<LO> coarseNodeFineIndices,
186 GO& myGID, LO& myPID, LO& myLID)
const {
187 LO ni = -1, nj = -1, li = -1, lj = -1, lk = -1;
188 LO myRankGuess = myRankIndex;
190 if (iGhosted == 0 && this->ghostInterface[0]) {
192 }
else if ((iGhosted == this->ghostedNodesPerDir[0] - 1) && this->ghostInterface[1]) {
195 if (jGhosted == 0 && this->ghostInterface[2]) {
197 }
else if ((jGhosted == this->ghostedNodesPerDir[1] - 1) && this->ghostInterface[3]) {
200 if (kGhosted == 0 && this->ghostInterface[4]) {
201 myRankGuess -= pj * pi;
202 }
else if ((kGhosted == this->ghostedNodesPerDir[2] - 1) && this->ghostInterface[5]) {
203 myRankGuess += pj * pi;
205 if (coarseNodeFineIndices[0] >= meshData[myRankGuess][3] && coarseNodeFineIndices[0] <= meshData[myRankGuess][4] && coarseNodeFineIndices[1] >= meshData[myRankGuess][5] && coarseNodeFineIndices[1] <= meshData[myRankGuess][6] && coarseNodeFineIndices[2] >= meshData[myRankGuess][7] && coarseNodeFineIndices[2] <= meshData[myRankGuess][8] && myRankGuess < numRanks - 1) {
206 myPID = meshData[myRankGuess][0];
207 ni = meshData[myRankGuess][4] - meshData[myRankGuess][3] + 1;
208 nj = meshData[myRankGuess][6] - meshData[myRankGuess][5] + 1;
209 li = coarseNodeFineIndices[0] - meshData[myRankGuess][3];
210 lj = coarseNodeFineIndices[1] - meshData[myRankGuess][5];
211 lk = coarseNodeFineIndices[2] - meshData[myRankGuess][7];
212 myLID = lk * nj * ni + lj * ni + li;
213 myGID = meshData[myRankGuess][9] + myLID;
217 auto nodeRank = std::find_if(myBlockStart, myBlockEnd,
218 [coarseNodeFineIndices](
const std::vector<GO>& vec) {
219 if (coarseNodeFineIndices[0] >= vec[3] && coarseNodeFineIndices[0] <= vec[4] && coarseNodeFineIndices[1] >= vec[5] && coarseNodeFineIndices[1] <= vec[6] && coarseNodeFineIndices[2] >= vec[7] && coarseNodeFineIndices[2] <= vec[8]) {
225 myPID = (*nodeRank)[0];
226 ni = (*nodeRank)[4] - (*nodeRank)[3] + 1;
227 nj = (*nodeRank)[6] - (*nodeRank)[5] + 1;
228 li = coarseNodeFineIndices[0] - (*nodeRank)[3];
229 lj = coarseNodeFineIndices[1] - (*nodeRank)[5];
230 lk = coarseNodeFineIndices[2] - (*nodeRank)[7];
231 myLID = lk * nj * ni + lj * ni + li;
232 myGID = (*nodeRank)[9] + myLID;
239 std::sort(meshData.begin(), meshData.end(),
240 [](
const std::vector<GO>& a,
const std::vector<GO>& b) ->
bool {
244 }
else if (a[2] == b[2]) {
247 }
else if (a[7] == b[7]) {
250 }
else if (a[5] == b[5]) {
260 numBlocks = meshData[numRanks - 1][2] + 1;
262 myBlockStart = std::lower_bound(meshData.begin(), meshData.end(), myBlock - 1,
263 [](
const std::vector<GO>& vec,
const GO val) ->
bool {
264 return (vec[2] < val) ? true : false;
266 myBlockEnd = std::upper_bound(meshData.begin(), meshData.end(), myBlock,
267 [](
const GO val,
const std::vector<GO>& vec) ->
bool {
268 return (val < vec[2]) ? true : false;
273 auto myKEnd = std::upper_bound(myBlockStart, myBlockEnd, (*myBlockStart)[3],
274 [](
const GO val,
const std::vector<GO>& vec) ->
bool {
275 return (val < vec[7]) ?
true : false;
277 auto myJEnd = std::upper_bound(myBlockStart, myKEnd, (*myBlockStart)[3],
278 [](
const GO val,
const std::vector<GO>& vec) ->
bool {
279 return (val < vec[5]) ?
true : false;
281 pi = std::distance(myBlockStart, myJEnd);
282 pj = std::distance(myBlockStart, myKEnd) / pi;
283 pk = std::distance(myBlockStart, myBlockEnd) / (pj * pi);
286 const int MyRank = myRank;
287 myRankIndex = std::distance(meshData.begin(),
288 std::find_if(myBlockStart, myBlockEnd,
289 [MyRank](
const std::vector<GO>& vec) ->
bool {
290 return (vec[0] == MyRank) ? true : false;
294 for (
int rankIndex = 0; rankIndex < numRanks; ++rankIndex) {
295 rankIndices[meshData[rankIndex][0]] = rankIndex;
302 Array<LO> rankOffset(3);
303 for (
int rank = 0; rank < numRanks; ++rank) {
304 coarseMeshData[rank].resize(10);
305 coarseMeshData[rank][0] = meshData[rank][0];
306 coarseMeshData[rank][1] = meshData[rank][1];
307 coarseMeshData[rank][2] = meshData[rank][2];
308 for (
int dim = 0; dim < 3; ++dim) {
309 coarseMeshData[rank][3 + 2 * dim] = meshData[rank][3 + 2 * dim] / this->coarseRate[dim];
310 if (meshData[rank][3 + 2 * dim] % this->coarseRate[dim] > 0) {
311 ++coarseMeshData[rank][3 + 2 * dim];
313 coarseMeshData[rank][3 + 2 * dim + 1] = meshData[rank][3 + 2 * dim + 1] / this->coarseRate[dim];
314 if (meshData[rank][3 + 2 * dim + 1] == this->gFineNodesPerDir[dim] - 1 &&
315 meshData[rank][3 + 2 * dim + 1] % this->coarseRate[dim] > 0) {
317 ++coarseMeshData[rank][3 + 2 * dim + 1];
321 coarseMeshData[rank][9] = coarseMeshData[rank - 1][9] + (coarseMeshData[rank - 1][8] - coarseMeshData[rank - 1][7] + 1) * (coarseMeshData[rank - 1][6] - coarseMeshData[rank - 1][5] + 1) * (coarseMeshData[rank - 1][4] - coarseMeshData[rank - 1][3] + 1);
405 const LO multiplier[3] = {1, this->lFineNodesPerDir[0], this->lNumFineNodes10};
406 const LO indices[3] = {i, j, k};
409 for (
int dim = 0; dim < 3; ++dim) {
410 if ((indices[dim] == this->getLocalCoarseNodesInDir(dim) - 1) && this->meshEdge[2 * dim + 1]) {
413 myLID += (this->getLocalFineNodesInDir(dim) - 1) * multiplier[dim];
415 myLID += (indices[dim] * this->getCoarseningRate(dim) + this->getCoarseNodeOffset(dim)) * multiplier[dim];