10 #ifndef MUELU_BLACKBOXPFACTORY_DEF_HPP
11 #define MUELU_BLACKBOXPFACTORY_DEF_HPP
22 #include <Xpetra_CrsMatrixWrap.hpp>
25 #include <Xpetra_MapFactory.hpp>
26 #include <Xpetra_MultiVectorFactory.hpp>
37 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
46 validParamList->
set<std::string>(
"Coarsen",
"{3}",
"Coarsening rate in all spatial dimensions");
50 validParamList->
set<
RCP<const FactoryBase> >(
"gNodesPerDim", Teuchos::null,
"Number of nodes per spatial dimmension provided by CoordinatesTransferFactory.");
51 validParamList->
set<
RCP<const FactoryBase> >(
"lNodesPerDim", Teuchos::null,
"Number of nodes per spatial dimmension provided by CoordinatesTransferFactory.");
52 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.");
53 validParamList->
set<std::string>(
"block strategy",
"coupled",
"The strategy used to handle systems of PDEs can be: coupled or uncoupled.");
55 return validParamList;
58 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
62 Input(fineLevel,
"A");
63 Input(fineLevel,
"Nullspace");
64 Input(fineLevel,
"Coordinates");
72 "gNodesPerDim was not provided by the user on level0!");
75 Input(fineLevel,
"gNodesPerDim");
85 "lNodesPerDim was not provided by the user on level0!");
88 Input(fineLevel,
"lNodesPerDim");
92 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
94 Level& coarseLevel)
const {
95 return BuildP(fineLevel, coarseLevel);
98 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
100 Level& coarseLevel)
const {
108 RCP<MultiVector> fineNullspace = Get<RCP<MultiVector> >(fineLevel,
"Nullspace");
110 Get<RCP<Xpetra::MultiVector<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO,
NO> > >(fineLevel,
"Coordinates");
111 LO numDimensions = coordinates->getNumVectors();
112 LO BlkSize = A->GetFixedBlockSize();
118 if (fineLevel.GetLevelID() == 0) {
123 gFineNodesPerDir = Get<Array<GO> >(fineLevel,
"gNodesPerDim");
126 lFineNodesPerDir = Get<Array<LO> >(fineLevel,
"lNodesPerDim");
128 for (LO i = 0; i < 3; ++i) {
129 if (gFineNodesPerDir[i] == 0) {
130 GetOStream(
Runtime0) <<
"gNodesPerDim in direction " << i <<
" is set to 1 from 0"
132 gFineNodesPerDir[i] = 1;
134 if (lFineNodesPerDir[i] == 0) {
135 GetOStream(
Runtime0) <<
"lNodesPerDim in direction " << i <<
" is set to 1 from 0"
137 lFineNodesPerDir[i] = 1;
140 GO gNumFineNodes = gFineNodesPerDir[2] * gFineNodesPerDir[1] * gFineNodesPerDir[0];
141 LO lNumFineNodes = lFineNodesPerDir[2] * lFineNodesPerDir[1] * lFineNodesPerDir[0];
144 std::string coarsenRate = pL.
get<std::string>(
"Coarsen");
149 crates = Teuchos::fromStringToArray<LO>(coarsenRate);
151 GetOStream(
Errors, -1) <<
" *** Coarsen must be a string convertible into an array! *** "
157 "Coarsen must have at least as many components as the number of"
158 " spatial dimensions in the problem.");
159 for (LO i = 0; i < 3; ++i) {
160 if (i < numDimensions) {
161 if (crates.
size() == 1) {
162 coarseRate[i] = crates[0];
163 }
else if (i < crates.
size()) {
164 coarseRate[i] = crates[i];
166 GetOStream(
Errors, -1) <<
" *** Coarsen must be at least as long as the number of"
167 " spatial dimensions! *** "
170 " *** Coarsen must be at least as long as the number of"
171 " spatial dimensions! *** \n");
180 const std::string stencilType = pL.
get<std::string>(
"stencil type");
181 if (stencilType !=
"full" && stencilType !=
"reduced") {
182 GetOStream(
Errors, -1) <<
" *** stencil type must be set to: full or reduced, any other value "
183 "is trated as an error! *** "
189 const std::string blockStrategy = pL.
get<std::string>(
"block strategy");
190 if (blockStrategy !=
"coupled" && blockStrategy !=
"uncoupled") {
191 GetOStream(
Errors, -1) <<
" *** block strategy must be set to: coupled or uncoupled, any other "
192 "value is trated as an error! *** "
197 GO gNumCoarseNodes = 0;
198 LO lNumCoarseNodes = 0;
199 Array<GO> gIndices(3), gCoarseNodesPerDir(3), ghostGIDs, coarseNodesGIDs, colGIDs;
200 Array<LO> myOffset(3), lCoarseNodesPerDir(3), glCoarseNodesPerDir(3), endRate(3);
205 for (LO dim = 0; dim < numDimensions; ++dim) {
206 fineNodes[dim] = coordinates->getData(dim)();
212 GetGeometricData(coordinates, coarseRate, gFineNodesPerDir, lFineNodesPerDir, BlkSize,
213 gIndices, myOffset, ghostInterface, endRate, gCoarseNodesPerDir,
214 lCoarseNodesPerDir, glCoarseNodesPerDir, ghostGIDs, coarseNodesGIDs, colGIDs,
215 gNumCoarseNodes, lNumCoarseNodes, coarseNodes, boundaryFlags,
222 coarseNodesGIDs.
view(0, lNumCoarseNodes),
223 coordinates->getMap()->getIndexBase(),
224 coordinates->getMap()->getComm());
226 for (LO dim = 0; dim < numDimensions; ++dim) {
227 coarseCoords[dim] = coarseNodes[dim]();
229 RCP<Xpetra::MultiVector<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO,
NO> > coarseCoordinates =
263 Array<GO> ghostRowGIDs, ghostColGIDs, nodeSteps(3);
265 nodeSteps[1] = gFineNodesPerDir[0];
266 nodeSteps[2] = gFineNodesPerDir[0] * gFineNodesPerDir[1];
268 GO startingGID = A->getRowMap()->getMinGlobalIndex();
269 for (LO dim = 0; dim < 3; ++dim) {
270 LO numCoarseNodes = 0;
271 if (dim < numDimensions) {
272 startingGID -= myOffset[dim] * nodeSteps[dim];
273 numCoarseNodes = lCoarseNodesPerDir[dim];
274 if (ghostInterface[2 * dim]) {
277 if (ghostInterface[2 * dim + 1]) {
280 if (gIndices[dim] + lFineNodesPerDir[dim] == gFineNodesPerDir[dim]) {
281 glFineNodesPerDir[dim] = (numCoarseNodes - 2) * coarseRate[dim] + endRate[dim] + 1;
283 glFineNodesPerDir[dim] = (numCoarseNodes - 1) * coarseRate[dim] + 1;
286 glFineNodesPerDir[dim] = 1;
289 ghostRowGIDs.
resize(glFineNodesPerDir[0] * glFineNodesPerDir[1] * glFineNodesPerDir[2] * BlkSize);
290 for (LO k = 0; k < glFineNodesPerDir[2]; ++k) {
291 for (LO j = 0; j < glFineNodesPerDir[1]; ++j) {
292 for (LO i = 0; i < glFineNodesPerDir[0]; ++i) {
293 for (LO l = 0; l < BlkSize; ++l) {
294 ghostRowGIDs[(k * glFineNodesPerDir[1] * glFineNodesPerDir[0] + j * glFineNodesPerDir[0] + i) * BlkSize + l] = startingGID + (k * gFineNodesPerDir[1] * gFineNodesPerDir[0] + j * gFineNodesPerDir[0] + i) * BlkSize + l;
301 Array<GO> startingGlobalIndices(numDimensions), dimStride(numDimensions);
302 Array<GO> startingColIndices(numDimensions), finishingColIndices(numDimensions);
306 for (
int dim = 1; dim < numDimensions; ++dim) {
307 dimStride[dim] = dimStride[dim - 1] * gFineNodesPerDir[dim - 1];
310 GO tmp = startingGID;
311 for (
int dim = numDimensions; dim > 0; --dim) {
312 startingGlobalIndices[dim - 1] = tmp / dimStride[dim - 1];
313 tmp = tmp % dimStride[dim - 1];
315 if (startingGlobalIndices[dim - 1] > 0) {
316 startingColIndices[dim - 1] = startingGlobalIndices[dim - 1] - 1;
318 if (startingGlobalIndices[dim - 1] + glFineNodesPerDir[dim - 1] < gFineNodesPerDir[dim - 1]) {
319 finishingColIndices[dim - 1] = startingGlobalIndices[dim - 1] + glFineNodesPerDir[dim - 1];
321 finishingColIndices[dim - 1] = startingGlobalIndices[dim - 1] + glFineNodesPerDir[dim - 1] - 1;
323 colRange[dim - 1] = finishingColIndices[dim - 1] - startingColIndices[dim - 1] + 1;
324 colMinGID += startingColIndices[dim - 1] * dimStride[dim - 1];
327 ghostColGIDs.
resize(colRange[0] * colRange[1] * colRange[2] * BlkSize);
328 for (LO k = 0; k < colRange[2]; ++k) {
329 for (LO j = 0; j < colRange[1]; ++j) {
330 for (LO i = 0; i < colRange[0]; ++i) {
331 for (LO l = 0; l < BlkSize; ++l) {
332 ghostColGIDs[(k * colRange[1] * colRange[0] + j * colRange[0] + i) * BlkSize + l] = colMinGID + (k * gFineNodesPerDir[1] * gFineNodesPerDir[0] + j * gFineNodesPerDir[0] + i) * BlkSize + l;
341 A->getRowMap()->getIndexBase(),
342 A->getRowMap()->getComm());
346 A->getRowMap()->getIndexBase(),
347 A->getRowMap()->getComm());
370 LO lNumGhostedNodes = ghostedCoarseNodes->GIDs.size();
372 std::vector<NodeID> colMapOrdering(lNumGhostedNodes);
373 for (LO ind = 0; ind < lNumGhostedNodes; ++ind) {
374 colMapOrdering[ind].GID = ghostedCoarseNodes->GIDs[ind];
375 if (ghostedCoarseNodes->PIDs[ind] == rowMapP->getComm()->getRank()) {
376 colMapOrdering[ind].PID = -1;
378 colMapOrdering[ind].PID = ghostedCoarseNodes->PIDs[ind];
380 colMapOrdering[ind].LID = ghostedCoarseNodes->LIDs[ind];
381 colMapOrdering[ind].lexiInd = ind;
383 std::sort(colMapOrdering.begin(), colMapOrdering.end(),
385 return ((a.
PID < b.PID) || ((a.
PID == b.PID) && (a.
GID < b.GID)));
388 colGIDs.
resize(BlkSize * lNumGhostedNodes);
389 for (LO ind = 0; ind < lNumGhostedNodes; ++ind) {
391 ghostedCoarseNodes->colInds[colMapOrdering[ind].lexiInd] = ind;
392 for (LO dof = 0; dof < BlkSize; ++dof) {
393 colGIDs[BlkSize * ind + dof] = BlkSize * colMapOrdering[ind].GID + dof;
397 BlkSize * gNumCoarseNodes,
398 colGIDs.
view(0, BlkSize * lNumCoarseNodes),
399 rowMapP->getIndexBase(),
404 rowMapP->getIndexBase(),
408 std::vector<size_t> strideInfo(1);
409 strideInfo[0] = BlkSize;
416 gnnzP += gNumCoarseNodes;
417 lnnzP += lNumCoarseNodes;
419 gnnzP += (gNumFineNodes - gNumCoarseNodes) * std::pow(2, numDimensions);
420 lnnzP += (lNumFineNodes - lNumCoarseNodes) * std::pow(2, numDimensions);
422 gnnzP = gnnzP * BlkSize;
423 lnnzP = lnnzP * BlkSize;
427 P =
rcp(
new CrsMatrixWrap(rowMapP, colMapP, 0));
428 RCP<CrsMatrix> PCrs = rcp_dynamic_cast<CrsMatrixWrap>(P)->getCrsMatrix();
434 PCrs->allocateAllValues(lnnzP, iaP, jaP, valP);
441 LO numCoarseElements = 1;
443 for (LO dim = 0; dim < numDimensions; ++dim) {
444 lCoarseElementsPerDir[dim] = lCoarseNodesPerDir[dim];
445 if (ghostInterface[2 * dim]) {
446 ++lCoarseElementsPerDir[dim];
448 if (!ghostInterface[2 * dim + 1]) {
449 --lCoarseElementsPerDir[dim];
451 numCoarseElements = numCoarseElements * lCoarseElementsPerDir[dim];
454 for (LO dim = numDimensions; dim < 3; ++dim) {
455 lCoarseElementsPerDir[dim] = 1;
460 Array<LO> elemInds(3), elementNodesPerDir(3), glElementRefTuple(3);
461 Array<LO> glElementRefTupleCG(3), glElementCoarseNodeCG(8);
462 const int numCoarseNodesInElement = std::pow(2, numDimensions);
463 const int nnzPerCoarseNode = (blockStrategy ==
"coupled") ? BlkSize : 1;
464 const int numRowsPerPoint = BlkSize;
465 for (elemInds[2] = 0; elemInds[2] < lCoarseElementsPerDir[2]; ++elemInds[2]) {
466 for (elemInds[1] = 0; elemInds[1] < lCoarseElementsPerDir[1]; ++elemInds[1]) {
467 for (elemInds[0] = 0; elemInds[0] < lCoarseElementsPerDir[0]; ++elemInds[0]) {
471 for (
int dim = 0; dim < 3; ++dim) {
473 if (elemInds[dim] == 0 && elemInds[dim] == lCoarseElementsPerDir[dim] - 1) {
474 elementFlags[dim] = boundaryFlags[dim];
475 }
else if (elemInds[dim] == 0 && (boundaryFlags[dim] == 1 || boundaryFlags[dim] == 3)) {
476 elementFlags[dim] += 1;
477 }
else if ((elemInds[dim] == lCoarseElementsPerDir[dim] - 1) && (boundaryFlags[dim] == 2 || boundaryFlags[dim] == 3)) {
478 elementFlags[dim] += 2;
480 elementFlags[dim] = 0;
484 if (dim < numDimensions) {
485 if ((elemInds[dim] == lCoarseElementsPerDir[dim]) && (gIndices[dim] + lFineNodesPerDir[dim] == gFineNodesPerDir[dim])) {
486 elementNodesPerDir[dim] = endRate[dim] + 1;
488 elementNodesPerDir[dim] = coarseRate[dim] + 1;
491 elementNodesPerDir[dim] = 1;
495 glElementRefTuple[dim] = elemInds[dim] * coarseRate[dim];
496 glElementRefTupleCG[dim] = elemInds[dim];
502 glElementCoarseNodeCG[elem] = glElementRefTupleCG[2] * glCoarseNodesPerDir[1] * glCoarseNodesPerDir[0] + glElementRefTupleCG[1] * glCoarseNodesPerDir[0] + glElementRefTupleCG[0];
504 glElementCoarseNodeCG[4] += glCoarseNodesPerDir[1] * glCoarseNodesPerDir[0];
505 glElementCoarseNodeCG[5] += glCoarseNodesPerDir[1] * glCoarseNodesPerDir[0];
506 glElementCoarseNodeCG[6] += glCoarseNodesPerDir[1] * glCoarseNodesPerDir[0];
507 glElementCoarseNodeCG[7] += glCoarseNodesPerDir[1] * glCoarseNodesPerDir[0];
509 glElementCoarseNodeCG[2] += glCoarseNodesPerDir[0];
510 glElementCoarseNodeCG[3] += glCoarseNodesPerDir[0];
511 glElementCoarseNodeCG[6] += glCoarseNodesPerDir[0];
512 glElementCoarseNodeCG[7] += glCoarseNodesPerDir[0];
514 glElementCoarseNodeCG[1] += 1;
515 glElementCoarseNodeCG[3] += 1;
516 glElementCoarseNodeCG[5] += 1;
517 glElementCoarseNodeCG[7] += 1;
519 LO numNodesInElement = elementNodesPerDir[0] * elementNodesPerDir[1] * elementNodesPerDir[2];
525 Array<LO> dofType(numNodesInElement * BlkSize), lDofInd(numNodesInElement * BlkSize);
526 ComputeLocalEntries(Aghost, coarseRate, endRate, BlkSize, elemInds, lCoarseElementsPerDir,
527 numDimensions, glFineNodesPerDir, gFineNodesPerDir, gIndices,
528 lCoarseNodesPerDir, ghostInterface, elementFlags, stencilType,
529 blockStrategy, elementNodesPerDir, numNodesInElement, colGIDs,
530 Pi, Pf, Pe, dofType, lDofInd);
537 for (nodeInd[2] = 0; nodeInd[2] < elementNodesPerDir[2]; ++nodeInd[2]) {
538 for (nodeInd[1] = 0; nodeInd[1] < elementNodesPerDir[1]; ++nodeInd[1]) {
539 for (nodeInd[0] = 0; nodeInd[0] < elementNodesPerDir[0]; ++nodeInd[0]) {
540 int stencilLength = 0;
541 if ((nodeInd[0] == 0 || nodeInd[0] == elementNodesPerDir[0] - 1) &&
542 (nodeInd[1] == 0 || nodeInd[1] == elementNodesPerDir[1] - 1) &&
543 (nodeInd[2] == 0 || nodeInd[2] == elementNodesPerDir[2] - 1)) {
546 stencilLength = std::pow(2, numDimensions);
548 LO nodeElementInd = nodeInd[2] * elementNodesPerDir[1] * elementNodesPerDir[1] + nodeInd[1] * elementNodesPerDir[0] + nodeInd[0];
549 for (
int dim = 0; dim < 3; ++dim) {
550 lNodeTuple[dim] = glElementRefTuple[dim] - myOffset[dim] + nodeInd[dim];
552 if (lNodeTuple[0] < 0 || lNodeTuple[1] < 0 || lNodeTuple[2] < 0 ||
553 lNodeTuple[0] > lFineNodesPerDir[0] - 1 ||
554 lNodeTuple[1] > lFineNodesPerDir[1] - 1 ||
555 lNodeTuple[2] > lFineNodesPerDir[2] - 1) {
558 lNodeLIDs[nodeElementInd] = -1;
559 }
else if ((nodeInd[0] == 0 && elemInds[0] != 0) ||
560 (nodeInd[1] == 0 && elemInds[1] != 0) ||
561 (nodeInd[2] == 0 && elemInds[2] != 0)) {
565 lNodeLIDs[nodeElementInd] = -2;
571 lNodeLIDs[nodeElementInd] = lNodeTuple[2] * lFineNodesPerDir[1] * lFineNodesPerDir[0] + lNodeTuple[1] * lFineNodesPerDir[0] + lNodeTuple[0];
578 for (
int dim = 2; dim > -1; --dim) {
580 refCoarsePointTuple[dim] = (lNodeTuple[dim] + myOffset[dim]) / coarseRate[dim];
581 if (myOffset[dim] == 0) {
582 ++refCoarsePointTuple[dim];
586 refCoarsePointTuple[dim] =
587 std::ceil(static_cast<double>(lNodeTuple[dim] + myOffset[dim]) / coarseRate[dim]);
589 if ((lNodeTuple[dim] + myOffset[dim]) % coarseRate[dim] > 0) {
593 const LO numCoarsePoints = refCoarsePointTuple[0] + refCoarsePointTuple[1] * lCoarseNodesPerDir[0] + refCoarsePointTuple[2] * lCoarseNodesPerDir[1] * lCoarseNodesPerDir[0];
594 const LO numFinePoints = lNodeLIDs[nodeElementInd] + 1;
598 size_t rowPtr = (numFinePoints - numCoarsePoints) * numRowsPerPoint * numCoarseNodesInElement * nnzPerCoarseNode + numCoarsePoints * numRowsPerPoint;
599 if (dofType[nodeElementInd * BlkSize] == 0) {
601 rowPtr = rowPtr - numRowsPerPoint;
603 rowPtr = rowPtr - numRowsPerPoint * numCoarseNodesInElement * nnzPerCoarseNode;
606 for (
int dof = 0; dof < BlkSize; ++dof) {
609 switch (dofType[nodeElementInd * BlkSize + dof]) {
611 if (nodeInd[2] == elementNodesPerDir[2] - 1) {
614 if (nodeInd[1] == elementNodesPerDir[1] - 1) {
617 if (nodeInd[0] == elementNodesPerDir[0] - 1) {
620 ia[lNodeLIDs[nodeElementInd] * BlkSize + dof + 1] = rowPtr + dof + 1;
621 ja[rowPtr + dof] = ghostedCoarseNodes->colInds[glElementCoarseNodeCG[cornerInd]] * BlkSize + dof;
622 val[rowPtr + dof] = 1.0;
626 ia[lNodeLIDs[nodeElementInd] * BlkSize + dof + 1] = rowPtr + (dof + 1) * numCoarseNodesInElement * nnzPerCoarseNode;
627 for (
int ind1 = 0; ind1 < stencilLength; ++ind1) {
628 if (blockStrategy ==
"coupled") {
629 for (
int ind2 = 0; ind2 < BlkSize; ++ind2) {
630 size_t lRowPtr = rowPtr + dof * numCoarseNodesInElement * nnzPerCoarseNode + ind1 * BlkSize + ind2;
631 ja[lRowPtr] = ghostedCoarseNodes->colInds[glElementCoarseNodeCG[ind1]] * BlkSize + ind2;
632 val[lRowPtr] = Pe(lDofInd[nodeElementInd * BlkSize + dof],
633 ind1 * BlkSize + ind2);
635 }
else if (blockStrategy ==
"uncoupled") {
636 size_t lRowPtr = rowPtr + dof * numCoarseNodesInElement * nnzPerCoarseNode + ind1;
637 ja[rowPtr + dof] = ghostedCoarseNodes->colInds[glElementCoarseNodeCG[ind1]] * BlkSize + dof;
638 val[lRowPtr] = Pe(lDofInd[nodeElementInd * BlkSize + dof],
639 ind1 * BlkSize + dof);
645 ia[lNodeLIDs[nodeElementInd] * BlkSize + dof + 1] = rowPtr + (dof + 1) * numCoarseNodesInElement * nnzPerCoarseNode;
646 for (
int ind1 = 0; ind1 < stencilLength; ++ind1) {
647 if (blockStrategy ==
"coupled") {
648 for (
int ind2 = 0; ind2 < BlkSize; ++ind2) {
649 size_t lRowPtr = rowPtr + dof * numCoarseNodesInElement * nnzPerCoarseNode + ind1 * BlkSize + ind2;
650 ja[lRowPtr] = ghostedCoarseNodes->colInds[glElementCoarseNodeCG[ind1]] * BlkSize + ind2;
651 val[lRowPtr] = Pf(lDofInd[nodeElementInd * BlkSize + dof],
652 ind1 * BlkSize + ind2);
654 }
else if (blockStrategy ==
"uncoupled") {
655 size_t lRowPtr = rowPtr + dof * numCoarseNodesInElement * nnzPerCoarseNode + ind1;
657 ja[lRowPtr] = ghostedCoarseNodes->colInds[glElementCoarseNodeCG[ind1]] * BlkSize + dof;
658 val[lRowPtr] = Pf(lDofInd[nodeElementInd * BlkSize + dof],
659 ind1 * BlkSize + dof);
665 ia[lNodeLIDs[nodeElementInd] * BlkSize + dof + 1] = rowPtr + (dof + 1) * numCoarseNodesInElement * nnzPerCoarseNode;
666 for (
int ind1 = 0; ind1 < stencilLength; ++ind1) {
667 if (blockStrategy ==
"coupled") {
668 for (
int ind2 = 0; ind2 < BlkSize; ++ind2) {
669 size_t lRowPtr = rowPtr + dof * numCoarseNodesInElement * nnzPerCoarseNode + ind1 * BlkSize + ind2;
670 ja[lRowPtr] = ghostedCoarseNodes->colInds[glElementCoarseNodeCG[ind1]] * BlkSize + ind2;
671 val[lRowPtr] = Pi(lDofInd[nodeElementInd * BlkSize + dof],
672 ind1 * BlkSize + ind2);
674 }
else if (blockStrategy ==
"uncoupled") {
675 size_t lRowPtr = rowPtr + dof * numCoarseNodesInElement * nnzPerCoarseNode + ind1;
676 ja[lRowPtr] = ghostedCoarseNodes->colInds[glElementCoarseNodeCG[ind1]] * BlkSize + dof;
677 val[lRowPtr] = Pi(lDofInd[nodeElementInd * BlkSize + dof],
678 ind1 * BlkSize + dof);
697 PCrs->setAllValues(iaP, jaP, valP);
698 PCrs->expertStaticFillComplete(domainMapP, rowMapP);
701 if (A->IsView(
"stridedMaps") ==
true) {
702 P->CreateView(
"stridedMaps", A->getRowMap(
"stridedMaps"), stridedDomainMapP);
704 P->CreateView(
"stridedMaps", P->getRangeMap(), stridedDomainMapP);
708 Set(coarseLevel,
"P", P);
709 Set(coarseLevel,
"coarseCoordinates", coarseCoordinates);
710 Set<Array<GO> >(coarseLevel,
"gCoarseNodesPerDim", gCoarseNodesPerDir);
711 Set<Array<LO> >(coarseLevel,
"lCoarseNodesPerDim", lCoarseNodesPerDir);
714 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
722 Array<GO>& colGIDs,
GO& gNumCoarseNodes,
LO& lNumCoarseNodes,
732 LO numDimensions = coordinates->getNumVectors();
743 GO minGlobalIndex = coordinatesMap->getMinGlobalIndex();
746 gIndices[2] = minGlobalIndex / (gFineNodesPerDir[1] * gFineNodesPerDir[0]);
747 tmp = minGlobalIndex % (gFineNodesPerDir[1] * gFineNodesPerDir[0]);
748 gIndices[1] = tmp / gFineNodesPerDir[0];
749 gIndices[0] = tmp % gFineNodesPerDir[0];
751 myOffset[2] = gIndices[2] % coarseRate[2];
752 myOffset[1] = gIndices[1] % coarseRate[1];
753 myOffset[0] = gIndices[0] % coarseRate[0];
756 for (
int dim = 0; dim < 3; ++dim) {
757 if (gIndices[dim] == 0) {
758 boundaryFlags[dim] += 1;
760 if (gIndices[dim] + lFineNodesPerDir[dim] == gFineNodesPerDir[dim]) {
761 boundaryFlags[dim] += 2;
766 for (
LO i = 0; i < numDimensions; ++i) {
767 if ((gIndices[i] != 0) && (gIndices[i] % coarseRate[i] > 0)) {
768 ghostInterface[2 * i] =
true;
770 if (((gIndices[i] + lFineNodesPerDir[i]) != gFineNodesPerDir[i]) && ((gIndices[i] + lFineNodesPerDir[i] - 1) % coarseRate[i] > 0)) {
771 ghostInterface[2 * i + 1] =
true;
775 for (
LO i = 0; i < 3; ++i) {
776 if (i < numDimensions) {
777 lCoarseNodesPerDir[i] = (lFineNodesPerDir[i] + myOffset[i] - 1) / coarseRate[i];
778 if (myOffset[i] == 0) {
779 ++lCoarseNodesPerDir[i];
781 gCoarseNodesPerDir[i] = (gFineNodesPerDir[i] - 1) / coarseRate[i];
782 endRate[i] = (gFineNodesPerDir[i] - 1) % coarseRate[i];
783 if (endRate[i] == 0) {
784 ++gCoarseNodesPerDir[i];
785 endRate[i] = coarseRate[i];
791 gCoarseNodesPerDir[i] = 1;
792 lCoarseNodesPerDir[i] = 1;
797 gNumCoarseNodes = gCoarseNodesPerDir[0] * gCoarseNodesPerDir[1] * gCoarseNodesPerDir[2];
798 lNumCoarseNodes = lCoarseNodesPerDir[0] * lCoarseNodesPerDir[1] * lCoarseNodesPerDir[2];
801 LO lNumGhostNodes = 0;
804 const int complementaryIndices[3][2] = {{1, 2}, {0, 2}, {0, 1}};
806 for (
LO i = 0; i < 3; ++i) {
810 if ((gIndices[i] == gFineNodesPerDir[i] - 1) && (gIndices[i] % coarseRate[i] == 0)) {
811 startGhostedCoarseNode[i] = gIndices[i] / coarseRate[i] - 1;
813 startGhostedCoarseNode[i] = gIndices[i] / coarseRate[i];
816 glCoarseNodesPerDir[i] = lCoarseNodesPerDir[i];
819 if (ghostInterface[2 * i] || ghostInterface[2 * i + 1]) {
820 ++glCoarseNodesPerDir[i];
822 tmp = lCoarseNodesPerDir[1] * lCoarseNodesPerDir[2];
825 tmp = lCoarseNodesPerDir[0] * lCoarseNodesPerDir[2];
828 tmp = lCoarseNodesPerDir[0] * lCoarseNodesPerDir[1];
832 if (ghostInterface[2 * i] && ghostInterface[2 * i + 1]) {
833 ++glCoarseNodesPerDir[i];
836 lNumGhostNodes += tmp;
839 for (
LO j = 0; j < 2; ++j) {
840 for (
LO k = 0; k < 2; ++k) {
842 if (ghostInterface[2 * complementaryIndices[i][0] + j] && ghostInterface[2 * complementaryIndices[i][1] + k]) {
843 lNumGhostNodes += lCoarseNodesPerDir[i];
846 if (ghostInterface[2 * i] && (i == 0)) {
849 if (ghostInterface[2 * i + 1] && (i == 0)) {
859 const LO lNumGhostedNodes = glCoarseNodesPerDir[0] * glCoarseNodesPerDir[1] * glCoarseNodesPerDir[2];
860 ghostedCoarseNodes->PIDs.resize(lNumGhostedNodes);
861 ghostedCoarseNodes->LIDs.resize(lNumGhostedNodes);
862 ghostedCoarseNodes->GIDs.resize(lNumGhostedNodes);
863 ghostedCoarseNodes->coarseGIDs.resize(lNumGhostedNodes);
864 ghostedCoarseNodes->colInds.resize(lNumGhostedNodes);
867 Array<LO> coarseNodeCoarseIndices(3), coarseNodeFineIndices(3), ijk(3);
868 LO currentIndex = -1;
869 for (ijk[2] = 0; ijk[2] < glCoarseNodesPerDir[2]; ++ijk[2]) {
870 for (ijk[1] = 0; ijk[1] < glCoarseNodesPerDir[1]; ++ijk[1]) {
871 for (ijk[0] = 0; ijk[0] < glCoarseNodesPerDir[0]; ++ijk[0]) {
872 currentIndex = ijk[2] * glCoarseNodesPerDir[1] * glCoarseNodesPerDir[0] + ijk[1] * glCoarseNodesPerDir[0] + ijk[0];
873 coarseNodeCoarseIndices[0] = startGhostedCoarseNode[0] + ijk[0];
874 coarseNodeFineIndices[0] = coarseNodeCoarseIndices[0] * coarseRate[0];
875 if (coarseNodeFineIndices[0] > gFineNodesPerDir[0] - 1) {
876 coarseNodeFineIndices[0] = gFineNodesPerDir[0] - 1;
878 coarseNodeCoarseIndices[1] = startGhostedCoarseNode[1] + ijk[1];
879 coarseNodeFineIndices[1] = coarseNodeCoarseIndices[1] * coarseRate[1];
880 if (coarseNodeFineIndices[1] > gFineNodesPerDir[1] - 1) {
881 coarseNodeFineIndices[1] = gFineNodesPerDir[1] - 1;
883 coarseNodeCoarseIndices[2] = startGhostedCoarseNode[2] + ijk[2];
884 coarseNodeFineIndices[2] = coarseNodeCoarseIndices[2] * coarseRate[2];
885 if (coarseNodeFineIndices[2] > gFineNodesPerDir[2] - 1) {
886 coarseNodeFineIndices[2] = gFineNodesPerDir[2] - 1;
888 GO myGID = 0, myCoarseGID = -1;
890 factor[2] = gFineNodesPerDir[1] * gFineNodesPerDir[0];
891 factor[1] = gFineNodesPerDir[0];
893 for (
int dim = 0; dim < 3; ++dim) {
894 if (dim < numDimensions) {
895 if (gIndices[dim] - myOffset[dim] + ijk[dim] * coarseRate[dim] < gFineNodesPerDir[dim] - 1) {
896 myGID += (gIndices[dim] - myOffset[dim] + ijk[dim] * coarseRate[dim]) * factor[dim];
898 myGID += (gIndices[dim] - myOffset[dim] + (ijk[dim] - 1) * coarseRate[dim] + endRate[dim]) * factor[dim];
902 myCoarseGID = coarseNodeCoarseIndices[0] + coarseNodeCoarseIndices[1] * gCoarseNodesPerDir[0] + coarseNodeCoarseIndices[2] * gCoarseNodesPerDir[1] * gCoarseNodesPerDir[0];
903 ghostedCoarseNodes->GIDs[currentIndex] = myGID;
904 ghostedCoarseNodes->coarseGIDs[currentIndex] = myCoarseGID;
908 coordinatesMap->getRemoteIndexList(ghostedCoarseNodes->GIDs(),
909 ghostedCoarseNodes->PIDs(),
910 ghostedCoarseNodes->LIDs());
921 ghostGIDs.
resize(lNumGhostNodes);
924 GO startingGID = minGlobalIndex;
928 if (ghostInterface[4] && (myOffset[2] == 0)) {
929 if (gIndices[2] + coarseRate[2] > gFineNodesPerDir[2]) {
930 startingGID -= endRate[2] * gFineNodesPerDir[1] * gFineNodesPerDir[0];
932 startingGID -= coarseRate[2] * gFineNodesPerDir[1] * gFineNodesPerDir[0];
935 startingGID -= myOffset[2] * gFineNodesPerDir[1] * gFineNodesPerDir[0];
937 if (ghostInterface[2] && (myOffset[1] == 0)) {
938 if (gIndices[1] + coarseRate[1] > gFineNodesPerDir[1]) {
939 startingGID -= endRate[1] * gFineNodesPerDir[0];
941 startingGID -= coarseRate[1] * gFineNodesPerDir[0];
944 startingGID -= myOffset[1] * gFineNodesPerDir[0];
946 if (ghostInterface[0] && (myOffset[0] == 0)) {
947 if (gIndices[0] + coarseRate[0] > gFineNodesPerDir[0]) {
948 startingGID -= endRate[0];
950 startingGID -= coarseRate[0];
953 startingGID -= myOffset[0];
958 startingIndices[2] = startingGID / (gFineNodesPerDir[1] * gFineNodesPerDir[0]);
959 tmp = startingGID % (gFineNodesPerDir[1] * gFineNodesPerDir[0]);
960 startingIndices[1] = tmp / gFineNodesPerDir[0];
961 startingIndices[0] = tmp % gFineNodesPerDir[0];
964 GO ghostOffset[3] = {0, 0, 0};
965 LO lengthZero = lCoarseNodesPerDir[0];
966 LO lengthOne = lCoarseNodesPerDir[1];
967 LO lengthTwo = lCoarseNodesPerDir[2];
968 if (ghostInterface[0]) {
971 if (ghostInterface[1]) {
974 if (ghostInterface[2]) {
977 if (ghostInterface[3]) {
980 if (ghostInterface[4]) {
983 if (ghostInterface[5]) {
988 if (ghostInterface[4]) {
989 ghostOffset[2] = startingGID;
990 for (
LO j = 0; j < lengthOne; ++j) {
991 if ((j == lengthOne - 1) && (startingIndices[1] + j * coarseRate[1] + 1 > gFineNodesPerDir[1])) {
992 ghostOffset[1] = ((j - 1) * coarseRate[1] + endRate[1]) * gFineNodesPerDir[0];
994 ghostOffset[1] = j * coarseRate[1] * gFineNodesPerDir[0];
996 for (
LO k = 0; k < lengthZero; ++k) {
997 if ((k == lengthZero - 1) && (startingIndices[0] + k * coarseRate[0] + 1 > gFineNodesPerDir[0])) {
998 ghostOffset[0] = (k - 1) * coarseRate[0] + endRate[0];
1000 ghostOffset[0] = k * coarseRate[0];
1005 ghostGIDs[countGhosts] = ghostOffset[2] + ghostOffset[1] + ghostOffset[0];
1013 for (
LO i = 0; i < lengthTwo; ++i) {
1016 if (!((i == lengthTwo - 1) && ghostInterface[5]) && !((i == 0) && ghostInterface[4])) {
1019 if ((i == lengthTwo - 1) && !ghostInterface[5]) {
1020 ghostOffset[2] = startingGID + ((i - 1) * coarseRate[2] + endRate[2]) * gFineNodesPerDir[1] * gFineNodesPerDir[0];
1022 ghostOffset[2] = startingGID + i * coarseRate[2] * gFineNodesPerDir[1] * gFineNodesPerDir[0];
1024 for (
LO j = 0; j < lengthOne; ++j) {
1025 if ((j == 0) && ghostInterface[2]) {
1026 for (
LO k = 0; k < lengthZero; ++k) {
1027 if ((k == lengthZero - 1) && (startingIndices[0] + k * coarseRate[0] + 1 > gFineNodesPerDir[0])) {
1029 ghostOffset[0] = endRate[0];
1031 ghostOffset[0] = (k - 1) * coarseRate[0] + endRate[0];
1034 ghostOffset[0] = k * coarseRate[0];
1037 ghostGIDs[countGhosts] = ghostOffset[2] + ghostOffset[0];
1040 }
else if ((j == lengthOne - 1) && ghostInterface[3]) {
1043 if ((j == lengthOne - 1) && (startingIndices[1] + j * coarseRate[1] + 1 > gFineNodesPerDir[1])) {
1044 ghostOffset[1] = ((j - 1) * coarseRate[1] + endRate[1]) * gFineNodesPerDir[0];
1046 ghostOffset[1] = j * coarseRate[1] * gFineNodesPerDir[0];
1048 for (
LO k = 0; k < lengthZero; ++k) {
1049 if ((k == lengthZero - 1) && (startingIndices[0] + k * coarseRate[0] + 1 > gFineNodesPerDir[0])) {
1050 ghostOffset[0] = (k - 1) * coarseRate[0] + endRate[0];
1052 ghostOffset[0] = k * coarseRate[0];
1054 ghostGIDs[countGhosts] = ghostOffset[2] + ghostOffset[1] + ghostOffset[0];
1059 if ((j == lengthOne - 1) && (startingIndices[1] + j * coarseRate[1] + 1 > gFineNodesPerDir[1])) {
1060 ghostOffset[1] = ((j - 1) * coarseRate[1] + endRate[1]) * gFineNodesPerDir[0];
1062 ghostOffset[1] = j * coarseRate[1] * gFineNodesPerDir[0];
1066 if (ghostInterface[0]) {
1067 ghostGIDs[countGhosts] = ghostOffset[2] + ghostOffset[1];
1070 if (ghostInterface[1]) {
1071 if ((startingIndices[0] + (lengthZero - 1) * coarseRate[0]) > gFineNodesPerDir[0] - 1) {
1072 if (lengthZero > 2) {
1073 ghostOffset[0] = (lengthZero - 2) * coarseRate[0] + endRate[0];
1075 ghostOffset[0] = endRate[0];
1078 ghostOffset[0] = (lengthZero - 1) * coarseRate[0];
1080 ghostGIDs[countGhosts] = ghostOffset[2] + ghostOffset[1] + ghostOffset[0];
1089 if (ghostInterface[5]) {
1090 if (startingIndices[2] + (lengthTwo - 1) * coarseRate[2] + 1 > gFineNodesPerDir[2]) {
1091 ghostOffset[2] = startingGID + ((lengthTwo - 2) * coarseRate[2] + endRate[2]) * gFineNodesPerDir[1] * gFineNodesPerDir[0];
1093 ghostOffset[2] = startingGID + (lengthTwo - 1) * coarseRate[2] * gFineNodesPerDir[1] * gFineNodesPerDir[0];
1095 for (
LO j = 0; j < lengthOne; ++j) {
1096 if ((j == lengthOne - 1) && (startingIndices[1] + j * coarseRate[1] + 1 > gFineNodesPerDir[1])) {
1097 ghostOffset[1] = ((j - 1) * coarseRate[1] + endRate[1]) * gFineNodesPerDir[0];
1099 ghostOffset[1] = j * coarseRate[1] * gFineNodesPerDir[0];
1101 for (
LO k = 0; k < lengthZero; ++k) {
1102 if ((k == lengthZero - 1) && (startingIndices[0] + k * coarseRate[0] + 1 > gFineNodesPerDir[0])) {
1103 ghostOffset[0] = (k - 1) * coarseRate[0] + endRate[0];
1105 ghostOffset[0] = k * coarseRate[0];
1107 ghostGIDs[countGhosts] = ghostOffset[2] + ghostOffset[1] + ghostOffset[0];
1120 Array<GO> gCoarseNodesGIDs(lNumCoarseNodes);
1121 LO currentNode, offset2, offset1, offset0;
1123 for (
LO ind2 = 0; ind2 < lCoarseNodesPerDir[2]; ++ind2) {
1124 if (myOffset[2] == 0) {
1125 offset2 = startingIndices[2] + myOffset[2];
1127 if (startingIndices[2] + endRate[2] == gFineNodesPerDir[2] - 1) {
1128 offset2 = startingIndices[2] + endRate[2];
1130 offset2 = startingIndices[2] + coarseRate[2];
1133 if (offset2 + ind2 * coarseRate[2] > gFineNodesPerDir[2] - 1) {
1134 offset2 += (ind2 - 1) * coarseRate[2] + endRate[2];
1136 offset2 += ind2 * coarseRate[2];
1138 offset2 = offset2 * gFineNodesPerDir[1] * gFineNodesPerDir[0];
1140 for (
LO ind1 = 0; ind1 < lCoarseNodesPerDir[1]; ++ind1) {
1141 if (myOffset[1] == 0) {
1142 offset1 = startingIndices[1] + myOffset[1];
1144 if (startingIndices[1] + endRate[1] == gFineNodesPerDir[1] - 1) {
1145 offset1 = startingIndices[1] + endRate[1];
1147 offset1 = startingIndices[1] + coarseRate[1];
1150 if (offset1 + ind1 * coarseRate[1] > gFineNodesPerDir[1] - 1) {
1151 offset1 += (ind1 - 1) * coarseRate[1] + endRate[1];
1153 offset1 += ind1 * coarseRate[1];
1155 offset1 = offset1 * gFineNodesPerDir[0];
1156 for (
LO ind0 = 0; ind0 < lCoarseNodesPerDir[0]; ++ind0) {
1157 offset0 = startingIndices[0];
1158 if (myOffset[0] == 0) {
1159 offset0 += ind0 * coarseRate[0];
1161 offset0 += (ind0 + 1) * coarseRate[0];
1163 if (offset0 > gFineNodesPerDir[0] - 1) {
1164 offset0 += endRate[0] - coarseRate[0];
1167 currentNode = ind2 * lCoarseNodesPerDir[1] * lCoarseNodesPerDir[0] + ind1 * lCoarseNodesPerDir[0] + ind0;
1168 gCoarseNodesGIDs[currentNode] = offset2 + offset1 + offset0;
1175 colGIDs.
resize(BlkSize * (lNumCoarseNodes + lNumGhostNodes));
1176 coarseNodesGIDs.
resize(lNumCoarseNodes);
1177 for (
LO i = 0; i < numDimensions; ++i) {
1178 coarseNodes[i].resize(lNumCoarseNodes);
1180 GO fineNodesPerCoarseSlab = coarseRate[2] * gFineNodesPerDir[1] * gFineNodesPerDir[0];
1181 GO fineNodesEndCoarseSlab = endRate[2] * gFineNodesPerDir[1] * gFineNodesPerDir[0];
1182 GO fineNodesPerCoarsePlane = coarseRate[1] * gFineNodesPerDir[0];
1183 GO fineNodesEndCoarsePlane = endRate[1] * gFineNodesPerDir[0];
1184 GO coarseNodesPerCoarseLayer = gCoarseNodesPerDir[1] * gCoarseNodesPerDir[0];
1185 GO gCoarseNodeOnCoarseGridGID;
1190 for (
LO k = 0; k < lNumGhostNodes; ++k) {
1193 coordinatesMap->getRemoteIndexList(ghostGIDs, ghostPIDs, ghostLIDs);
1194 sh_sort_permute(ghostPIDs.
begin(), ghostPIDs.
end(), ghostPermut.
begin(), ghostPermut.
end());
1197 GO tmpInds[3], tmpVars[2];
1205 LO firstCoarseNodeInds[3], currentCoarseNode;
1206 for (
LO dim = 0; dim < 3; ++dim) {
1207 if (myOffset[dim] == 0) {
1208 firstCoarseNodeInds[dim] = 0;
1210 firstCoarseNodeInds[dim] = coarseRate[dim] - myOffset[dim];
1214 for (
LO dim = 0; dim < numDimensions; ++dim) {
1215 fineNodes[dim] = coordinates->getData(dim);
1217 for (
LO k = 0; k < lCoarseNodesPerDir[2]; ++k) {
1218 for (
LO j = 0; j < lCoarseNodesPerDir[1]; ++j) {
1219 for (
LO i = 0; i < lCoarseNodesPerDir[0]; ++i) {
1220 col = k * lCoarseNodesPerDir[1] * lCoarseNodesPerDir[0] + j * lCoarseNodesPerDir[0] + i;
1223 currentCoarseNode = 0;
1224 if (firstCoarseNodeInds[0] + i * coarseRate[0] > lFineNodesPerDir[0] - 1) {
1225 currentCoarseNode += firstCoarseNodeInds[0] + (i - 1) * coarseRate[0] + endRate[0];
1227 currentCoarseNode += firstCoarseNodeInds[0] + i * coarseRate[0];
1229 if (firstCoarseNodeInds[1] + j * coarseRate[1] > lFineNodesPerDir[1] - 1) {
1230 currentCoarseNode += (firstCoarseNodeInds[1] + (j - 1) * coarseRate[1] + endRate[1]) * lFineNodesPerDir[0];
1232 currentCoarseNode += (firstCoarseNodeInds[1] + j * coarseRate[1]) * lFineNodesPerDir[0];
1234 if (firstCoarseNodeInds[2] + k * coarseRate[2] > lFineNodesPerDir[2] - 1) {
1235 currentCoarseNode += (firstCoarseNodeInds[2] + (k - 1) * coarseRate[2] + endRate[2]) * lFineNodesPerDir[1] * lFineNodesPerDir[0];
1237 currentCoarseNode += (firstCoarseNodeInds[2] + k * coarseRate[2]) * lFineNodesPerDir[1] * lFineNodesPerDir[0];
1240 for (
LO dim = 0; dim < numDimensions; ++dim) {
1241 coarseNodes[dim][col] = fineNodes[dim][currentCoarseNode];
1244 if ((endRate[2] != coarseRate[2]) && (gCoarseNodesGIDs[col] > (gCoarseNodesPerDir[2] - 2) * fineNodesPerCoarseSlab + fineNodesEndCoarseSlab - 1)) {
1245 tmpInds[2] = gCoarseNodesGIDs[col] / fineNodesPerCoarseSlab + 1;
1246 tmpVars[0] = gCoarseNodesGIDs[col] - (tmpInds[2] - 1) * fineNodesPerCoarseSlab - fineNodesEndCoarseSlab;
1248 tmpInds[2] = gCoarseNodesGIDs[col] / fineNodesPerCoarseSlab;
1249 tmpVars[0] = gCoarseNodesGIDs[col] % fineNodesPerCoarseSlab;
1251 if ((endRate[1] != coarseRate[1]) && (tmpVars[0] > (gCoarseNodesPerDir[1] - 2) * fineNodesPerCoarsePlane + fineNodesEndCoarsePlane - 1)) {
1252 tmpInds[1] = tmpVars[0] / fineNodesPerCoarsePlane + 1;
1253 tmpVars[1] = tmpVars[0] - (tmpInds[1] - 1) * fineNodesPerCoarsePlane - fineNodesEndCoarsePlane;
1255 tmpInds[1] = tmpVars[0] / fineNodesPerCoarsePlane;
1256 tmpVars[1] = tmpVars[0] % fineNodesPerCoarsePlane;
1258 if (tmpVars[1] == gFineNodesPerDir[0] - 1) {
1259 tmpInds[0] = gCoarseNodesPerDir[0] - 1;
1261 tmpInds[0] = tmpVars[1] / coarseRate[0];
1263 gInd[2] = col / (lCoarseNodesPerDir[1] * lCoarseNodesPerDir[0]);
1264 tmp = col % (lCoarseNodesPerDir[1] * lCoarseNodesPerDir[0]);
1265 gInd[1] = tmp / lCoarseNodesPerDir[0];
1266 gInd[0] = tmp % lCoarseNodesPerDir[0];
1267 lCol = gInd[2] * (lCoarseNodesPerDir[1] * lCoarseNodesPerDir[0]) + gInd[1] * lCoarseNodesPerDir[0] + gInd[0];
1268 gCoarseNodeOnCoarseGridGID = tmpInds[2] * coarseNodesPerCoarseLayer + tmpInds[1] * gCoarseNodesPerDir[0] + tmpInds[0];
1269 coarseNodesGIDs[lCol] = gCoarseNodeOnCoarseGridGID;
1270 for (
LO dof = 0; dof < BlkSize; ++dof) {
1271 colGIDs[BlkSize * lCol + dof] = BlkSize * gCoarseNodeOnCoarseGridGID + dof;
1278 for (col = lNumCoarseNodes; col < lNumCoarseNodes + lNumGhostNodes; ++col) {
1279 if ((endRate[2] != coarseRate[2]) && (ghostGIDs[ghostPermut[col - lNumCoarseNodes]] > (gCoarseNodesPerDir[2] - 2) * fineNodesPerCoarseSlab + fineNodesEndCoarseSlab - 1)) {
1280 tmpInds[2] = ghostGIDs[ghostPermut[col - lNumCoarseNodes]] / fineNodesPerCoarseSlab + 1;
1281 tmpVars[0] = ghostGIDs[ghostPermut[col - lNumCoarseNodes]] - (tmpInds[2] - 1) * fineNodesPerCoarseSlab - fineNodesEndCoarseSlab;
1283 tmpInds[2] = ghostGIDs[ghostPermut[col - lNumCoarseNodes]] / fineNodesPerCoarseSlab;
1284 tmpVars[0] = ghostGIDs[ghostPermut[col - lNumCoarseNodes]] % fineNodesPerCoarseSlab;
1286 if ((endRate[1] != coarseRate[1]) && (tmpVars[0] > (gCoarseNodesPerDir[1] - 2) * fineNodesPerCoarsePlane + fineNodesEndCoarsePlane - 1)) {
1287 tmpInds[1] = tmpVars[0] / fineNodesPerCoarsePlane + 1;
1288 tmpVars[1] = tmpVars[0] - (tmpInds[1] - 1) * fineNodesPerCoarsePlane - fineNodesEndCoarsePlane;
1290 tmpInds[1] = tmpVars[0] / fineNodesPerCoarsePlane;
1291 tmpVars[1] = tmpVars[0] % fineNodesPerCoarsePlane;
1293 if (tmpVars[1] == gFineNodesPerDir[0] - 1) {
1294 tmpInds[0] = gCoarseNodesPerDir[0] - 1;
1296 tmpInds[0] = tmpVars[1] / coarseRate[0];
1298 gCoarseNodeOnCoarseGridGID = tmpInds[2] * coarseNodesPerCoarseLayer + tmpInds[1] * gCoarseNodesPerDir[0] + tmpInds[0];
1299 for (
LO dof = 0; dof < BlkSize; ++dof) {
1300 colGIDs[BlkSize * col + dof] = BlkSize * gCoarseNodeOnCoarseGridGID + dof;
1307 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1315 const std::string stencilType,
const std::string ,
1316 const Array<LO> elementNodesPerDir,
const LO numNodesInElement,
1330 LO countInterior = 0, countFace = 0, countEdge = 0, countCorner = 0;
1331 Array<LO> collapseDir(numNodesInElement * BlkSize);
1332 for (
LO ke = 0; ke < elementNodesPerDir[2]; ++ke) {
1333 for (
LO je = 0; je < elementNodesPerDir[1]; ++je) {
1334 for (
LO ie = 0; ie < elementNodesPerDir[0]; ++ie) {
1336 if ((ke == 0 || ke == elementNodesPerDir[2] - 1) && (je == 0 || je == elementNodesPerDir[1] - 1) && (ie == 0 || ie == elementNodesPerDir[0] - 1)) {
1337 for (
LO dof = 0; dof < BlkSize; ++dof) {
1338 dofType[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = 0;
1339 lDofInd[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = BlkSize * countCorner + dof;
1344 }
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))) {
1345 for (
LO dof = 0; dof < BlkSize; ++dof) {
1346 dofType[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = 1;
1347 lDofInd[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = BlkSize * countEdge + dof;
1348 if ((ke == 0 || ke == elementNodesPerDir[2] - 1) && (je == 0 || je == elementNodesPerDir[1] - 1)) {
1349 collapseDir[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = 0;
1350 }
else if ((ke == 0 || ke == elementNodesPerDir[2] - 1) && (ie == 0 || ie == elementNodesPerDir[0] - 1)) {
1351 collapseDir[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = 1;
1352 }
else if ((je == 0 || je == elementNodesPerDir[1] - 1) && (ie == 0 || ie == elementNodesPerDir[0] - 1)) {
1353 collapseDir[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = 2;
1359 }
else if ((ke == 0 || ke == elementNodesPerDir[2] - 1) || (je == 0 || je == elementNodesPerDir[1] - 1) || (ie == 0 || ie == elementNodesPerDir[0] - 1)) {
1360 for (
LO dof = 0; dof < BlkSize; ++dof) {
1361 dofType[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = 2;
1362 lDofInd[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = BlkSize * countFace + dof;
1363 if (ke == 0 || ke == elementNodesPerDir[2] - 1) {
1364 collapseDir[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = 2;
1365 }
else if (je == 0 || je == elementNodesPerDir[1] - 1) {
1366 collapseDir[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = 1;
1367 }
else if (ie == 0 || ie == elementNodesPerDir[0] - 1) {
1368 collapseDir[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = 0;
1375 for (
LO dof = 0; dof < BlkSize; ++dof) {
1376 dofType[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = 3;
1377 lDofInd[BlkSize * (ke * elementNodesPerDir[1] * elementNodesPerDir[0] + je * elementNodesPerDir[0] + ie) + dof] = BlkSize * countInterior + dof;
1385 LO numInteriorNodes = 0, numFaceNodes = 0, numEdgeNodes = 0, numCornerNodes = 8;
1386 numInteriorNodes = (elementNodesPerDir[0] - 2) * (elementNodesPerDir[1] - 2) * (elementNodesPerDir[2] - 2);
1387 numFaceNodes = 2 * (elementNodesPerDir[0] - 2) * (elementNodesPerDir[1] - 2) + 2 * (elementNodesPerDir[0] - 2) * (elementNodesPerDir[2] - 2) + 2 * (elementNodesPerDir[1] - 2) * (elementNodesPerDir[2] - 2);
1388 numEdgeNodes = 4 * (elementNodesPerDir[0] - 2) + 4 * (elementNodesPerDir[1] - 2) + 4 * (elementNodesPerDir[2] - 2);
1401 Pi.
shape(BlkSize * numInteriorNodes, BlkSize * numCornerNodes);
1402 Pf.
shape(BlkSize * numFaceNodes, BlkSize * numCornerNodes);
1403 Pe.
shape(BlkSize * numEdgeNodes, BlkSize * numCornerNodes);
1407 LO idof, iInd, jInd;
1408 int iType = 0, jType = 0;
1409 int orientation = -1;
1410 int collapseFlags[3] = {};
1411 Array<SC> stencil((std::pow(3, numDimensions)) * BlkSize);
1415 for (
LO ke = 0; ke < elementNodesPerDir[2]; ++ke) {
1416 for (
LO je = 0; je < elementNodesPerDir[1]; ++je) {
1417 for (
LO ie = 0; ie < elementNodesPerDir[0]; ++ie) {
1418 collapseFlags[0] = 0;
1419 collapseFlags[1] = 0;
1420 collapseFlags[2] = 0;
1421 if ((elementFlags[0] == 1 || elementFlags[0] == 3) && ie == 0) {
1422 collapseFlags[0] += 1;
1424 if ((elementFlags[0] == 2 || elementFlags[0] == 3) && ie == elementNodesPerDir[0] - 1) {
1425 collapseFlags[0] += 2;
1427 if ((elementFlags[1] == 1 || elementFlags[1] == 3) && je == 0) {
1428 collapseFlags[1] += 1;
1430 if ((elementFlags[1] == 2 || elementFlags[1] == 3) && je == elementNodesPerDir[1] - 1) {
1431 collapseFlags[1] += 2;
1433 if ((elementFlags[2] == 1 || elementFlags[2] == 3) && ke == 0) {
1434 collapseFlags[2] += 1;
1436 if ((elementFlags[2] == 2 || elementFlags[2] == 3) && ke == elementNodesPerDir[2] - 1) {
1437 collapseFlags[2] += 2;
1441 GetNodeInfo(ie, je, ke, elementNodesPerDir, &iType, iInd, &orientation);
1442 for (
LO dof0 = 0; dof0 < BlkSize; ++dof0) {
1444 idof = ((elemInds[2] * coarseRate[2] + ke) * lFineNodesPerDir[1] * lFineNodesPerDir[0] + (elemInds[1] * coarseRate[1] + je) * lFineNodesPerDir[0] + elemInds[0] * coarseRate[0] + ie) * BlkSize + dof0;
1445 Aghost->getLocalRowView(idof, rowIndices, rowValues);
1446 FormatStencil(BlkSize, ghostInterface, ie, je, ke, rowValues,
1447 elementNodesPerDir, collapseFlags, stencilType, stencil);
1450 for (
LO interactingNode = 0; interactingNode < 27; ++interactingNode) {
1452 ko = ke + (interactingNode / 9 - 1);
1454 LO tmp = interactingNode % 9;
1455 jo = je + (tmp / 3 - 1);
1456 io = ie + (tmp % 3 - 1);
1458 GetNodeInfo(io, jo, ko, elementNodesPerDir, &jType, jInd, &dummy);
1460 if ((io > -1 && io < elementNodesPerDir[0]) &&
1461 (jo > -1 && jo < elementNodesPerDir[1]) &&
1462 (ko > -1 && ko < elementNodesPerDir[2])) {
1463 for (
LO dof1 = 0; dof1 < BlkSize; ++dof1) {
1465 Aii(iInd * BlkSize + dof0, jInd * BlkSize + dof1) =
1466 stencil[interactingNode * BlkSize + dof1];
1467 }
else if (jType == 2) {
1468 Aif(iInd * BlkSize + dof0, jInd * BlkSize + dof1) =
1469 stencil[interactingNode * BlkSize + dof1];
1470 }
else if (jType == 1) {
1471 Aie(iInd * BlkSize + dof0, jInd * BlkSize + dof1) =
1472 stencil[interactingNode * BlkSize + dof1];
1473 }
else if (jType == 0) {
1474 Aic(iInd * BlkSize + dof0, jInd * BlkSize + dof1) =
1475 -stencil[interactingNode * BlkSize + dof1];
1480 }
else if (iType == 2) {
1481 CollapseStencil(2, orientation, collapseFlags, stencil);
1482 for (
LO interactingNode = 0; interactingNode < 27; ++interactingNode) {
1484 ko = ke + (interactingNode / 9 - 1);
1486 LO tmp = interactingNode % 9;
1487 jo = je + (tmp / 3 - 1);
1488 io = ie + (tmp % 3 - 1);
1490 GetNodeInfo(io, jo, ko, elementNodesPerDir, &jType, jInd, &dummy);
1492 if ((io > -1 && io < elementNodesPerDir[0]) &&
1493 (jo > -1 && jo < elementNodesPerDir[1]) &&
1494 (ko > -1 && ko < elementNodesPerDir[2])) {
1495 for (
LO dof1 = 0; dof1 < BlkSize; ++dof1) {
1497 Aff(iInd * BlkSize + dof0, jInd * BlkSize + dof1) =
1498 stencil[interactingNode * BlkSize + dof1];
1499 }
else if (jType == 1) {
1500 Afe(iInd * BlkSize + dof0, jInd * BlkSize + dof1) =
1501 stencil[interactingNode * BlkSize + dof1];
1502 }
else if (jType == 0) {
1503 Afc(iInd * BlkSize + dof0, jInd * BlkSize + dof1) =
1504 -stencil[interactingNode * BlkSize + dof1];
1509 }
else if (iType == 1) {
1510 CollapseStencil(1, orientation, collapseFlags, stencil);
1511 for (
LO interactingNode = 0; interactingNode < 27; ++interactingNode) {
1513 ko = ke + (interactingNode / 9 - 1);
1515 LO tmp = interactingNode % 9;
1516 jo = je + (tmp / 3 - 1);
1517 io = ie + (tmp % 3 - 1);
1519 GetNodeInfo(io, jo, ko, elementNodesPerDir, &jType, jInd, &dummy);
1521 if ((io > -1 && io < elementNodesPerDir[0]) &&
1522 (jo > -1 && jo < elementNodesPerDir[1]) &&
1523 (ko > -1 && ko < elementNodesPerDir[2])) {
1524 for (
LO dof1 = 0; dof1 < BlkSize; ++dof1) {
1526 Aee(iInd * BlkSize + dof0, jInd * BlkSize + dof1) =
1527 stencil[interactingNode * BlkSize + dof1];
1528 }
else if (jType == 0) {
1529 Aec(iInd * BlkSize + dof0, jInd * BlkSize + dof1) =
1530 -stencil[interactingNode * BlkSize + dof1];
1589 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1595 if (orientation == 0) {
1596 for (
LO i = 0; i < 9; ++i) {
1597 stencil[3 * i + 1] = stencil[3 * i] + stencil[3 * i + 1] + stencil[3 * i + 2];
1599 stencil[3 * i + 2] = 0;
1601 }
else if (orientation == 1) {
1602 for (
LO i = 0; i < 3; ++i) {
1603 stencil[9 * i + 3] = stencil[9 * i + 0] + stencil[9 * i + 3] + stencil[9 * i + 6];
1604 stencil[9 * i + 0] = 0;
1605 stencil[9 * i + 6] = 0;
1606 stencil[9 * i + 4] = stencil[9 * i + 1] + stencil[9 * i + 4] + stencil[9 * i + 7];
1607 stencil[9 * i + 1] = 0;
1608 stencil[9 * i + 7] = 0;
1609 stencil[9 * i + 5] = stencil[9 * i + 2] + stencil[9 * i + 5] + stencil[9 * i + 8];
1610 stencil[9 * i + 2] = 0;
1611 stencil[9 * i + 8] = 0;
1613 }
else if (orientation == 2) {
1614 for (
LO i = 0; i < 9; ++i) {
1615 stencil[i + 9] = stencil[i] + stencil[i + 9] + stencil[i + 18];
1617 stencil[i + 18] = 0;
1620 }
else if (type == 1) {
1621 SC tmp1 = 0, tmp2 = 0, tmp3 = 0;
1622 if (orientation == 0) {
1623 for (
LO i = 0; i < 9; ++i) {
1624 tmp1 += stencil[0 + 3 * i];
1625 stencil[0 + 3 * i] = 0;
1626 tmp2 += stencil[1 + 3 * i];
1627 stencil[1 + 3 * i] = 0;
1628 tmp3 += stencil[2 + 3 * i];
1629 stencil[2 + 3 * i] = 0;
1634 }
else if (orientation == 1) {
1635 for (
LO i = 0; i < 3; ++i) {
1636 tmp1 += stencil[0 + i] + stencil[9 + i] + stencil[18 + i];
1639 stencil[18 + i] = 0;
1640 tmp2 += stencil[3 + i] + stencil[12 + i] + stencil[21 + i];
1642 stencil[12 + i] = 0;
1643 stencil[21 + i] = 0;
1644 tmp3 += stencil[6 + i] + stencil[15 + i] + stencil[24 + i];
1646 stencil[15 + i] = 0;
1647 stencil[24 + i] = 0;
1652 }
else if (orientation == 2) {
1653 for (
LO i = 0; i < 9; ++i) {
1656 tmp2 += stencil[i + 9];
1658 tmp3 += stencil[i + 18];
1659 stencil[i + 18] = 0;
1668 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1672 const int collapseFlags[3],
const std::string stencilType,
Array<SC>& stencil)
1674 if (stencilType ==
"reduced") {
1676 fullStencilInds[0] = 4;
1677 fullStencilInds[1] = 10;
1678 fullStencilInds[2] = 12;
1679 fullStencilInds[3] = 13;
1680 fullStencilInds[4] = 14;
1681 fullStencilInds[5] = 16;
1682 fullStencilInds[6] = 22;
1686 int stencilSize = rowValues.
size();
1687 if (collapseFlags[0] + collapseFlags[1] + collapseFlags[2] > 0) {
1688 if (stencilSize == 1) {
1701 if (collapseFlags[2] == 1 || collapseFlags[2] == 3) {
1704 if (collapseFlags[2] == 2 || collapseFlags[2] == 3) {
1707 if (collapseFlags[1] == 1 || collapseFlags[1] == 3) {
1710 if (collapseFlags[1] == 2 || collapseFlags[1] == 3) {
1713 if (collapseFlags[0] == 1 || collapseFlags[0] == 3) {
1716 if (collapseFlags[0] == 2 || collapseFlags[0] == 3) {
1723 for (
int ind = 0; ind < 7; ++ind) {
1724 if (mask[ind] == 1) {
1725 for (
int dof = 0; dof < BlkSize; ++dof) {
1726 stencil[BlkSize * fullStencilInds[ind] + dof] = 0.0;
1730 for (
int dof = 0; dof < BlkSize; ++dof) {
1731 stencil[BlkSize * fullStencilInds[ind] + dof] = rowValues[BlkSize * (ind - offset) + dof];
1735 }
else if (stencilType ==
"full") {
1738 if (collapseFlags[2] == 1 || collapseFlags[2] == 3) {
1739 for (
int ind = 0; ind < 9; ++ind) {
1743 if (collapseFlags[2] == 2 || collapseFlags[2] == 3) {
1744 for (
int ind = 0; ind < 9; ++ind) {
1748 if (collapseFlags[1] == 1 || collapseFlags[1] == 3) {
1749 for (
int ind1 = 0; ind1 < 3; ++ind1) {
1750 for (
int ind2 = 0; ind2 < 3; ++ind2) {
1751 mask[ind1 * 9 + ind2] = 1;
1755 if (collapseFlags[1] == 2 || collapseFlags[1] == 3) {
1756 for (
int ind1 = 0; ind1 < 3; ++ind1) {
1757 for (
int ind2 = 0; ind2 < 3; ++ind2) {
1758 mask[ind1 * 9 + ind2 + 6] = 1;
1762 if (collapseFlags[0] == 1 || collapseFlags[0] == 3) {
1763 for (
int ind = 0; ind < 9; ++ind) {
1767 if (collapseFlags[0] == 2 || collapseFlags[0] == 3) {
1768 for (
int ind = 0; ind < 9; ++ind) {
1769 mask[3 * ind + 2] = 1;
1775 for (
LO ind = 0; ind < 27; ++ind) {
1776 if (mask[ind] == 0) {
1777 for (
int dof = 0; dof < BlkSize; ++dof) {
1778 stencil[BlkSize * ind + dof] = 0.0;
1782 for (
int dof = 0; dof < BlkSize; ++dof) {
1783 stencil[BlkSize * ind + dof] = rowValues[BlkSize * (ind - offset) + dof];
1790 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1792 const LO ie,
const LO je,
const LO ke,
1794 int* type,
LO& ind,
int* orientation)
const {
1796 *type = -1, ind = 0, *orientation = -1;
1797 if ((ke == 0 || ke == elementNodesPerDir[2] - 1) && (je == 0 || je == elementNodesPerDir[1] - 1) && (ie == 0 || ie == elementNodesPerDir[0] - 1)) {
1800 ind = 4 * ke / (elementNodesPerDir[2] - 1) + 2 * je / (elementNodesPerDir[1] - 1) + ie / (elementNodesPerDir[0] - 1);
1801 }
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))) {
1805 ind += 2 * (elementNodesPerDir[0] - 2 + elementNodesPerDir[1] - 2);
1807 if (ke == elementNodesPerDir[2] - 1) {
1808 ind += 4 * (elementNodesPerDir[2] - 2);
1810 if ((ke == 0) || (ke == elementNodesPerDir[2] - 1)) {
1814 }
else if (je == elementNodesPerDir[1] - 1) {
1816 ind += 2 * (elementNodesPerDir[1] - 2) + elementNodesPerDir[0] - 2 + ie - 1;
1819 ind += elementNodesPerDir[0] - 2 + 2 * (je - 1) + ie / (elementNodesPerDir[0] - 1);
1823 ind += 4 * (ke - 1) + 2 * (je / (elementNodesPerDir[1] - 1)) + ie / (elementNodesPerDir[0] - 1);
1825 }
else if ((ke == 0 || ke == elementNodesPerDir[2] - 1) || (je == 0 || je == elementNodesPerDir[1] - 1) || (ie == 0 || ie == elementNodesPerDir[0] - 1)) {
1830 ind = (je - 1) * (elementNodesPerDir[0] - 2) + ie - 1;
1833 ind += (elementNodesPerDir[1] - 2) * (elementNodesPerDir[0] - 2);
1835 ind += 2 * (ke - 1) * (elementNodesPerDir[1] - 2 + elementNodesPerDir[0] - 2);
1836 if (ke == elementNodesPerDir[2] - 1) {
1838 ind += (je - 1) * (elementNodesPerDir[0] - 2) + ie - 1;
1843 }
else if (je == elementNodesPerDir[1] - 1) {
1845 ind += 2 * (elementNodesPerDir[1] - 2) + elementNodesPerDir[0] - 2 + ie - 1;
1848 ind += elementNodesPerDir[0] - 2 + 2 * (je - 1) + ie / (elementNodesPerDir[0] - 1);
1855 ind = (ke - 1) * (elementNodesPerDir[1] - 2) * (elementNodesPerDir[0] - 2) + (je - 1) * (elementNodesPerDir[0] - 2) + ie - 1;
1859 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1865 typedef typename std::iterator_traits<typename Teuchos::Array<LocalOrdinal>::iterator>::difference_type DT;
1866 DT n = last1 - first1;
1871 for (DT j = 0; j < max; j++) {
1872 for (DT k = j; k >= 0; k -= m) {
1873 if (first1[first2[k + m]] >= first1[first2[k]])
1875 std::swap(first2[k + m], first2[k]);
1884 #define MUELU_BLACKBOXPFACTORY_SHORT
1885 #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)
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.
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
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