145 Level& coarseLevel)
const {
149 using xdMV = Xpetra::MultiVector<typename Teuchos::ScalarTraits<Scalar>::coordinateType,LO,GO,NO>;
152 RCP<xdMV> fineCoords =
Get< RCP<xdMV> >(fineLevel,
"Coordinates");
153 RCP<xdMV> coarseCoords;
159 const LO blkSize = A->GetFixedBlockSize();
160 RCP<const Map> rowMap = A->getRowMap();
164 myGeometry->meshLayout = pL.get<std::string>(
"meshLayout");
166 if(myGeometry->meshLayout ==
"Local Lexicographic") {
170 "The meshData array is empty, somehow the input for geometric"
171 " multigrid are not captured correctly.");
172 myGeometry->meshData.resize(rowMap->getComm()->getSize());
173 for(
int i = 0; i < rowMap->getComm()->getSize(); ++i) {
174 myGeometry->meshData[i].resize(10);
175 for(
int j = 0; j < 10; ++j) {
176 myGeometry->meshData[i][j] = meshData[10*i + j];
183 "Coordinates cannot be accessed from fine level!");
184 myGeometry->numDimensions = fineCoords->getNumVectors();
188 myGeometry->gFineNodesPerDir = fineLevel.
Get<Array<GO> >(
"gNodesPerDim",
NoFactory::get());
189 myGeometry->lFineNodesPerDir = fineLevel.
Get<Array<LO> >(
"lNodesPerDim",
NoFactory::get());
192 myGeometry->gFineNodesPerDir =
Get<Array<GO> >(fineLevel,
"gNodesPerDim");
195 myGeometry->lFineNodesPerDir =
Get<Array<LO> >(fineLevel,
"lNodesPerDim");
197 myGeometry->gNumFineNodes10 = myGeometry->gFineNodesPerDir[1]*myGeometry->gFineNodesPerDir[0];
198 myGeometry->gNumFineNodes = myGeometry->gFineNodesPerDir[2]*myGeometry->gNumFineNodes10;
199 myGeometry->lNumFineNodes10 = myGeometry->lFineNodesPerDir[1]*myGeometry->lFineNodesPerDir[0];
200 myGeometry->lNumFineNodes = myGeometry->lFineNodesPerDir[2]*myGeometry->lNumFineNodes10;
202 TEUCHOS_TEST_FOR_EXCEPTION(fineCoords->getLocalLength()
203 !=
static_cast<size_t>(myGeometry->lNumFineNodes),
205 "The local number of elements in Coordinates is not equal to the"
206 " number of nodes given by: lNodesPerDim!");
207 TEUCHOS_TEST_FOR_EXCEPTION(fineCoords->getGlobalLength()
208 !=
static_cast<size_t>(myGeometry->gNumFineNodes),
210 "The global number of elements in Coordinates is not equal to the"
211 " number of nodes given by: gNodesPerDim!");
214 std::string coarsenRate = pL.get<std::string>(
"Coarsen");
215 Teuchos::Array<LO> crates;
217 crates = Teuchos::fromStringToArray<LO>(coarsenRate);
218 }
catch(
const Teuchos::InvalidArrayStringRepresentation& e) {
219 GetOStream(
Errors,-1) <<
" *** Coarsen must be a string convertible into an array! *** "
223 TEUCHOS_TEST_FOR_EXCEPTION((crates.size() > 1) && (crates.size() < myGeometry->numDimensions),
225 "Coarsen must have at least as many components as the number of"
226 " spatial dimensions in the problem.");
228 for(LO i = 0; i < 3; ++i) {
229 if(i < myGeometry->numDimensions) {
230 if(crates.size()==1) {
231 myGeometry->coarseRate[i] = crates[0];
232 }
else if(crates.size() == myGeometry->numDimensions) {
233 myGeometry->coarseRate[i] = crates[i];
236 myGeometry->coarseRate[i] = 1;
240 int interpolationOrder = pL.get<
int>(
"order");
241 TEUCHOS_TEST_FOR_EXCEPTION((interpolationOrder < 0) || (interpolationOrder > 1),
243 "The interpolation order can only be set to 0 or 1.");
246 Array<LO> mapDirG2L(3), mapDirL2G(3);
247 for(LO i = 0; i < myGeometry->numDimensions; ++i) {
250 for(LO i = 0; i < myGeometry->numDimensions; ++i) {
251 TEUCHOS_TEST_FOR_EXCEPTION(mapDirG2L[i] > myGeometry->numDimensions,
253 "axis permutation values must all be less than"
254 " the number of spatial dimensions.");
255 mapDirL2G[mapDirG2L[i]] = i;
257 RCP<const Map> fineCoordsMap = fineCoords->getMap();
260 RCP<NodesIDs> ghostedCoarseNodes = rcp(
new NodesIDs{});
261 Array<Array<GO> > lCoarseNodesGIDs(2);
262 if((fineLevel.
GetLevelID() == 0) && (myGeometry->meshLayout !=
"Global Lexicographic")) {
264 ghostedCoarseNodes, lCoarseNodesGIDs);
269 GetCoarsePoints(interpolationOrder, blkSize, fineCoordsMap, myGeometry, ghostedCoarseNodes,
278 RCP<const Map> stridedDomainMapP;
284 GO lnnzP = Teuchos::as<LO>(std::pow(interpolationOrder + 1, myGeometry->numDimensions))
285 *(myGeometry->lNumFineNodes - myGeometry->lNumCoarseNodes) + myGeometry->lNumCoarseNodes;
286 lnnzP = lnnzP*blkSize;
287 GO gnnzP = Teuchos::as<LO>(std::pow(interpolationOrder + 1, myGeometry->numDimensions))
288 *(myGeometry->gNumFineNodes - myGeometry->gNumCoarseNodes) + myGeometry->gNumCoarseNodes;
289 gnnzP = gnnzP*blkSize;
292 <<
" x " << blkSize*myGeometry->gNumCoarseNodes << std::endl;
294 << myGeometry->gFineNodesPerDir[1] <<
" -- "
295 << myGeometry->gFineNodesPerDir[2] << std::endl;
296 GetOStream(
Runtime1) <<
"P Coarse grid : " << myGeometry->gCoarseNodesPerDir[0] <<
" -- "
297 << myGeometry->gCoarseNodesPerDir[1] <<
" -- "
298 << myGeometry->gCoarseNodesPerDir[2] << std::endl;
302 A, P, coarseCoords, ghostedCoarseNodes, lCoarseNodesGIDs,
306 if (A->IsView(
"stridedMaps") ==
true) {
307 P->CreateView(
"stridedMaps", A->getRowMap(
"stridedMaps"), stridedDomainMapP);
309 P->CreateView(
"stridedMaps", P->getRangeMap(), stridedDomainMapP);
313 Set(coarseLevel,
"P", P);
314 Set(coarseLevel,
"coarseCoordinates", coarseCoords);
315 Set<Array<GO> >(coarseLevel,
"gCoarseNodesPerDim", myGeometry->gCoarseNodesPerDir);
316 Set<Array<LO> >(coarseLevel,
"lCoarseNodesPerDim", myGeometry->lCoarseNodesPerDir);
320 RCP<MultiVector> coarseNullspace = MultiVectorFactory::Build(P->getDomainMap(),
321 fineNullspace->getNumVectors());
322 P->apply(*fineNullspace, *coarseNullspace, Teuchos::TRANS, Teuchos::ScalarTraits<SC>::one(),
323 Teuchos::ScalarTraits<SC>::zero());
324 Set(coarseLevel,
"Nullspace", coarseNullspace);
331 RCP<GeometricData> myGeo, RCP<NodesIDs> ghostedCoarseNodes,
332 Array<Array<GO> >& lCoarseNodesGIDs)
const{
339 int numRanks = fineCoordsMap->getComm()->getSize();
340 int myRank = fineCoordsMap->getComm()->getRank();
342 myGeo->myBlock = myGeo->meshData[myRank][2];
343 myGeo->startIndices[0] = myGeo->meshData[myRank][3];
344 myGeo->startIndices[1] = myGeo->meshData[myRank][5];
345 myGeo->startIndices[2] = myGeo->meshData[myRank][7];
346 myGeo->startIndices[3] = myGeo->meshData[myRank][4];
347 myGeo->startIndices[4] = myGeo->meshData[myRank][6];
348 myGeo->startIndices[5] = myGeo->meshData[myRank][8];
349 std::sort(myGeo->meshData.begin(), myGeo->meshData.end(),
350 [](
const std::vector<GO>& a,
const std::vector<GO>& b)->bool {
354 }
else if(a[2] == b[2]) {
357 }
else if(a[7] == b[7]) {
360 }
else if(a[5] == b[5]) {
361 if(a[3] < b[3]) {return true;}
368 myGeo->numBlocks = myGeo->meshData[numRanks - 1][2] + 1;
370 auto myBlockStart = std::lower_bound(myGeo->meshData.begin(), myGeo->meshData.end(),
372 [](
const std::vector<GO>& vec,
const GO val)->bool{
373 return (vec[2] < val) ? true : false;
375 auto myBlockEnd = std::upper_bound(myGeo->meshData.begin(), myGeo->meshData.end(),
377 [](
const GO val,
const std::vector<GO>& vec)->bool{
378 return (val < vec[2]) ? true : false;
383 auto myKEnd = std::upper_bound(myBlockStart, myBlockEnd, (*myBlockStart)[3],
384 [](
const GO val,
const std::vector<GO>& vec)->
bool{
385 return (val < vec[7]) ? true :
false;
387 auto myJEnd = std::upper_bound(myBlockStart, myKEnd, (*myBlockStart)[3],
388 [](
const GO val,
const std::vector<GO>& vec)->
bool{
389 return (val < vec[5]) ? true :
false;
391 LO pi = std::distance(myBlockStart, myJEnd);
392 LO pj = std::distance(myBlockStart, myKEnd) / pi;
393 LO pk = std::distance(myBlockStart, myBlockEnd) / (pj*pi);
396 LO myRankIndex = std::distance(myGeo->meshData.begin(),
397 std::find_if(myBlockStart, myBlockEnd,
398 [myRank](
const std::vector<GO>& vec)->bool{
399 return (vec[0] == myRank) ? true : false;
403 for(
int dim = 0; dim < 3; ++dim) {
404 if(dim < myGeo->numDimensions) {
405 myGeo->offsets[dim]= Teuchos::as<LO>(myGeo->startIndices[dim]) % myGeo->coarseRate[dim];
406 myGeo->offsets[dim + 3]= Teuchos::as<LO>(myGeo->startIndices[dim]) % myGeo->coarseRate[dim];
412 for(
int dim = 0; dim < 3; ++dim) {
413 if(dim < myGeo->numDimensions && (myGeo->startIndices[dim] % myGeo->coarseRate[dim] != 0 ||
414 myGeo->startIndices[dim] == myGeo->gFineNodesPerDir[dim]-1)) {
415 myGeo->ghostInterface[2*dim] =
true;
417 if(dim < myGeo->numDimensions
418 && myGeo->startIndices[dim + 3] != myGeo->gFineNodesPerDir[dim] - 1
419 && (myGeo->lFineNodesPerDir[dim] == 1 ||
420 myGeo->startIndices[dim + 3] % myGeo->coarseRate[dim] != 0)) {
421 myGeo->ghostInterface[2*dim+1] =
true;
437 for(
int i = 0; i < 3; ++i) {
438 if(i < myGeo->numDimensions) {
441 myGeo->gCoarseNodesPerDir[i] = (myGeo->gFineNodesPerDir[i] - 1) / myGeo->coarseRate[i];
442 myGeo->endRate[i] = Teuchos::as<LO>((myGeo->gFineNodesPerDir[i] - 1) %myGeo->coarseRate[i]);
443 if(myGeo->endRate[i] == 0) {
444 myGeo->endRate[i] = myGeo->coarseRate[i];
445 ++myGeo->gCoarseNodesPerDir[i];
447 myGeo->gCoarseNodesPerDir[i] += 2;
450 myGeo->endRate[i] = 1;
451 myGeo->gCoarseNodesPerDir[i] = 1;
455 myGeo->gNumCoarseNodes = myGeo->gCoarseNodesPerDir[0]*myGeo->gCoarseNodesPerDir[1]
456 *myGeo->gCoarseNodesPerDir[2];
458 for(LO i = 0; i < 3; ++i) {
459 if(i < myGeo->numDimensions) {
463 if( (myGeo->startIndices[i] + myGeo->lFineNodesPerDir[i]) == myGeo->gFineNodesPerDir[i] ) {
464 myGeo->lCoarseNodesPerDir[i] = (myGeo->lFineNodesPerDir[i] - myGeo->endRate[i]
465 + myGeo->offsets[i] - 1) / myGeo->coarseRate[i] + 1;
466 if(myGeo->offsets[i] == 0) {++myGeo->lCoarseNodesPerDir[i];}
468 myGeo->lCoarseNodesPerDir[i] = (myGeo->lFineNodesPerDir[i] + myGeo->offsets[i] - 1)
469 / myGeo->coarseRate[i];
470 if(myGeo->offsets[i] == 0) {++myGeo->lCoarseNodesPerDir[i];}
473 myGeo->lCoarseNodesPerDir[i] = 1;
477 if(myGeo->lFineNodesPerDir[i] < 1) {myGeo->lCoarseNodesPerDir[i] = 0;}
483 myGeo->lNumCoarseNodes = myGeo->lCoarseNodesPerDir[0]*myGeo->lCoarseNodesPerDir[1]
484 *myGeo->lCoarseNodesPerDir[2];
487 for(
int dim = 0; dim < 3; ++dim) {
491 if(myGeo->startIndices[dim] == myGeo->gFineNodesPerDir[dim] - 1 &&
492 myGeo->startIndices[dim] % myGeo->coarseRate[dim] == 0) {
493 myGeo->startGhostedCoarseNode[dim] = myGeo->startIndices[dim] / myGeo->coarseRate[dim] - 1;
495 myGeo->startGhostedCoarseNode[dim] = myGeo->startIndices[dim] / myGeo->coarseRate[dim];
497 myGeo->ghostedCoarseNodesPerDir[dim] = myGeo->lCoarseNodesPerDir[dim];
499 if(myGeo->ghostInterface[2*dim]) {myGeo->ghostedCoarseNodesPerDir[dim] += 1;}
501 if(myGeo->ghostInterface[2*dim + 1]) {myGeo->ghostedCoarseNodesPerDir[dim] += 1;}
503 myGeo->lNumGhostedNodes = myGeo->ghostedCoarseNodesPerDir[2]*myGeo->ghostedCoarseNodesPerDir[1]
504 *myGeo->ghostedCoarseNodesPerDir[0];
505 myGeo->lNumGhostNodes = myGeo->lNumGhostedNodes - myGeo->lNumCoarseNodes;
506 ghostedCoarseNodes->PIDs.resize(myGeo->lNumGhostedNodes);
507 ghostedCoarseNodes->LIDs.resize(myGeo->lNumGhostedNodes);
508 ghostedCoarseNodes->GIDs.resize(myGeo->lNumGhostedNodes);
509 ghostedCoarseNodes->coarseGIDs.resize(myGeo->lNumGhostedNodes);
510 ghostedCoarseNodes->colInds.resize(myGeo->lNumGhostedNodes);
511 lCoarseNodesGIDs[0].resize(myGeo->lNumCoarseNodes);
512 lCoarseNodesGIDs[1].resize(myGeo->lNumCoarseNodes);
519 Array<LO> coarseNodeCoarseIndices(3), coarseNodeFineIndices(3);
520 LO currentIndex = -1, countCoarseNodes = 0;
521 for(
int k = 0; k < myGeo->ghostedCoarseNodesPerDir[2]; ++k) {
522 for(
int j = 0; j < myGeo->ghostedCoarseNodesPerDir[1]; ++j) {
523 for(
int i = 0; i < myGeo->ghostedCoarseNodesPerDir[0]; ++i) {
524 currentIndex = k*myGeo->ghostedCoarseNodesPerDir[1]*myGeo->ghostedCoarseNodesPerDir[0]
525 + j*myGeo->ghostedCoarseNodesPerDir[0] + i;
526 coarseNodeCoarseIndices[0] = myGeo->startGhostedCoarseNode[0] + i;
527 coarseNodeFineIndices[0] = coarseNodeCoarseIndices[0]*myGeo->coarseRate[0];
528 if(coarseNodeFineIndices[0] > myGeo->gFineNodesPerDir[0] - 1) {
529 coarseNodeFineIndices[0] = myGeo->gFineNodesPerDir[0] - 1;
531 coarseNodeCoarseIndices[1] = myGeo->startGhostedCoarseNode[1] + j;
532 coarseNodeFineIndices[1] = coarseNodeCoarseIndices[1]*myGeo->coarseRate[1];
533 if(coarseNodeFineIndices[1] > myGeo->gFineNodesPerDir[1] - 1) {
534 coarseNodeFineIndices[1] = myGeo->gFineNodesPerDir[1] - 1;
536 coarseNodeCoarseIndices[2] = myGeo->startGhostedCoarseNode[2] + k;
537 coarseNodeFineIndices[2] = coarseNodeCoarseIndices[2]*myGeo->coarseRate[2];
538 if(coarseNodeFineIndices[2] > myGeo->gFineNodesPerDir[2] - 1) {
539 coarseNodeFineIndices[2] = myGeo->gFineNodesPerDir[2] - 1;
541 GO myGID = -1, myCoarseGID = -1;
542 LO myLID = -1, myPID = -1;
543 GetGIDLocalLexicographic(i, j, k, coarseNodeFineIndices, myGeo, myRankIndex, pi, pj, pk,
544 myBlockStart, myBlockEnd, myGID, myPID, myLID);
545 myCoarseGID = coarseNodeCoarseIndices[0]
546 + coarseNodeCoarseIndices[1]*myGeo->gCoarseNodesPerDir[0]
547 + coarseNodeCoarseIndices[2]*myGeo->gCoarseNodesPerDir[1]*myGeo->gCoarseNodesPerDir[0];
548 ghostedCoarseNodes->PIDs[currentIndex] = myPID;
549 ghostedCoarseNodes->LIDs[currentIndex] = myLID;
550 ghostedCoarseNodes->GIDs[currentIndex] = myGID;
551 ghostedCoarseNodes->coarseGIDs[currentIndex] = myCoarseGID;
553 lCoarseNodesGIDs[0][countCoarseNodes] = myCoarseGID;
554 lCoarseNodesGIDs[1][countCoarseNodes] = myGID;
566 RCP<GeometricData> myGeo, RCP<NodesIDs> ghostedCoarseNodes,
567 Array<Array<GO> >& lCoarseNodesGIDs)
const{
576 myGeo->startIndices[2] = fineCoordsMap->getMinGlobalIndex()
577 / (myGeo->gFineNodesPerDir[1]*myGeo->gFineNodesPerDir[0]);
578 tmp = fineCoordsMap->getMinGlobalIndex()
579 % (myGeo->gFineNodesPerDir[1]*myGeo->gFineNodesPerDir[0]);
580 myGeo->startIndices[1] = tmp / myGeo->gFineNodesPerDir[0];
581 myGeo->startIndices[0] = tmp % myGeo->gFineNodesPerDir[0];
583 for(
int dim = 0; dim < 3; ++dim) {
584 myGeo->startIndices[dim + 3] = myGeo->startIndices[dim] + myGeo->lFineNodesPerDir[dim] - 1;
587 for(
int dim = 0; dim < 3; ++dim) {
588 if(dim < myGeo->numDimensions) {
589 myGeo->offsets[dim]= Teuchos::as<LO>(myGeo->startIndices[dim]) % myGeo->coarseRate[dim];
590 myGeo->offsets[dim + 3]= Teuchos::as<LO>(myGeo->startIndices[dim]) % myGeo->coarseRate[dim];
596 for(
int dim = 0; dim < 3; ++dim) {
597 if(dim < myGeo->numDimensions && (myGeo->startIndices[dim] % myGeo->coarseRate[dim] != 0 ||
598 myGeo->startIndices[dim] == myGeo->gFineNodesPerDir[dim]-1)) {
599 myGeo->ghostInterface[2*dim] =
true;
601 if(dim < myGeo->numDimensions
602 && myGeo->startIndices[dim + 3] != myGeo->gFineNodesPerDir[dim] - 1
603 && (myGeo->lFineNodesPerDir[dim] == 1 ||
604 myGeo->startIndices[dim + 3] % myGeo->coarseRate[dim] != 0)) {
605 myGeo->ghostInterface[2*dim + 1] =
true;
621 for(
int i = 0; i < 3; ++i) {
622 if(i < myGeo->numDimensions) {
625 myGeo->gCoarseNodesPerDir[i] = (myGeo->gFineNodesPerDir[i] - 1) / myGeo->coarseRate[i];
626 myGeo->endRate[i] = Teuchos::as<LO>((myGeo->gFineNodesPerDir[i] - 1) %myGeo->coarseRate[i]);
627 if(myGeo->endRate[i] == 0) {
628 myGeo->endRate[i] = myGeo->coarseRate[i];
629 ++myGeo->gCoarseNodesPerDir[i];
631 myGeo->gCoarseNodesPerDir[i] += 2;
634 myGeo->endRate[i] = 1;
635 myGeo->gCoarseNodesPerDir[i] = 1;
639 myGeo->gNumCoarseNodes = myGeo->gCoarseNodesPerDir[0]*myGeo->gCoarseNodesPerDir[1]
640 *myGeo->gCoarseNodesPerDir[2];
642 for(LO i = 0; i < 3; ++i) {
643 if(i < myGeo->numDimensions) {
647 if( (myGeo->startIndices[i] + myGeo->lFineNodesPerDir[i]) == myGeo->gFineNodesPerDir[i] ) {
648 myGeo->lCoarseNodesPerDir[i] = (myGeo->lFineNodesPerDir[i] - myGeo->endRate[i]
649 + myGeo->offsets[i] - 1) / myGeo->coarseRate[i] + 1;
650 if(myGeo->offsets[i] == 0) {++myGeo->lCoarseNodesPerDir[i];}
652 myGeo->lCoarseNodesPerDir[i] = (myGeo->lFineNodesPerDir[i] + myGeo->offsets[i] - 1)
653 / myGeo->coarseRate[i];
654 if(myGeo->offsets[i] == 0) {++myGeo->lCoarseNodesPerDir[i];}
657 myGeo->lCoarseNodesPerDir[i] = 1;
661 if(myGeo->lFineNodesPerDir[i] < 1) {myGeo->lCoarseNodesPerDir[i] = 0;}
667 myGeo->lNumCoarseNodes = myGeo->lCoarseNodesPerDir[0]*myGeo->lCoarseNodesPerDir[1]
668 *myGeo->lCoarseNodesPerDir[2];
671 bool ghostedDir[6] = {
false};
672 for(
int dim = 0; dim < 3; ++dim) {
676 if(myGeo->startIndices[dim] == myGeo->gFineNodesPerDir[dim] - 1 &&
677 myGeo->startIndices[dim] % myGeo->coarseRate[dim] == 0) {
678 myGeo->startGhostedCoarseNode[dim] = myGeo->startIndices[dim] / myGeo->coarseRate[dim] - 1;
680 myGeo->startGhostedCoarseNode[dim] = myGeo->startIndices[dim] / myGeo->coarseRate[dim];
682 myGeo->ghostedCoarseNodesPerDir[dim] = myGeo->lCoarseNodesPerDir[dim];
684 if(myGeo->ghostInterface[2*dim]) {
685 myGeo->ghostedCoarseNodesPerDir[dim] += 1;
686 ghostedDir[2*dim] =
true;
689 if(myGeo->ghostInterface[2*dim + 1]) {
690 myGeo->ghostedCoarseNodesPerDir[dim] += 1;
691 ghostedDir[2*dim + 1] =
true;
694 myGeo->lNumGhostedNodes = myGeo->ghostedCoarseNodesPerDir[2]*myGeo->ghostedCoarseNodesPerDir[1]
695 *myGeo->ghostedCoarseNodesPerDir[0];
696 myGeo->lNumGhostNodes = myGeo->lNumGhostedNodes - myGeo->lNumCoarseNodes;
697 ghostedCoarseNodes->PIDs.resize(myGeo->lNumGhostedNodes);
698 ghostedCoarseNodes->LIDs.resize(myGeo->lNumGhostedNodes);
699 ghostedCoarseNodes->GIDs.resize(myGeo->lNumGhostedNodes);
700 ghostedCoarseNodes->coarseGIDs.resize(myGeo->lNumGhostedNodes);
701 ghostedCoarseNodes->colInds.resize(myGeo->lNumGhostedNodes);
702 lCoarseNodesGIDs[0].resize(myGeo->lNumCoarseNodes);
703 lCoarseNodesGIDs[1].resize(myGeo->lNumCoarseNodes);
710 Array<LO> coarseNodeCoarseIndices(3), coarseNodeFineIndices(3), ijk(3);
711 LO currentIndex = -1, countCoarseNodes = 0;
712 for(ijk[2] = 0; ijk[2] < myGeo->ghostedCoarseNodesPerDir[2]; ++ijk[2]) {
713 for(ijk[1] = 0; ijk[1] < myGeo->ghostedCoarseNodesPerDir[1]; ++ijk[1]) {
714 for(ijk[0] = 0; ijk[0] < myGeo->ghostedCoarseNodesPerDir[0]; ++ijk[0]) {
715 currentIndex = ijk[2]*myGeo->ghostedCoarseNodesPerDir[1]*myGeo->ghostedCoarseNodesPerDir[0]
716 + ijk[1]*myGeo->ghostedCoarseNodesPerDir[0] + ijk[0];
717 coarseNodeCoarseIndices[0] = myGeo->startGhostedCoarseNode[0] + ijk[0];
718 coarseNodeFineIndices[0] = coarseNodeCoarseIndices[0]*myGeo->coarseRate[0];
719 if(coarseNodeFineIndices[0] > myGeo->gFineNodesPerDir[0] - 1) {
720 coarseNodeFineIndices[0] = myGeo->gFineNodesPerDir[0] - 1;
722 coarseNodeCoarseIndices[1] = myGeo->startGhostedCoarseNode[1] + ijk[1];
723 coarseNodeFineIndices[1] = coarseNodeCoarseIndices[1]*myGeo->coarseRate[1];
724 if(coarseNodeFineIndices[1] > myGeo->gFineNodesPerDir[1] - 1) {
725 coarseNodeFineIndices[1] = myGeo->gFineNodesPerDir[1] - 1;
727 coarseNodeCoarseIndices[2] = myGeo->startGhostedCoarseNode[2] + ijk[2];
728 coarseNodeFineIndices[2] = coarseNodeCoarseIndices[2]*myGeo->coarseRate[2];
729 if(coarseNodeFineIndices[2] > myGeo->gFineNodesPerDir[2] - 1) {
730 coarseNodeFineIndices[2] = myGeo->gFineNodesPerDir[2] - 1;
732 GO myGID = 0, myCoarseGID = -1;
734 factor[2] = myGeo->gNumFineNodes10;
735 factor[1] = myGeo->gFineNodesPerDir[0];
737 for(
int dim = 0; dim < 3; ++dim) {
738 if(dim < myGeo->numDimensions) {
739 if(myGeo->startIndices[dim] - myGeo->offsets[dim] + ijk[dim]*myGeo->coarseRate[dim]
740 < myGeo->gFineNodesPerDir[dim] - 1) {
741 myGID += (myGeo->startIndices[dim] - myGeo->offsets[dim]
742 + ijk[dim]*myGeo->coarseRate[dim])*factor[dim];
744 myGID += (myGeo->startIndices[dim] - myGeo->offsets[dim]
745 + (ijk[dim] - 1)*myGeo->coarseRate[dim] + myGeo->endRate[dim])*factor[dim];
749 myCoarseGID = coarseNodeCoarseIndices[0]
750 + coarseNodeCoarseIndices[1]*myGeo->gCoarseNodesPerDir[0]
751 + coarseNodeCoarseIndices[2]*myGeo->gCoarseNodesPerDir[1]*myGeo->gCoarseNodesPerDir[0];
752 ghostedCoarseNodes->GIDs[currentIndex] = myGID;
753 ghostedCoarseNodes->coarseGIDs[currentIndex] = myCoarseGID;
754 if((!ghostedDir[0] || ijk[0] != 0)
755 && (!ghostedDir[2] || ijk[1] != 0)
756 && (!ghostedDir[4] || ijk[2] != 0)
757 && (!ghostedDir[1] || ijk[0] != myGeo->ghostedCoarseNodesPerDir[0] - 1)
758 && (!ghostedDir[3] || ijk[1] != myGeo->ghostedCoarseNodesPerDir[1] - 1)
759 && (!ghostedDir[5] || ijk[2] != myGeo->ghostedCoarseNodesPerDir[2] - 1)){
760 lCoarseNodesGIDs[0][countCoarseNodes] = myCoarseGID;
761 lCoarseNodesGIDs[1][countCoarseNodes] = myGID;
767 Array<int> ghostsPIDs(myGeo->lNumGhostedNodes);
768 Array<LO> ghostsLIDs(myGeo->lNumGhostedNodes);
769 fineCoordsMap->getRemoteIndexList(ghostedCoarseNodes->GIDs(),
770 ghostedCoarseNodes->PIDs(),
771 ghostedCoarseNodes->LIDs());
777 const RCP<Xpetra::MultiVector<
typename Teuchos::ScalarTraits<Scalar>::coordinateType,LO,GO,
Node> >& fineCoords,
778 const LO nnzP,
const LO dofsPerNode,
779 RCP<const Map>& stridedDomainMapP,RCP<Matrix> & Amat, RCP<Matrix>& P,
780 RCP<Xpetra::MultiVector<
typename Teuchos::ScalarTraits<Scalar>::coordinateType,LO,GO,
Node> >& coarseCoords,
781 RCP<NodesIDs> ghostedCoarseNodes, Array<Array<GO> > coarseNodesGIDs,
782 int interpolationOrder)
const {
802 using xdMV = Xpetra::MultiVector<typename Teuchos::ScalarTraits<Scalar>::coordinateType,LO,GO,NO>;
803 Xpetra::global_size_t OTI = Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid();
805 LO myRank = Amat->getRowMap()->getComm()->getRank();
806 GO numGloCols = dofsPerNode*myGeo->gNumCoarseNodes;
810 RCP<const Map> rowMapP = Amat->getDomainMap();
812 RCP<const Map> domainMapP;
814 RCP<const Map> colMapP;
826 std::vector<NodeID> colMapOrdering(myGeo->lNumGhostedNodes);
827 for(LO ind = 0; ind < myGeo->lNumGhostedNodes; ++ind) {
828 colMapOrdering[ind].GID = ghostedCoarseNodes->GIDs[ind];
829 if(ghostedCoarseNodes->PIDs[ind] == myRank) {
830 colMapOrdering[ind].PID = -1;
832 colMapOrdering[ind].PID = ghostedCoarseNodes->PIDs[ind];
834 colMapOrdering[ind].LID = ghostedCoarseNodes->LIDs[ind];
835 colMapOrdering[ind].lexiInd = ind;
837 std::sort(colMapOrdering.begin(), colMapOrdering.end(),
839 return ( (a.PID < b.PID) || ((a.PID == b.PID) && (a.GID < b.GID)) );
842 Array<GO> colGIDs(dofsPerNode*myGeo->lNumGhostedNodes);
843 for(LO ind = 0; ind < myGeo->lNumGhostedNodes; ++ind) {
845 ghostedCoarseNodes->colInds[colMapOrdering[ind].lexiInd] = ind;
846 for(LO dof = 0; dof < dofsPerNode; ++dof) {
847 colGIDs[dofsPerNode*ind + dof] = dofsPerNode*colMapOrdering[ind].GID + dof;
850 domainMapP = Xpetra::MapFactory<LO,GO,NO>::Build(rowMapP->lib(),
852 colGIDs.view(0,dofsPerNode*
853 myGeo->lNumCoarseNodes),
854 rowMapP->getIndexBase(),
856 colMapP = Xpetra::MapFactory<LO,GO,NO>::Build(rowMapP->lib(),
858 colGIDs.view(0, colGIDs.size()),
859 rowMapP->getIndexBase(),
863 std::vector<size_t> strideInfo(1);
864 strideInfo[0] = dofsPerNode;
865 stridedDomainMapP = Xpetra::StridedMapFactory<LO,GO,NO>::Build(domainMapP, strideInfo);
870 RCP<const Map> coarseCoordsMap = MapFactory::Build (fineCoords->getMap()->lib(),
871 myGeo->gNumCoarseNodes,
872 coarseNodesGIDs[0](),
873 fineCoords->getMap()->getIndexBase(),
874 fineCoords->getMap()->getComm());
875 RCP<const Map> coarseCoordsFineMap = MapFactory::Build (fineCoords->getMap()->lib(),
876 myGeo->gNumCoarseNodes,
877 coarseNodesGIDs[1](),
878 fineCoords->getMap()->getIndexBase(),
879 fineCoords->getMap()->getComm());
881 RCP<const Import> coarseImporter = ImportFactory::Build(fineCoords->getMap(),
882 coarseCoordsFineMap);
883 coarseCoords = Xpetra::MultiVectorFactory<typename Teuchos::ScalarTraits<Scalar>::coordinateType,LO,GO,NO>
::Build(coarseCoordsFineMap,
884 myGeo->numDimensions);
885 coarseCoords->doImport(*fineCoords, *coarseImporter, Xpetra::INSERT);
886 coarseCoords->replaceMap(coarseCoordsMap);
889 RCP<const Map> ghostMap = Xpetra::MapFactory<LO,GO,NO>::Build(fineCoords->getMap()->lib(),
891 ghostedCoarseNodes->GIDs(),
892 fineCoords->getMap()->getIndexBase(),
893 fineCoords->getMap()->getComm());
894 RCP<const Import> ghostImporter = ImportFactory::Build(fineCoords->getMap(), ghostMap);
895 RCP<xdMV> ghostCoords = Xpetra::MultiVectorFactory<typename Teuchos::ScalarTraits<Scalar>::coordinateType,LO,GO,NO>
::Build(ghostMap,
896 myGeo->numDimensions);
897 ghostCoords->doImport(*fineCoords, *ghostImporter, Xpetra::INSERT);
899 P = rcp(
new CrsMatrixWrap(rowMapP, colMapP, 0));
900 RCP<CrsMatrix> PCrs = rcp_dynamic_cast<CrsMatrixWrap>(P)->getCrsMatrix();
902 ArrayRCP<size_t> iaP;
906 PCrs->allocateAllValues(nnzP, iaP, jaP, valP);
908 ArrayView<size_t> ia = iaP();
909 ArrayView<LO> ja = jaP();
910 ArrayView<SC> val = valP();
913 Array<ArrayRCP<typename Teuchos::ScalarTraits<Scalar>::coordinateType> > ghostedCoords(3);
915 ArrayRCP<typename Teuchos::ScalarTraits<Scalar>::coordinateType> tmp(ghostCoords->getLocalLength(), 0.0);
916 for(
int dim = 0; dim < 3; ++dim) {
917 if(dim < myGeo->numDimensions) {
918 ghostedCoords[dim] = ghostCoords->getDataNonConst(dim);
920 ghostedCoords[dim] = tmp;
927 RCP<Xpetra::Vector<typename Teuchos::ScalarTraits<Scalar>::coordinateType,LO,GO,NO> > zeros
928 = Xpetra::VectorFactory<typename Teuchos::ScalarTraits<Scalar>::coordinateType,LO,GO,NO>
::Build(fineCoords->getMap(),
true);
929 ArrayRCP< ArrayRCP<typename Teuchos::ScalarTraits<Scalar>::coordinateType> > lFineCoords(3);
930 for(
int dim = 0; dim < 3; ++dim) {
931 if(dim < myGeo->numDimensions) {
932 lFineCoords[dim] = fineCoords->getDataNonConst(dim);
934 lFineCoords[dim] = zeros->getDataNonConst(0);
939 for(
int currentIndex = 0; currentIndex < myGeo->lNumFineNodes; ++currentIndex) {
940 Array<GO> ghostedIndices(3), firstInterpolationIndices(3);
941 Array<LO> interpolationPIDs(8), interpolationLIDs(8), interpolationGIDs(8);
942 Array<Array<typename Teuchos::ScalarTraits<Scalar>::coordinateType> > interpolationCoords(9);
943 interpolationCoords[0].resize(3);
944 GO firstInterpolationNodeIndex;
946 for(
int dim = 0; dim < 3; ++dim) {
947 interpolationCoords[0][dim] = lFineCoords[dim][currentIndex];
953 ghostedIndices[2] = currentIndex / (myGeo->lFineNodesPerDir[1]*myGeo->lFineNodesPerDir[0]);
954 LO tmp = currentIndex % (myGeo->lFineNodesPerDir[1]*myGeo->lFineNodesPerDir[0]);
955 ghostedIndices[1] = tmp / myGeo->lFineNodesPerDir[0];
956 ghostedIndices[0] = tmp % myGeo->lFineNodesPerDir[0];
957 for(
int dim = 0; dim < 3; ++dim) {
958 ghostedIndices[dim] += myGeo->offsets[dim];
967 for(
int dim = 0; dim < 3; ++dim) {
968 firstInterpolationIndices[dim] = ghostedIndices[dim] / myGeo->coarseRate[dim];
971 if(firstInterpolationIndices[dim] == myGeo->ghostedCoarseNodesPerDir[dim] - 1
972 && myGeo->ghostedCoarseNodesPerDir[dim] > 1) {
973 firstInterpolationIndices[dim] -= 1;
976 firstInterpolationNodeIndex =
977 firstInterpolationIndices[2]*myGeo->ghostedCoarseNodesPerDir[1]*myGeo->ghostedCoarseNodesPerDir[0]
978 + firstInterpolationIndices[1]*myGeo->ghostedCoarseNodesPerDir[0]
979 + firstInterpolationIndices[0];
985 for(
int k = 0; k < 2; ++k) {
986 for(
int j = 0; j < 2; ++j) {
987 for(
int i = 0; i < 2; ++i) {
989 interpolationLIDs[ind] = firstInterpolationNodeIndex
990 + k*myGeo->ghostedCoarseNodesPerDir[1]*myGeo->ghostedCoarseNodesPerDir[0]
991 + j*myGeo->ghostedCoarseNodesPerDir[0] + i;
992 if(ghostedCoarseNodes->PIDs[interpolationLIDs[ind]] == rowMapP->getComm()->getRank()){
993 interpolationPIDs[ind] = -1;
995 interpolationPIDs[ind] = ghostedCoarseNodes->PIDs[interpolationLIDs[ind]];
997 interpolationGIDs[ind] = ghostedCoarseNodes->coarseGIDs[interpolationLIDs[ind]];
999 interpolationCoords[ind + 1].resize(3);
1000 for(
int dim = 0; dim < 3; ++dim) {
1001 interpolationCoords[ind + 1][dim]
1002 = ghostedCoords[dim][interpolationLIDs[ind]];
1011 std::vector<double> stencil(8);
1012 Array<GO> firstCoarseNodeFineIndices(3);
1014 for(
int dim = 0; dim < 3; ++dim) {
1015 firstCoarseNodeFineIndices[dim] = firstInterpolationIndices[dim]*myGeo->coarseRate[dim];
1016 if((myGeo->startIndices[dim + 3] == myGeo->gFineNodesPerDir[dim] - 1)
1017 && (ghostedIndices[dim] >=
1018 (myGeo->ghostedCoarseNodesPerDir[dim] - 2)*myGeo->coarseRate[dim])) {
1019 rate[dim] = myGeo->endRate[dim];
1021 rate[dim] = myGeo->coarseRate[dim];
1024 Array<GO> trueGhostedIndices(3);
1028 for(
int dim = 0; dim < 3; ++dim) {
1029 if (myGeo->startIndices[dim] == myGeo->gFineNodesPerDir[dim] - 1) {
1030 trueGhostedIndices[dim] = ghostedIndices[dim] + rate[dim];
1032 trueGhostedIndices[dim] = ghostedIndices[dim];
1035 ComputeStencil(myGeo->numDimensions, trueGhostedIndices, firstCoarseNodeFineIndices, rate,
1036 interpolationCoords, interpolationOrder, stencil);
1041 Array<LO> nzIndStencil(8), permutation(8);
1042 for(LO k = 0; k < 8; ++k) {permutation[k] = k;}
1043 if(interpolationOrder == 0) {
1045 for(LO k = 0; k < 8; ++k) {
1046 nzIndStencil[k] =
static_cast<LO
>(stencil[0]);
1049 stencil[nzIndStencil[0]] = 1.0;
1050 }
else if(interpolationOrder == 1) {
1051 Array<GO> currentNodeGlobalFineIndices(3);
1052 for(
int dim = 0; dim < 3; ++dim) {
1053 currentNodeGlobalFineIndices[dim] = ghostedIndices[dim] - myGeo->offsets[dim]
1054 + myGeo->startIndices[dim];
1056 if( ((ghostedIndices[0] % myGeo->coarseRate[0] == 0)
1057 || currentNodeGlobalFineIndices[0] == myGeo->gFineNodesPerDir[0] - 1)
1058 && ((ghostedIndices[1] % myGeo->coarseRate[1] == 0)
1059 || currentNodeGlobalFineIndices[1] == myGeo->gFineNodesPerDir[1] - 1)
1060 && ((ghostedIndices[2] % myGeo->coarseRate[2] == 0)
1061 || currentNodeGlobalFineIndices[2] == myGeo->gFineNodesPerDir[2] - 1) ) {
1062 if((currentNodeGlobalFineIndices[0] == myGeo->gFineNodesPerDir[0] - 1) ||
1063 (ghostedIndices[0] / myGeo->coarseRate[0] == myGeo->ghostedCoarseNodesPerDir[0] - 1)) {
1064 nzIndStencil[0] += 1;
1066 if(((currentNodeGlobalFineIndices[1] == myGeo->gFineNodesPerDir[1] - 1) ||
1067 (ghostedIndices[1] / myGeo->coarseRate[1] == myGeo->ghostedCoarseNodesPerDir[1] - 1))
1068 && (myGeo->numDimensions > 1)){
1069 nzIndStencil[0] += 2;
1071 if(((currentNodeGlobalFineIndices[2] == myGeo->gFineNodesPerDir[2] - 1) ||
1072 (ghostedIndices[2] / myGeo->coarseRate[2] == myGeo->ghostedCoarseNodesPerDir[2] - 1))
1073 && myGeo->numDimensions > 2) {
1074 nzIndStencil[0] += 4;
1077 for(LO k = 0; k < 8; ++k) {
1078 nzIndStencil[k] = nzIndStencil[0];
1082 for(LO k = 0; k < 8; ++k) {
1083 nzIndStencil[k] = k;
1096 sh_sort2(interpolationPIDs.begin(),interpolationPIDs.end(),
1097 permutation.begin(), permutation.end());
1100 for(LO j = 0; j < dofsPerNode; ++j) {
1101 ia[currentIndex*dofsPerNode + j + 1] = ia[currentIndex*dofsPerNode + j] + nStencil;
1102 for(LO k = 0; k < nStencil; ++k) {
1103 colInd = ghostedCoarseNodes->colInds[interpolationLIDs[nzIndStencil[permutation[k]]]];
1104 ja[ia[currentIndex*dofsPerNode + j] + k] = colInd*dofsPerNode + j;
1105 val[ia[currentIndex*dofsPerNode + j] + k] = stencil[nzIndStencil[permutation[k]]];
1108 tStencil += nStencil;
1112 if (rowMapP->lib() == Xpetra::UseTpetra) {
1116 jaP .resize(tStencil);
1117 valP.resize(tStencil);
1121 PCrs->setAllValues(iaP, jaP, valP);
1122 PCrs->expertStaticFillComplete(domainMapP,rowMapP);
1647 std::vector<double>& stencil)
1665 Teuchos::SerialDenseMatrix<LO,double> Jacobian(numDimensions, numDimensions);
1666 Teuchos::SerialDenseVector<LO,double> residual(numDimensions);
1667 Teuchos::SerialDenseVector<LO,double> solutionDirection(numDimensions);
1668 Teuchos::SerialDenseVector<LO,double> paramCoords(numDimensions);
1669 Teuchos::SerialDenseSolver<LO,double> problem;
1670 LO numTerms = std::pow(2,numDimensions), iter = 0, max_iter = 5;
1671 double functions[4][8], norm_ref = 1, norm2 = 1, tol = 1e-5;
1672 paramCoords.size(numDimensions);
1674 while( (iter < max_iter) && (norm2 > tol*norm_ref) ) {
1677 solutionDirection.size(numDimensions);
1678 residual.size(numDimensions);
1683 for(LO i = 0; i < numDimensions; ++i) {
1684 residual(i) = coord[0][i];
1685 for(LO k = 0; k < numTerms; ++k) {
1686 residual(i) -= functions[0][k]*coord[k+1][i];
1689 norm_ref += residual(i)*residual(i);
1690 if(i == numDimensions - 1) {
1691 norm_ref = std::sqrt(norm_ref);
1695 for(LO j = 0; j < numDimensions; ++j) {
1696 for(LO k = 0; k < numTerms; ++k) {
1697 Jacobian(i,j) += functions[j+1][k]*coord[k+1][i];
1703 problem.setMatrix(Teuchos::rcp(&Jacobian,
false));
1704 problem.setVectors(Teuchos::rcp(&solutionDirection,
false), Teuchos::rcp(&residual,
false));
1705 problem.factorWithEquilibration(
true);
1707 problem.unequilibrateLHS();
1709 for(LO i = 0; i < numDimensions; ++i) {
1710 paramCoords(i) = paramCoords(i) + solutionDirection(i);
1715 for(LO i = 0; i < numDimensions; ++i) {
1716 double tmp = coord[0][i];
1717 for(LO k = 0; k < numTerms; ++k) {
1718 tmp -= functions[0][k]*coord[k+1][i];
1723 norm2 = std::sqrt(norm2);
1727 for(LO i = 0; i < 8; ++i) {
1728 stencil[i] = functions[0][i];
1736 const Teuchos::SerialDenseVector<LO,double> parameters,
1737 double functions[4][8])
const {
1738 double xi = 0.0, eta = 0.0, zeta = 0.0, denominator = 0.0;
1739 if(numDimensions == 1) {
1742 }
else if(numDimensions == 2) {
1744 eta = parameters[1];
1746 }
else if(numDimensions == 3) {
1748 eta = parameters[1];
1749 zeta = parameters[2];
1753 functions[0][0] = (1.0 - xi)*(1.0 - eta)*(1.0 - zeta) / denominator;
1754 functions[0][1] = (1.0 + xi)*(1.0 - eta)*(1.0 - zeta) / denominator;
1755 functions[0][2] = (1.0 - xi)*(1.0 + eta)*(1.0 - zeta) / denominator;
1756 functions[0][3] = (1.0 + xi)*(1.0 + eta)*(1.0 - zeta) / denominator;
1757 functions[0][4] = (1.0 - xi)*(1.0 - eta)*(1.0 + zeta) / denominator;
1758 functions[0][5] = (1.0 + xi)*(1.0 - eta)*(1.0 + zeta) / denominator;
1759 functions[0][6] = (1.0 - xi)*(1.0 + eta)*(1.0 + zeta) / denominator;
1760 functions[0][7] = (1.0 + xi)*(1.0 + eta)*(1.0 + zeta) / denominator;
1762 functions[1][0] = -(1.0 - eta)*(1.0 - zeta) / denominator;
1763 functions[1][1] = (1.0 - eta)*(1.0 - zeta) / denominator;
1764 functions[1][2] = -(1.0 + eta)*(1.0 - zeta) / denominator;
1765 functions[1][3] = (1.0 + eta)*(1.0 - zeta) / denominator;
1766 functions[1][4] = -(1.0 - eta)*(1.0 + zeta) / denominator;
1767 functions[1][5] = (1.0 - eta)*(1.0 + zeta) / denominator;
1768 functions[1][6] = -(1.0 + eta)*(1.0 + zeta) / denominator;
1769 functions[1][7] = (1.0 + eta)*(1.0 + zeta) / denominator;
1771 functions[2][0] = -(1.0 - xi)*(1.0 - zeta) / denominator;
1772 functions[2][1] = -(1.0 + xi)*(1.0 - zeta) / denominator;
1773 functions[2][2] = (1.0 - xi)*(1.0 - zeta) / denominator;
1774 functions[2][3] = (1.0 + xi)*(1.0 - zeta) / denominator;
1775 functions[2][4] = -(1.0 - xi)*(1.0 + zeta) / denominator;
1776 functions[2][5] = -(1.0 + xi)*(1.0 + zeta) / denominator;
1777 functions[2][6] = (1.0 - xi)*(1.0 + zeta) / denominator;
1778 functions[2][7] = (1.0 + xi)*(1.0 + zeta) / denominator;
1780 functions[3][0] = -(1.0 - xi)*(1.0 - eta) / denominator;
1781 functions[3][1] = -(1.0 + xi)*(1.0 - eta) / denominator;
1782 functions[3][2] = -(1.0 - xi)*(1.0 + eta) / denominator;
1783 functions[3][3] = -(1.0 + xi)*(1.0 + eta) / denominator;
1784 functions[3][4] = (1.0 - xi)*(1.0 - eta) / denominator;
1785 functions[3][5] = (1.0 + xi)*(1.0 - eta) / denominator;
1786 functions[3][6] = (1.0 - xi)*(1.0 + eta) / denominator;
1787 functions[3][7] = (1.0 + xi)*(1.0 + eta) / denominator;
1849 const Array<LO> coarseNodeFineIndices,
const RCP<GeometricData> myGeo,
1850 const LO myRankIndex,
const LO pi,
const LO pj,
const LO ,
1851 const typename std::vector<std::vector<GO> >::iterator blockStart,
1852 const typename std::vector<std::vector<GO> >::iterator blockEnd,
1853 GO& myGID, LO& myPID, LO& myLID)
const {
1855 LO ni = -1, nj = -1, li = -1, lj = -1, lk = -1;
1856 LO myRankGuess = myRankIndex;
1858 if(i == 0 && myGeo->ghostInterface[0]) {
1860 }
else if((i == myGeo->ghostedCoarseNodesPerDir[0] - 1) && myGeo->ghostInterface[1]) {
1863 if(j == 0 && myGeo->ghostInterface[2]) {
1865 }
else if((j == myGeo->ghostedCoarseNodesPerDir[1] - 1) && myGeo->ghostInterface[3]) {
1868 if(k == 0 && myGeo->ghostInterface[4]) {
1869 myRankGuess -= pj*pi;
1870 }
else if((k == myGeo->ghostedCoarseNodesPerDir[2] - 1) && myGeo->ghostInterface[5]) {
1871 myRankGuess += pj*pi;
1873 if(coarseNodeFineIndices[0] >= myGeo->meshData[myRankGuess][3]
1874 && coarseNodeFineIndices[0] <= myGeo->meshData[myRankGuess][4]
1875 && coarseNodeFineIndices[1] >= myGeo->meshData[myRankGuess][5]
1876 && coarseNodeFineIndices[1] <= myGeo->meshData[myRankGuess][6]
1877 && coarseNodeFineIndices[2] >= myGeo->meshData[myRankGuess][7]
1878 && coarseNodeFineIndices[2] <= myGeo->meshData[myRankGuess][8]) {
1879 myPID = myGeo->meshData[myRankGuess][0];
1880 ni = myGeo->meshData[myRankGuess][4] - myGeo->meshData[myRankGuess][3] + 1;
1881 nj = myGeo->meshData[myRankGuess][6] - myGeo->meshData[myRankGuess][5] + 1;
1882 li = coarseNodeFineIndices[0] - myGeo->meshData[myRankGuess][3];
1883 lj = coarseNodeFineIndices[1] - myGeo->meshData[myRankGuess][5];
1884 lk = coarseNodeFineIndices[2] - myGeo->meshData[myRankGuess][7];
1885 myLID = lk*nj*ni + lj*ni + li;
1886 myGID = myGeo->meshData[myRankGuess][9] + myLID;
1890 auto nodeRank = std::find_if(blockStart, blockEnd,
1891 [coarseNodeFineIndices](
const std::vector<GO>& vec){
1892 if(coarseNodeFineIndices[0] >= vec[3]
1893 && coarseNodeFineIndices[0] <= vec[4]
1894 && coarseNodeFineIndices[1] >= vec[5]
1895 && coarseNodeFineIndices[1] <= vec[6]
1896 && coarseNodeFineIndices[2] >= vec[7]
1897 && coarseNodeFineIndices[2] <= vec[8]) {
1903 myPID = (*nodeRank)[0];
1904 ni = (*nodeRank)[4] - (*nodeRank)[3] + 1;
1905 nj = (*nodeRank)[6] - (*nodeRank)[5] + 1;
1906 li = coarseNodeFineIndices[0] - (*nodeRank)[3];
1907 lj = coarseNodeFineIndices[1] - (*nodeRank)[5];
1908 lk = coarseNodeFineIndices[2] - (*nodeRank)[7];
1909 myLID = lk*nj*ni + lj*ni + li;
1910 myGID = (*nodeRank)[9] + myLID;