MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_GlobalLexicographicIndexManager_def.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// MueLu: A package for multigrid based preconditioning
4//
5// Copyright 2012 NTESS and the MueLu contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef MUELU_GLOBALLEXICOGRAPHICINDEXMANAGER_DEF_HPP_
11#define MUELU_GLOBALLEXICOGRAPHICINDEXMANAGER_DEF_HPP_
12
14#include <Xpetra_MapFactory.hpp>
15
16namespace MueLu {
17
18template <class LocalOrdinal, class GlobalOrdinal, class Node>
20 GlobalLexicographicIndexManager(const RCP<const Teuchos::Comm<int> > comm, const bool coupled,
21 const int NumDimensions, const int interpolationOrder,
22 const Array<GO> GFineNodesPerDir,
23 const Array<LO> LFineNodesPerDir, const Array<LO> CoarseRate,
24 const GO MinGlobalIndex)
25 : IndexManager(comm, coupled, false, NumDimensions, interpolationOrder, GFineNodesPerDir, LFineNodesPerDir) {
26 // Load coarse rate, being careful about formating.
27 for (int dim = 0; dim < 3; ++dim) {
28 if (dim < this->numDimensions) {
29 if (CoarseRate.size() == 1) {
30 this->coarseRate[dim] = CoarseRate[0];
31 } else if (CoarseRate.size() == this->numDimensions) {
32 this->coarseRate[dim] = CoarseRate[dim];
33 }
34 } else {
35 this->coarseRate[dim] = 1;
36 }
37 }
38
39 {
40 GO tmp = 0;
41 this->startIndices[2] = MinGlobalIndex / (this->gFineNodesPerDir[1] * this->gFineNodesPerDir[0]);
42 tmp = MinGlobalIndex % (this->gFineNodesPerDir[1] * this->gFineNodesPerDir[0]);
43 this->startIndices[1] = tmp / this->gFineNodesPerDir[0];
44 this->startIndices[0] = tmp % this->gFineNodesPerDir[0];
45
46 for (int dim = 0; dim < 3; ++dim) {
47 this->startIndices[dim + 3] = this->startIndices[dim] + this->lFineNodesPerDir[dim] - 1;
48 }
49 }
50
53}
54
55template <class LocalOrdinal, class GlobalOrdinal, class Node>
58 this->gNumCoarseNodes10 = this->gCoarseNodesPerDir[0] * this->gCoarseNodesPerDir[1];
59 this->gNumCoarseNodes = this->gNumCoarseNodes10 * this->gCoarseNodesPerDir[2];
60}
61
62template <class LocalOrdinal, class GlobalOrdinal, class Node>
64 getGhostedNodesData(const RCP<const Map> fineMap,
65 Array<LO>& ghostedNodeCoarseLIDs, Array<int>& ghostedNodeCoarsePIDs, Array<GO>& ghostedNodeCoarseGIDs) const {
66 ghostedNodeCoarseLIDs.resize(this->getNumLocalGhostedNodes());
67 ghostedNodeCoarsePIDs.resize(this->getNumLocalGhostedNodes());
68 ghostedNodeCoarseGIDs.resize(this->numGhostedNodes);
69
70 // Find the GIDs, LIDs and PIDs of the coarse points on the fine mesh and coarse
71 // mesh as this data will be used to fill vertex2AggId and procWinner vectors.
72 Array<GO> lCoarseNodeCoarseGIDs(this->lNumCoarseNodes),
73 lCoarseNodeFineGIDs(this->lNumCoarseNodes);
74 Array<GO> ghostedCoarseNodeFineGIDs(this->numGhostedNodes);
75 Array<LO> ghostedCoarseNodeCoarseIndices(3), ghostedCoarseNodeFineIndices(3), ijk(3);
76 LO currentIndex = -1, currentCoarseIndex = -1;
77 for (ijk[2] = 0; ijk[2] < this->ghostedNodesPerDir[2]; ++ijk[2]) {
78 for (ijk[1] = 0; ijk[1] < this->ghostedNodesPerDir[1]; ++ijk[1]) {
79 for (ijk[0] = 0; ijk[0] < this->ghostedNodesPerDir[0]; ++ijk[0]) {
80 currentIndex = ijk[2] * this->numGhostedNodes10 + ijk[1] * this->ghostedNodesPerDir[0] + ijk[0];
81 ghostedCoarseNodeCoarseIndices[0] = this->startGhostedCoarseNode[0] + ijk[0];
82 ghostedCoarseNodeCoarseIndices[1] = this->startGhostedCoarseNode[1] + ijk[1];
83 ghostedCoarseNodeCoarseIndices[2] = this->startGhostedCoarseNode[2] + ijk[2];
84 GO myCoarseGID = ghostedCoarseNodeCoarseIndices[0] + ghostedCoarseNodeCoarseIndices[1] * this->gCoarseNodesPerDir[0] + ghostedCoarseNodeCoarseIndices[2] * this->gNumCoarseNodes10;
85 ghostedNodeCoarseGIDs[currentIndex] = myCoarseGID;
86 GO myGID = 0, factor[3] = {};
87 factor[2] = this->gNumFineNodes10;
88 factor[1] = this->gFineNodesPerDir[0];
89 factor[0] = 1;
90 for (int dim = 0; dim < 3; ++dim) {
91 if (dim < this->numDimensions) {
92 if (this->startIndices[dim] - this->offsets[dim] + ijk[dim] * this->coarseRate[dim] < this->gFineNodesPerDir[dim] - 1) {
93 myGID += (this->startIndices[dim] - this->offsets[dim] + ijk[dim] * this->coarseRate[dim]) * factor[dim];
94 } else {
95 myGID += (this->startIndices[dim] - this->offsets[dim] + (ijk[dim] - 1) * this->coarseRate[dim] + this->endRate[dim]) * factor[dim];
96 }
97 }
98 }
99 // lbv 02-08-2018:
100 // This check is simplistic and should be replaced by a condition that checks
101 // if the local tuple of the current index is wihin the range of local nodes
102 // or not in the range of ghosted nodes.
103 if ((!this->ghostInterface[0] || ijk[0] != 0) &&
104 (!this->ghostInterface[2] || ijk[1] != 0) &&
105 (!this->ghostInterface[4] || ijk[2] != 0) &&
106 (!this->ghostInterface[1] || ijk[0] != this->ghostedNodesPerDir[0] - 1) &&
107 (!this->ghostInterface[3] || ijk[1] != this->ghostedNodesPerDir[1] - 1) &&
108 (!this->ghostInterface[5] || ijk[2] != this->ghostedNodesPerDir[2] - 1)) {
109 // this->getGhostedNodeFineLID(ijk[0], ijk[1], ijk[2], coarseNodeFineLID);
110 if (this->interpolationOrder_ == 0) {
111 currentCoarseIndex = 0;
112 if (this->ghostInterface[4]) {
113 currentCoarseIndex += (ijk[2] - 1) * this->lNumCoarseNodes10;
114 } else {
115 currentCoarseIndex += ijk[2] * this->lNumCoarseNodes10;
116 }
117 if (this->ghostInterface[2]) {
118 currentCoarseIndex += (ijk[1] - 1) * this->getLocalCoarseNodesInDir(0);
119 } else {
120 currentCoarseIndex += ijk[1] * this->getLocalCoarseNodesInDir(0);
121 }
122 if (this->ghostInterface[0]) {
123 currentCoarseIndex += ijk[0] - 1;
124 } else {
125 currentCoarseIndex += ijk[0];
126 }
127 } else {
128 this->getGhostedNodeCoarseLID(ijk[0], ijk[1], ijk[2], currentCoarseIndex);
129 }
130
131 lCoarseNodeCoarseGIDs[currentCoarseIndex] = myCoarseGID;
132 lCoarseNodeFineGIDs[currentCoarseIndex] = myGID;
133 }
134 ghostedCoarseNodeFineGIDs[currentIndex] = myGID;
135 }
136 }
137 }
138
139 RCP<const Map> coarseMap = Xpetra::MapFactory<LO, GO, NO>::Build(fineMap->lib(),
140 this->gNumCoarseNodes,
141 lCoarseNodeCoarseGIDs(),
142 fineMap->getIndexBase(),
143 fineMap->getComm());
144
145 coarseMap->getRemoteIndexList(ghostedNodeCoarseGIDs(),
146 ghostedNodeCoarsePIDs(),
147 ghostedNodeCoarseLIDs());
148
149} // End getGhostedMeshData
150
151template <class LocalOrdinal, class GlobalOrdinal, class Node>
153 getCoarseNodesData(const RCP<const Map> fineCoordinatesMap,
154 Array<GO>& coarseNodeCoarseGIDs,
155 Array<GO>& coarseNodeFineGIDs) const {
156 // Allocate sufficient storage space for outputs
157 coarseNodeCoarseGIDs.resize(this->getNumLocalCoarseNodes());
158 coarseNodeFineGIDs.resize(this->getNumLocalCoarseNodes());
159
160 // Load all the GIDs on the fine mesh
161 ArrayView<const GO> fineNodeGIDs = fineCoordinatesMap->getLocalElementList();
162
163 Array<GO> coarseStartIndices(3);
164 GO tmp;
165 for (int dim = 0; dim < 3; ++dim) {
166 coarseStartIndices[dim] = this->startIndices[dim] / this->coarseRate[dim];
167 tmp = this->startIndices[dim] % this->coarseRate[dim];
168 if (tmp > 0) {
169 ++coarseStartIndices[dim];
170 }
171 }
172
173 // Extract the fine LIDs of the coarse nodes and store the corresponding GIDs
174 LO fineLID;
175 Array<LO> lCoarseIndices(3);
176 Array<GO> gCoarseIndices(3);
177 for (LO coarseLID = 0; coarseLID < this->getNumLocalCoarseNodes(); ++coarseLID) {
178 this->getCoarseNodeLocalTuple(coarseLID,
179 lCoarseIndices[0],
180 lCoarseIndices[1],
181 lCoarseIndices[2]);
182 getCoarseNodeFineLID(lCoarseIndices[0], lCoarseIndices[1], lCoarseIndices[2], fineLID);
183 coarseNodeFineGIDs[coarseLID] = fineNodeGIDs[fineLID];
184
185 // Get Coarse Global IJK
186 for (int dim = 0; dim < 3; dim++) {
187 gCoarseIndices[dim] = coarseStartIndices[dim] + lCoarseIndices[dim];
188 }
189 getCoarseNodeGID(gCoarseIndices[0],
190 gCoarseIndices[1],
191 gCoarseIndices[2],
192 coarseNodeCoarseGIDs[coarseLID]);
193 }
194}
195
196template <class LocalOrdinal, class GlobalOrdinal, class Node>
198 getCoarseMeshData() const {
199 std::vector<std::vector<GO> > coarseMeshData;
200 return coarseMeshData;
201}
202
203template <class LocalOrdinal, class GlobalOrdinal, class Node>
205 getFineNodeGlobalTuple(const GO myGID, GO& i, GO& j, GO& k) const {
206 GO tmp;
207 k = myGID / this->gNumFineNodes10;
208 tmp = myGID % this->gNumFineNodes10;
209 j = tmp / this->gFineNodesPerDir[0];
210 i = tmp % this->gFineNodesPerDir[0];
211}
212
213template <class LocalOrdinal, class GlobalOrdinal, class Node>
215 getFineNodeLocalTuple(const LO myLID, LO& i, LO& j, LO& k) const {
216 LO tmp;
217 k = myLID / this->lNumFineNodes10;
218 tmp = myLID % this->lNumFineNodes10;
219 j = tmp / this->lFineNodesPerDir[0];
220 i = tmp % this->lFineNodesPerDir[0];
221}
222
223template <class LocalOrdinal, class GlobalOrdinal, class Node>
225 getFineNodeGhostedTuple(const LO myLID, LO& i, LO& j, LO& k) const {
226 LO tmp;
227 k = myLID / this->lNumFineNodes10;
228 tmp = myLID % this->lNumFineNodes10;
229 j = tmp / this->lFineNodesPerDir[0];
230 i = tmp % this->lFineNodesPerDir[0];
231
232 k += this->offsets[2];
233 j += this->offsets[1];
234 i += this->offsets[0];
235}
236
237template <class LocalOrdinal, class GlobalOrdinal, class Node>
239 getFineNodeGID(const GO i, const GO j, const GO k, GO& myGID) const {
240 myGID = k * this->gNumFineNodes10 + j * this->gFineNodesPerDir[0] + i;
241}
242
243template <class LocalOrdinal, class GlobalOrdinal, class Node>
245 getFineNodeLID(const LO i, const LO j, const LO k, LO& myLID) const {
246 myLID = k * this->lNumFineNodes10 + j * this->lFineNodesPerDir[0] + i;
247}
248
249template <class LocalOrdinal, class GlobalOrdinal, class Node>
251 getCoarseNodeGlobalTuple(const GO myGID, GO& i, GO& j, GO& k) const {
252 GO tmp;
253 k = myGID / this->gNumCoarseNodes10;
254 tmp = myGID % this->gNumCoarseNodes10;
255 j = tmp / this->gCoarseNodesPerDir[0];
256 i = tmp % this->gCoarseNodesPerDir[0];
257}
258
259template <class LocalOrdinal, class GlobalOrdinal, class Node>
261 getCoarseNodeLocalTuple(const LO myLID, LO& i, LO& j, LO& k) const {
262 LO tmp;
263 k = myLID / this->lNumCoarseNodes10;
264 tmp = myLID % this->lNumCoarseNodes10;
265 j = tmp / this->lCoarseNodesPerDir[0];
266 i = tmp % this->lCoarseNodesPerDir[0];
267}
268
269template <class LocalOrdinal, class GlobalOrdinal, class Node>
271 getCoarseNodeGID(const GO i, const GO j, const GO k, GO& myGID) const {
272 myGID = k * this->gNumCoarseNodes10 + j * this->gCoarseNodesPerDir[0] + i;
273}
274
275template <class LocalOrdinal, class GlobalOrdinal, class Node>
277 getCoarseNodeLID(const LO i, const LO j, const LO k, LO& myLID) const {
278 myLID = k * this->lNumCoarseNodes10 + j * this->lCoarseNodesPerDir[0] + i;
279}
280
281template <class LocalOrdinal, class GlobalOrdinal, class Node>
283 getCoarseNodeGhostedLID(const LO i, const LO j, const LO k, LO& myLID) const {
284 myLID = k * this->numGhostedNodes10 + j * this->ghostedNodesPerDir[0] + i;
285}
286
287template <class LocalOrdinal, class GlobalOrdinal, class Node>
289 getCoarseNodeFineLID(const LO i, const LO j, const LO k, LO& myLID) const {
290 // Assumptions: (i,j,k) is a tuple on the coarse mesh
291 // myLID is the corresponding local ID on the fine mesh
292 const LO multiplier[3] = {1, this->lFineNodesPerDir[0], this->lNumFineNodes10};
293 const LO indices[3] = {i, j, k};
294
295 myLID = 0;
296 for (int dim = 0; dim < 3; ++dim) {
297 if ((indices[dim] == this->getLocalCoarseNodesInDir(dim) - 1) && this->meshEdge[2 * dim + 1]) {
298 // We are dealing with the last node on the mesh in direction dim
299 // so we can simply use the number of nodes on the fine mesh in that direction
300 myLID += (this->getLocalFineNodesInDir(dim) - 1) * multiplier[dim];
301 } else {
302 myLID += (indices[dim] * this->getCoarseningRate(dim) + this->getCoarseNodeOffset(dim)) * multiplier[dim];
303 }
304 }
305}
306
307template <class LocalOrdinal, class GlobalOrdinal, class Node>
309 getGhostedNodeFineLID(const LO i, const LO j, const LO k, LO& myLID) const {
310 LO itmp = i - (this->offsets[0] > 0 ? 1 : 0);
311 LO jtmp = j - (this->offsets[1] > 0 ? 1 : 0);
312 LO ktmp = k - (this->offsets[2] > 0 ? 1 : 0);
313 myLID = 0;
314 if (ktmp * this->coarseRate[2] < this->lFineNodesPerDir[2]) {
315 myLID += ktmp * this->coarseRate[2] * this->lNumCoarseNodes10;
316 } else {
317 myLID += (this->lFineNodesPerDir[2] - 1) * this->lNumCoarseNodes10;
318 }
319
320 if (jtmp * this->coarseRate[1] < this->lFineNodesPerDir[1]) {
321 myLID += jtmp * this->coarseRate[1] * this->lFineNodesPerDir[0];
322 } else {
323 myLID += (this->lFineNodesPerDir[1] - 1) * this->lFineNodesPerDir[1];
324 }
325
326 if (itmp * this->coarseRate[0] < this->lFineNodesPerDir[0]) {
327 myLID += itmp * this->coarseRate[0];
328 } else {
329 myLID += this->lFineNodesPerDir[0] - 1;
330 }
331}
332
333template <class LocalOrdinal, class GlobalOrdinal, class Node>
335 getGhostedNodeCoarseLID(const LO i, const LO j, const LO k, LO& myLID) const {
336 LO itmp = i - (this->offsets[0] > 0 ? 1 : 0);
337 LO jtmp = j - (this->offsets[1] > 0 ? 1 : 0);
338 LO ktmp = k - (this->offsets[2] > 0 ? 1 : 0);
339 myLID = ktmp * this->lNumCoarseNodes10 + jtmp * this->lCoarseNodesPerDir[0] + itmp;
340}
341
342} // namespace MueLu
343
344#endif /* MUELU_GLOBALLEXICOGRAPHICINDEXMANAGER_DEF_HPP_ */
void getFineNodeGlobalTuple(const GO myGID, GO &i, GO &j, GO &k) const
void getCoarseNodeLocalTuple(const LO myLID, LO &i, LO &j, LO &k) const
void getGhostedNodeFineLID(const LO i, const LO j, const LO k, LO &myLID) const
void getFineNodeLocalTuple(const LO myLID, LO &i, LO &j, LO &k) const
void getCoarseNodesData(const RCP< const Map > fineCoordinatesMap, Array< GO > &coarseNodeCoarseGIDs, Array< GO > &coarseNodeFineGIDs) const
void getCoarseNodeGhostedLID(const LO i, const LO j, const LO k, LO &myLID) const
void getFineNodeGhostedTuple(const LO myLID, LO &i, LO &j, LO &k) const
void getGhostedNodeCoarseLID(const LO i, const LO j, const LO k, LO &myLID) const
void getCoarseNodeGID(const GO i, const GO j, const GO k, GO &myGID) const
void getCoarseNodeGlobalTuple(const GO myGID, GO &i, GO &j, GO &k) const
void getCoarseNodeFineLID(const LO i, const LO j, const LO k, LO &myLID) const
void getFineNodeGID(const GO i, const GO j, const GO k, GO &myGID) const
void getFineNodeLID(const LO i, const LO j, const LO k, LO &myLID) const
void getGhostedNodesData(const RCP< const Map > fineMap, Array< LO > &ghostedNodeCoarseLIDs, Array< int > &ghostedNodeCoarsePIDs, Array< GO > &ghostedNodeCoarseGIDs) const
void getCoarseNodeLID(const LO i, const LO j, const LO k, LO &myLID) const
Container class for mesh layout and indices calculation.
const Array< LO > lFineNodesPerDir
local number of nodes per direction.
Array< GO > startIndices
lowest global tuple (i,j,k) of a node on the local process
Array< int > coarseRate
coarsening rate in each direction
const int numDimensions
Number of spacial dimensions in the problem.
const Array< GO > gFineNodesPerDir
global number of nodes per direction.
Namespace for MueLu classes and methods.