46 #ifndef MUELU_GENERALGEOMETRICPFACTORY_DEF_HPP
47 #define MUELU_GENERALGEOMETRICPFACTORY_DEF_HPP
75 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
84 validParamList->
set<std::string > (
"Coarsen",
"{2}",
85 "Coarsening rate in all spatial dimensions");
86 validParamList->
set<
int> (
"order", 1,
87 "Order of the interpolation scheme used");
89 "Generating factory of the matrix A");
91 "Generating factory of the nullspace");
93 "Generating factory for coorindates");
95 "Number of nodes per spatial dimmension provided by CoordinatesTransferFactory.");
97 "Number of nodes per spatial dimmension provided by CoordinatesTransferFactory.");
98 validParamList->
set<std::string > (
"meshLayout",
"Global Lexicographic",
99 "Type of mesh ordering");
101 "Mesh ordering associated data");
103 return validParamList;
106 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
109 Input(fineLevel,
"A");
110 Input(fineLevel,
"Nullspace");
111 Input(fineLevel,
"Coordinates");
119 "gNodesPerDim was not provided by the user on level0!");
122 Input(fineLevel,
"gNodesPerDim");
132 "lNodesPerDim was not provided by the user on level0!");
135 Input(fineLevel,
"lNodesPerDim");
139 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
141 Level& coarseLevel)
const {
142 return BuildP(fineLevel, coarseLevel);
145 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
147 Level& coarseLevel)
const {
152 RCP<Matrix> A = Get< RCP<Matrix> > (fineLevel,
"A");
153 RCP<MultiVector> fineNullspace = Get< RCP<MultiVector> > (fineLevel,
"Nullspace");
154 RCP<xdMV> fineCoords = Get< RCP<xdMV> >(fineLevel,
"Coordinates");
161 const LO blkSize = A->GetFixedBlockSize();
166 myGeometry->meshLayout = pL.
get<std::string>(
"meshLayout");
167 if(fineLevel.GetLevelID() == 0) {
168 if(myGeometry->meshLayout ==
"Local Lexicographic") {
172 "The meshData array is empty, somehow the input for geometric"
173 " multigrid are not captured correctly.");
174 myGeometry->meshData.resize(rowMap->getComm()->getSize());
175 for(
int i = 0; i < rowMap->getComm()->getSize(); ++i) {
176 myGeometry->meshData[i].resize(10);
177 for(
int j = 0; j < 10; ++j) {
178 myGeometry->meshData[i][j] = meshData[10*i + j];
185 "Coordinates cannot be accessed from fine level!");
186 myGeometry->numDimensions = fineCoords->getNumVectors();
189 if(fineLevel.GetLevelID() == 0) {
194 myGeometry->gFineNodesPerDir = Get<Array<GO> >(fineLevel,
"gNodesPerDim");
197 myGeometry->lFineNodesPerDir = Get<Array<LO> >(fineLevel,
"lNodesPerDim");
199 myGeometry->gNumFineNodes10 = myGeometry->gFineNodesPerDir[1]*myGeometry->gFineNodesPerDir[0];
200 myGeometry->gNumFineNodes = myGeometry->gFineNodesPerDir[2]*myGeometry->gNumFineNodes10;
201 myGeometry->lNumFineNodes10 = myGeometry->lFineNodesPerDir[1]*myGeometry->lFineNodesPerDir[0];
202 myGeometry->lNumFineNodes = myGeometry->lFineNodesPerDir[2]*myGeometry->lNumFineNodes10;
205 !=
static_cast<size_t>(myGeometry->lNumFineNodes),
207 "The local number of elements in Coordinates is not equal to the"
208 " number of nodes given by: lNodesPerDim!");
210 !=
static_cast<size_t>(myGeometry->gNumFineNodes),
212 "The global number of elements in Coordinates is not equal to the"
213 " number of nodes given by: gNodesPerDim!");
216 std::string coarsenRate = pL.
get<std::string>(
"Coarsen");
219 crates = Teuchos::fromStringToArray<LO>(coarsenRate);
221 GetOStream(
Errors,-1) <<
" *** Coarsen must be a string convertible into an array! *** "
227 "Coarsen must have at least as many components as the number of"
228 " spatial dimensions in the problem.");
230 for(LO i = 0; i < 3; ++i) {
231 if(i < myGeometry->numDimensions) {
232 if(crates.size()==1) {
233 myGeometry->coarseRate[i] = crates[0];
234 }
else if(crates.size() == myGeometry->numDimensions) {
235 myGeometry->coarseRate[i] = crates[i];
238 myGeometry->coarseRate[i] = 1;
242 int interpolationOrder = pL.
get<
int>(
"order");
245 "The interpolation order can only be set to 0 or 1.");
249 for(LO i = 0; i < myGeometry->numDimensions; ++i) {
252 for(LO i = 0; i < myGeometry->numDimensions; ++i) {
253 TEUCHOS_TEST_FOR_EXCEPTION(mapDirG2L[i] > myGeometry->numDimensions,
255 "axis permutation values must all be less than"
256 " the number of spatial dimensions.");
257 mapDirL2G[mapDirG2L[i]] = i;
264 if((fineLevel.GetLevelID() == 0) && (myGeometry->meshLayout !=
"Global Lexicographic")) {
265 MeshLayoutInterface(interpolationOrder, blkSize, fineCoordsMap, myGeometry,
266 ghostedCoarseNodes, lCoarseNodesGIDs);
271 GetCoarsePoints(interpolationOrder, blkSize, fineCoordsMap, myGeometry, ghostedCoarseNodes,
286 GO lnnzP = Teuchos::as<LO>(std::pow(interpolationOrder + 1, myGeometry->numDimensions))
287 *(myGeometry->lNumFineNodes - myGeometry->lNumCoarseNodes) + myGeometry->lNumCoarseNodes;
288 lnnzP = lnnzP*blkSize;
289 GO gnnzP = Teuchos::as<LO>(std::pow(interpolationOrder + 1, myGeometry->numDimensions))
290 *(myGeometry->gNumFineNodes - myGeometry->gNumCoarseNodes) + myGeometry->gNumCoarseNodes;
291 gnnzP = gnnzP*blkSize;
293 GetOStream(
Runtime1) <<
"P size = " << blkSize*myGeometry->gNumFineNodes
294 <<
" x " << blkSize*myGeometry->gNumCoarseNodes << std::endl;
295 GetOStream(
Runtime1) <<
"P Fine grid : " << myGeometry->gFineNodesPerDir[0] <<
" -- "
296 << myGeometry->gFineNodesPerDir[1] <<
" -- "
297 << myGeometry->gFineNodesPerDir[2] << std::endl;
298 GetOStream(
Runtime1) <<
"P Coarse grid : " << myGeometry->gCoarseNodesPerDir[0] <<
" -- "
299 << myGeometry->gCoarseNodesPerDir[1] <<
" -- "
300 << myGeometry->gCoarseNodesPerDir[2] << std::endl;
301 GetOStream(
Runtime1) <<
"P nnz estimate: " << gnnzP << std::endl;
303 MakeGeneralGeometricP(myGeometry, fineCoords, lnnzP, blkSize, stridedDomainMapP,
304 A, P, coarseCoords, ghostedCoarseNodes, lCoarseNodesGIDs,
308 if (A->IsView(
"stridedMaps") ==
true) {
309 P->CreateView(
"stridedMaps", A->getRowMap(
"stridedMaps"), stridedDomainMapP);
311 P->CreateView(
"stridedMaps", P->getRangeMap(), stridedDomainMapP);
315 Set(coarseLevel,
"P", P);
316 Set(coarseLevel,
"coarseCoordinates", coarseCoords);
317 Set<Array<GO> >(coarseLevel,
"gCoarseNodesPerDim", myGeometry->gCoarseNodesPerDir);
318 Set<Array<LO> >(coarseLevel,
"lCoarseNodesPerDim", myGeometry->lCoarseNodesPerDir);
322 RCP<MultiVector> coarseNullspace = MultiVectorFactory::Build(P->getDomainMap(),
323 fineNullspace->getNumVectors());
326 Set(coarseLevel,
"Nullspace", coarseNullspace);
330 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
341 int numRanks = fineCoordsMap->getComm()->getSize();
342 int myRank = fineCoordsMap->getComm()->getRank();
344 myGeo->myBlock = myGeo->meshData[myRank][2];
345 myGeo->startIndices[0] = myGeo->meshData[myRank][3];
346 myGeo->startIndices[1] = myGeo->meshData[myRank][5];
347 myGeo->startIndices[2] = myGeo->meshData[myRank][7];
348 myGeo->startIndices[3] = myGeo->meshData[myRank][4];
349 myGeo->startIndices[4] = myGeo->meshData[myRank][6];
350 myGeo->startIndices[5] = myGeo->meshData[myRank][8];
351 std::sort(myGeo->meshData.begin(), myGeo->meshData.end(),
352 [](
const std::vector<GO>& a,
const std::vector<GO>& b)->
bool {
356 }
else if(a[2] == b[2]) {
359 }
else if(a[7] == b[7]) {
362 }
else if(a[5] == b[5]) {
363 if(a[3] < b[3]) {
return true;}
370 myGeo->numBlocks = myGeo->meshData[numRanks - 1][2] + 1;
372 auto myBlockStart = std::lower_bound(myGeo->meshData.begin(), myGeo->meshData.end(),
374 [](
const std::vector<GO>& vec,
const GO val)->
bool{
375 return (vec[2] < val) ?
true :
false;
377 auto myBlockEnd = std::upper_bound(myGeo->meshData.begin(), myGeo->meshData.end(),
379 [](
const GO val,
const std::vector<GO>& vec)->
bool{
380 return (val < vec[2]) ?
true :
false;
385 auto myKEnd = std::upper_bound(myBlockStart, myBlockEnd, (*myBlockStart)[3],
386 [](
const GO val,
const std::vector<GO>& vec)->
bool{
387 return (val < vec[7]) ?
true :
false;
389 auto myJEnd = std::upper_bound(myBlockStart, myKEnd, (*myBlockStart)[3],
390 [](
const GO val,
const std::vector<GO>& vec)->
bool{
391 return (val < vec[5]) ?
true :
false;
393 LO pi = std::distance(myBlockStart, myJEnd);
394 LO pj = std::distance(myBlockStart, myKEnd) / pi;
395 LO pk = std::distance(myBlockStart, myBlockEnd) / (pj*pi);
398 LO myRankIndex = std::distance(myGeo->meshData.begin(),
399 std::find_if(myBlockStart, myBlockEnd,
400 [myRank](
const std::vector<GO>& vec)->
bool{
401 return (vec[0] == myRank) ?
true :
false;
405 for(
int dim = 0; dim < 3; ++dim) {
406 if(dim < myGeo->numDimensions) {
407 myGeo->offsets[dim]= Teuchos::as<LO>(myGeo->startIndices[dim]) % myGeo->coarseRate[dim];
408 myGeo->offsets[dim + 3]= Teuchos::as<LO>(myGeo->startIndices[dim]) % myGeo->coarseRate[dim];
414 for(
int dim = 0; dim < 3; ++dim) {
415 if(dim < myGeo->numDimensions && (myGeo->startIndices[dim] % myGeo->coarseRate[dim] != 0 ||
416 myGeo->startIndices[dim] == myGeo->gFineNodesPerDir[dim]-1)) {
417 myGeo->ghostInterface[2*dim] =
true;
419 if(dim < myGeo->numDimensions
420 && myGeo->startIndices[dim + 3] != myGeo->gFineNodesPerDir[dim] - 1
421 && (myGeo->lFineNodesPerDir[dim] == 1 ||
422 myGeo->startIndices[dim + 3] % myGeo->coarseRate[dim] != 0)) {
423 myGeo->ghostInterface[2*dim+1] =
true;
439 for(
int i = 0; i < 3; ++i) {
440 if(i < myGeo->numDimensions) {
443 myGeo->gCoarseNodesPerDir[i] = (myGeo->gFineNodesPerDir[i] - 1) / myGeo->coarseRate[i];
444 myGeo->endRate[i] = Teuchos::as<LO>((myGeo->gFineNodesPerDir[i] - 1) %myGeo->coarseRate[i]);
445 if(myGeo->endRate[i] == 0) {
446 myGeo->endRate[i] = myGeo->coarseRate[i];
447 ++myGeo->gCoarseNodesPerDir[i];
449 myGeo->gCoarseNodesPerDir[i] += 2;
452 myGeo->endRate[i] = 1;
453 myGeo->gCoarseNodesPerDir[i] = 1;
457 myGeo->gNumCoarseNodes = myGeo->gCoarseNodesPerDir[0]*myGeo->gCoarseNodesPerDir[1]
458 *myGeo->gCoarseNodesPerDir[2];
460 for(
LO i = 0; i < 3; ++i) {
461 if(i < myGeo->numDimensions) {
465 if( (myGeo->startIndices[i] + myGeo->lFineNodesPerDir[i]) == myGeo->gFineNodesPerDir[i] ) {
466 myGeo->lCoarseNodesPerDir[i] = (myGeo->lFineNodesPerDir[i] - myGeo->endRate[i]
467 + myGeo->offsets[i] - 1) / myGeo->coarseRate[i] + 1;
468 if(myGeo->offsets[i] == 0) {++myGeo->lCoarseNodesPerDir[i];}
470 myGeo->lCoarseNodesPerDir[i] = (myGeo->lFineNodesPerDir[i] + myGeo->offsets[i] - 1)
471 / myGeo->coarseRate[i];
472 if(myGeo->offsets[i] == 0) {++myGeo->lCoarseNodesPerDir[i];}
475 myGeo->lCoarseNodesPerDir[i] = 1;
479 if(myGeo->lFineNodesPerDir[i] < 1) {myGeo->lCoarseNodesPerDir[i] = 0;}
485 myGeo->lNumCoarseNodes = myGeo->lCoarseNodesPerDir[0]*myGeo->lCoarseNodesPerDir[1]
486 *myGeo->lCoarseNodesPerDir[2];
489 for(
int dim = 0; dim < 3; ++dim) {
493 if(myGeo->startIndices[dim] == myGeo->gFineNodesPerDir[dim] - 1 &&
494 myGeo->startIndices[dim] % myGeo->coarseRate[dim] == 0) {
495 myGeo->startGhostedCoarseNode[dim] = myGeo->startIndices[dim] / myGeo->coarseRate[dim] - 1;
497 myGeo->startGhostedCoarseNode[dim] = myGeo->startIndices[dim] / myGeo->coarseRate[dim];
499 myGeo->ghostedCoarseNodesPerDir[dim] = myGeo->lCoarseNodesPerDir[dim];
501 if(myGeo->ghostInterface[2*dim]) {myGeo->ghostedCoarseNodesPerDir[dim] += 1;}
503 if(myGeo->ghostInterface[2*dim + 1]) {myGeo->ghostedCoarseNodesPerDir[dim] += 1;}
505 myGeo->lNumGhostedNodes = myGeo->ghostedCoarseNodesPerDir[2]*myGeo->ghostedCoarseNodesPerDir[1]
506 *myGeo->ghostedCoarseNodesPerDir[0];
507 myGeo->lNumGhostNodes = myGeo->lNumGhostedNodes - myGeo->lNumCoarseNodes;
508 ghostedCoarseNodes->PIDs.resize(myGeo->lNumGhostedNodes);
509 ghostedCoarseNodes->LIDs.resize(myGeo->lNumGhostedNodes);
510 ghostedCoarseNodes->GIDs.resize(myGeo->lNumGhostedNodes);
511 ghostedCoarseNodes->coarseGIDs.resize(myGeo->lNumGhostedNodes);
512 ghostedCoarseNodes->colInds.resize(myGeo->lNumGhostedNodes);
513 lCoarseNodesGIDs[0].resize(myGeo->lNumCoarseNodes);
514 lCoarseNodesGIDs[1].resize(myGeo->lNumCoarseNodes);
521 Array<LO> coarseNodeCoarseIndices(3), coarseNodeFineIndices(3);
522 LO currentIndex = -1, countCoarseNodes = 0;
523 for(
int k = 0; k < myGeo->ghostedCoarseNodesPerDir[2]; ++k) {
524 for(
int j = 0; j < myGeo->ghostedCoarseNodesPerDir[1]; ++j) {
525 for(
int i = 0; i < myGeo->ghostedCoarseNodesPerDir[0]; ++i) {
526 currentIndex = k*myGeo->ghostedCoarseNodesPerDir[1]*myGeo->ghostedCoarseNodesPerDir[0]
527 + j*myGeo->ghostedCoarseNodesPerDir[0] + i;
528 coarseNodeCoarseIndices[0] = myGeo->startGhostedCoarseNode[0] + i;
529 coarseNodeFineIndices[0] = coarseNodeCoarseIndices[0]*myGeo->coarseRate[0];
530 if(coarseNodeFineIndices[0] > myGeo->gFineNodesPerDir[0] - 1) {
531 coarseNodeFineIndices[0] = myGeo->gFineNodesPerDir[0] - 1;
533 coarseNodeCoarseIndices[1] = myGeo->startGhostedCoarseNode[1] + j;
534 coarseNodeFineIndices[1] = coarseNodeCoarseIndices[1]*myGeo->coarseRate[1];
535 if(coarseNodeFineIndices[1] > myGeo->gFineNodesPerDir[1] - 1) {
536 coarseNodeFineIndices[1] = myGeo->gFineNodesPerDir[1] - 1;
538 coarseNodeCoarseIndices[2] = myGeo->startGhostedCoarseNode[2] + k;
539 coarseNodeFineIndices[2] = coarseNodeCoarseIndices[2]*myGeo->coarseRate[2];
540 if(coarseNodeFineIndices[2] > myGeo->gFineNodesPerDir[2] - 1) {
541 coarseNodeFineIndices[2] = myGeo->gFineNodesPerDir[2] - 1;
543 GO myGID = -1, myCoarseGID = -1;
544 LO myLID = -1, myPID = -1;
545 GetGIDLocalLexicographic(i, j, k, coarseNodeFineIndices, myGeo, myRankIndex, pi, pj, pk,
546 myBlockStart, myBlockEnd, myGID, myPID, myLID);
547 myCoarseGID = coarseNodeCoarseIndices[0]
548 + coarseNodeCoarseIndices[1]*myGeo->gCoarseNodesPerDir[0]
549 + coarseNodeCoarseIndices[2]*myGeo->gCoarseNodesPerDir[1]*myGeo->gCoarseNodesPerDir[0];
550 ghostedCoarseNodes->PIDs[currentIndex] = myPID;
551 ghostedCoarseNodes->LIDs[currentIndex] = myLID;
552 ghostedCoarseNodes->GIDs[currentIndex] = myGID;
553 ghostedCoarseNodes->coarseGIDs[currentIndex] = myCoarseGID;
555 lCoarseNodesGIDs[0][countCoarseNodes] = myCoarseGID;
556 lCoarseNodesGIDs[1][countCoarseNodes] = myGID;
565 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
578 myGeo->startIndices[2] = fineCoordsMap->getMinGlobalIndex()
579 / (myGeo->gFineNodesPerDir[1]*myGeo->gFineNodesPerDir[0]);
580 tmp = fineCoordsMap->getMinGlobalIndex()
581 % (myGeo->gFineNodesPerDir[1]*myGeo->gFineNodesPerDir[0]);
582 myGeo->startIndices[1] = tmp / myGeo->gFineNodesPerDir[0];
583 myGeo->startIndices[0] = tmp % myGeo->gFineNodesPerDir[0];
585 for(
int dim = 0; dim < 3; ++dim) {
586 myGeo->startIndices[dim + 3] = myGeo->startIndices[dim] + myGeo->lFineNodesPerDir[dim] - 1;
589 for(
int dim = 0; dim < 3; ++dim) {
590 if(dim < myGeo->numDimensions) {
591 myGeo->offsets[dim]= Teuchos::as<LO>(myGeo->startIndices[dim]) % myGeo->coarseRate[dim];
592 myGeo->offsets[dim + 3]= Teuchos::as<LO>(myGeo->startIndices[dim]) % myGeo->coarseRate[dim];
598 for(
int dim = 0; dim < 3; ++dim) {
599 if(dim < myGeo->numDimensions && (myGeo->startIndices[dim] % myGeo->coarseRate[dim] != 0 ||
600 myGeo->startIndices[dim] == myGeo->gFineNodesPerDir[dim]-1)) {
601 myGeo->ghostInterface[2*dim] =
true;
603 if(dim < myGeo->numDimensions
604 && myGeo->startIndices[dim + 3] != myGeo->gFineNodesPerDir[dim] - 1
605 && (myGeo->lFineNodesPerDir[dim] == 1 ||
606 myGeo->startIndices[dim + 3] % myGeo->coarseRate[dim] != 0)) {
607 myGeo->ghostInterface[2*dim + 1] =
true;
623 for(
int i = 0; i < 3; ++i) {
624 if(i < myGeo->numDimensions) {
627 myGeo->gCoarseNodesPerDir[i] = (myGeo->gFineNodesPerDir[i] - 1) / myGeo->coarseRate[i];
628 myGeo->endRate[i] = Teuchos::as<LO>((myGeo->gFineNodesPerDir[i] - 1) %myGeo->coarseRate[i]);
629 if(myGeo->endRate[i] == 0) {
630 myGeo->endRate[i] = myGeo->coarseRate[i];
631 ++myGeo->gCoarseNodesPerDir[i];
633 myGeo->gCoarseNodesPerDir[i] += 2;
636 myGeo->endRate[i] = 1;
637 myGeo->gCoarseNodesPerDir[i] = 1;
641 myGeo->gNumCoarseNodes = myGeo->gCoarseNodesPerDir[0]*myGeo->gCoarseNodesPerDir[1]
642 *myGeo->gCoarseNodesPerDir[2];
644 for(
LO i = 0; i < 3; ++i) {
645 if(i < myGeo->numDimensions) {
649 if( (myGeo->startIndices[i] + myGeo->lFineNodesPerDir[i]) == myGeo->gFineNodesPerDir[i] ) {
650 myGeo->lCoarseNodesPerDir[i] = (myGeo->lFineNodesPerDir[i] - myGeo->endRate[i]
651 + myGeo->offsets[i] - 1) / myGeo->coarseRate[i] + 1;
652 if(myGeo->offsets[i] == 0) {++myGeo->lCoarseNodesPerDir[i];}
654 myGeo->lCoarseNodesPerDir[i] = (myGeo->lFineNodesPerDir[i] + myGeo->offsets[i] - 1)
655 / myGeo->coarseRate[i];
656 if(myGeo->offsets[i] == 0) {++myGeo->lCoarseNodesPerDir[i];}
659 myGeo->lCoarseNodesPerDir[i] = 1;
663 if(myGeo->lFineNodesPerDir[i] < 1) {myGeo->lCoarseNodesPerDir[i] = 0;}
669 myGeo->lNumCoarseNodes = myGeo->lCoarseNodesPerDir[0]*myGeo->lCoarseNodesPerDir[1]
670 *myGeo->lCoarseNodesPerDir[2];
673 bool ghostedDir[6] = {
false};
674 for(
int dim = 0; dim < 3; ++dim) {
678 if(myGeo->startIndices[dim] == myGeo->gFineNodesPerDir[dim] - 1 &&
679 myGeo->startIndices[dim] % myGeo->coarseRate[dim] == 0) {
680 myGeo->startGhostedCoarseNode[dim] = myGeo->startIndices[dim] / myGeo->coarseRate[dim] - 1;
682 myGeo->startGhostedCoarseNode[dim] = myGeo->startIndices[dim] / myGeo->coarseRate[dim];
684 myGeo->ghostedCoarseNodesPerDir[dim] = myGeo->lCoarseNodesPerDir[dim];
686 if(myGeo->ghostInterface[2*dim]) {
687 myGeo->ghostedCoarseNodesPerDir[dim] += 1;
688 ghostedDir[2*dim] =
true;
691 if(myGeo->ghostInterface[2*dim + 1]) {
692 myGeo->ghostedCoarseNodesPerDir[dim] += 1;
693 ghostedDir[2*dim + 1] =
true;
696 myGeo->lNumGhostedNodes = myGeo->ghostedCoarseNodesPerDir[2]*myGeo->ghostedCoarseNodesPerDir[1]
697 *myGeo->ghostedCoarseNodesPerDir[0];
698 myGeo->lNumGhostNodes = myGeo->lNumGhostedNodes - myGeo->lNumCoarseNodes;
699 ghostedCoarseNodes->PIDs.resize(myGeo->lNumGhostedNodes);
700 ghostedCoarseNodes->LIDs.resize(myGeo->lNumGhostedNodes);
701 ghostedCoarseNodes->GIDs.resize(myGeo->lNumGhostedNodes);
702 ghostedCoarseNodes->coarseGIDs.resize(myGeo->lNumGhostedNodes);
703 ghostedCoarseNodes->colInds.resize(myGeo->lNumGhostedNodes);
704 lCoarseNodesGIDs[0].resize(myGeo->lNumCoarseNodes);
705 lCoarseNodesGIDs[1].resize(myGeo->lNumCoarseNodes);
712 Array<LO> coarseNodeCoarseIndices(3), coarseNodeFineIndices(3), ijk(3);
713 LO currentIndex = -1, countCoarseNodes = 0;
714 for(ijk[2] = 0; ijk[2] < myGeo->ghostedCoarseNodesPerDir[2]; ++ijk[2]) {
715 for(ijk[1] = 0; ijk[1] < myGeo->ghostedCoarseNodesPerDir[1]; ++ijk[1]) {
716 for(ijk[0] = 0; ijk[0] < myGeo->ghostedCoarseNodesPerDir[0]; ++ijk[0]) {
717 currentIndex = ijk[2]*myGeo->ghostedCoarseNodesPerDir[1]*myGeo->ghostedCoarseNodesPerDir[0]
718 + ijk[1]*myGeo->ghostedCoarseNodesPerDir[0] + ijk[0];
719 coarseNodeCoarseIndices[0] = myGeo->startGhostedCoarseNode[0] + ijk[0];
720 coarseNodeFineIndices[0] = coarseNodeCoarseIndices[0]*myGeo->coarseRate[0];
721 if(coarseNodeFineIndices[0] > myGeo->gFineNodesPerDir[0] - 1) {
722 coarseNodeFineIndices[0] = myGeo->gFineNodesPerDir[0] - 1;
724 coarseNodeCoarseIndices[1] = myGeo->startGhostedCoarseNode[1] + ijk[1];
725 coarseNodeFineIndices[1] = coarseNodeCoarseIndices[1]*myGeo->coarseRate[1];
726 if(coarseNodeFineIndices[1] > myGeo->gFineNodesPerDir[1] - 1) {
727 coarseNodeFineIndices[1] = myGeo->gFineNodesPerDir[1] - 1;
729 coarseNodeCoarseIndices[2] = myGeo->startGhostedCoarseNode[2] + ijk[2];
730 coarseNodeFineIndices[2] = coarseNodeCoarseIndices[2]*myGeo->coarseRate[2];
731 if(coarseNodeFineIndices[2] > myGeo->gFineNodesPerDir[2] - 1) {
732 coarseNodeFineIndices[2] = myGeo->gFineNodesPerDir[2] - 1;
734 GO myGID = 0, myCoarseGID = -1;
736 factor[2] = myGeo->gNumFineNodes10;
737 factor[1] = myGeo->gFineNodesPerDir[0];
739 for(
int dim = 0; dim < 3; ++dim) {
740 if(dim < myGeo->numDimensions) {
741 if(myGeo->startIndices[dim] - myGeo->offsets[dim] + ijk[dim]*myGeo->coarseRate[dim]
742 < myGeo->gFineNodesPerDir[dim] - 1) {
743 myGID += (myGeo->startIndices[dim] - myGeo->offsets[dim]
744 + ijk[dim]*myGeo->coarseRate[dim])*factor[dim];
746 myGID += (myGeo->startIndices[dim] - myGeo->offsets[dim]
747 + (ijk[dim] - 1)*myGeo->coarseRate[dim] + myGeo->endRate[dim])*factor[dim];
751 myCoarseGID = coarseNodeCoarseIndices[0]
752 + coarseNodeCoarseIndices[1]*myGeo->gCoarseNodesPerDir[0]
753 + coarseNodeCoarseIndices[2]*myGeo->gCoarseNodesPerDir[1]*myGeo->gCoarseNodesPerDir[0];
754 ghostedCoarseNodes->GIDs[currentIndex] = myGID;
755 ghostedCoarseNodes->coarseGIDs[currentIndex] = myCoarseGID;
756 if((!ghostedDir[0] || ijk[0] != 0)
757 && (!ghostedDir[2] || ijk[1] != 0)
758 && (!ghostedDir[4] || ijk[2] != 0)
759 && (!ghostedDir[1] || ijk[0] != myGeo->ghostedCoarseNodesPerDir[0] - 1)
760 && (!ghostedDir[3] || ijk[1] != myGeo->ghostedCoarseNodesPerDir[1] - 1)
761 && (!ghostedDir[5] || ijk[2] != myGeo->ghostedCoarseNodesPerDir[2] - 1)){
762 lCoarseNodesGIDs[0][countCoarseNodes] = myCoarseGID;
763 lCoarseNodesGIDs[1][countCoarseNodes] = myGID;
769 Array<int> ghostsPIDs(myGeo->lNumGhostedNodes);
770 Array<LO> ghostsLIDs(myGeo->lNumGhostedNodes);
771 fineCoordsMap->getRemoteIndexList(ghostedCoarseNodes->GIDs(),
772 ghostedCoarseNodes->PIDs(),
773 ghostedCoarseNodes->LIDs());
776 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
780 const LO nnzP,
const LO dofsPerNode,
784 int interpolationOrder)
const {
807 LO myRank = Amat->getRowMap()->getComm()->getRank();
808 GO numGloCols = dofsPerNode*myGeo->gNumCoarseNodes;
828 std::vector<NodeID> colMapOrdering(myGeo->lNumGhostedNodes);
829 for(LO ind = 0; ind < myGeo->lNumGhostedNodes; ++ind) {
830 colMapOrdering[ind].GID = ghostedCoarseNodes->GIDs[ind];
831 if(ghostedCoarseNodes->PIDs[ind] == myRank) {
832 colMapOrdering[ind].PID = -1;
834 colMapOrdering[ind].PID = ghostedCoarseNodes->PIDs[ind];
836 colMapOrdering[ind].LID = ghostedCoarseNodes->LIDs[ind];
837 colMapOrdering[ind].lexiInd = ind;
839 std::sort(colMapOrdering.begin(), colMapOrdering.end(),
841 return ( (a.
PID < b.PID) || ((a.
PID == b.PID) && (a.
GID < b.GID)) );
844 Array<GO> colGIDs(dofsPerNode*myGeo->lNumGhostedNodes);
845 for(LO ind = 0; ind < myGeo->lNumGhostedNodes; ++ind) {
847 ghostedCoarseNodes->colInds[colMapOrdering[ind].lexiInd] = ind;
848 for(LO dof = 0; dof < dofsPerNode; ++dof) {
849 colGIDs[dofsPerNode*ind + dof] = dofsPerNode*colMapOrdering[ind].GID + dof;
854 colGIDs.view(0,dofsPerNode*
855 myGeo->lNumCoarseNodes),
856 rowMapP->getIndexBase(),
860 colGIDs.view(0, colGIDs.size()),
861 rowMapP->getIndexBase(),
865 std::vector<size_t> strideInfo(1);
866 strideInfo[0] = dofsPerNode;
872 RCP<const Map> coarseCoordsMap = MapFactory::Build (fineCoords->getMap()->lib(),
873 myGeo->gNumCoarseNodes,
874 coarseNodesGIDs[0](),
875 fineCoords->getMap()->getIndexBase(),
876 fineCoords->getMap()->getComm());
877 RCP<const Map> coarseCoordsFineMap = MapFactory::Build (fineCoords->getMap()->lib(),
878 myGeo->gNumCoarseNodes,
879 coarseNodesGIDs[1](),
880 fineCoords->getMap()->getIndexBase(),
881 fineCoords->getMap()->getComm());
884 coarseCoordsFineMap);
886 myGeo->numDimensions);
887 coarseCoords->doImport(*fineCoords, *coarseImporter,
Xpetra::INSERT);
888 coarseCoords->replaceMap(coarseCoordsMap);
893 ghostedCoarseNodes->GIDs(),
894 fineCoords->getMap()->getIndexBase(),
895 fineCoords->getMap()->getComm());
896 RCP<const Import> ghostImporter = ImportFactory::Build(fineCoords->getMap(), ghostMap);
898 myGeo->numDimensions);
899 ghostCoords->doImport(*fineCoords, *ghostImporter,
Xpetra::INSERT);
902 RCP<CrsMatrix> PCrs = rcp_dynamic_cast<CrsMatrixWrap>(P)->getCrsMatrix();
908 PCrs->allocateAllValues(nnzP, iaP, jaP, valP);
918 for(
int dim = 0; dim < 3; ++dim) {
919 if(dim < myGeo->numDimensions) {
920 ghostedCoords[dim] = ghostCoords->getDataNonConst(dim);
922 ghostedCoords[dim] = tmp;
932 for(
int dim = 0; dim < 3; ++dim) {
933 if(dim < myGeo->numDimensions) {
934 lFineCoords[dim] = fineCoords->getDataNonConst(dim);
936 lFineCoords[dim] = zeros->getDataNonConst(0);
941 for(
int currentIndex = 0; currentIndex < myGeo->lNumFineNodes; ++currentIndex) {
942 Array<GO> ghostedIndices(3), firstInterpolationIndices(3);
943 Array<LO> interpolationPIDs(8), interpolationLIDs(8), interpolationGIDs(8);
945 interpolationCoords[0].
resize(3);
946 GO firstInterpolationNodeIndex;
948 for(
int dim = 0; dim < 3; ++dim) {
949 interpolationCoords[0][dim] = lFineCoords[dim][currentIndex];
955 ghostedIndices[2] = currentIndex / (myGeo->lFineNodesPerDir[1]*myGeo->lFineNodesPerDir[0]);
956 LO tmp = currentIndex % (myGeo->lFineNodesPerDir[1]*myGeo->lFineNodesPerDir[0]);
957 ghostedIndices[1] = tmp / myGeo->lFineNodesPerDir[0];
958 ghostedIndices[0] = tmp % myGeo->lFineNodesPerDir[0];
959 for(
int dim = 0; dim < 3; ++dim) {
960 ghostedIndices[dim] += myGeo->offsets[dim];
969 for(
int dim = 0; dim < 3; ++dim) {
970 firstInterpolationIndices[dim] = ghostedIndices[dim] / myGeo->coarseRate[dim];
973 if(firstInterpolationIndices[dim] == myGeo->ghostedCoarseNodesPerDir[dim] - 1
974 && myGeo->ghostedCoarseNodesPerDir[dim] > 1) {
975 firstInterpolationIndices[dim] -= 1;
978 firstInterpolationNodeIndex =
979 firstInterpolationIndices[2]*myGeo->ghostedCoarseNodesPerDir[1]*myGeo->ghostedCoarseNodesPerDir[0]
980 + firstInterpolationIndices[1]*myGeo->ghostedCoarseNodesPerDir[0]
981 + firstInterpolationIndices[0];
987 for(
int k = 0; k < 2; ++k) {
988 for(
int j = 0; j < 2; ++j) {
989 for(
int i = 0; i < 2; ++i) {
991 interpolationLIDs[ind] = firstInterpolationNodeIndex
992 + k*myGeo->ghostedCoarseNodesPerDir[1]*myGeo->ghostedCoarseNodesPerDir[0]
993 + j*myGeo->ghostedCoarseNodesPerDir[0] + i;
994 if(ghostedCoarseNodes->PIDs[interpolationLIDs[ind]] == rowMapP->getComm()->getRank()){
995 interpolationPIDs[ind] = -1;
997 interpolationPIDs[ind] = ghostedCoarseNodes->PIDs[interpolationLIDs[ind]];
999 interpolationGIDs[ind] = ghostedCoarseNodes->coarseGIDs[interpolationLIDs[ind]];
1001 interpolationCoords[ind + 1].
resize(3);
1002 for(
int dim = 0; dim < 3; ++dim) {
1003 interpolationCoords[ind + 1][dim]
1004 = ghostedCoords[dim][interpolationLIDs[ind]];
1013 std::vector<double> stencil(8);
1014 Array<GO> firstCoarseNodeFineIndices(3);
1016 for(
int dim = 0; dim < 3; ++dim) {
1017 firstCoarseNodeFineIndices[dim] = firstInterpolationIndices[dim]*myGeo->coarseRate[dim];
1018 if((myGeo->startIndices[dim + 3] == myGeo->gFineNodesPerDir[dim] - 1)
1019 && (ghostedIndices[dim] >=
1020 (myGeo->ghostedCoarseNodesPerDir[dim] - 2)*myGeo->coarseRate[dim])) {
1021 rate[dim] = myGeo->endRate[dim];
1023 rate[dim] = myGeo->coarseRate[dim];
1030 for(
int dim = 0; dim < 3; ++dim) {
1031 if (myGeo->startIndices[dim] == myGeo->gFineNodesPerDir[dim] - 1) {
1032 trueGhostedIndices[dim] = ghostedIndices[dim] + rate[dim];
1034 trueGhostedIndices[dim] = ghostedIndices[dim];
1037 ComputeStencil(myGeo->numDimensions, trueGhostedIndices, firstCoarseNodeFineIndices, rate,
1038 interpolationCoords, interpolationOrder, stencil);
1043 Array<LO> nzIndStencil(8), permutation(8);
1044 for(LO k = 0; k < 8; ++k) {permutation[k] = k;}
1045 if(interpolationOrder == 0) {
1047 for(LO k = 0; k < 8; ++k) {
1048 nzIndStencil[k] =
static_cast<LO
>(stencil[0]);
1051 stencil[nzIndStencil[0]] = 1.0;
1052 }
else if(interpolationOrder == 1) {
1053 Array<GO> currentNodeGlobalFineIndices(3);
1054 for(
int dim = 0; dim < 3; ++dim) {
1055 currentNodeGlobalFineIndices[dim] = ghostedIndices[dim] - myGeo->offsets[dim]
1056 + myGeo->startIndices[dim];
1058 if( ((ghostedIndices[0] % myGeo->coarseRate[0] == 0)
1059 || currentNodeGlobalFineIndices[0] == myGeo->gFineNodesPerDir[0] - 1)
1060 && ((ghostedIndices[1] % myGeo->coarseRate[1] == 0)
1061 || currentNodeGlobalFineIndices[1] == myGeo->gFineNodesPerDir[1] - 1)
1062 && ((ghostedIndices[2] % myGeo->coarseRate[2] == 0)
1063 || currentNodeGlobalFineIndices[2] == myGeo->gFineNodesPerDir[2] - 1) ) {
1064 if((currentNodeGlobalFineIndices[0] == myGeo->gFineNodesPerDir[0] - 1) ||
1065 (ghostedIndices[0] / myGeo->coarseRate[0] == myGeo->ghostedCoarseNodesPerDir[0] - 1)) {
1066 nzIndStencil[0] += 1;
1068 if(((currentNodeGlobalFineIndices[1] == myGeo->gFineNodesPerDir[1] - 1) ||
1069 (ghostedIndices[1] / myGeo->coarseRate[1] == myGeo->ghostedCoarseNodesPerDir[1] - 1))
1070 && (myGeo->numDimensions > 1)){
1071 nzIndStencil[0] += 2;
1073 if(((currentNodeGlobalFineIndices[2] == myGeo->gFineNodesPerDir[2] - 1) ||
1074 (ghostedIndices[2] / myGeo->coarseRate[2] == myGeo->ghostedCoarseNodesPerDir[2] - 1))
1075 && myGeo->numDimensions > 2) {
1076 nzIndStencil[0] += 4;
1079 for(LO k = 0; k < 8; ++k) {
1080 nzIndStencil[k] = nzIndStencil[0];
1084 for(LO k = 0; k < 8; ++k) {
1085 nzIndStencil[k] = k;
1098 sh_sort2(interpolationPIDs.begin(),interpolationPIDs.end(),
1099 permutation.
begin(), permutation.
end());
1102 for(LO j = 0; j < dofsPerNode; ++j) {
1103 ia[currentIndex*dofsPerNode + j + 1] = ia[currentIndex*dofsPerNode + j] + nStencil;
1104 for(LO k = 0; k < nStencil; ++k) {
1105 colInd = ghostedCoarseNodes->colInds[interpolationLIDs[nzIndStencil[permutation[k]]]];
1106 ja[ia[currentIndex*dofsPerNode + j] + k] = colInd*dofsPerNode + j;
1107 val[ia[currentIndex*dofsPerNode + j] + k] = stencil[nzIndStencil[permutation[k]]];
1110 tStencil += nStencil;
1123 PCrs->setAllValues(iaP, jaP, valP);
1124 PCrs->expertStaticFillComplete(domainMapP,rowMapP);
1602 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1604 const LO numDimensions,
const Array<GO> currentNodeIndices,
1605 const Array<GO> coarseNodeIndices,
const LO rate[3],
1607 std::vector<double>& stencil)
const {
1611 "The interpolation order can be set to 0 or 1 only.");
1613 if(interpolationOrder == 0) {
1614 ComputeConstantInterpolationStencil(numDimensions, currentNodeIndices, coarseNodeIndices,
1616 }
else if(interpolationOrder == 1) {
1617 ComputeLinearInterpolationStencil(numDimensions, coord, stencil);
1622 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1625 const Array<GO> coarseNodeIndices,
const LO rate[3],
1626 std::vector<double>& stencil)
const {
1629 if(numDimensions > 2) {
1630 if((currentNodeIndices[2] - coarseNodeIndices[2]) > (rate[2] / 2)) {
1634 if(numDimensions > 1) {
1635 if((currentNodeIndices[1] - coarseNodeIndices[1]) > (rate[1] / 2)) {
1639 if((currentNodeIndices[0] - coarseNodeIndices[0]) > (rate[0] / 2)) {
1642 stencil[0] = coarseNode;
1646 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1649 std::vector<double>& stencil)
1672 LO numTerms = std::pow(2,numDimensions),
iter = 0, max_iter = 5;
1673 double functions[4][8], norm_ref = 1, norm2 = 1, tol = 1e-5;
1674 paramCoords.
size(numDimensions);
1676 while( (
iter < max_iter) && (norm2 > tol*norm_ref) ) {
1679 solutionDirection.
size(numDimensions);
1680 residual.
size(numDimensions);
1684 GetInterpolationFunctions(numDimensions, paramCoords, functions);
1685 for(
LO i = 0; i < numDimensions; ++i) {
1686 residual(i) = coord[0][i];
1687 for(
LO k = 0; k < numTerms; ++k) {
1688 residual(i) -= functions[0][k]*coord[k+1][i];
1691 norm_ref += residual(i)*residual(i);
1692 if(i == numDimensions - 1) {
1693 norm_ref = std::sqrt(norm_ref);
1697 for(
LO j = 0; j < numDimensions; ++j) {
1698 for(
LO k = 0; k < numTerms; ++k) {
1699 Jacobian(i,j) += functions[j+1][k]*coord[k+1][i];
1711 for(
LO i = 0; i < numDimensions; ++i) {
1712 paramCoords(i) = paramCoords(i) + solutionDirection(i);
1716 GetInterpolationFunctions(numDimensions, paramCoords, functions);
1717 for(
LO i = 0; i < numDimensions; ++i) {
1718 double tmp = coord[0][i];
1719 for(
LO k = 0; k < numTerms; ++k) {
1720 tmp -= functions[0][k]*coord[k+1][i];
1725 norm2 = std::sqrt(norm2);
1729 for(
LO i = 0; i < 8; ++i) {
1730 stencil[i] = functions[0][i];
1735 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1739 double functions[4][8])
const {
1740 double xi = 0.0, eta = 0.0, zeta = 0.0, denominator = 0.0;
1741 if(numDimensions == 1) {
1744 }
else if(numDimensions == 2) {
1746 eta = parameters[1];
1748 }
else if(numDimensions == 3) {
1750 eta = parameters[1];
1751 zeta = parameters[2];
1755 functions[0][0] = (1.0 - xi)*(1.0 - eta)*(1.0 - zeta) / denominator;
1756 functions[0][1] = (1.0 + xi)*(1.0 - eta)*(1.0 - zeta) / denominator;
1757 functions[0][2] = (1.0 - xi)*(1.0 + eta)*(1.0 - zeta) / denominator;
1758 functions[0][3] = (1.0 + xi)*(1.0 + eta)*(1.0 - zeta) / denominator;
1759 functions[0][4] = (1.0 - xi)*(1.0 - eta)*(1.0 + zeta) / denominator;
1760 functions[0][5] = (1.0 + xi)*(1.0 - eta)*(1.0 + zeta) / denominator;
1761 functions[0][6] = (1.0 - xi)*(1.0 + eta)*(1.0 + zeta) / denominator;
1762 functions[0][7] = (1.0 + xi)*(1.0 + eta)*(1.0 + zeta) / denominator;
1764 functions[1][0] = -(1.0 - eta)*(1.0 - zeta) / denominator;
1765 functions[1][1] = (1.0 - eta)*(1.0 - zeta) / denominator;
1766 functions[1][2] = -(1.0 + eta)*(1.0 - zeta) / denominator;
1767 functions[1][3] = (1.0 + eta)*(1.0 - zeta) / denominator;
1768 functions[1][4] = -(1.0 - eta)*(1.0 + zeta) / denominator;
1769 functions[1][5] = (1.0 - eta)*(1.0 + zeta) / denominator;
1770 functions[1][6] = -(1.0 + eta)*(1.0 + zeta) / denominator;
1771 functions[1][7] = (1.0 + eta)*(1.0 + zeta) / denominator;
1773 functions[2][0] = -(1.0 - xi)*(1.0 - zeta) / denominator;
1774 functions[2][1] = -(1.0 + xi)*(1.0 - zeta) / denominator;
1775 functions[2][2] = (1.0 - xi)*(1.0 - zeta) / denominator;
1776 functions[2][3] = (1.0 + xi)*(1.0 - zeta) / denominator;
1777 functions[2][4] = -(1.0 - xi)*(1.0 + zeta) / denominator;
1778 functions[2][5] = -(1.0 + xi)*(1.0 + zeta) / denominator;
1779 functions[2][6] = (1.0 - xi)*(1.0 + zeta) / denominator;
1780 functions[2][7] = (1.0 + xi)*(1.0 + zeta) / denominator;
1782 functions[3][0] = -(1.0 - xi)*(1.0 - eta) / denominator;
1783 functions[3][1] = -(1.0 + xi)*(1.0 - eta) / denominator;
1784 functions[3][2] = -(1.0 - xi)*(1.0 + eta) / denominator;
1785 functions[3][3] = -(1.0 + xi)*(1.0 + eta) / denominator;
1786 functions[3][4] = (1.0 - xi)*(1.0 - eta) / denominator;
1787 functions[3][5] = (1.0 + xi)*(1.0 - eta) / denominator;
1788 functions[3][6] = (1.0 - xi)*(1.0 + eta) / denominator;
1789 functions[3][7] = (1.0 + xi)*(1.0 + eta) / denominator;
1793 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1800 typedef typename std::iterator_traits<typename Teuchos::Array<LocalOrdinal>::iterator>::difference_type DT;
1801 DT n = last1 - first1;
1807 for (DT j = 0; j < max; j++)
1809 for (DT k = j; k >= 0; k-=m)
1811 if (first1[first2[k+m]] >= first1[first2[k]])
1813 std::swap(first2[k+m], first2[k]);
1820 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1827 typedef typename std::iterator_traits<typename Teuchos::Array<LocalOrdinal>::iterator>::difference_type DT;
1828 DT n = last1 - first1;
1834 for (DT j = 0; j < max; j++)
1836 for (DT k = j; k >= 0; k-=m)
1838 if (first1[k+m] >= first1[k])
1840 std::swap(first1[k+m], first1[k]);
1841 std::swap(first2[k+m], first2[k]);
1848 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1852 const LO myRankIndex,
const LO pi,
const LO pj,
const LO ,
1853 const typename std::vector<std::vector<GO> >::iterator blockStart,
1854 const typename std::vector<std::vector<GO> >::iterator blockEnd,
1855 GO& myGID,
LO& myPID,
LO& myLID)
const {
1857 LO ni = -1, nj = -1, li = -1, lj = -1, lk = -1;
1858 LO myRankGuess = myRankIndex;
1860 if(i == 0 && myGeo->ghostInterface[0]) {
1862 }
else if((i == myGeo->ghostedCoarseNodesPerDir[0] - 1) && myGeo->ghostInterface[1]) {
1865 if(j == 0 && myGeo->ghostInterface[2]) {
1867 }
else if((j == myGeo->ghostedCoarseNodesPerDir[1] - 1) && myGeo->ghostInterface[3]) {
1870 if(k == 0 && myGeo->ghostInterface[4]) {
1871 myRankGuess -= pj*pi;
1872 }
else if((k == myGeo->ghostedCoarseNodesPerDir[2] - 1) && myGeo->ghostInterface[5]) {
1873 myRankGuess += pj*pi;
1875 if(coarseNodeFineIndices[0] >= myGeo->meshData[myRankGuess][3]
1876 && coarseNodeFineIndices[0] <= myGeo->meshData[myRankGuess][4]
1877 && coarseNodeFineIndices[1] >= myGeo->meshData[myRankGuess][5]
1878 && coarseNodeFineIndices[1] <= myGeo->meshData[myRankGuess][6]
1879 && coarseNodeFineIndices[2] >= myGeo->meshData[myRankGuess][7]
1880 && coarseNodeFineIndices[2] <= myGeo->meshData[myRankGuess][8]) {
1881 myPID = myGeo->meshData[myRankGuess][0];
1882 ni = myGeo->meshData[myRankGuess][4] - myGeo->meshData[myRankGuess][3] + 1;
1883 nj = myGeo->meshData[myRankGuess][6] - myGeo->meshData[myRankGuess][5] + 1;
1884 li = coarseNodeFineIndices[0] - myGeo->meshData[myRankGuess][3];
1885 lj = coarseNodeFineIndices[1] - myGeo->meshData[myRankGuess][5];
1886 lk = coarseNodeFineIndices[2] - myGeo->meshData[myRankGuess][7];
1887 myLID = lk*nj*ni + lj*ni + li;
1888 myGID = myGeo->meshData[myRankGuess][9] + myLID;
1892 auto nodeRank = std::find_if(blockStart, blockEnd,
1893 [coarseNodeFineIndices](
const std::vector<GO>& vec){
1894 if(coarseNodeFineIndices[0] >= vec[3]
1895 && coarseNodeFineIndices[0] <= vec[4]
1896 && coarseNodeFineIndices[1] >= vec[5]
1897 && coarseNodeFineIndices[1] <= vec[6]
1898 && coarseNodeFineIndices[2] >= vec[7]
1899 && coarseNodeFineIndices[2] <= vec[8]) {
1905 myPID = (*nodeRank)[0];
1906 ni = (*nodeRank)[4] - (*nodeRank)[3] + 1;
1907 nj = (*nodeRank)[6] - (*nodeRank)[5] + 1;
1908 li = coarseNodeFineIndices[0] - (*nodeRank)[3];
1909 lj = coarseNodeFineIndices[1] - (*nodeRank)[5];
1910 lk = coarseNodeFineIndices[2] - (*nodeRank)[7];
1911 myLID = lk*nj*ni + lj*ni + li;
1912 myGID = (*nodeRank)[9] + myLID;
1918 #define MUELU_GENERALGEOMETRICPFACTORY_SHORT
1919 #endif // MUELU_GENERALGEOMETRICPFACTORY_DEF_HPP
void ComputeLinearInterpolationStencil(const LO numDimension, const Array< Array< typename Teuchos::ScalarTraits< Scalar >::coordinateType > > coord, std::vector< double > &stencil) const
void GetCoarsePoints(const int interpolationOrder, const LO blkSize, RCP< const Map > fineCoordsMap, RCP< GeometricData > myGeometry, RCP< NodesIDs > ghostedCoarseNodes, Array< Array< GO > > &lCoarseNodesGIDs) const
void MakeGeneralGeometricP(RCP< GeometricData > myGeo, const RCP< Xpetra::MultiVector< typename Teuchos::ScalarTraits< Scalar >::coordinateType, LO, GO, NO > > &fCoords, const LO nnzP, const LO dofsPerNode, RCP< const Map > &stridedDomainMapP, RCP< Matrix > &Amat, RCP< Matrix > &P, RCP< Xpetra::MultiVector< typename Teuchos::ScalarTraits< Scalar >::coordinateType, LO, GO, NO > > &cCoords, RCP< NodesIDs > ghostedCoarseNodes, Array< Array< GO > > coarseNodesGIDs, int interpolationOrder) const
static RCP< StridedMap > Build(UnderlyingLib lib, global_size_t numGlobalElements, GlobalOrdinal indexBase, std::vector< size_t > &stridingInfo, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalOrdinal stridedBlockId=-1, GlobalOrdinal offset=0, LocalGlobal lg=Xpetra::GloballyDistributed)
T & get(const std::string &name, T def_value)
void BuildP(Level &fineLevel, Level &coarseLevel) const
Abstract Build method.
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
Timer to be used in factories. Similar to Monitor but with additional timers.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
static const NoFactory * get()
void resize(const size_type n, const T &val=T())
void MeshLayoutInterface(const int interpolationOrder, const LO blkSize, RCP< const Map > fineCoordsMap, RCP< GeometricData > myGeometry, RCP< NodesIDs > ghostedCoarseNodes, Array< Array< GO > > &lCoarseNodesGIDs) const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Class that holds all level-specific information.
void factorWithEquilibration(bool flag)
void sh_sort2(const typename Teuchos::Array< LocalOrdinal >::iterator &first1, const typename Teuchos::Array< LocalOrdinal >::iterator &last1, const typename Teuchos::Array< LocalOrdinal >::iterator &first2, const typename Teuchos::Array< LocalOrdinal >::iterator &last2) const
void ComputeStencil(const LO numDimension, const Array< GO > currentNodeIndices, const Array< GO > coarseNodeIndices, const LO rate[3], const Array< Array< typename Teuchos::ScalarTraits< Scalar >::coordinateType > > coord, const int interpolationOrder, std::vector< double > &stencil) const
void GetGIDLocalLexicographic(const GO i, const GO j, const GO k, const Array< LO > coarseNodeFineIndices, const RCP< GeometricData > myGeo, const LO myRankIndex, const LO pi, const LO pj, const LO pk, const typename std::vector< std::vector< GO > >::iterator blockStart, const typename std::vector< std::vector< GO > >::iterator blockEnd, GO &myGID, LO &myPID, LO &myLID) const
void resize(size_type new_size, const value_type &x=value_type())
void GetInterpolationFunctions(const LO numDimension, const Teuchos::SerialDenseVector< LO, double > parameters, double functions[4][8]) const
void ComputeConstantInterpolationStencil(const LO numDimension, const Array< GO > currentNodeIndices, const Array< GO > coarseNodeIndices, const LO rate[3], std::vector< double > &stencil) const
void DeclareInput(Level &fineLevel, Level &coarseLevel) const
Input.
void sh_sort_permute(const typename Teuchos::Array< LocalOrdinal >::iterator &first1, const typename Teuchos::Array< LocalOrdinal >::iterator &last1, const typename Teuchos::Array< LocalOrdinal >::iterator &first2, const typename Teuchos::Array< LocalOrdinal >::iterator &last2) const
int size(OrdinalType length_in)
int setVectors(const RCP< SerialDenseMatrix< OrdinalType, ScalarType > > &X, const RCP< SerialDenseMatrix< OrdinalType, ScalarType > > &B)
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
int GetLevelID() const
Return level number.
Exception throws to report errors in the internal logical of the program.
static Teuchos::RCP< Map< LocalOrdinal, GlobalOrdinal, Node > > Build(UnderlyingLib lib, global_size_t numGlobalElements, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalGlobal lg=Xpetra::GloballyDistributed)
Description of what is happening (more verbose)
std::vector< T >::iterator iterator
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need's value has been saved.
int setMatrix(const RCP< SerialDenseMatrix< OrdinalType, ScalarType > > &A)