46#ifndef MUELU_LOCALLEXICOGRAPHICINDEXMANAGER_DEF_HPP_
47#define MUELU_LOCALLEXICOGRAPHICINDEXMANAGER_DEF_HPP_
50#include <Xpetra_MapFactory.hpp>
54 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
57 const int NumDimensions,
const int interpolationOrder,
58 const int MyRank,
const int NumRanks,
59 const Array<GO> GFineNodesPerDir,
const Array<LO> LFineNodesPerDir,
60 const Array<LO> CoarseRate,
const Array<GO> MeshData) :
61 IndexManager(comm, coupled, false, NumDimensions, interpolationOrder, GFineNodesPerDir, LFineNodesPerDir),
70 for(
int dim = 0; dim < 3; ++dim) {
72 if(CoarseRate.size() == 1) {
74 }
else if(CoarseRate.size() == this->numDimensions) {
83 for(
int rank = 0; rank <
numRanks; ++rank) {
85 for(
int entry = 0; entry < 10; ++entry) {
86 meshData[rank][entry] = MeshData[10*rank + entry];
97 for(
int dim = 0; dim < 3; ++dim) {
107 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
114 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
117 Array<LO>& ghostedNodeCoarseLIDs,
118 Array<int>& ghostedNodeCoarsePIDs,
119 Array<GO>& ghostedNodeCoarseGIDs)
const {
131 Array<LO> ghostedCoarseNodeCoarseIndices(3), ghostedCoarseNodeFineIndices(3);
132 Array<LO> lCoarseNodeCoarseIndices(3);
134 LO currentIndex = -1, countCoarseNodes = 0;
136 for(
int j = 0; j < this->ghostedNodesPerDir[1]; ++j) {
137 for(
int i = 0; i < this->ghostedNodesPerDir[0]; ++i) {
140 ghostedCoarseNodeFineIndices[0] = ghostedCoarseNodeCoarseIndices[0]*this->
coarseRate[0];
145 ghostedCoarseNodeFineIndices[1] = ghostedCoarseNodeCoarseIndices[1]*this->coarseRate[1];
150 ghostedCoarseNodeFineIndices[2] = ghostedCoarseNodeCoarseIndices[2]*this->coarseRate[2];
155 GO myGID = -1, myCoarseGID = -1;
156 LO myLID = -1, myPID = -1, myCoarseLID = -1;
160 for(
int dim = 0; dim < 3; ++dim) {
162 lCoarseNodeCoarseIndices[dim] = ghostedCoarseNodeCoarseIndices[dim]
170 *myRankIndexCoarseNodesInDir0;
171 myCoarseLID = lCoarseNodeCoarseIndices[2]*myRankIndexCoarseNodes10
172 + lCoarseNodeCoarseIndices[1]*myRankIndexCoarseNodesInDir0
173 + lCoarseNodeCoarseIndices[0];
176 ghostedNodeCoarseLIDs[currentIndex] = myCoarseLID;
177 ghostedNodeCoarsePIDs[currentIndex] = myPID;
178 ghostedNodeCoarseGIDs[currentIndex] = myCoarseGID;
181 lCoarseNodeCoarseGIDs[countCoarseNodes] = myCoarseGID;
189 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
192 Array<GO>& coarseNodeCoarseGIDs,
193 Array<GO>& coarseNodeFineGIDs)
const {
200 ArrayView<const GO> fineNodeGIDs = fineCoordinatesMap->getLocalElementList();
202 Array<GO> coarseStartIndices(3);
203 for(
int dim = 0; dim < 3; ++dim) {
210 Array<LO> coarseIndices(3), fineIndices(3), gCoarseIndices(3);
216 coarseNodeFineGIDs[coarseLID] = fineNodeGIDs[fineLID];
222 *myRankIndexCoarseNodesInDir0;
223 LO myCoarseLID = coarseIndices[2]*myRankIndexCoarseNodes10
224 + coarseIndices[1]*myRankIndexCoarseNodesInDir0
227 coarseNodeCoarseGIDs[coarseLID] = myCoarseGID;
232 template<
class LocalOrdinal,
class GlobalOrdinal,
class Node>
235 const Array<LO> coarseNodeFineIndices,
236 GO& myGID, LO& myPID, LO& myLID)
const {
238 LO ni = -1, nj = -1, li = -1, lj = -1, lk = -1;
252 myRankGuess -=
pj*
pi;
254 myRankGuess +=
pj*
pi;
256 if(coarseNodeFineIndices[0] >=
meshData[myRankGuess][3]
257 && coarseNodeFineIndices[0] <=
meshData[myRankGuess][4]
258 && coarseNodeFineIndices[1] >=
meshData[myRankGuess][5]
259 && coarseNodeFineIndices[1] <=
meshData[myRankGuess][6]
260 && coarseNodeFineIndices[2] >=
meshData[myRankGuess][7]
261 && coarseNodeFineIndices[2] <=
meshData[myRankGuess][8]
266 li = coarseNodeFineIndices[0] -
meshData[myRankGuess][3];
267 lj = coarseNodeFineIndices[1] -
meshData[myRankGuess][5];
268 lk = coarseNodeFineIndices[2] -
meshData[myRankGuess][7];
269 myLID = lk*nj*ni + lj*ni + li;
270 myGID =
meshData[myRankGuess][9] + myLID;
275 [coarseNodeFineIndices](
const std::vector<GO>& vec){
276 if(coarseNodeFineIndices[0] >= vec[3]
277 && coarseNodeFineIndices[0] <= vec[4]
278 && coarseNodeFineIndices[1] >= vec[5]
279 && coarseNodeFineIndices[1] <= vec[6]
280 && coarseNodeFineIndices[2] >= vec[7]
281 && coarseNodeFineIndices[2] <= vec[8]) {
287 myPID = (*nodeRank)[0];
288 ni = (*nodeRank)[4] - (*nodeRank)[3] + 1;
289 nj = (*nodeRank)[6] - (*nodeRank)[5] + 1;
290 li = coarseNodeFineIndices[0] - (*nodeRank)[3];
291 lj = coarseNodeFineIndices[1] - (*nodeRank)[5];
292 lk = coarseNodeFineIndices[2] - (*nodeRank)[7];
293 myLID = lk*nj*ni + lj*ni + li;
294 myGID = (*nodeRank)[9] + myLID;
298 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
303 [](
const std::vector<GO>& a,
const std::vector<GO>& b)->bool {
307 }
else if(a[2] == b[2]) {
310 }
else if(a[7] == b[7]) {
313 }
else if(a[5] == b[5]) {
314 if(a[3] < b[3]) {return true;}
321 numBlocks = meshData[numRanks - 1][2] + 1;
323 myBlockStart = std::lower_bound(meshData.begin(), meshData.end(), myBlock - 1,
324 [] (
const std::vector<GO>& vec,
const GO val)->bool {
325 return (vec[2] < val) ? true : false;
327 myBlockEnd = std::upper_bound(meshData.begin(), meshData.end(), myBlock,
328 [] (
const GO val,
const std::vector<GO>& vec)->bool {
329 return (val < vec[2]) ? true : false;
334 auto myKEnd = std::upper_bound(myBlockStart, myBlockEnd, (*myBlockStart)[3],
335 [] (
const GO val,
const std::vector<GO>& vec)->
bool {
336 return (val < vec[7]) ? true :
false;
338 auto myJEnd = std::upper_bound(myBlockStart, myKEnd, (*myBlockStart)[3],
339 [] (
const GO val,
const std::vector<GO>& vec)->
bool {
340 return (val < vec[5]) ? true :
false;
342 pi = std::distance(myBlockStart, myJEnd);
343 pj = std::distance(myBlockStart, myKEnd) / pi;
344 pk = std::distance(myBlockStart, myBlockEnd) / (pj*pi);
347 const int MyRank = myRank;
348 myRankIndex = std::distance(meshData.begin(),
349 std::find_if(myBlockStart, myBlockEnd,
350 [MyRank] (
const std::vector<GO>& vec)->bool {
351 return (vec[0] == MyRank) ? true : false;
356 for(
int rankIndex = 0; rankIndex < numRanks; ++rankIndex) {
357 rankIndices[meshData[rankIndex][0]] = rankIndex;
361 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
364 Array<LO> rankOffset(3);
365 for(
int rank = 0; rank <
numRanks; ++rank) {
370 for(
int dim = 0; dim < 3; ++dim) {
391 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
395 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
400 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
410 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
424 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
429 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
434 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
439 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
449 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
454 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
459 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
465 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
471 const LO indices[3] = {i, j, k};
474 for(
int dim = 0; dim < 3; ++dim) {
486 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
491 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
LO getNumLocalGhostedNodes() const
Array< LO > offsets
distance between lowest (resp. highest) index to the lowest (resp. highest) ghostedNodeIndex in that ...
GO gNumCoarseNodes
global number of nodes remaining after coarsening.
const bool coupled_
Flag for coupled vs uncoupled aggregation mode, if true aggregation is coupled.
Array< LO > ghostedNodesPerDir
local number of ghosted nodes (i.e. ghost + coarse nodes) per direction
Array< GO > startGhostedCoarseNode
lowest coarse global tuple (i,j,k) of a node remaing on the local process after coarsening.
const Array< LO > lFineNodesPerDir
local number of nodes per direction.
LO numGhostedNodes10
local number of ghosted nodes (i.e. ghost + coarse nodes) per 0-1 slice.
Array< GO > gCoarseNodesPerDir
global number of nodes per direction remaining after coarsening.
int getCoarseningRate(const int dim) const
void computeMeshParameters()
Array< GO > startIndices
lowest global tuple (i,j,k) of a node on the local process
LO lNumCoarseNodes
local number of nodes remaining after coarsening.
Array< int > coarseRate
coarsening rate in each direction
LO getLocalCoarseNodesInDir(const int dim) const
LO getNumLocalCoarseNodes() const
bool meshEdge[6]
flags indicating if we run into the edge of the mesh in ilo, ihi, jlo, jhi, klo or khi.
bool ghostInterface[6]
flags indicating if ghost points are needed at ilo, ihi, jlo, jhi, klo and khi boundaries.
const int numDimensions
Number of spacial dimensions in the problem.
LO lNumCoarseNodes10
local number of nodes per 0-1 slice remaining after coarsening.
LO lNumFineNodes10
local number of nodes per 0-1 slice.
LO getCoarseNodeOffset(int const dim) const
GO gNumCoarseNodes10
global number of nodes per 0-1 slice remaining after coarsening.
LO numGhostedNodes
local number of ghosted nodes (i.e. ghost + coarse nodes).
const Array< GO > gFineNodesPerDir
global number of nodes per direction.
Array< LO > lCoarseNodesPerDir
local number of nodes per direction remaing after coarsening.
LO getLocalFineNodesInDir(const int dim) const
std::vector< std::vector< GO > >::iterator myBlockEnd
void getGhostedNodesData(const RCP< const Map > fineMap, Array< LO > &ghostedNodeCoarseLIDs, Array< int > &ghostedNodeCoarsePIDs, Array< GO > &ghostedNodeCoarseGIDs) const
const int numRanks
Number of ranks used to decompose the problem.
void computeGlobalCoarseParameters()
int myRankIndex
local process index for record in meshData after sorting.
void sortLocalLexicographicData()
int myBlock
local mesh block ID.
void getGIDLocalLexicographic(const LO iGhosted, const LO jGhosted, const LO kGhosted, const Array< LO > coarseNodeFineIndices, GO &myGID, LO &myPID, LO &myLID) const
LocalLexicographicIndexManager()=default
std::vector< std::vector< GO > > meshData
layout of indices accross all processes.
std::vector< std::vector< GO > > coarseMeshData
layout of indices accross all processes after coarsening.
Array< int > rankIndices
mapping between rank ID and reordered rank ID.
void getCoarseNodeLocalTuple(const LO myLID, LO &i, LO &j, LO &k) const
const int myRank
Local rank ID.
std::vector< std::vector< GO > >::iterator myBlockStart
void getCoarseNodeFineLID(const LO i, const LO j, const LO k, LO &myLID) const
void getCoarseNodesData(const RCP< const Map > fineCoordinatesMap, Array< GO > &coarseNodeCoarseGIDs, Array< GO > &coarseNodeFineGIDs) const
void computeCoarseLocalLexicographicData()
Namespace for MueLu classes and methods.