MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_GlobalLexicographicIndexManager_def.hpp
Go to the documentation of this file.
1// @HEADER
2//
3// ***********************************************************************
4//
5// MueLu: A package for multigrid based preconditioning
6// Copyright 2012 Sandia Corporation
7//
8// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9// the U.S. Government retains certain rights in this software.
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17//
18// 2. Redistributions in binary form must reproduce the above copyright
19// notice, this list of conditions and the following disclaimer in the
20// documentation and/or other materials provided with the distribution.
21//
22// 3. Neither the name of the Corporation nor the names of the
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Questions? Contact
39// Jonathan Hu (jhu@sandia.gov)
40// Ray Tuminaro (rstumin@sandia.gov)
41// Luc Berger-Vergoat (lberge@sandia.gov)
42//
43// ***********************************************************************
44//
45// @HEADER
46#ifndef MUELU_GLOBALLEXICOGRAPHICINDEXMANAGER_DEF_HPP_
47#define MUELU_GLOBALLEXICOGRAPHICINDEXMANAGER_DEF_HPP_
48
50#include <Xpetra_MapFactory.hpp>
51
52namespace MueLu {
53
54 template <class LocalOrdinal, class GlobalOrdinal, class Node>
56 GlobalLexicographicIndexManager(const RCP<const Teuchos::Comm<int> > comm, const bool coupled,
57 const int NumDimensions, const int interpolationOrder,
58 const Array<GO> GFineNodesPerDir,
59 const Array<LO> LFineNodesPerDir, const Array<LO> CoarseRate,
60 const GO MinGlobalIndex) :
61 IndexManager(comm, coupled, false, NumDimensions, interpolationOrder, GFineNodesPerDir, LFineNodesPerDir) {
62
63 // Load coarse rate, being careful about formating.
64 for(int dim = 0; dim < 3; ++dim) {
65 if(dim < this->numDimensions) {
66 if(CoarseRate.size() == 1) {
67 this->coarseRate[dim] = CoarseRate[0];
68 } else if(CoarseRate.size() == this->numDimensions) {
69 this->coarseRate[dim] = CoarseRate[dim];
70 }
71 } else {
72 this->coarseRate[dim] = 1;
73 }
74 }
75
76 {
77 GO tmp = 0;
78 this->startIndices[2]= MinGlobalIndex / (this->gFineNodesPerDir[1]*this->gFineNodesPerDir[0]);
79 tmp = MinGlobalIndex % (this->gFineNodesPerDir[1]*this->gFineNodesPerDir[0]);
80 this->startIndices[1]= tmp / this->gFineNodesPerDir[0];
81 this->startIndices[0]= tmp % this->gFineNodesPerDir[0];
82
83 for(int dim = 0; dim < 3; ++dim) {
84 this->startIndices[dim + 3] = this->startIndices[dim] + this->lFineNodesPerDir[dim] - 1;
85 }
86 }
87
90
91 }
92
93 template <class LocalOrdinal, class GlobalOrdinal, class Node>
96 this->gNumCoarseNodes10 = this->gCoarseNodesPerDir[0]*this->gCoarseNodesPerDir[1];
97 this->gNumCoarseNodes = this->gNumCoarseNodes10*this->gCoarseNodesPerDir[2];
98 }
99
100 template <class LocalOrdinal, class GlobalOrdinal, class Node>
102 getGhostedNodesData(const RCP<const Map> fineMap,
103 Array<LO>& ghostedNodeCoarseLIDs, Array<int>& ghostedNodeCoarsePIDs, Array<GO>&ghostedNodeCoarseGIDs) const {
104
105 ghostedNodeCoarseLIDs.resize(this->getNumLocalGhostedNodes());
106 ghostedNodeCoarsePIDs.resize(this->getNumLocalGhostedNodes());
107 ghostedNodeCoarseGIDs.resize(this->numGhostedNodes);
108
109 // Find the GIDs, LIDs and PIDs of the coarse points on the fine mesh and coarse
110 // mesh as this data will be used to fill vertex2AggId and procWinner vectors.
111 Array<GO> lCoarseNodeCoarseGIDs(this->lNumCoarseNodes),
112 lCoarseNodeFineGIDs(this->lNumCoarseNodes);
113 Array<GO> ghostedCoarseNodeFineGIDs(this->numGhostedNodes);
114 Array<LO> ghostedCoarseNodeCoarseIndices(3), ghostedCoarseNodeFineIndices(3), ijk(3);
115 LO currentIndex = -1, currentCoarseIndex = -1;
116 for(ijk[2] = 0; ijk[2] < this->ghostedNodesPerDir[2]; ++ijk[2]) {
117 for(ijk[1] = 0; ijk[1] < this->ghostedNodesPerDir[1]; ++ijk[1]) {
118 for(ijk[0] = 0; ijk[0] < this->ghostedNodesPerDir[0]; ++ijk[0]) {
119 currentIndex = ijk[2]*this->numGhostedNodes10 + ijk[1]*this->ghostedNodesPerDir[0] + ijk[0];
120 ghostedCoarseNodeCoarseIndices[0] = this->startGhostedCoarseNode[0] + ijk[0];
121 ghostedCoarseNodeCoarseIndices[1] = this->startGhostedCoarseNode[1] + ijk[1];
122 ghostedCoarseNodeCoarseIndices[2] = this->startGhostedCoarseNode[2] + ijk[2];
123 GO myCoarseGID = ghostedCoarseNodeCoarseIndices[0]
124 + ghostedCoarseNodeCoarseIndices[1]*this->gCoarseNodesPerDir[0]
125 + ghostedCoarseNodeCoarseIndices[2]*this->gNumCoarseNodes10;
126 ghostedNodeCoarseGIDs[currentIndex] = myCoarseGID;
127 GO myGID = 0, factor[3] = {};
128 factor[2] = this->gNumFineNodes10;
129 factor[1] = this->gFineNodesPerDir[0];
130 factor[0] = 1;
131 for(int dim = 0; dim < 3; ++dim) {
132 if(dim < this->numDimensions) {
133 if(this->startIndices[dim] - this->offsets[dim] + ijk[dim]*this->coarseRate[dim]
134 < this->gFineNodesPerDir[dim] - 1) {
135 myGID += (this->startIndices[dim] - this->offsets[dim]
136 + ijk[dim]*this->coarseRate[dim])*factor[dim];
137 } else {
138 myGID += (this->startIndices[dim] - this->offsets[dim] + (ijk[dim] - 1)
139 *this->coarseRate[dim] + this->endRate[dim])*factor[dim];
140 }
141 }
142 }
143 // lbv 02-08-2018:
144 // This check is simplistic and should be replaced by a condition that checks
145 // if the local tuple of the current index is wihin the range of local nodes
146 // or not in the range of ghosted nodes.
147 if((!this->ghostInterface[0] || ijk[0] != 0) &&
148 (!this->ghostInterface[2] || ijk[1] != 0) &&
149 (!this->ghostInterface[4] || ijk[2] != 0) &&
150 (!this->ghostInterface[1] || ijk[0] != this->ghostedNodesPerDir[0] - 1) &&
151 (!this->ghostInterface[3] || ijk[1] != this->ghostedNodesPerDir[1] - 1) &&
152 (!this->ghostInterface[5] || ijk[2] != this->ghostedNodesPerDir[2] - 1)) {
153
154 // this->getGhostedNodeFineLID(ijk[0], ijk[1], ijk[2], coarseNodeFineLID);
155 if(this->interpolationOrder_ == 0) {
156 currentCoarseIndex = 0;
157 if(this->ghostInterface[4]) {
158 currentCoarseIndex += (ijk[2] - 1)*this->lNumCoarseNodes10;
159 } else {
160 currentCoarseIndex += ijk[2]*this->lNumCoarseNodes10;
161 }
162 if(this->ghostInterface[2]) {
163 currentCoarseIndex += (ijk[1] - 1)*this->getLocalCoarseNodesInDir(0);
164 } else {
165 currentCoarseIndex += ijk[1]*this->getLocalCoarseNodesInDir(0);
166 }
167 if(this->ghostInterface[0]) {
168 currentCoarseIndex += ijk[0] - 1;
169 } else {
170 currentCoarseIndex += ijk[0];
171 }
172 } else {
173 this->getGhostedNodeCoarseLID(ijk[0], ijk[1], ijk[2], currentCoarseIndex);
174 }
175
176 lCoarseNodeCoarseGIDs[currentCoarseIndex] = myCoarseGID;
177 lCoarseNodeFineGIDs[currentCoarseIndex] = myGID;
178 }
179 ghostedCoarseNodeFineGIDs[currentIndex] = myGID;
180 }
181 }
182 }
183
184 RCP<const Map> coarseMap = Xpetra::MapFactory<LO,GO,NO>::Build (fineMap->lib(),
185 this->gNumCoarseNodes,
186 lCoarseNodeCoarseGIDs(),
187 fineMap->getIndexBase(),
188 fineMap->getComm());
189
190 coarseMap->getRemoteIndexList(ghostedNodeCoarseGIDs(),
191 ghostedNodeCoarsePIDs(),
192 ghostedNodeCoarseLIDs());
193
194 } // End getGhostedMeshData
195
196 template <class LocalOrdinal, class GlobalOrdinal, class Node>
198 getCoarseNodesData(const RCP<const Map> fineCoordinatesMap,
199 Array<GO>& coarseNodeCoarseGIDs,
200 Array<GO>& coarseNodeFineGIDs) const {
201
202 // Allocate sufficient storage space for outputs
203 coarseNodeCoarseGIDs.resize(this->getNumLocalCoarseNodes());
204 coarseNodeFineGIDs.resize(this->getNumLocalCoarseNodes());
205
206 // Load all the GIDs on the fine mesh
207 ArrayView<const GO> fineNodeGIDs = fineCoordinatesMap->getLocalElementList();
208
209 Array<GO> coarseStartIndices(3);
210 GO tmp;
211 for(int dim = 0; dim < 3; ++dim) {
212 coarseStartIndices[dim] = this->startIndices[dim] / this->coarseRate[dim];
213 tmp = this->startIndices[dim] % this->coarseRate[dim];
214 if(tmp > 0) {++coarseStartIndices[dim];}
215 }
216
217 // Extract the fine LIDs of the coarse nodes and store the corresponding GIDs
218 LO fineLID;
219 Array<LO> lCoarseIndices(3);
220 Array<GO> gCoarseIndices(3);
221 for(LO coarseLID = 0; coarseLID < this->getNumLocalCoarseNodes(); ++coarseLID) {
222 this->getCoarseNodeLocalTuple(coarseLID,
223 lCoarseIndices[0],
224 lCoarseIndices[1],
225 lCoarseIndices[2]);
226 getCoarseNodeFineLID(lCoarseIndices[0], lCoarseIndices[1], lCoarseIndices[2], fineLID);
227 coarseNodeFineGIDs[coarseLID] = fineNodeGIDs[fineLID];
228
229 // Get Coarse Global IJK
230 for(int dim=0; dim<3; dim++) {
231 gCoarseIndices[dim] = coarseStartIndices[dim] + lCoarseIndices[dim];
232 }
233 getCoarseNodeGID(gCoarseIndices[0],
234 gCoarseIndices[1],
235 gCoarseIndices[2],
236 coarseNodeCoarseGIDs[coarseLID] );
237
238 }
239
240 }
241
242 template <class LocalOrdinal, class GlobalOrdinal, class Node>
244 getCoarseMeshData() const {
245 std::vector<std::vector<GO> > coarseMeshData;
246 return coarseMeshData;
247 }
248
249 template <class LocalOrdinal, class GlobalOrdinal, class Node>
251 getFineNodeGlobalTuple(const GO myGID, GO& i, GO& j, GO& k) const {
252 GO tmp;
253 k = myGID / this->gNumFineNodes10;
254 tmp = myGID % this->gNumFineNodes10;
255 j = tmp / this->gFineNodesPerDir[0];
256 i = tmp % this->gFineNodesPerDir[0];
257 }
258
259 template <class LocalOrdinal, class GlobalOrdinal, class Node>
261 getFineNodeLocalTuple(const LO myLID, LO& i, LO& j, LO& k) const {
262 LO tmp;
263 k = myLID / this->lNumFineNodes10;
264 tmp = myLID % this->lNumFineNodes10;
265 j = tmp / this->lFineNodesPerDir[0];
266 i = tmp % this->lFineNodesPerDir[0];
267 }
268
269 template <class LocalOrdinal, class GlobalOrdinal, class Node>
271 getFineNodeGhostedTuple(const LO myLID, LO& i, LO& j, LO& k) const {
272 LO tmp;
273 k = myLID / this->lNumFineNodes10;
274 tmp = myLID % this->lNumFineNodes10;
275 j = tmp / this->lFineNodesPerDir[0];
276 i = tmp % this->lFineNodesPerDir[0];
277
278 k += this->offsets[2];
279 j += this->offsets[1];
280 i += this->offsets[0];
281 }
282
283 template <class LocalOrdinal, class GlobalOrdinal, class Node>
285 getFineNodeGID(const GO i, const GO j, const GO k, GO& myGID) const {
286 myGID = k*this->gNumFineNodes10 + j*this->gFineNodesPerDir[0] + i;
287 }
288
289 template <class LocalOrdinal, class GlobalOrdinal, class Node>
291 getFineNodeLID(const LO i, const LO j, const LO k, LO& myLID) const {
292 myLID = k*this->lNumFineNodes10 + j*this->lFineNodesPerDir[0] + i;
293 }
294
295 template <class LocalOrdinal, class GlobalOrdinal, class Node>
297 getCoarseNodeGlobalTuple(const GO myGID, GO& i, GO& j, GO& k) const {
298 GO tmp;
299 k = myGID / this->gNumCoarseNodes10;
300 tmp = myGID % this->gNumCoarseNodes10;
301 j = tmp / this->gCoarseNodesPerDir[0];
302 i = tmp % this->gCoarseNodesPerDir[0];
303 }
304
305 template <class LocalOrdinal, class GlobalOrdinal, class Node>
307 getCoarseNodeLocalTuple(const LO myLID, LO& i, LO& j, LO& k) const {
308 LO tmp;
309 k = myLID / this->lNumCoarseNodes10;
310 tmp = myLID % this->lNumCoarseNodes10;
311 j = tmp / this->lCoarseNodesPerDir[0];
312 i = tmp % this->lCoarseNodesPerDir[0];
313 }
314
315 template <class LocalOrdinal, class GlobalOrdinal, class Node>
317 getCoarseNodeGID(const GO i, const GO j, const GO k, GO& myGID) const {
318 myGID = k*this->gNumCoarseNodes10 + j*this->gCoarseNodesPerDir[0] + i;
319 }
320
321 template <class LocalOrdinal, class GlobalOrdinal, class Node>
323 getCoarseNodeLID(const LO i, const LO j, const LO k, LO& myLID) const {
324 myLID = k*this->lNumCoarseNodes10 + j*this->lCoarseNodesPerDir[0] + i;
325 }
326
327 template <class LocalOrdinal, class GlobalOrdinal, class Node>
329 getCoarseNodeGhostedLID(const LO i, const LO j, const LO k, LO& myLID) const {
330 myLID = k*this->numGhostedNodes10 + j*this->ghostedNodesPerDir[0] + i;
331 }
332
333 template <class LocalOrdinal, class GlobalOrdinal, class Node>
335 getCoarseNodeFineLID(const LO i, const LO j, const LO k, LO& myLID) const {
336 // Assumptions: (i,j,k) is a tuple on the coarse mesh
337 // myLID is the corresponding local ID on the fine mesh
338 const LO multiplier[3] = {1, this->lFineNodesPerDir[0], this->lNumFineNodes10};
339 const LO indices[3] = {i, j, k};
340
341 myLID = 0;
342 for(int dim = 0; dim < 3; ++dim) {
343 if((indices[dim] == this->getLocalCoarseNodesInDir(dim) - 1) && this->meshEdge[2*dim + 1]) {
344 // We are dealing with the last node on the mesh in direction dim
345 // so we can simply use the number of nodes on the fine mesh in that direction
346 myLID += (this->getLocalFineNodesInDir(dim) - 1)*multiplier[dim];
347 } else {
348 myLID += (indices[dim]*this->getCoarseningRate(dim) + this->getCoarseNodeOffset(dim))
349 *multiplier[dim];
350 }
351 }
352 }
353
354 template <class LocalOrdinal, class GlobalOrdinal, class Node>
356 getGhostedNodeFineLID(const LO i, const LO j, const LO k, LO& myLID) const {
357 LO itmp = i - (this->offsets[0] > 0 ? 1 : 0);
358 LO jtmp = j - (this->offsets[1] > 0 ? 1 : 0);
359 LO ktmp = k - (this->offsets[2] > 0 ? 1 : 0);
360 myLID = 0;
361 if(ktmp*this->coarseRate[2] < this->lFineNodesPerDir[2]) {
362 myLID += ktmp*this->coarseRate[2]*this->lNumCoarseNodes10;
363 } else {
364 myLID += (this->lFineNodesPerDir[2] - 1)*this->lNumCoarseNodes10;
365 }
366
367 if(jtmp*this->coarseRate[1] < this->lFineNodesPerDir[1]) {
368 myLID += jtmp*this->coarseRate[1]*this->lFineNodesPerDir[0];
369 } else {
370 myLID += (this->lFineNodesPerDir[1] - 1)*this->lFineNodesPerDir[1];
371 }
372
373 if(itmp*this->coarseRate[0] < this->lFineNodesPerDir[0]) {
374 myLID += itmp*this->coarseRate[0];
375 } else {
376 myLID += this->lFineNodesPerDir[0] - 1;
377 }
378 }
379
380 template <class LocalOrdinal, class GlobalOrdinal, class Node>
382 getGhostedNodeCoarseLID(const LO i, const LO j, const LO k, LO& myLID) const {
383 LO itmp = i - (this->offsets[0] > 0 ? 1 : 0);
384 LO jtmp = j - (this->offsets[1] > 0 ? 1 : 0);
385 LO ktmp = k - (this->offsets[2] > 0 ? 1 : 0);
386 myLID = ktmp*this->lNumCoarseNodes10 + jtmp*this->lCoarseNodesPerDir[0] + itmp;
387 }
388
389} //namespace MueLu
390
391#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.