46 #ifndef MUELU_BLACKBOXPFACTORY_DEF_HPP
47 #define MUELU_BLACKBOXPFACTORY_DEF_HPP
58 #include <Xpetra_CrsMatrixWrap.hpp>
61 #include <Xpetra_MapFactory.hpp>
62 #include <Xpetra_MultiVectorFactory.hpp>
73 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
82 validParamList->
set<std::string>(
"Coarsen",
"{3}",
"Coarsening rate in all spatial dimensions");
86 validParamList->
set<
RCP<const FactoryBase> >(
"gNodesPerDim", Teuchos::null,
"Number of nodes per spatial dimmension provided by CoordinatesTransferFactory.");
87 validParamList->
set<
RCP<const FactoryBase> >(
"lNodesPerDim", Teuchos::null,
"Number of nodes per spatial dimmension provided by CoordinatesTransferFactory.");
88 validParamList->
set<std::string>(
"stencil type",
"full",
"You can use two type of stencils: full and reduced, that correspond to 27 and 7 points stencils respectively in 3D.");
89 validParamList->
set<std::string>(
"block strategy",
"coupled",
"The strategy used to handle systems of PDEs can be: coupled or uncoupled.");
91 return validParamList;
94 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
98 Input(fineLevel,
"A");
99 Input(fineLevel,
"Nullspace");
100 Input(fineLevel,
"Coordinates");
108 "gNodesPerDim was not provided by the user on level0!");
111 Input(fineLevel,
"gNodesPerDim");
121 "lNodesPerDim was not provided by the user on level0!");
124 Input(fineLevel,
"lNodesPerDim");
128 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
130 Level& coarseLevel)
const {
131 return BuildP(fineLevel, coarseLevel);
134 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
136 Level& coarseLevel)
const {
144 RCP<MultiVector> fineNullspace = Get<RCP<MultiVector> >(fineLevel,
"Nullspace");
146 Get<RCP<Xpetra::MultiVector<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO,
NO> > >(fineLevel,
"Coordinates");
147 LO numDimensions = coordinates->getNumVectors();
148 LO BlkSize = A->GetFixedBlockSize();
154 if (fineLevel.GetLevelID() == 0) {
159 gFineNodesPerDir = Get<Array<GO> >(fineLevel,
"gNodesPerDim");
162 lFineNodesPerDir = Get<Array<LO> >(fineLevel,
"lNodesPerDim");
164 for (LO i = 0; i < 3; ++i) {
165 if (gFineNodesPerDir[i] == 0) {
166 GetOStream(
Runtime0) <<
"gNodesPerDim in direction " << i <<
" is set to 1 from 0"
168 gFineNodesPerDir[i] = 1;
170 if (lFineNodesPerDir[i] == 0) {
171 GetOStream(
Runtime0) <<
"lNodesPerDim in direction " << i <<
" is set to 1 from 0"
173 lFineNodesPerDir[i] = 1;
176 GO gNumFineNodes = gFineNodesPerDir[2] * gFineNodesPerDir[1] * gFineNodesPerDir[0];
177 LO lNumFineNodes = lFineNodesPerDir[2] * lFineNodesPerDir[1] * lFineNodesPerDir[0];
180 std::string coarsenRate = pL.
get<std::string>(
"Coarsen");
185 crates = Teuchos::fromStringToArray<LO>(coarsenRate);
187 GetOStream(
Errors, -1) <<
" *** Coarsen must be a string convertible into an array! *** "
193 "Coarsen must have at least as many components as the number of"
194 " spatial dimensions in the problem.");
195 for (LO i = 0; i < 3; ++i) {
196 if (i < numDimensions) {
197 if (crates.
size() == 1) {
198 coarseRate[i] = crates[0];
199 }
else if (i < crates.
size()) {
200 coarseRate[i] = crates[i];
202 GetOStream(
Errors, -1) <<
" *** Coarsen must be at least as long as the number of"
203 " spatial dimensions! *** "
206 " *** Coarsen must be at least as long as the number of"
207 " spatial dimensions! *** \n");
216 const std::string stencilType = pL.
get<std::string>(
"stencil type");
217 if (stencilType !=
"full" && stencilType !=
"reduced") {
218 GetOStream(
Errors, -1) <<
" *** stencil type must be set to: full or reduced, any other value "
219 "is trated as an error! *** "
225 const std::string blockStrategy = pL.
get<std::string>(
"block strategy");
226 if (blockStrategy !=
"coupled" && blockStrategy !=
"uncoupled") {
227 GetOStream(
Errors, -1) <<
" *** block strategy must be set to: coupled or uncoupled, any other "
228 "value is trated as an error! *** "
233 GO gNumCoarseNodes = 0;
234 LO lNumCoarseNodes = 0;
235 Array<GO> gIndices(3), gCoarseNodesPerDir(3), ghostGIDs, coarseNodesGIDs, colGIDs;
236 Array<LO> myOffset(3), lCoarseNodesPerDir(3), glCoarseNodesPerDir(3), endRate(3);
241 for (LO dim = 0; dim < numDimensions; ++dim) {
242 fineNodes[dim] = coordinates->getData(dim)();
248 GetGeometricData(coordinates, coarseRate, gFineNodesPerDir, lFineNodesPerDir, BlkSize,
249 gIndices, myOffset, ghostInterface, endRate, gCoarseNodesPerDir,
250 lCoarseNodesPerDir, glCoarseNodesPerDir, ghostGIDs, coarseNodesGIDs, colGIDs,
251 gNumCoarseNodes, lNumCoarseNodes, coarseNodes, boundaryFlags,
258 coarseNodesGIDs.
view(0, lNumCoarseNodes),
259 coordinates->getMap()->getIndexBase(),
260 coordinates->getMap()->getComm());
262 for (LO dim = 0; dim < numDimensions; ++dim) {
263 coarseCoords[dim] = coarseNodes[dim]();
265 RCP<Xpetra::MultiVector<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO,
NO> > coarseCoordinates =
299 Array<GO> ghostRowGIDs, ghostColGIDs, nodeSteps(3);
301 nodeSteps[1] = gFineNodesPerDir[0];
302 nodeSteps[2] = gFineNodesPerDir[0] * gFineNodesPerDir[1];
304 GO startingGID = A->getRowMap()->getMinGlobalIndex();
305 for (LO dim = 0; dim < 3; ++dim) {
306 LO numCoarseNodes = 0;
307 if (dim < numDimensions) {
308 startingGID -= myOffset[dim] * nodeSteps[dim];
309 numCoarseNodes = lCoarseNodesPerDir[dim];
310 if (ghostInterface[2 * dim]) {
313 if (ghostInterface[2 * dim + 1]) {
316 if (gIndices[dim] + lFineNodesPerDir[dim] == gFineNodesPerDir[dim]) {
317 glFineNodesPerDir[dim] = (numCoarseNodes - 2) * coarseRate[dim] + endRate[dim] + 1;
319 glFineNodesPerDir[dim] = (numCoarseNodes - 1) * coarseRate[dim] + 1;
322 glFineNodesPerDir[dim] = 1;
325 ghostRowGIDs.
resize(glFineNodesPerDir[0] * glFineNodesPerDir[1] * glFineNodesPerDir[2] * BlkSize);
326 for (LO k = 0; k < glFineNodesPerDir[2]; ++k) {
327 for (LO j = 0; j < glFineNodesPerDir[1]; ++j) {
328 for (LO i = 0; i < glFineNodesPerDir[0]; ++i) {
329 for (LO l = 0; l < BlkSize; ++l) {
330 ghostRowGIDs[(k * glFineNodesPerDir[1] * glFineNodesPerDir[0] + j * glFineNodesPerDir[0] + i) * BlkSize + l] = startingGID + (k * gFineNodesPerDir[1] * gFineNodesPerDir[0] + j * gFineNodesPerDir[0] + i) * BlkSize + l;
337 Array<GO> startingGlobalIndices(numDimensions), dimStride(numDimensions);
338 Array<GO> startingColIndices(numDimensions), finishingColIndices(numDimensions);
342 for (
int dim = 1; dim < numDimensions; ++dim) {
343 dimStride[dim] = dimStride[dim - 1] * gFineNodesPerDir[dim - 1];
346 GO tmp = startingGID;
347 for (
int dim = numDimensions; dim > 0; --dim) {
348 startingGlobalIndices[dim - 1] = tmp / dimStride[dim - 1];
349 tmp = tmp % dimStride[dim - 1];
351 if (startingGlobalIndices[dim - 1] > 0) {
352 startingColIndices[dim - 1] = startingGlobalIndices[dim - 1] - 1;
354 if (startingGlobalIndices[dim - 1] + glFineNodesPerDir[dim - 1] < gFineNodesPerDir[dim - 1]) {
355 finishingColIndices[dim - 1] = startingGlobalIndices[dim - 1] + glFineNodesPerDir[dim - 1];
357 finishingColIndices[dim - 1] = startingGlobalIndices[dim - 1] + glFineNodesPerDir[dim - 1] - 1;
359 colRange[dim - 1] = finishingColIndices[dim - 1] - startingColIndices[dim - 1] + 1;
360 colMinGID += startingColIndices[dim - 1] * dimStride[dim - 1];
363 ghostColGIDs.
resize(colRange[0] * colRange[1] * colRange[2] * BlkSize);
364 for (LO k = 0; k < colRange[2]; ++k) {
365 for (LO j = 0; j < colRange[1]; ++j) {
366 for (LO i = 0; i < colRange[0]; ++i) {
367 for (LO l = 0; l < BlkSize; ++l) {
368 ghostColGIDs[(k * colRange[1] * colRange[0] + j * colRange[0] + i) * BlkSize + l] = colMinGID + (k * gFineNodesPerDir[1] * gFineNodesPerDir[0] + j * gFineNodesPerDir[0] + i) * BlkSize + l;
377 A->getRowMap()->getIndexBase(),
378 A->getRowMap()->getComm());
382 A->getRowMap()->getIndexBase(),
383 A->getRowMap()->getComm());
406 LO lNumGhostedNodes = ghostedCoarseNodes->GIDs.size();
408 std::vector<NodeID> colMapOrdering(lNumGhostedNodes);
409 for (LO ind = 0; ind < lNumGhostedNodes; ++ind) {
410 colMapOrdering[ind].GID = ghostedCoarseNodes->GIDs[ind];
411 if (ghostedCoarseNodes->PIDs[ind] == rowMapP->getComm()->getRank()) {
412 colMapOrdering[ind].PID = -1;
414 colMapOrdering[ind].PID = ghostedCoarseNodes->PIDs[ind];
416 colMapOrdering[ind].LID = ghostedCoarseNodes->LIDs[ind];
417 colMapOrdering[ind].lexiInd = ind;
419 std::sort(colMapOrdering.begin(), colMapOrdering.end(),
421 return ((a.
PID < b.PID) || ((a.
PID == b.PID) && (a.
GID < b.GID)));
424 colGIDs.
resize(BlkSize * lNumGhostedNodes);
425 for (LO ind = 0; ind < lNumGhostedNodes; ++ind) {
427 ghostedCoarseNodes->colInds[colMapOrdering[ind].lexiInd] = ind;
428 for (LO dof = 0; dof < BlkSize; ++dof) {
429 colGIDs[BlkSize * ind + dof] = BlkSize * colMapOrdering[ind].GID + dof;
433 BlkSize * gNumCoarseNodes,
434 colGIDs.
view(0, BlkSize * lNumCoarseNodes),
435 rowMapP->getIndexBase(),
440 rowMapP->getIndexBase(),
444 std::vector<size_t> strideInfo(1);
445 strideInfo[0] = BlkSize;
452 gnnzP += gNumCoarseNodes;
453 lnnzP += lNumCoarseNodes;
455 gnnzP += (gNumFineNodes - gNumCoarseNodes) * std::pow(2, numDimensions);
456 lnnzP += (lNumFineNodes - lNumCoarseNodes) * std::pow(2, numDimensions);
458 gnnzP = gnnzP * BlkSize;
459 lnnzP = lnnzP * BlkSize;
463 P =
rcp(
new CrsMatrixWrap(rowMapP, colMapP, 0));
464 RCP<CrsMatrix> PCrs = rcp_dynamic_cast<CrsMatrixWrap>(P)->getCrsMatrix();
470 PCrs->allocateAllValues(lnnzP, iaP, jaP, valP);
477 LO numCoarseElements = 1;
479 for (LO dim = 0; dim < numDimensions; ++dim) {
480 lCoarseElementsPerDir[dim] = lCoarseNodesPerDir[dim];
481 if (ghostInterface[2 * dim]) {
482 ++lCoarseElementsPerDir[dim];
484 if (!ghostInterface[2 * dim + 1]) {
485 --lCoarseElementsPerDir[dim];
487 numCoarseElements = numCoarseElements * lCoarseElementsPerDir[dim];
490 for (LO dim = numDimensions; dim < 3; ++dim) {
491 lCoarseElementsPerDir[dim] = 1;
496 Array<LO> elemInds(3), elementNodesPerDir(3), glElementRefTuple(3);
497 Array<LO> glElementRefTupleCG(3), glElementCoarseNodeCG(8);
498 const int numCoarseNodesInElement = std::pow(2, numDimensions);
499 const int nnzPerCoarseNode = (blockStrategy ==
"coupled") ? BlkSize : 1;
500 const int numRowsPerPoint = BlkSize;
501 for (elemInds[2] = 0; elemInds[2] < lCoarseElementsPerDir[2]; ++elemInds[2]) {
502 for (elemInds[1] = 0; elemInds[1] < lCoarseElementsPerDir[1]; ++elemInds[1]) {
503 for (elemInds[0] = 0; elemInds[0] < lCoarseElementsPerDir[0]; ++elemInds[0]) {
507 for (
int dim = 0; dim < 3; ++dim) {
509 if (elemInds[dim] == 0 && elemInds[dim] == lCoarseElementsPerDir[dim] - 1) {
510 elementFlags[dim] = boundaryFlags[dim];
511 }
else if (elemInds[dim] == 0 && (boundaryFlags[dim] == 1 || boundaryFlags[dim] == 3)) {
512 elementFlags[dim] += 1;
513 }
else if ((elemInds[dim] == lCoarseElementsPerDir[dim] - 1) && (boundaryFlags[dim] == 2 || boundaryFlags[dim] == 3)) {
514 elementFlags[dim] += 2;
516 elementFlags[dim] = 0;
520 if (dim < numDimensions) {
521 if ((elemInds[dim] == lCoarseElementsPerDir[dim]) && (gIndices[dim] + lFineNodesPerDir[dim] == gFineNodesPerDir[dim])) {
522 elementNodesPerDir[dim] = endRate[dim] + 1;
524 elementNodesPerDir[dim] = coarseRate[dim] + 1;
527 elementNodesPerDir[dim] = 1;
531 glElementRefTuple[dim] = elemInds[dim] * coarseRate[dim];
532 glElementRefTupleCG[dim] = elemInds[dim];
538 glElementCoarseNodeCG[elem] = glElementRefTupleCG[2] * glCoarseNodesPerDir[1] * glCoarseNodesPerDir[0] + glElementRefTupleCG[1] * glCoarseNodesPerDir[0] + glElementRefTupleCG[0];
540 glElementCoarseNodeCG[4] += glCoarseNodesPerDir[1] * glCoarseNodesPerDir[0];
541 glElementCoarseNodeCG[5] += glCoarseNodesPerDir[1] * glCoarseNodesPerDir[0];
542 glElementCoarseNodeCG[6] += glCoarseNodesPerDir[1] * glCoarseNodesPerDir[0];
543 glElementCoarseNodeCG[7] += glCoarseNodesPerDir[1] * glCoarseNodesPerDir[0];
545 glElementCoarseNodeCG[2] += glCoarseNodesPerDir[0];
546 glElementCoarseNodeCG[3] += glCoarseNodesPerDir[0];
547 glElementCoarseNodeCG[6] += glCoarseNodesPerDir[0];
548 glElementCoarseNodeCG[7] += glCoarseNodesPerDir[0];
550 glElementCoarseNodeCG[1] += 1;
551 glElementCoarseNodeCG[3] += 1;
552 glElementCoarseNodeCG[5] += 1;
553 glElementCoarseNodeCG[7] += 1;
555 LO numNodesInElement = elementNodesPerDir[0] * elementNodesPerDir[1] * elementNodesPerDir[2];
561 Array<LO> dofType(numNodesInElement * BlkSize), lDofInd(numNodesInElement * BlkSize);
562 ComputeLocalEntries(Aghost, coarseRate, endRate, BlkSize, elemInds, lCoarseElementsPerDir,
563 numDimensions, glFineNodesPerDir, gFineNodesPerDir, gIndices,
564 lCoarseNodesPerDir, ghostInterface, elementFlags, stencilType,
565 blockStrategy, elementNodesPerDir, numNodesInElement, colGIDs,
566 Pi, Pf, Pe, dofType, lDofInd);
573 for (nodeInd[2] = 0; nodeInd[2] < elementNodesPerDir[2]; ++nodeInd[2]) {
574 for (nodeInd[1] = 0; nodeInd[1] < elementNodesPerDir[1]; ++nodeInd[1]) {
575 for (nodeInd[0] = 0; nodeInd[0] < elementNodesPerDir[0]; ++nodeInd[0]) {
576 int stencilLength = 0;
577 if ((nodeInd[0] == 0 || nodeInd[0] == elementNodesPerDir[0] - 1) &&
578 (nodeInd[1] == 0 || nodeInd[1] == elementNodesPerDir[1] - 1) &&
579 (nodeInd[2] == 0 || nodeInd[2] == elementNodesPerDir[2] - 1)) {
582 stencilLength = std::pow(2, numDimensions);
584 LO nodeElementInd = nodeInd[2] * elementNodesPerDir[1] * elementNodesPerDir[1] + nodeInd[1] * elementNodesPerDir[0] + nodeInd[0];
585 for (
int dim = 0; dim < 3; ++dim) {
586 lNodeTuple[dim] = glElementRefTuple[dim] - myOffset[dim] + nodeInd[dim];
588 if (lNodeTuple[0] < 0 || lNodeTuple[1] < 0 || lNodeTuple[2] < 0 ||
589 lNodeTuple[0] > lFineNodesPerDir[0] - 1 ||
590 lNodeTuple[1] > lFineNodesPerDir[1] - 1 ||
591 lNodeTuple[2] > lFineNodesPerDir[2] - 1) {
594 lNodeLIDs[nodeElementInd] = -1;
595 }
else if ((nodeInd[0] == 0 && elemInds[0] != 0) ||
596 (nodeInd[1] == 0 && elemInds[1] != 0) ||
597 (nodeInd[2] == 0 && elemInds[2] != 0)) {
601 lNodeLIDs[nodeElementInd] = -2;
607 lNodeLIDs[nodeElementInd] = lNodeTuple[2] * lFineNodesPerDir[1] * lFineNodesPerDir[0] + lNodeTuple[1] * lFineNodesPerDir[0] + lNodeTuple[0];
614 for (
int dim = 2; dim > -1; --dim) {
616 refCoarsePointTuple[dim] = (lNodeTuple[dim] + myOffset[dim]) / coarseRate[dim];
617 if (myOffset[dim] == 0) {
618 ++refCoarsePointTuple[dim];
622 refCoarsePointTuple[dim] =
623 std::ceil(static_cast<double>(lNodeTuple[dim] + myOffset[dim]) / coarseRate[dim]);
625 if ((lNodeTuple[dim] + myOffset[dim]) % coarseRate[dim] > 0) {
629 const LO numCoarsePoints = refCoarsePointTuple[0] + refCoarsePointTuple[1] * lCoarseNodesPerDir[0] + refCoarsePointTuple[2] * lCoarseNodesPerDir[1] * lCoarseNodesPerDir[0];
630 const LO numFinePoints = lNodeLIDs[nodeElementInd] + 1;
634 size_t rowPtr = (numFinePoints - numCoarsePoints) * numRowsPerPoint * numCoarseNodesInElement * nnzPerCoarseNode + numCoarsePoints * numRowsPerPoint;
635 if (dofType[nodeElementInd * BlkSize] == 0) {
637 rowPtr = rowPtr - numRowsPerPoint;
639 rowPtr = rowPtr - numRowsPerPoint * numCoarseNodesInElement * nnzPerCoarseNode;
642 for (
int dof = 0; dof < BlkSize; ++dof) {
645 switch (dofType[nodeElementInd * BlkSize + dof]) {
647 if (nodeInd[2] == elementNodesPerDir[2] - 1) {
650 if (nodeInd[1] == elementNodesPerDir[1] - 1) {
653 if (nodeInd[0] == elementNodesPerDir[0] - 1) {
656 ia[lNodeLIDs[nodeElementInd] * BlkSize + dof + 1] = rowPtr + dof + 1;
657 ja[rowPtr + dof] = ghostedCoarseNodes->colInds[glElementCoarseNodeCG[cornerInd]] * BlkSize + dof;
658 val[rowPtr + dof] = 1.0;
662 ia[lNodeLIDs[nodeElementInd] * BlkSize + dof + 1] = rowPtr + (dof + 1) * numCoarseNodesInElement * nnzPerCoarseNode;
663 for (
int ind1 = 0; ind1 < stencilLength; ++ind1) {
664 if (blockStrategy ==
"coupled") {
665 for (
int ind2 = 0; ind2 < BlkSize; ++ind2) {
666 size_t lRowPtr = rowPtr + dof * numCoarseNodesInElement * nnzPerCoarseNode + ind1 * BlkSize + ind2;
667 ja[lRowPtr] = ghostedCoarseNodes->colInds[glElementCoarseNodeCG[ind1]] * BlkSize + ind2;
668 val[lRowPtr] = Pe(lDofInd[nodeElementInd * BlkSize + dof],
669 ind1 * BlkSize + ind2);
671 }
else if (blockStrategy ==
"uncoupled") {
672 size_t lRowPtr = rowPtr + dof * numCoarseNodesInElement * nnzPerCoarseNode + ind1;
673 ja[rowPtr + dof] = ghostedCoarseNodes->colInds[glElementCoarseNodeCG[ind1]] * BlkSize + dof;
674 val[lRowPtr] = Pe(lDofInd[nodeElementInd * BlkSize + dof],
675 ind1 * BlkSize + dof);
681 ia[lNodeLIDs[nodeElementInd] * BlkSize + dof + 1] = rowPtr + (dof + 1) * numCoarseNodesInElement * nnzPerCoarseNode;
682 for (
int ind1 = 0; ind1 < stencilLength; ++ind1) {
683 if (blockStrategy ==
"coupled") {
684 for (
int ind2 = 0; ind2 < BlkSize; ++ind2) {
685 size_t lRowPtr = rowPtr + dof * numCoarseNodesInElement * nnzPerCoarseNode + ind1 * BlkSize + ind2;
686 ja[lRowPtr] = ghostedCoarseNodes->colInds[glElementCoarseNodeCG[ind1]] * BlkSize + ind2;
687 val[lRowPtr] = Pf(lDofInd[nodeElementInd * BlkSize + dof],
688 ind1 * BlkSize + ind2);
690 }
else if (blockStrategy ==
"uncoupled") {
691 size_t lRowPtr = rowPtr + dof * numCoarseNodesInElement * nnzPerCoarseNode + ind1;
693 ja[lRowPtr] = ghostedCoarseNodes->colInds[glElementCoarseNodeCG[ind1]] * BlkSize + dof;
694 val[lRowPtr] = Pf(lDofInd[nodeElementInd * BlkSize + dof],
695 ind1 * BlkSize + dof);
701 ia[lNodeLIDs[nodeElementInd] * BlkSize + dof + 1] = rowPtr + (dof + 1) * numCoarseNodesInElement * nnzPerCoarseNode;
702 for (
int ind1 = 0; ind1 < stencilLength; ++ind1) {
703 if (blockStrategy ==
"coupled") {
704 for (
int ind2 = 0; ind2 < BlkSize; ++ind2) {
705 size_t lRowPtr = rowPtr + dof * numCoarseNodesInElement * nnzPerCoarseNode + ind1 * BlkSize + ind2;
706 ja[lRowPtr] = ghostedCoarseNodes->colInds[glElementCoarseNodeCG[ind1]] * BlkSize + ind2;
707 val[lRowPtr] = Pi(lDofInd[nodeElementInd * BlkSize + dof],
708 ind1 * BlkSize + ind2);
710 }
else if (blockStrategy ==
"uncoupled") {
711 size_t lRowPtr = rowPtr + dof * numCoarseNodesInElement * nnzPerCoarseNode + ind1;
712 ja[lRowPtr] = ghostedCoarseNodes->colInds[glElementCoarseNodeCG[ind1]] * BlkSize + dof;
713 val[lRowPtr] = Pi(lDofInd[nodeElementInd * BlkSize + dof],
714 ind1 * BlkSize + dof);
733 PCrs->setAllValues(iaP, jaP, valP);
734 PCrs->expertStaticFillComplete(domainMapP, rowMapP);
737 if (A->IsView(
"stridedMaps") ==
true) {
738 P->CreateView(
"stridedMaps", A->getRowMap(
"stridedMaps"), stridedDomainMapP);
740 P->CreateView(
"stridedMaps", P->getRangeMap(), stridedDomainMapP);
744 Set(coarseLevel,
"P", P);
745 Set(coarseLevel,
"coarseCoordinates", coarseCoordinates);
746 Set<Array<GO> >(coarseLevel,
"gCoarseNodesPerDim", gCoarseNodesPerDir);
747 Set<Array<LO> >(coarseLevel,
"lCoarseNodesPerDim", lCoarseNodesPerDir);
750 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
758 Array<GO>& colGIDs,
GO& gNumCoarseNodes,
LO& lNumCoarseNodes,
768 LO numDimensions = coordinates->getNumVectors();
779 GO minGlobalIndex = coordinatesMap->getMinGlobalIndex();
782 gIndices[2] = minGlobalIndex / (gFineNodesPerDir[1] * gFineNodesPerDir[0]);
783 tmp = minGlobalIndex % (gFineNodesPerDir[1] * gFineNodesPerDir[0]);
784 gIndices[1] = tmp / gFineNodesPerDir[0];
785 gIndices[0] = tmp % gFineNodesPerDir[0];
787 myOffset[2] = gIndices[2] % coarseRate[2];
788 myOffset[1] = gIndices[1] % coarseRate[1];
789 myOffset[0] = gIndices[0] % coarseRate[0];
792 for (
int dim = 0; dim < 3; ++dim) {
793 if (gIndices[dim] == 0) {
794 boundaryFlags[dim] += 1;
796 if (gIndices[dim] + lFineNodesPerDir[dim] == gFineNodesPerDir[dim]) {
797 boundaryFlags[dim] += 2;
802 for (
LO i = 0; i < numDimensions; ++i) {
803 if ((gIndices[i] != 0) && (gIndices[i] % coarseRate[i] > 0)) {
804 ghostInterface[2 * i] =
true;
806 if (((gIndices[i] + lFineNodesPerDir[i]) != gFineNodesPerDir[i]) && ((gIndices[i] + lFineNodesPerDir[i] - 1) % coarseRate[i] > 0)) {
807 ghostInterface[2 * i + 1] =
true;
811 for (
LO i = 0; i < 3; ++i) {
812 if (i < numDimensions) {
813 lCoarseNodesPerDir[i] = (lFineNodesPerDir[i] + myOffset[i] - 1) / coarseRate[i];
814 if (myOffset[i] == 0) {
815 ++lCoarseNodesPerDir[i];
817 gCoarseNodesPerDir[i] = (gFineNodesPerDir[i] - 1) / coarseRate[i];
818 endRate[i] = (gFineNodesPerDir[i] - 1) % coarseRate[i];
819 if (endRate[i] == 0) {
820 ++gCoarseNodesPerDir[i];
821 endRate[i] = coarseRate[i];
827 gCoarseNodesPerDir[i] = 1;
828 lCoarseNodesPerDir[i] = 1;
833 gNumCoarseNodes = gCoarseNodesPerDir[0] * gCoarseNodesPerDir[1] * gCoarseNodesPerDir[2];
834 lNumCoarseNodes = lCoarseNodesPerDir[0] * lCoarseNodesPerDir[1] * lCoarseNodesPerDir[2];
837 LO lNumGhostNodes = 0;
840 const int complementaryIndices[3][2] = {{1, 2}, {0, 2}, {0, 1}};
842 for (
LO i = 0; i < 3; ++i) {
846 if ((gIndices[i] == gFineNodesPerDir[i] - 1) && (gIndices[i] % coarseRate[i] == 0)) {
847 startGhostedCoarseNode[i] = gIndices[i] / coarseRate[i] - 1;
849 startGhostedCoarseNode[i] = gIndices[i] / coarseRate[i];
852 glCoarseNodesPerDir[i] = lCoarseNodesPerDir[i];
855 if (ghostInterface[2 * i] || ghostInterface[2 * i + 1]) {
856 ++glCoarseNodesPerDir[i];
858 tmp = lCoarseNodesPerDir[1] * lCoarseNodesPerDir[2];
861 tmp = lCoarseNodesPerDir[0] * lCoarseNodesPerDir[2];
864 tmp = lCoarseNodesPerDir[0] * lCoarseNodesPerDir[1];
868 if (ghostInterface[2 * i] && ghostInterface[2 * i + 1]) {
869 ++glCoarseNodesPerDir[i];
872 lNumGhostNodes += tmp;
875 for (
LO j = 0; j < 2; ++j) {
876 for (
LO k = 0; k < 2; ++k) {
878 if (ghostInterface[2 * complementaryIndices[i][0] + j] && ghostInterface[2 * complementaryIndices[i][1] + k]) {
879 lNumGhostNodes += lCoarseNodesPerDir[i];
882 if (ghostInterface[2 * i] && (i == 0)) {
885 if (ghostInterface[2 * i + 1] && (i == 0)) {
895 const LO lNumGhostedNodes = glCoarseNodesPerDir[0] * glCoarseNodesPerDir[1] * glCoarseNodesPerDir[2];
896 ghostedCoarseNodes->PIDs.resize(lNumGhostedNodes);
897 ghostedCoarseNodes->LIDs.resize(lNumGhostedNodes);
898 ghostedCoarseNodes->GIDs.resize(lNumGhostedNodes);
899 ghostedCoarseNodes->coarseGIDs.resize(lNumGhostedNodes);
900 ghostedCoarseNodes->colInds.resize(lNumGhostedNodes);
903 Array<LO> coarseNodeCoarseIndices(3), coarseNodeFineIndices(3), ijk(3);
904 LO currentIndex = -1;
905 for (ijk[2] = 0; ijk[2] < glCoarseNodesPerDir[2]; ++ijk[2]) {
906 for (ijk[1] = 0; ijk[1] < glCoarseNodesPerDir[1]; ++ijk[1]) {
907 for (ijk[0] = 0; ijk[0] < glCoarseNodesPerDir[0]; ++ijk[0]) {
908 currentIndex = ijk[2] * glCoarseNodesPerDir[1] * glCoarseNodesPerDir[0] + ijk[1] * glCoarseNodesPerDir[0] + ijk[0];
909 coarseNodeCoarseIndices[0] = startGhostedCoarseNode[0] + ijk[0];
910 coarseNodeFineIndices[0] = coarseNodeCoarseIndices[0] * coarseRate[0];
911 if (coarseNodeFineIndices[0] > gFineNodesPerDir[0] - 1) {
912 coarseNodeFineIndices[0] = gFineNodesPerDir[0] - 1;
914 coarseNodeCoarseIndices[1] = startGhostedCoarseNode[1] + ijk[1];
915 coarseNodeFineIndices[1] = coarseNodeCoarseIndices[1] * coarseRate[1];
916 if (coarseNodeFineIndices[1] > gFineNodesPerDir[1] - 1) {
917 coarseNodeFineIndices[1] = gFineNodesPerDir[1] - 1;
919 coarseNodeCoarseIndices[2] = startGhostedCoarseNode[2] + ijk[2];
920 coarseNodeFineIndices[2] = coarseNodeCoarseIndices[2] * coarseRate[2];
921 if (coarseNodeFineIndices[2] > gFineNodesPerDir[2] - 1) {
922 coarseNodeFineIndices[2] = gFineNodesPerDir[2] - 1;
924 GO myGID = 0, myCoarseGID = -1;
926 factor[2] = gFineNodesPerDir[1] * gFineNodesPerDir[0];
927 factor[1] = gFineNodesPerDir[0];
929 for (
int dim = 0; dim < 3; ++dim) {
930 if (dim < numDimensions) {
931 if (gIndices[dim] - myOffset[dim] + ijk[dim] * coarseRate[dim] < gFineNodesPerDir[dim] - 1) {
932 myGID += (gIndices[dim] - myOffset[dim] + ijk[dim] * coarseRate[dim]) * factor[dim];
934 myGID += (gIndices[dim] - myOffset[dim] + (ijk[dim] - 1) * coarseRate[dim] + endRate[dim]) * factor[dim];
938 myCoarseGID = coarseNodeCoarseIndices[0] + coarseNodeCoarseIndices[1] * gCoarseNodesPerDir[0] + coarseNodeCoarseIndices[2] * gCoarseNodesPerDir[1] * gCoarseNodesPerDir[0];
939 ghostedCoarseNodes->GIDs[currentIndex] = myGID;
940 ghostedCoarseNodes->coarseGIDs[currentIndex] = myCoarseGID;
944 coordinatesMap->getRemoteIndexList(ghostedCoarseNodes->GIDs(),
945 ghostedCoarseNodes->PIDs(),
946 ghostedCoarseNodes->LIDs());
957 ghostGIDs.
resize(lNumGhostNodes);
960 GO startingGID = minGlobalIndex;
964 if (ghostInterface[4] && (myOffset[2] == 0)) {
965 if (gIndices[2] + coarseRate[2] > gFineNodesPerDir[2]) {
966 startingGID -= endRate[2] * gFineNodesPerDir[1] * gFineNodesPerDir[0];
968 startingGID -= coarseRate[2] * gFineNodesPerDir[1] * gFineNodesPerDir[0];
971 startingGID -= myOffset[2] * gFineNodesPerDir[1] * gFineNodesPerDir[0];
973 if (ghostInterface[2] && (myOffset[1] == 0)) {
974 if (gIndices[1] + coarseRate[1] > gFineNodesPerDir[1]) {
975 startingGID -= endRate[1] * gFineNodesPerDir[0];
977 startingGID -= coarseRate[1] * gFineNodesPerDir[0];
980 startingGID -= myOffset[1] * gFineNodesPerDir[0];
982 if (ghostInterface[0] && (myOffset[0] == 0)) {
983 if (gIndices[0] + coarseRate[0] > gFineNodesPerDir[0]) {
984 startingGID -= endRate[0];
986 startingGID -= coarseRate[0];
989 startingGID -= myOffset[0];
994 startingIndices[2] = startingGID / (gFineNodesPerDir[1] * gFineNodesPerDir[0]);
995 tmp = startingGID % (gFineNodesPerDir[1] * gFineNodesPerDir[0]);
996 startingIndices[1] = tmp / gFineNodesPerDir[0];
997 startingIndices[0] = tmp % gFineNodesPerDir[0];
1000 GO ghostOffset[3] = {0, 0, 0};
1001 LO lengthZero = lCoarseNodesPerDir[0];
1002 LO lengthOne = lCoarseNodesPerDir[1];
1003 LO lengthTwo = lCoarseNodesPerDir[2];
1004 if (ghostInterface[0]) {
1007 if (ghostInterface[1]) {
1010 if (ghostInterface[2]) {
1013 if (ghostInterface[3]) {
1016 if (ghostInterface[4]) {
1019 if (ghostInterface[5]) {
1024 if (ghostInterface[4]) {
1025 ghostOffset[2] = startingGID;
1026 for (
LO j = 0; j < lengthOne; ++j) {
1027 if ((j == lengthOne - 1) && (startingIndices[1] + j * coarseRate[1] + 1 > gFineNodesPerDir[1])) {
1028 ghostOffset[1] = ((j - 1) * coarseRate[1] + endRate[1]) * gFineNodesPerDir[0];
1030 ghostOffset[1] = j * coarseRate[1] * gFineNodesPerDir[0];
1032 for (
LO k = 0; k < lengthZero; ++k) {
1033 if ((k == lengthZero - 1) && (startingIndices[0] + k * coarseRate[0] + 1 > gFineNodesPerDir[0])) {
1034 ghostOffset[0] = (k - 1) * coarseRate[0] + endRate[0];
1036 ghostOffset[0] = k * coarseRate[0];
1041 ghostGIDs[countGhosts] = ghostOffset[2] + ghostOffset[1] + ghostOffset[0];
1049 for (
LO i = 0; i < lengthTwo; ++i) {
1052 if (!((i == lengthTwo - 1) && ghostInterface[5]) && !((i == 0) && ghostInterface[4])) {
1055 if ((i == lengthTwo - 1) && !ghostInterface[5]) {
1056 ghostOffset[2] = startingGID + ((i - 1) * coarseRate[2] + endRate[2]) * gFineNodesPerDir[1] * gFineNodesPerDir[0];
1058 ghostOffset[2] = startingGID + i * coarseRate[2] * gFineNodesPerDir[1] * gFineNodesPerDir[0];
1060 for (
LO j = 0; j < lengthOne; ++j) {
1061 if ((j == 0) && ghostInterface[2]) {
1062 for (
LO k = 0; k < lengthZero; ++k) {
1063 if ((k == lengthZero - 1) && (startingIndices[0] + k * coarseRate[0] + 1 > gFineNodesPerDir[0])) {
1065 ghostOffset[0] = endRate[0];
1067 ghostOffset[0] = (k - 1) * coarseRate[0] + endRate[0];
1070 ghostOffset[0] = k * coarseRate[0];
1073 ghostGIDs[countGhosts] = ghostOffset[2] + ghostOffset[0];
1076 }
else if ((j == lengthOne - 1) && ghostInterface[3]) {
1079 if ((j == lengthOne - 1) && (startingIndices[1] + j * coarseRate[1] + 1 > gFineNodesPerDir[1])) {
1080 ghostOffset[1] = ((j - 1) * coarseRate[1] + endRate[1]) * gFineNodesPerDir[0];
1082 ghostOffset[1] = j * coarseRate[1] * gFineNodesPerDir[0];
1084 for (
LO k = 0; k < lengthZero; ++k) {
1085 if ((k == lengthZero - 1) && (startingIndices[0] + k * coarseRate[0] + 1 > gFineNodesPerDir[0])) {
1086 ghostOffset[0] = (k - 1) * coarseRate[0] + endRate[0];
1088 ghostOffset[0] = k * coarseRate[0];
1090 ghostGIDs[countGhosts] = ghostOffset[2] + ghostOffset[1] + ghostOffset[0];
1095 if ((j == lengthOne - 1) && (startingIndices[1] + j * coarseRate[1] + 1 > gFineNodesPerDir[1])) {
1096 ghostOffset[1] = ((j - 1) * coarseRate[1] + endRate[1]) * gFineNodesPerDir[0];
1098 ghostOffset[1] = j * coarseRate[1] * gFineNodesPerDir[0];
1102 if (ghostInterface[0]) {
1103 ghostGIDs[countGhosts] = ghostOffset[2] + ghostOffset[1];
1106 if (ghostInterface[1]) {
1107 if ((startingIndices[0] + (lengthZero - 1) * coarseRate[0]) > gFineNodesPerDir[0] - 1) {
1108 if (lengthZero > 2) {
1109 ghostOffset[0] = (lengthZero - 2) * coarseRate[0] + endRate[0];
1111 ghostOffset[0] = endRate[0];
1114 ghostOffset[0] = (lengthZero - 1) * coarseRate[0];
1116 ghostGIDs[countGhosts] = ghostOffset[2] + ghostOffset[1] + ghostOffset[0];
1125 if (ghostInterface[5]) {
1126 if (startingIndices[2] + (lengthTwo - 1) * coarseRate[2] + 1 > gFineNodesPerDir[2]) {
1127 ghostOffset[2] = startingGID + ((lengthTwo - 2) * coarseRate[2] + endRate[2]) * gFineNodesPerDir[1] * gFineNodesPerDir[0];
1129 ghostOffset[2] = startingGID + (lengthTwo - 1) * coarseRate[2] * gFineNodesPerDir[1] * gFineNodesPerDir[0];
1131 for (
LO j = 0; j < lengthOne; ++j) {
1132 if ((j == lengthOne - 1) && (startingIndices[1] + j * coarseRate[1] + 1 > gFineNodesPerDir[1])) {
1133 ghostOffset[1] = ((j - 1) * coarseRate[1] + endRate[1]) * gFineNodesPerDir[0];
1135 ghostOffset[1] = j * coarseRate[1] * gFineNodesPerDir[0];
1137 for (
LO k = 0; k < lengthZero; ++k) {
1138 if ((k == lengthZero - 1) && (startingIndices[0] + k * coarseRate[0] + 1 > gFineNodesPerDir[0])) {
1139 ghostOffset[0] = (k - 1) * coarseRate[0] + endRate[0];
1141 ghostOffset[0] = k * coarseRate[0];
1143 ghostGIDs[countGhosts] = ghostOffset[2] + ghostOffset[1] + ghostOffset[0];
1156 Array<GO> gCoarseNodesGIDs(lNumCoarseNodes);
1157 LO currentNode, offset2, offset1, offset0;
1159 for (
LO ind2 = 0; ind2 < lCoarseNodesPerDir[2]; ++ind2) {
1160 if (myOffset[2] == 0) {
1161 offset2 = startingIndices[2] + myOffset[2];
1163 if (startingIndices[2] + endRate[2] == gFineNodesPerDir[2] - 1) {
1164 offset2 = startingIndices[2] + endRate[2];
1166 offset2 = startingIndices[2] + coarseRate[2];
1169 if (offset2 + ind2 * coarseRate[2] > gFineNodesPerDir[2] - 1) {
1170 offset2 += (ind2 - 1) * coarseRate[2] + endRate[2];
1172 offset2 += ind2 * coarseRate[2];
1174 offset2 = offset2 * gFineNodesPerDir[1] * gFineNodesPerDir[0];
1176 for (
LO ind1 = 0; ind1 < lCoarseNodesPerDir[1]; ++ind1) {
1177 if (myOffset[1] == 0) {
1178 offset1 = startingIndices[1] + myOffset[1];
1180 if (startingIndices[1] + endRate[1] == gFineNodesPerDir[1] - 1) {
1181 offset1 = startingIndices[1] + endRate[1];
1183 offset1 = startingIndices[1] + coarseRate[1];
1186 if (offset1 + ind1 * coarseRate[1] > gFineNodesPerDir[1] - 1) {
1187 offset1 += (ind1 - 1) * coarseRate[1] + endRate[1];
1189 offset1 += ind1 * coarseRate[1];
1191 offset1 = offset1 * gFineNodesPerDir[0];
1192 for (
LO ind0 = 0; ind0 < lCoarseNodesPerDir[0]; ++ind0) {
1193 offset0 = startingIndices[0];
1194 if (myOffset[0] == 0) {
1195 offset0 += ind0 * coarseRate[0];
1197 offset0 += (ind0 + 1) * coarseRate[0];
1199 if (offset0 > gFineNodesPerDir[0] - 1) {
1200 offset0 += endRate[0] - coarseRate[0];
1203 currentNode = ind2 * lCoarseNodesPerDir[1] * lCoarseNodesPerDir[0] + ind1 * lCoarseNodesPerDir[0] + ind0;
1204 gCoarseNodesGIDs[currentNode] = offset2 + offset1 + offset0;
1211 colGIDs.
resize(BlkSize * (lNumCoarseNodes + lNumGhostNodes));
1212 coarseNodesGIDs.
resize(lNumCoarseNodes);
1213 for (
LO i = 0; i < numDimensions; ++i) {
1214 coarseNodes[i].resize(lNumCoarseNodes);
1216 GO fineNodesPerCoarseSlab = coarseRate[2] * gFineNodesPerDir[1] * gFineNodesPerDir[0];
1217 GO fineNodesEndCoarseSlab = endRate[2] * gFineNodesPerDir[1] * gFineNodesPerDir[0];
1218 GO fineNodesPerCoarsePlane = coarseRate[1] * gFineNodesPerDir[0];
1219 GO fineNodesEndCoarsePlane = endRate[1] * gFineNodesPerDir[0];
1220 GO coarseNodesPerCoarseLayer = gCoarseNodesPerDir[1] * gCoarseNodesPerDir[0];
1221 GO gCoarseNodeOnCoarseGridGID;
1226 for (
LO k = 0; k < lNumGhostNodes; ++k) {
1229 coordinatesMap->getRemoteIndexList(ghostGIDs, ghostPIDs, ghostLIDs);
1230 sh_sort_permute(ghostPIDs.
begin(), ghostPIDs.
end(), ghostPermut.
begin(), ghostPermut.
end());
1233 GO tmpInds[3], tmpVars[2];
1241 LO firstCoarseNodeInds[3], currentCoarseNode;
1242 for (
LO dim = 0; dim < 3; ++dim) {
1243 if (myOffset[dim] == 0) {
1244 firstCoarseNodeInds[dim] = 0;
1246 firstCoarseNodeInds[dim] = coarseRate[dim] - myOffset[dim];
1250 for (
LO dim = 0; dim < numDimensions; ++dim) {
1251 fineNodes[dim] = coordinates->getData(dim);
1253 for (
LO k = 0; k < lCoarseNodesPerDir[2]; ++k) {
1254 for (
LO j = 0; j < lCoarseNodesPerDir[1]; ++j) {
1255 for (
LO i = 0; i < lCoarseNodesPerDir[0]; ++i) {
1256 col = k * lCoarseNodesPerDir[1] * lCoarseNodesPerDir[0] + j * lCoarseNodesPerDir[0] + i;
1259 currentCoarseNode = 0;
1260 if (firstCoarseNodeInds[0] + i * coarseRate[0] > lFineNodesPerDir[0] - 1) {
1261 currentCoarseNode += firstCoarseNodeInds[0] + (i - 1) * coarseRate[0] + endRate[0];
1263 currentCoarseNode += firstCoarseNodeInds[0] + i * coarseRate[0];
1265 if (firstCoarseNodeInds[1] + j * coarseRate[1] > lFineNodesPerDir[1] - 1) {
1266 currentCoarseNode += (firstCoarseNodeInds[1] + (j - 1) * coarseRate[1] + endRate[1]) * lFineNodesPerDir[0];
1268 currentCoarseNode += (firstCoarseNodeInds[1] + j * coarseRate[1]) * lFineNodesPerDir[0];
1270 if (firstCoarseNodeInds[2] + k * coarseRate[2] > lFineNodesPerDir[2] - 1) {
1271 currentCoarseNode += (firstCoarseNodeInds[2] + (k - 1) * coarseRate[2] + endRate[2]) * lFineNodesPerDir[1] * lFineNodesPerDir[0];
1273 currentCoarseNode += (firstCoarseNodeInds[2] + k * coarseRate[2]) * lFineNodesPerDir[1] * lFineNodesPerDir[0];
1276 for (
LO dim = 0; dim < numDimensions; ++dim) {
1277 coarseNodes[dim][col] = fineNodes[dim][currentCoarseNode];
1280 if ((endRate[2] != coarseRate[2]) && (gCoarseNodesGIDs[col] > (gCoarseNodesPerDir[2] - 2) * fineNodesPerCoarseSlab + fineNodesEndCoarseSlab - 1)) {
1281 tmpInds[2] = gCoarseNodesGIDs[col] / fineNodesPerCoarseSlab + 1;
1282 tmpVars[0] = gCoarseNodesGIDs[col] - (tmpInds[2] - 1) * fineNodesPerCoarseSlab - fineNodesEndCoarseSlab;
1284 tmpInds[2] = gCoarseNodesGIDs[col] / fineNodesPerCoarseSlab;
1285 tmpVars[0] = gCoarseNodesGIDs[col] % fineNodesPerCoarseSlab;
1287 if ((endRate[1] != coarseRate[1]) && (tmpVars[0] > (gCoarseNodesPerDir[1] - 2) * fineNodesPerCoarsePlane + fineNodesEndCoarsePlane - 1)) {
1288 tmpInds[1] = tmpVars[0] / fineNodesPerCoarsePlane + 1;
1289 tmpVars[1] = tmpVars[0] - (tmpInds[1] - 1) * fineNodesPerCoarsePlane - fineNodesEndCoarsePlane;
1291 tmpInds[1] = tmpVars[0] / fineNodesPerCoarsePlane;
1292 tmpVars[1] = tmpVars[0] % fineNodesPerCoarsePlane;
1294 if (tmpVars[1] == gFineNodesPerDir[0] - 1) {
1295 tmpInds[0] = gCoarseNodesPerDir[0] - 1;
1297 tmpInds[0] = tmpVars[1] / coarseRate[0];
1299 gInd[2] = col / (lCoarseNodesPerDir[1] * lCoarseNodesPerDir[0]);
1300 tmp = col % (lCoarseNodesPerDir[1] * lCoarseNodesPerDir[0]);
1301 gInd[1] = tmp / lCoarseNodesPerDir[0];
1302 gInd[0] = tmp % lCoarseNodesPerDir[0];
1303 lCol = gInd[2] * (lCoarseNodesPerDir[1] * lCoarseNodesPerDir[0]) + gInd[1] * lCoarseNodesPerDir[0] + gInd[0];
1304 gCoarseNodeOnCoarseGridGID = tmpInds[2] * coarseNodesPerCoarseLayer + tmpInds[1] * gCoarseNodesPerDir[0] + tmpInds[0];
1305 coarseNodesGIDs[lCol] = gCoarseNodeOnCoarseGridGID;
1306 for (
LO dof = 0; dof < BlkSize; ++dof) {
1307 colGIDs[BlkSize * lCol + dof] = BlkSize * gCoarseNodeOnCoarseGridGID + dof;
1314 for (col = lNumCoarseNodes; col < lNumCoarseNodes + lNumGhostNodes; ++col) {
1315 if ((endRate[2] != coarseRate[2]) && (ghostGIDs[ghostPermut[col - lNumCoarseNodes]] > (gCoarseNodesPerDir[2] - 2) * fineNodesPerCoarseSlab + fineNodesEndCoarseSlab - 1)) {
1316 tmpInds[2] = ghostGIDs[ghostPermut[col - lNumCoarseNodes]] / fineNodesPerCoarseSlab + 1;
1317 tmpVars[0] = ghostGIDs[ghostPermut[col - lNumCoarseNodes]] - (tmpInds[2] - 1) * fineNodesPerCoarseSlab - fineNodesEndCoarseSlab;
1319 tmpInds[2] = ghostGIDs[ghostPermut[col - lNumCoarseNodes]] / fineNodesPerCoarseSlab;
1320 tmpVars[0] = ghostGIDs[ghostPermut[col - lNumCoarseNodes]] % fineNodesPerCoarseSlab;
1322 if ((endRate[1] != coarseRate[1]) && (tmpVars[0] > (gCoarseNodesPerDir[1] - 2) * fineNodesPerCoarsePlane + fineNodesEndCoarsePlane - 1)) {
1323 tmpInds[1] = tmpVars[0] / fineNodesPerCoarsePlane + 1;
1324 tmpVars[1] = tmpVars[0] - (tmpInds[1] - 1) * fineNodesPerCoarsePlane - fineNodesEndCoarsePlane;
1326 tmpInds[1] = tmpVars[0] / fineNodesPerCoarsePlane;
1327 tmpVars[1] = tmpVars[0] % fineNodesPerCoarsePlane;
1329 if (tmpVars[1] == gFineNodesPerDir[0] - 1) {
1330 tmpInds[0] = gCoarseNodesPerDir[0] - 1;
1332 tmpInds[0] = tmpVars[1] / coarseRate[0];
1334 gCoarseNodeOnCoarseGridGID = tmpInds[2] * coarseNodesPerCoarseLayer + tmpInds[1] * gCoarseNodesPerDir[0] + tmpInds[0];
1335 for (
LO dof = 0; dof < BlkSize; ++dof) {
1336 colGIDs[BlkSize * col + dof] = BlkSize * gCoarseNodeOnCoarseGridGID + dof;
1343 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1351 const std::string stencilType,
const std::string ,
1352 const Array<LO> elementNodesPerDir,
const LO numNodesInElement,
1366 LO countInterior = 0, countFace = 0, countEdge = 0, countCorner = 0;
1367 Array<LO> collapseDir(numNodesInElement * BlkSize);
1368 for (
LO ke = 0; ke < elementNodesPerDir[2]; ++ke) {
1369 for (
LO je = 0; je < elementNodesPerDir[1]; ++je) {
1370 for (
LO ie = 0; ie < elementNodesPerDir[0]; ++ie) {
1372 if ((ke == 0 || ke == elementNodesPerDir[2] - 1) && (je == 0 || je == elementNodesPerDir[1] - 1) && (ie == 0 || ie == elementNodesPerDir[0] - 1)) {
1373 for (
LO dof = 0; dof < BlkSize; ++dof) {
1374 dofType[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = 0;
1375 lDofInd[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = BlkSize * countCorner + dof;
1380 }
else if (((ke == 0 || ke == elementNodesPerDir[2] - 1) && (je == 0 || je == elementNodesPerDir[1] - 1)) || ((ke == 0 || ke == elementNodesPerDir[2] - 1) && (ie == 0 || ie == elementNodesPerDir[0] - 1)) || ((je == 0 || je == elementNodesPerDir[1] - 1) && (ie == 0 || ie == elementNodesPerDir[0] - 1))) {
1381 for (
LO dof = 0; dof < BlkSize; ++dof) {
1382 dofType[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = 1;
1383 lDofInd[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = BlkSize * countEdge + dof;
1384 if ((ke == 0 || ke == elementNodesPerDir[2] - 1) && (je == 0 || je == elementNodesPerDir[1] - 1)) {
1385 collapseDir[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = 0;
1386 }
else if ((ke == 0 || ke == elementNodesPerDir[2] - 1) && (ie == 0 || ie == elementNodesPerDir[0] - 1)) {
1387 collapseDir[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = 1;
1388 }
else if ((je == 0 || je == elementNodesPerDir[1] - 1) && (ie == 0 || ie == elementNodesPerDir[0] - 1)) {
1389 collapseDir[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = 2;
1395 }
else if ((ke == 0 || ke == elementNodesPerDir[2] - 1) || (je == 0 || je == elementNodesPerDir[1] - 1) || (ie == 0 || ie == elementNodesPerDir[0] - 1)) {
1396 for (
LO dof = 0; dof < BlkSize; ++dof) {
1397 dofType[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = 2;
1398 lDofInd[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = BlkSize * countFace + dof;
1399 if (ke == 0 || ke == elementNodesPerDir[2] - 1) {
1400 collapseDir[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = 2;
1401 }
else if (je == 0 || je == elementNodesPerDir[1] - 1) {
1402 collapseDir[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = 1;
1403 }
else if (ie == 0 || ie == elementNodesPerDir[0] - 1) {
1404 collapseDir[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = 0;
1411 for (
LO dof = 0; dof < BlkSize; ++dof) {
1412 dofType[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = 3;
1413 lDofInd[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = BlkSize * countInterior + dof;
1421 LO numInteriorNodes = 0, numFaceNodes = 0, numEdgeNodes = 0, numCornerNodes = 8;
1422 numInteriorNodes = (elementNodesPerDir[0] - 2) * (elementNodesPerDir[1] - 2) * (elementNodesPerDir[2] - 2);
1423 numFaceNodes = 2 * (elementNodesPerDir[0] - 2) * (elementNodesPerDir[1] - 2) + 2 * (elementNodesPerDir[0] - 2) * (elementNodesPerDir[2] - 2) + 2 * (elementNodesPerDir[1] - 2) * (elementNodesPerDir[2] - 2);
1424 numEdgeNodes = 4 * (elementNodesPerDir[0] - 2) + 4 * (elementNodesPerDir[1] - 2) + 4 * (elementNodesPerDir[2] - 2);
1437 Pi.
shape(BlkSize * numInteriorNodes, BlkSize * numCornerNodes);
1438 Pf.
shape(BlkSize * numFaceNodes, BlkSize * numCornerNodes);
1439 Pe.
shape(BlkSize * numEdgeNodes, BlkSize * numCornerNodes);
1443 LO idof, iInd, jInd;
1444 int iType = 0, jType = 0;
1445 int orientation = -1;
1446 int collapseFlags[3] = {};
1447 Array<SC> stencil((std::pow(3, numDimensions)) * BlkSize);
1451 for (
LO ke = 0; ke < elementNodesPerDir[2]; ++ke) {
1452 for (
LO je = 0; je < elementNodesPerDir[1]; ++je) {
1453 for (
LO ie = 0; ie < elementNodesPerDir[0]; ++ie) {
1454 collapseFlags[0] = 0;
1455 collapseFlags[1] = 0;
1456 collapseFlags[2] = 0;
1457 if ((elementFlags[0] == 1 || elementFlags[0] == 3) && ie == 0) {
1458 collapseFlags[0] += 1;
1460 if ((elementFlags[0] == 2 || elementFlags[0] == 3) && ie == elementNodesPerDir[0] - 1) {
1461 collapseFlags[0] += 2;
1463 if ((elementFlags[1] == 1 || elementFlags[1] == 3) && je == 0) {
1464 collapseFlags[1] += 1;
1466 if ((elementFlags[1] == 2 || elementFlags[1] == 3) && je == elementNodesPerDir[1] - 1) {
1467 collapseFlags[1] += 2;
1469 if ((elementFlags[2] == 1 || elementFlags[2] == 3) && ke == 0) {
1470 collapseFlags[2] += 1;
1472 if ((elementFlags[2] == 2 || elementFlags[2] == 3) && ke == elementNodesPerDir[2] - 1) {
1473 collapseFlags[2] += 2;
1477 GetNodeInfo(ie, je, ke, elementNodesPerDir, &iType, iInd, &orientation);
1478 for (
LO dof0 = 0; dof0 < BlkSize; ++dof0) {
1480 idof = ((elemInds[2] * coarseRate[2] + ke) * lFineNodesPerDir[1] * lFineNodesPerDir[0] + (elemInds[1] * coarseRate[1] + je) * lFineNodesPerDir[0] + elemInds[0] * coarseRate[0] + ie) * BlkSize + dof0;
1481 Aghost->getLocalRowView(idof, rowIndices, rowValues);
1482 FormatStencil(BlkSize, ghostInterface, ie, je, ke, rowValues,
1483 elementNodesPerDir, collapseFlags, stencilType, stencil);
1486 for (
LO interactingNode = 0; interactingNode < 27; ++interactingNode) {
1488 ko = ke + (interactingNode / 9 - 1);
1490 LO tmp = interactingNode % 9;
1491 jo = je + (tmp / 3 - 1);
1492 io = ie + (tmp % 3 - 1);
1494 GetNodeInfo(io, jo, ko, elementNodesPerDir, &jType, jInd, &dummy);
1496 if ((io > -1 && io < elementNodesPerDir[0]) &&
1497 (jo > -1 && jo < elementNodesPerDir[1]) &&
1498 (ko > -1 && ko < elementNodesPerDir[2])) {
1499 for (
LO dof1 = 0; dof1 < BlkSize; ++dof1) {
1501 Aii(iInd * BlkSize + dof0, jInd * BlkSize + dof1) =
1502 stencil[interactingNode * BlkSize + dof1];
1503 }
else if (jType == 2) {
1504 Aif(iInd * BlkSize + dof0, jInd * BlkSize + dof1) =
1505 stencil[interactingNode * BlkSize + dof1];
1506 }
else if (jType == 1) {
1507 Aie(iInd * BlkSize + dof0, jInd * BlkSize + dof1) =
1508 stencil[interactingNode * BlkSize + dof1];
1509 }
else if (jType == 0) {
1510 Aic(iInd * BlkSize + dof0, jInd * BlkSize + dof1) =
1511 -stencil[interactingNode * BlkSize + dof1];
1516 }
else if (iType == 2) {
1517 CollapseStencil(2, orientation, collapseFlags, stencil);
1518 for (
LO interactingNode = 0; interactingNode < 27; ++interactingNode) {
1520 ko = ke + (interactingNode / 9 - 1);
1522 LO tmp = interactingNode % 9;
1523 jo = je + (tmp / 3 - 1);
1524 io = ie + (tmp % 3 - 1);
1526 GetNodeInfo(io, jo, ko, elementNodesPerDir, &jType, jInd, &dummy);
1528 if ((io > -1 && io < elementNodesPerDir[0]) &&
1529 (jo > -1 && jo < elementNodesPerDir[1]) &&
1530 (ko > -1 && ko < elementNodesPerDir[2])) {
1531 for (
LO dof1 = 0; dof1 < BlkSize; ++dof1) {
1533 Aff(iInd * BlkSize + dof0, jInd * BlkSize + dof1) =
1534 stencil[interactingNode * BlkSize + dof1];
1535 }
else if (jType == 1) {
1536 Afe(iInd * BlkSize + dof0, jInd * BlkSize + dof1) =
1537 stencil[interactingNode * BlkSize + dof1];
1538 }
else if (jType == 0) {
1539 Afc(iInd * BlkSize + dof0, jInd * BlkSize + dof1) =
1540 -stencil[interactingNode * BlkSize + dof1];
1545 }
else if (iType == 1) {
1546 CollapseStencil(1, orientation, collapseFlags, stencil);
1547 for (
LO interactingNode = 0; interactingNode < 27; ++interactingNode) {
1549 ko = ke + (interactingNode / 9 - 1);
1551 LO tmp = interactingNode % 9;
1552 jo = je + (tmp / 3 - 1);
1553 io = ie + (tmp % 3 - 1);
1555 GetNodeInfo(io, jo, ko, elementNodesPerDir, &jType, jInd, &dummy);
1557 if ((io > -1 && io < elementNodesPerDir[0]) &&
1558 (jo > -1 && jo < elementNodesPerDir[1]) &&
1559 (ko > -1 && ko < elementNodesPerDir[2])) {
1560 for (
LO dof1 = 0; dof1 < BlkSize; ++dof1) {
1562 Aee(iInd * BlkSize + dof0, jInd * BlkSize + dof1) =
1563 stencil[interactingNode * BlkSize + dof1];
1564 }
else if (jType == 0) {
1565 Aec(iInd * BlkSize + dof0, jInd * BlkSize + dof1) =
1566 -stencil[interactingNode * BlkSize + dof1];
1625 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1631 if (orientation == 0) {
1632 for (
LO i = 0; i < 9; ++i) {
1633 stencil[3 * i + 1] = stencil[3 * i] + stencil[3 * i + 1] + stencil[3 * i + 2];
1635 stencil[3 * i + 2] = 0;
1637 }
else if (orientation == 1) {
1638 for (
LO i = 0; i < 3; ++i) {
1639 stencil[9 * i + 3] = stencil[9 * i + 0] + stencil[9 * i + 3] + stencil[9 * i + 6];
1640 stencil[9 * i + 0] = 0;
1641 stencil[9 * i + 6] = 0;
1642 stencil[9 * i + 4] = stencil[9 * i + 1] + stencil[9 * i + 4] + stencil[9 * i + 7];
1643 stencil[9 * i + 1] = 0;
1644 stencil[9 * i + 7] = 0;
1645 stencil[9 * i + 5] = stencil[9 * i + 2] + stencil[9 * i + 5] + stencil[9 * i + 8];
1646 stencil[9 * i + 2] = 0;
1647 stencil[9 * i + 8] = 0;
1649 }
else if (orientation == 2) {
1650 for (
LO i = 0; i < 9; ++i) {
1651 stencil[i + 9] = stencil[i] + stencil[i + 9] + stencil[i + 18];
1653 stencil[i + 18] = 0;
1656 }
else if (type == 1) {
1657 SC tmp1 = 0, tmp2 = 0, tmp3 = 0;
1658 if (orientation == 0) {
1659 for (
LO i = 0; i < 9; ++i) {
1660 tmp1 += stencil[0 + 3 * i];
1661 stencil[0 + 3 * i] = 0;
1662 tmp2 += stencil[1 + 3 * i];
1663 stencil[1 + 3 * i] = 0;
1664 tmp3 += stencil[2 + 3 * i];
1665 stencil[2 + 3 * i] = 0;
1670 }
else if (orientation == 1) {
1671 for (
LO i = 0; i < 3; ++i) {
1672 tmp1 += stencil[0 + i] + stencil[9 + i] + stencil[18 + i];
1675 stencil[18 + i] = 0;
1676 tmp2 += stencil[3 + i] + stencil[12 + i] + stencil[21 + i];
1678 stencil[12 + i] = 0;
1679 stencil[21 + i] = 0;
1680 tmp3 += stencil[6 + i] + stencil[15 + i] + stencil[24 + i];
1682 stencil[15 + i] = 0;
1683 stencil[24 + i] = 0;
1688 }
else if (orientation == 2) {
1689 for (
LO i = 0; i < 9; ++i) {
1692 tmp2 += stencil[i + 9];
1694 tmp3 += stencil[i + 18];
1695 stencil[i + 18] = 0;
1704 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1708 const int collapseFlags[3],
const std::string stencilType,
Array<SC>& stencil)
1710 if (stencilType ==
"reduced") {
1712 fullStencilInds[0] = 4;
1713 fullStencilInds[1] = 10;
1714 fullStencilInds[2] = 12;
1715 fullStencilInds[3] = 13;
1716 fullStencilInds[4] = 14;
1717 fullStencilInds[5] = 16;
1718 fullStencilInds[6] = 22;
1722 int stencilSize = rowValues.
size();
1723 if (collapseFlags[0] + collapseFlags[1] + collapseFlags[2] > 0) {
1724 if (stencilSize == 1) {
1737 if (collapseFlags[2] == 1 || collapseFlags[2] == 3) {
1740 if (collapseFlags[2] == 2 || collapseFlags[2] == 3) {
1743 if (collapseFlags[1] == 1 || collapseFlags[1] == 3) {
1746 if (collapseFlags[1] == 2 || collapseFlags[1] == 3) {
1749 if (collapseFlags[0] == 1 || collapseFlags[0] == 3) {
1752 if (collapseFlags[0] == 2 || collapseFlags[0] == 3) {
1759 for (
int ind = 0; ind < 7; ++ind) {
1760 if (mask[ind] == 1) {
1761 for (
int dof = 0; dof < BlkSize; ++dof) {
1762 stencil[BlkSize * fullStencilInds[ind] + dof] = 0.0;
1766 for (
int dof = 0; dof < BlkSize; ++dof) {
1767 stencil[BlkSize * fullStencilInds[ind] + dof] = rowValues[BlkSize * (ind - offset) + dof];
1771 }
else if (stencilType ==
"full") {
1774 if (collapseFlags[2] == 1 || collapseFlags[2] == 3) {
1775 for (
int ind = 0; ind < 9; ++ind) {
1779 if (collapseFlags[2] == 2 || collapseFlags[2] == 3) {
1780 for (
int ind = 0; ind < 9; ++ind) {
1784 if (collapseFlags[1] == 1 || collapseFlags[1] == 3) {
1785 for (
int ind1 = 0; ind1 < 3; ++ind1) {
1786 for (
int ind2 = 0; ind2 < 3; ++ind2) {
1787 mask[ind1 * 9 + ind2] = 1;
1791 if (collapseFlags[1] == 2 || collapseFlags[1] == 3) {
1792 for (
int ind1 = 0; ind1 < 3; ++ind1) {
1793 for (
int ind2 = 0; ind2 < 3; ++ind2) {
1794 mask[ind1 * 9 + ind2 + 6] = 1;
1798 if (collapseFlags[0] == 1 || collapseFlags[0] == 3) {
1799 for (
int ind = 0; ind < 9; ++ind) {
1803 if (collapseFlags[0] == 2 || collapseFlags[0] == 3) {
1804 for (
int ind = 0; ind < 9; ++ind) {
1805 mask[3 * ind + 2] = 1;
1811 for (
LO ind = 0; ind < 27; ++ind) {
1812 if (mask[ind] == 0) {
1813 for (
int dof = 0; dof < BlkSize; ++dof) {
1814 stencil[BlkSize * ind + dof] = 0.0;
1818 for (
int dof = 0; dof < BlkSize; ++dof) {
1819 stencil[BlkSize * ind + dof] = rowValues[BlkSize * (ind - offset) + dof];
1826 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1828 const LO ie,
const LO je,
const LO ke,
1830 int* type,
LO& ind,
int* orientation)
const {
1832 *type = -1, ind = 0, *orientation = -1;
1833 if ((ke == 0 || ke == elementNodesPerDir[2] - 1) && (je == 0 || je == elementNodesPerDir[1] - 1) && (ie == 0 || ie == elementNodesPerDir[0] - 1)) {
1836 ind = 4 * ke / (elementNodesPerDir[2] - 1) + 2 * je / (elementNodesPerDir[1] - 1) + ie / (elementNodesPerDir[0] - 1);
1837 }
else if (((ke == 0 || ke == elementNodesPerDir[2] - 1) && (je == 0 || je == elementNodesPerDir[1] - 1)) || ((ke == 0 || ke == elementNodesPerDir[2] - 1) && (ie == 0 || ie == elementNodesPerDir[0] - 1)) || ((je == 0 || je == elementNodesPerDir[1] - 1) && (ie == 0 || ie == elementNodesPerDir[0] - 1))) {
1841 ind += 2 * (elementNodesPerDir[0] - 2 + elementNodesPerDir[1] - 2);
1843 if (ke == elementNodesPerDir[2] - 1) {
1844 ind += 4 * (elementNodesPerDir[2] - 2);
1846 if ((ke == 0) || (ke == elementNodesPerDir[2] - 1)) {
1850 }
else if (je == elementNodesPerDir[1] - 1) {
1852 ind += 2 * (elementNodesPerDir[1] - 2) + elementNodesPerDir[0] - 2 + ie - 1;
1855 ind += elementNodesPerDir[0] - 2 + 2 * (je - 1) + ie / (elementNodesPerDir[0] - 1);
1859 ind += 4 * (ke - 1) + 2 * (je / (elementNodesPerDir[1] - 1)) + ie / (elementNodesPerDir[0] - 1);
1861 }
else if ((ke == 0 || ke == elementNodesPerDir[2] - 1) || (je == 0 || je == elementNodesPerDir[1] - 1) || (ie == 0 || ie == elementNodesPerDir[0] - 1)) {
1866 ind = (je - 1) * (elementNodesPerDir[0] - 2) + ie - 1;
1869 ind += (elementNodesPerDir[1] - 2) * (elementNodesPerDir[0] - 2);
1871 ind += 2 * (ke - 1) * (elementNodesPerDir[1] - 2 + elementNodesPerDir[0] - 2);
1872 if (ke == elementNodesPerDir[2] - 1) {
1874 ind += (je - 1) * (elementNodesPerDir[0] - 2) + ie - 1;
1879 }
else if (je == elementNodesPerDir[1] - 1) {
1881 ind += 2 * (elementNodesPerDir[1] - 2) + elementNodesPerDir[0] - 2 + ie - 1;
1884 ind += elementNodesPerDir[0] - 2 + 2 * (je - 1) + ie / (elementNodesPerDir[0] - 1);
1891 ind = (ke - 1) * (elementNodesPerDir[1] - 2) * (elementNodesPerDir[0] - 2) + (je - 1) * (elementNodesPerDir[0] - 2) + ie - 1;
1895 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1901 typedef typename std::iterator_traits<typename Teuchos::Array<LocalOrdinal>::iterator>::difference_type DT;
1902 DT n = last1 - first1;
1907 for (DT j = 0; j < max; j++) {
1908 for (DT k = j; k >= 0; k -= m) {
1909 if (first1[first2[k + m]] >= first1[first2[k]])
1911 std::swap(first2[k + m], first2[k]);
1920 #define MUELU_BLACKBOXPFACTORY_SHORT
1921 #endif // MUELU_BLACKBOXPFACTORY_DEF_HPP
void GetGeometricData(RCP< Xpetra::MultiVector< typename Teuchos::ScalarTraits< Scalar >::magnitudeType, LO, GO, NO > > &coordinates, const Array< LO > coarseRate, const Array< GO > gFineNodesPerDir, const Array< LO > lFineNodesPerDir, const LO BlkSize, Array< GO > &gIndices, Array< LO > &myOffset, Array< bool > &ghostInterface, Array< LO > &endRate, Array< GO > &gCoarseNodesPerDir, Array< LO > &lCoarseNodesPerDir, Array< LO > &glCoarseNodesPerDir, Array< GO > &ghostGIDs, Array< GO > &coarseNodesGIDs, Array< GO > &colGIDs, GO &gNumCoarseNodes, LO &lNumCoarseNodes, ArrayRCP< Array< typename Teuchos::ScalarTraits< Scalar >::magnitudeType > > coarseNodes, Array< int > &boundaryFlags, RCP< NodesIDs > ghostedCoarseNodes) const
T & get(const std::string &name, T def_value)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
ArrayView< T > view(size_type offset, size_type size)
int multiply(ETransp transa, ETransp transb, ScalarType alpha, const SerialDenseMatrix< OrdinalType, ScalarType > &A, const SerialDenseMatrix< OrdinalType, ScalarType > &B, ScalarType beta)
Timer to be used in factories. Similar to Monitor but with additional timers.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void GetNodeInfo(const LO ie, const LO je, const LO ke, const Array< LO > elementNodesPerDir, int *type, LO &ind, int *orientation) const
void ComputeLocalEntries(const RCP< const Matrix > &Aghost, const Array< LO > coarseRate, const Array< LO > endRate, const LO BlkSize, const Array< LO > elemInds, const Array< LO > lCoarseElementsPerDir, const LO numDimensions, const Array< LO > lFineNodesPerDir, const Array< GO > gFineNodesPerDir, const Array< GO > gIndices, const Array< LO > lCoarseNodesPerDir, const Array< bool > ghostInterface, const Array< int > elementFlags, const std::string stencilType, const std::string blockStrategy, const Array< LO > elementNodesPerDir, const LO numNodesInElement, const Array< GO > colGIDs, Teuchos::SerialDenseMatrix< LO, SC > &Pi, Teuchos::SerialDenseMatrix< LO, SC > &Pf, Teuchos::SerialDenseMatrix< LO, SC > &Pe, Array< LO > &dofType, Array< LO > &lDofInd) const
One-liner description of what is happening.
static const NoFactory * get()
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Class that holds all level-specific information.
void DeclareInput(Level &fineLevel, Level &coarseLevel) const
Input.
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)
void factorWithEquilibration(bool flag)
void FormatStencil(const LO BlkSize, const Array< bool > ghostInterface, const LO ie, const LO je, const LO ke, const ArrayView< const SC > rowValues, const Array< LO > elementNodesPerDir, const int collapseFlags[3], const std::string stencilType, Array< SC > &stencil) const
void resize(size_type new_size, const value_type &x=value_type())
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
void CollapseStencil(const int type, const int orientation, const int collapseFlags[3], Array< SC > &stencil) const
static void sortCrsEntries(const Teuchos::ArrayView< size_t > &CRS_rowptr, const Teuchos::ArrayView< LocalOrdinal > &CRS_colind, const Teuchos::ArrayView< Scalar > &CRS_vals, const UnderlyingLib lib)
int setVectors(const RCP< SerialDenseMatrix< OrdinalType, ScalarType > > &X, const RCP< SerialDenseMatrix< OrdinalType, ScalarType > > &B)
void BuildP(Level &fineLevel, Level &coarseLevel) const
Abstract Build method.
static RCP< Xpetra::StridedMap< LocalOrdinal, GlobalOrdinal, Node > > 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)
int GetLevelID() const
Return level number.
static RCP< Matrix > Build(const RCP< const Map > &rowMap, size_t maxNumEntriesPerRow, Xpetra::ProfileType pftype=Xpetra::DynamicProfile)
Exception throws to report errors in the internal logical of the program.
int shape(OrdinalType numRows, OrdinalType numCols)
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()
static RCP< Import< LocalOrdinal, GlobalOrdinal, Node > > Build(const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &source, const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &target, const Teuchos::RCP< Teuchos::ParameterList > &plist=Teuchos::null)
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)
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