10#ifndef MUELU_LOCALLEXICOGRAPHICINDEXMANAGER_DEF_HPP_
11#define MUELU_LOCALLEXICOGRAPHICINDEXMANAGER_DEF_HPP_
14#include <Xpetra_MapFactory.hpp>
18template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
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)
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) {
71template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
78template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
81 Array<LO>& ghostedNodeCoarseLIDs,
82 Array<int>& ghostedNodeCoarsePIDs,
83 Array<GO>& ghostedNodeCoarseGIDs)
const {
94 Array<LO> ghostedCoarseNodeCoarseIndices(3), ghostedCoarseNodeFineIndices(3);
95 Array<LO> lCoarseNodeCoarseIndices(3);
97 LO currentIndex = -1, countCoarseNodes = 0;
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;
103 ghostedCoarseNodeFineIndices[0] = ghostedCoarseNodeCoarseIndices[0] * this->
coarseRate[0];
108 ghostedCoarseNodeFineIndices[1] = ghostedCoarseNodeCoarseIndices[1] * this->coarseRate[1];
113 ghostedCoarseNodeFineIndices[2] = ghostedCoarseNodeCoarseIndices[2] * this->coarseRate[2];
118 GO myGID = -1, myCoarseGID = -1;
119 LO myLID = -1, myPID = -1, myCoarseLID = -1;
123 for (
int dim = 0; dim < 3; ++dim) {
125 lCoarseNodeCoarseIndices[dim] = ghostedCoarseNodeCoarseIndices[dim] -
coarseMeshData[rankIndex][3 + 2 * dim];
130 myCoarseLID = lCoarseNodeCoarseIndices[2] * myRankIndexCoarseNodes10 + lCoarseNodeCoarseIndices[1] * myRankIndexCoarseNodesInDir0 + lCoarseNodeCoarseIndices[0];
133 ghostedNodeCoarseLIDs[currentIndex] = myCoarseLID;
134 ghostedNodeCoarsePIDs[currentIndex] = myPID;
135 ghostedNodeCoarseGIDs[currentIndex] = myCoarseGID;
138 lCoarseNodeCoarseGIDs[countCoarseNodes] = myCoarseGID;
146template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
149 Array<GO>& coarseNodeCoarseGIDs,
150 Array<GO>& coarseNodeFineGIDs)
const {
156 ArrayView<const GO> fineNodeGIDs = fineCoordinatesMap->getLocalElementList();
158 Array<GO> coarseStartIndices(3);
159 for (
int dim = 0; dim < 3; ++dim) {
166 Array<LO> coarseIndices(3), fineIndices(3), gCoarseIndices(3);
172 coarseNodeFineGIDs[coarseLID] = fineNodeGIDs[fineLID];
176 LO myCoarseLID = coarseIndices[2] * myRankIndexCoarseNodes10 + coarseIndices[1] * myRankIndexCoarseNodesInDir0 + coarseIndices[0];
178 coarseNodeCoarseGIDs[coarseLID] = myCoarseGID;
182template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
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;
201 myRankGuess -=
pj *
pi;
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) {
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;
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;
236template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
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;
299template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
302 Array<LO> rankOffset(3);
303 for (
int rank = 0; rank <
numRanks; ++rank) {
308 for (
int dim = 0; dim < 3; ++dim) {
326template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
330template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
335template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
345template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
359template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
364template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
369template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
374template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
384template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
389template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
394template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
400template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
406 const LO indices[3] = {i, j, k};
409 for (
int dim = 0; dim < 3; ++dim) {
420template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
425template <
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.