46 #ifndef MUELU_TENTATIVEPFACTORY_DEF_HPP
47 #define MUELU_TENTATIVEPFACTORY_DEF_HPP
49 #include <Xpetra_MapFactory.hpp>
50 #include <Xpetra_Map.hpp>
56 #include <Xpetra_MultiVectorFactory.hpp>
60 #include <Xpetra_CrsMatrixWrap.hpp>
61 #include <Xpetra_StridedMap.hpp>
62 #include <Xpetra_StridedMapFactory.hpp>
65 #include "Xpetra_TpetraBlockCrsMatrix.hpp"
69 #include "MueLu_Aggregates.hpp"
70 #include "MueLu_AmalgamationInfo.hpp"
73 #include "MueLu_PerfUtils.hpp"
74 #include "MueLu_Utilities.hpp"
78 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
82 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
86 #undef SET_VALID_ENTRY
87 validParamList->
set<std::string>(
"Nullspace name",
"Nullspace",
"Name for the input nullspace");
92 validParamList->
set<
RCP<const FactoryBase> >(
"Scaled Nullspace", Teuchos::null,
"Generating factory of the scaled nullspace");
93 validParamList->
set<
RCP<const FactoryBase> >(
"UnAmalgamationInfo", Teuchos::null,
"Generating factory of UnAmalgamationInfo");
96 validParamList->
set<
RCP<const FactoryBase> >(
"Node Comm", Teuchos::null,
"Generating factory of the node level communicator");
100 norecurse.disableRecursiveValidation();
101 validParamList->
set<
ParameterList>(
"matrixmatrix: kernel params", norecurse,
"MatrixMatrix kernel parameters");
103 return validParamList;
106 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
110 std::string nspName =
"Nullspace";
111 if (pL.
isParameter(
"Nullspace name")) nspName = pL.
get<std::string>(
"Nullspace name");
113 Input(fineLevel,
"A");
114 Input(fineLevel,
"Aggregates");
115 Input(fineLevel, nspName);
116 Input(fineLevel,
"UnAmalgamationInfo");
117 Input(fineLevel,
"CoarseMap");
120 pL.
get<
bool>(
"tentative: build coarse coordinates")) {
121 bTransferCoordinates_ =
true;
122 Input(fineLevel,
"Coordinates");
123 }
else if (bTransferCoordinates_) {
124 Input(fineLevel,
"Coordinates");
128 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
130 return BuildP(fineLevel, coarseLevel);
133 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
141 std::string nspName =
"Nullspace";
142 if (pL.
isParameter(
"Nullspace name")) nspName = pL.
get<std::string>(
"Nullspace name");
146 RCP<Aggregates> aggregates = Get<RCP<Aggregates> >(fineLevel,
"Aggregates");
149 if (aggregates->GetNumGlobalAggregatesComputeIfNeeded() == 0) {
150 Ptentative = Teuchos::null;
151 Set(coarseLevel,
"P", Ptentative);
156 RCP<MultiVector> fineNullspace = Get<RCP<MultiVector> >(fineLevel, nspName);
157 RCP<const Map> coarseMap = Get<RCP<const Map> >(fineLevel,
"CoarseMap");
159 if (bTransferCoordinates_) {
160 fineCoords = Get<RCP<RealValuedMultiVector> >(fineLevel,
"Coordinates");
164 if (fineLevel.IsAvailable(
"Node Comm")) {
166 Set<RCP<const Teuchos::Comm<int> > >(coarseLevel,
"Node Comm", nodeComm);
176 if (bTransferCoordinates_) {
181 if (rcp_dynamic_cast<const StridedMap>(coarseMap) != Teuchos::null) {
182 blkSize = rcp_dynamic_cast<
const StridedMap>(coarseMap)->getFixedBlockSize();
184 GO indexBase = coarseMap->getIndexBase();
185 LO numCoarseNodes = Teuchos::as<LO>(elementAList.
size() / blkSize);
187 const int numDimensions = fineCoords->getNumVectors();
189 for (
LO i = 0; i < numCoarseNodes; i++) {
190 nodeList[i] = (elementAList[i * blkSize] - indexBase) / blkSize + indexBase;
192 RCP<const Map> coarseCoordsMap = MapFactory::Build(fineCoords->getMap()->lib(),
196 fineCoords->getMap()->getComm());
197 coarseCoords = RealValuedMultiVectorFactory::Build(coarseCoordsMap, numDimensions);
201 if (aggregates->AggregatesCrossProcessors()) {
205 ghostedCoords = RealValuedMultiVectorFactory::Build(aggMap, numDimensions);
208 ghostedCoords = fineCoords;
212 int myPID = coarseCoordsMap->getComm()->getRank();
213 LO numAggs = aggregates->GetNumAggregates();
214 ArrayRCP<LO> aggSizes = aggregates->ComputeAggregateSizesArrayRCP();
219 for (
int dim = 0; dim < numDimensions; ++dim) {
223 for (
LO lnode = 0; lnode < Teuchos::as<LO>(vertex2AggID.
size()); lnode++) {
224 if (procWinner[lnode] == myPID &&
225 lnode < fineCoordsData.
size() &&
226 vertex2AggID[lnode] < coarseCoordsData.
size() &&
228 coarseCoordsData[vertex2AggID[lnode]] += fineCoordsData[lnode];
231 for (
LO agg = 0; agg < numAggs; agg++) {
232 coarseCoordsData[agg] /= aggSizes[agg];
237 if (!aggregates->AggregatesCrossProcessors()) {
239 BuildPuncoupledBlockCrs(A, aggregates, amalgInfo, fineNullspace, coarseMap, Ptentative, coarseNullspace, coarseLevel.
GetLevelID());
241 BuildPuncoupled(A, aggregates, amalgInfo, fineNullspace, coarseMap, Ptentative, coarseNullspace, coarseLevel.
GetLevelID());
244 BuildPcoupled(A, aggregates, amalgInfo, fineNullspace, coarseMap, Ptentative, coarseNullspace);
254 if (A->IsView(
"stridedMaps") ==
true)
255 Ptentative->CreateView(
"stridedMaps", A->getRowMap(
"stridedMaps"), coarseMap);
257 Ptentative->CreateView(
"stridedMaps", Ptentative->getRangeMap(), coarseMap);
259 if (bTransferCoordinates_) {
260 Set(coarseLevel,
"Coordinates", coarseCoords);
262 Set(coarseLevel,
"Nullspace", coarseNullspace);
263 Set(coarseLevel,
"P", Ptentative);
267 params->
set(
"printLoadBalancingInfo",
true);
272 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
289 const size_t numFineBlockRows = rowMap->getLocalNumElements();
293 const SC zero = STS::zero();
294 const SC one = STS::one();
298 const size_t NSDim = fineNullspace->getNumVectors();
305 const size_t numCoarseBlockRows = coarsePointMap->getLocalNumElements() / NSDim;
306 RCP<const Map> coarseBlockMap = MapFactory::Build(coarsePointMap->lib(),
309 coarsePointMap->getIndexBase(),
310 coarsePointMap->getComm());
313 const bool&
doQRStep = pL.get<
bool>(
"tentative: calculate qr");
314 const bool& constantColSums = pL.get<
bool>(
"tentative: constant column sums");
317 "MueLu::TentativePFactory::MakeTentative: cannot use 'constant column sums' and 'calculate qr' at the same time");
335 GetOStream(
Runtime1) <<
"Column map is consistent with the row map, good." << std::endl;
337 throw std::runtime_error(
"TentativePFactory::PuncoupledBlockCrs: Inconsistent maps not currently supported");
340 coarseNullspace = MultiVectorFactory::Build(coarsePointMap, NSDim);
345 for (
size_t i = 0; i < NSDim; i++) {
346 fineNS[i] = fineNullspace->getData(i);
347 if (coarsePointMap->getLocalNumElements() > 0)
348 coarseNS[i] = coarseNullspace->getDataNonConst(i);
354 RCP<CrsGraph> BlockGraph = CrsGraphFactory::Build(rowMap, coarseBlockMap, 0);
357 BlockGraph->allocateAllIndices(numFineBlockRows, iaPtent, jaPtent);
361 for (
size_t i = 0; i < numFineBlockRows; i++) {
365 ia[numCoarseBlockRows] = numCoarseBlockRows;
367 for (
GO agg = 0; agg < numAggs; agg++) {
368 LO aggSize = aggStart[agg + 1] - aggStart[agg];
371 for (
LO j = 0; j < aggSize; j++) {
373 const LO localRow = aggToRowMapLO[aggStart[agg] + j];
374 const size_t rowStart = ia[localRow];
375 ja[rowStart] = offset;
381 size_t ia_tmp = 0, nnz = 0;
382 for (
size_t i = 0; i < numFineBlockRows; i++) {
383 for (
size_t j = ia_tmp; j < ia[i + 1]; j++)
384 if (ja[j] != INVALID) {
399 GetOStream(
Runtime1) <<
"TentativePFactory : generating block graph" << std::endl;
400 BlockGraph->setAllIndices(iaPtent, jaPtent);
405 if (pL.isSublist(
"matrixmatrix: kernel params"))
406 FCparams =
rcp(
new ParameterList(pL.sublist(
"matrixmatrix: kernel params")));
411 FCparams->
set(
"compute global constants", FCparams->
get(
"compute global constants",
true));
412 std::string levelIDs =
toString(levelID);
413 FCparams->
set(
"Timer Label", std::string(
"MueLu::TentativeP-") + levelIDs);
416 BlockGraph->expertStaticFillComplete(coarseBlockMap, rowMap, dummy_i, dummy_e, FCparams);
423 if (P_tpetra.
is_null())
throw std::runtime_error(
"BuildPUncoupled: Matrix factory did not return a Tpetra::BlockCrsMatrix");
436 GetOStream(
Runtime1) <<
"TentativePFactory : bypassing local QR phase" << std::endl;
437 for (
LO agg = 0; agg < numAggs; agg++) {
439 const LO aggSize = aggStart[agg + 1] - aggStart[agg];
444 for (
LO j = 0; j < aggSize; j++) {
445 const LO localBlockRow = aggToRowMapLO[aggStart[agg] + j];
447 for (
size_t r = 0; r < NSDim; r++) {
448 LO localPointRow = localBlockRow * NSDim + r;
449 for (
size_t c = 0; c < NSDim; c++)
450 block[r * NSDim + c] = fineNS[c][localPointRow];
453 P_tpetra->replaceLocalValues(localBlockRow, bcol(), block());
457 for (
size_t j = 0; j < NSDim; j++)
458 coarseNS[j][offset + j] = one;
465 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
470 typedef typename STS::magnitudeType Magnitude;
471 const SC zero = STS::zero();
472 const SC one = STS::one();
487 for (
GO i = 0; i < numAggs; ++i) {
488 LO sizeOfThisAgg = aggStart[i + 1] - aggStart[i];
489 if (sizeOfThisAgg > maxAggSize) maxAggSize = sizeOfThisAgg;
493 const size_t NSDim = fineNullspace->getNumVectors();
496 GO indexBase = A->getRowMap()->getIndexBase();
501 RCP<MultiVector> fineNullspaceWithOverlap = MultiVectorFactory::Build(nonUniqueMap, NSDim);
502 fineNullspaceWithOverlap->doImport(*fineNullspace, *importer,
Xpetra::INSERT);
506 for (
size_t i = 0; i < NSDim; ++i)
507 fineNS[i] = fineNullspaceWithOverlap->getData(i);
510 coarseNullspace = MultiVectorFactory::Build(coarseMap, NSDim);
513 for (
size_t i = 0; i < NSDim; ++i)
514 if (coarseMap->getLocalNumElements() > 0) coarseNS[i] = coarseNullspace->getDataNonConst(i);
520 const Map& rowMapForPtentRef = *rowMapForPtent;
535 for (
LO j = 0; j < numAggs; ++j) {
536 for (
LO k = aggStart[j]; k < aggStart[j + 1]; ++k) {
537 if (rowMapForPtentRef.isNodeGlobalElement(aggToRowMap[k]) ==
false) {
542 ghostQMap = MapFactory::Build(A->getRowMap()->lib(),
545 indexBase, A->getRowMap()->getComm());
547 ghostQvalues = MultiVectorFactory::Build(ghostQMap, NSDim);
551 ghostQcolumns.
resize(NSDim);
552 for (
size_t i = 0; i < NSDim; ++i)
555 if (ghostQvalues->getLocalLength() > 0) {
558 for (
size_t i = 0; i < NSDim; ++i) {
559 ghostQvals[i] = ghostQvalues->getDataNonConst(i);
560 ghostQcols[i] = ghostQcolumns[i]->getDataNonConst(0);
562 ghostQrows = ghostQrowNums->getDataNonConst(0);
566 importer = ImportFactory::Build(ghostQMap, A->getRowMap());
572 Array<GO> globalColPtr(maxAggSize * NSDim, 0);
573 Array<LO> localColPtr(maxAggSize * NSDim, 0);
574 Array<SC> valPtr(maxAggSize * NSDim, 0.);
577 const Map& coarseMapRef = *coarseMap;
597 PtentCrs = PtentCrsWrap->getCrsMatrix();
598 Ptentative = PtentCrsWrap;
604 const Map& nonUniqueMapRef = *nonUniqueMap;
606 size_t total_nnz_count = 0;
608 for (
GO agg = 0; agg < numAggs; ++agg) {
609 LO myAggSize = aggStart[agg + 1] - aggStart[agg];
613 for (
size_t j = 0; j < NSDim; ++j) {
614 bool bIsZeroNSColumn =
true;
615 for (
LO k = 0; k < myAggSize; ++k) {
619 SC nsVal = fineNS[j][nonUniqueMapRef.getLocalElement(aggToRowMap[aggStart[agg] + k])];
620 localQR(k, j) = nsVal;
621 if (nsVal != zero) bIsZeroNSColumn =
false;
623 GetOStream(
Runtime1, -1) <<
"length of fine level nsp: " << fineNullspace->getGlobalLength() << std::endl;
624 GetOStream(
Runtime1, -1) <<
"length of fine level nsp w overlap: " << fineNullspaceWithOverlap->getGlobalLength() << std::endl;
625 GetOStream(
Runtime1, -1) <<
"(local?) aggId=" << agg << std::endl;
626 GetOStream(
Runtime1, -1) <<
"aggSize=" << myAggSize << std::endl;
627 GetOStream(
Runtime1, -1) <<
"agg DOF=" << k << std::endl;
628 GetOStream(
Runtime1, -1) <<
"NS vector j=" << j << std::endl;
629 GetOStream(
Runtime1, -1) <<
"j*myAggSize + k = " << j * myAggSize + k << std::endl;
630 GetOStream(
Runtime1, -1) <<
"aggToRowMap[" << agg <<
"][" << k <<
"] = " << aggToRowMap[aggStart[agg] + k] << std::endl;
631 GetOStream(
Runtime1, -1) <<
"id aggToRowMap[agg][k]=" << aggToRowMap[aggStart[agg] + k] <<
" is global element in nonUniqueMap = " << nonUniqueMapRef.isNodeGlobalElement(aggToRowMap[aggStart[agg] + k]) << std::endl;
632 GetOStream(
Runtime1, -1) <<
"colMap local id aggToRowMap[agg][k]=" << nonUniqueMapRef.getLocalElement(aggToRowMap[aggStart[agg] + k]) << std::endl;
633 GetOStream(
Runtime1, -1) <<
"fineNS...=" << fineNS[j][nonUniqueMapRef.getLocalElement(aggToRowMap[aggStart[agg] + k])] << std::endl;
634 GetOStream(
Errors, -1) <<
"caught an error!" << std::endl;
642 if (myAggSize >= Teuchos::as<LocalOrdinal>(NSDim)) {
647 SC tau = localQR(0, 0);
652 for (
size_t k = 0; k < Teuchos::as<size_t>(myAggSize); ++k) {
653 Magnitude tmag = STS::magnitude(localQR(k, 0));
654 dtemp += tmag * tmag;
658 localQR(0, 0) = dtemp;
667 for (
size_t j = 0; j < NSDim; ++j) {
668 for (
size_t k = 0; k <= j; ++k) {
670 if (coarseMapRef.isNodeLocalElement(offset + k)) {
671 coarseNS[j][offset + k] = localQR(k, j);
674 GetOStream(
Errors, -1) <<
"caught error in coarseNS insert, j=" << j <<
", offset+k = " << offset + k << std::endl;
688 localQR(i, 0) *= dtemp;
693 for (
size_t j = 0; j < NSDim; j++) {
694 for (
size_t i = 0; i < Teuchos::as<size_t>(myAggSize); i++) {
695 localQR(i, j) = (*qFactor)(i, j);
705 for (
size_t j = 0; j < NSDim; j++)
706 for (
size_t k = 0; k < NSDim; k++) {
708 "Caught error in coarseNS insert, j=" << j <<
", offset+k = " << offset + k);
710 if (k < as<size_t>(myAggSize))
711 coarseNS[j][offset + k] = localQR(k, j);
713 coarseNS[j][offset + k] = (k == j ? one : zero);
717 for (
size_t i = 0; i < as<size_t>(myAggSize); i++)
718 for (
size_t j = 0; j < NSDim; j++)
719 localQR(i, j) = (j == i ? one : zero);
726 for (
GO j = 0; j < myAggSize; ++j) {
730 GO globalRow = aggToRowMap[aggStart[agg] + j];
733 if (rowMapForPtentRef.isNodeGlobalElement(globalRow) ==
false) {
734 ghostQrows[qctr] = globalRow;
735 for (
size_t k = 0; k < NSDim; ++k) {
736 ghostQcols[k][qctr] = coarseMapRef.getGlobalElement(agg * NSDim + k);
737 ghostQvals[k][qctr] = localQR(j, k);
742 for (
size_t k = 0; k < NSDim; ++k) {
745 localColPtr[nnz] = agg * NSDim + k;
746 globalColPtr[nnz] = coarseMapRef.getGlobalElement(localColPtr[nnz]);
747 valPtr[nnz] = localQR(j, k);
752 GetOStream(
Errors, -1) <<
"caught error in colPtr/valPtr insert, current index=" << nnz << std::endl;
757 Ptentative->insertGlobalValues(globalRow, globalColPtr.
view(0, nnz), valPtr.
view(0, nnz));
759 GetOStream(
Errors, -1) <<
"pid " << A->getRowMap()->getComm()->getRank()
760 <<
"caught error during Ptent row insertion, global row "
761 << globalRow << std::endl;
771 GetOStream(
Runtime1) <<
"TentativePFactory : aggregates may cross process boundaries" << std::endl;
775 targetQrowNums->putScalar(-1);
776 targetQrowNums->doImport(*ghostQrowNums, *importer,
Xpetra::INSERT);
777 ArrayRCP<GO> targetQrows = targetQrowNums->getDataNonConst(0);
787 RCP<const Map> reducedMap = MapFactory::Build(A->getRowMap()->lib(),
789 gidsToImport, indexBase, A->getRowMap()->getComm());
792 importer = ImportFactory::Build(ghostQMap, reducedMap);
795 for (
size_t i = 0; i < NSDim; ++i) {
797 targetQcolumns[i]->doImport(*(ghostQcolumns[i]), *importer,
Xpetra::INSERT);
799 RCP<MultiVector> targetQvalues = MultiVectorFactory::Build(reducedMap, NSDim);
800 targetQvalues->doImport(*ghostQvalues, *importer,
Xpetra::INSERT);
804 if (targetQvalues->getLocalLength() > 0) {
805 targetQvals.
resize(NSDim);
806 targetQcols.
resize(NSDim);
807 for (
size_t i = 0; i < NSDim; ++i) {
808 targetQvals[i] = targetQvalues->getDataNonConst(i);
809 targetQcols[i] = targetQcolumns[i]->getDataNonConst(0);
816 if (targetQvalues->getLocalLength() > 0) {
817 for (
size_t j = 0; j < NSDim; ++j) {
818 valPtr[j] = targetQvals[j][reducedMap->getLocalElement(*r)];
819 globalColPtr[j] = targetQcols[j][reducedMap->getLocalElement(*r)];
821 Ptentative->insertGlobalValues(*r, globalColPtr.
view(0, NSDim), valPtr.
view(0, NSDim));
825 Ptentative->fillComplete(coarseMap, A->getDomainMap());
828 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
834 const size_t numRows = rowMap->getLocalNumElements();
837 typedef typename STS::magnitudeType Magnitude;
838 const SC zero = STS::zero();
839 const SC one = STS::one();
843 const size_t NSDim = fineNullspace->getNumVectors();
848 const bool&
doQRStep = pL.
get<
bool>(
"tentative: calculate qr");
849 const bool& constantColSums = pL.
get<
bool>(
"tentative: constant column sums");
852 "MueLu::TentativePFactory::MakeTentative: cannot use 'constant column sums' and 'calculate qr' at the same time");
868 GetOStream(
Runtime1) <<
"Column map is consistent with the row map, good." << std::endl;
872 GetOStream(
Warnings0) <<
"Column map is not consistent with the row map\n"
873 <<
"using GO->LO conversion with performance penalty" << std::endl;
875 coarseNullspace = MultiVectorFactory::Build(coarseMap, NSDim);
880 for (
size_t i = 0; i < NSDim; i++) {
881 fineNS[i] = fineNullspace->getData(i);
882 if (coarseMap->getLocalNumElements() > 0)
883 coarseNS[i] = coarseNullspace->getDataNonConst(i);
886 size_t nnzEstimate = numRows * NSDim;
889 Ptentative =
rcp(
new CrsMatrixWrap(rowMap, coarseMap, 0));
890 RCP<CrsMatrix> PtentCrs = rcp_dynamic_cast<CrsMatrixWrap>(Ptentative)->getCrsMatrix();
896 PtentCrs->allocateAllValues(nnzEstimate, iaPtent, jaPtent, valPtent);
903 for (
size_t i = 1; i <= numRows; i++)
904 ia[i] = ia[i - 1] + NSDim;
906 for (
size_t j = 0; j < nnzEstimate; j++) {
915 for (
GO agg = 0; agg < numAggs; agg++) {
916 LO aggSize = aggStart[agg + 1] - aggStart[agg];
925 for (
size_t j = 0; j < NSDim; j++)
926 for (
LO k = 0; k < aggSize; k++)
927 localQR(k, j) = fineNS[j][aggToRowMapLO[aggStart[agg] + k]];
929 for (
size_t j = 0; j < NSDim; j++)
930 for (
LO k = 0; k < aggSize; k++)
931 localQR(k, j) = fineNS[j][rowMap->getLocalElement(aggToRowMapGO[aggStart[agg] + k])];
935 for (
size_t j = 0; j < NSDim; j++) {
936 bool bIsZeroNSColumn =
true;
938 for (
LO k = 0; k < aggSize; k++)
939 if (localQR(k, j) != zero)
940 bIsZeroNSColumn =
false;
943 "MueLu::TentativePFactory::MakeTentative: fine level NS part has a zero column in NS column " << j);
948 if (aggSize >= Teuchos::as<LO>(NSDim)) {
951 Magnitude norm = STS::magnitude(zero);
952 for (
size_t k = 0; k < Teuchos::as<size_t>(aggSize); k++)
953 norm += STS::magnitude(localQR(k, 0) * localQR(k, 0));
957 coarseNS[0][offset] = norm;
960 for (
LO i = 0; i < aggSize; i++)
961 localQR(i, 0) /= norm;
969 for (
size_t j = 0; j < NSDim; j++)
970 for (
size_t k = 0; k <= j; k++)
971 coarseNS[j][offset + k] = localQR(k, j);
977 for (
size_t j = 0; j < NSDim; j++)
978 for (
size_t i = 0; i < Teuchos::as<size_t>(aggSize); i++)
979 localQR(i, j) = (*qFactor)(i, j);
1010 for (
size_t j = 0; j < NSDim; j++)
1011 for (
size_t k = 0; k < NSDim; k++)
1012 if (k < as<size_t>(aggSize))
1013 coarseNS[j][offset + k] = localQR(k, j);
1015 coarseNS[j][offset + k] = (k == j ? one : zero);
1018 for (
size_t i = 0; i < as<size_t>(aggSize); i++)
1019 for (
size_t j = 0; j < NSDim; j++)
1020 localQR(i, j) = (j == i ? one : zero);
1025 for (
LO j = 0; j < aggSize; j++) {
1026 LO localRow = (goodMap ? aggToRowMapLO[aggStart[agg] + j] : rowMap->getLocalElement(aggToRowMapGO[aggStart[agg] + j]));
1028 size_t rowStart = ia[localRow];
1029 for (
size_t k = 0, lnnz = 0; k < NSDim; k++) {
1031 if (localQR(j, k) != zero) {
1032 ja[rowStart + lnnz] = offset + k;
1033 val[rowStart + lnnz] = localQR(j, k);
1041 GetOStream(
Runtime1) <<
"TentativePFactory : bypassing local QR phase" << std::endl;
1043 GetOStream(
Warnings0) <<
"TentativePFactory : for nontrivial nullspace, this may degrade performance" << std::endl;
1053 for (
GO agg = 0; agg < numAggs; agg++) {
1054 const LO aggSize = aggStart[agg + 1] - aggStart[agg];
1059 for (
LO j = 0; j < aggSize; j++) {
1063 const LO localRow = aggToRowMapLO[aggStart[agg] + j];
1065 const size_t rowStart = ia[localRow];
1067 for (
size_t k = 0, lnnz = 0; k < NSDim; k++) {
1069 SC qr_jk = fineNS[k][aggToRowMapLO[aggStart[agg] + j]];
1070 if (constantColSums) qr_jk = qr_jk / (Magnitude)aggSizes[agg];
1071 if (qr_jk != zero) {
1072 ja[rowStart + lnnz] = offset + k;
1073 val[rowStart + lnnz] = qr_jk;
1078 for (
size_t j = 0; j < NSDim; j++)
1079 coarseNS[j][offset + j] = one;
1083 for (
GO agg = 0; agg < numAggs; agg++) {
1084 const LO aggSize = aggStart[agg + 1] - aggStart[agg];
1086 for (
LO j = 0; j < aggSize; j++) {
1087 const LO localRow = rowMap->getLocalElement(aggToRowMapGO[aggStart[agg] + j]);
1089 const size_t rowStart = ia[localRow];
1091 for (
size_t k = 0, lnnz = 0; k < NSDim; ++k) {
1093 SC qr_jk = fineNS[k][rowMap->getLocalElement(aggToRowMapGO[aggStart[agg] + j])];
1094 if (constantColSums) qr_jk = qr_jk / (Magnitude)aggSizes[agg];
1095 if (qr_jk != zero) {
1096 ja[rowStart + lnnz] = offset + k;
1097 val[rowStart + lnnz] = qr_jk;
1102 for (
size_t j = 0; j < NSDim; j++)
1103 coarseNS[j][offset + j] = one;
1112 size_t ia_tmp = 0, nnz = 0;
1113 for (
size_t i = 0; i < numRows; i++) {
1114 for (
size_t j = ia_tmp; j < ia[i + 1]; j++)
1115 if (ja[j] != INVALID) {
1131 GetOStream(
Runtime1) <<
"TentativePFactory : aggregates do not cross process boundaries" << std::endl;
1133 PtentCrs->setAllValues(iaPtent, jaPtent, valPtent);
1137 if (pL.
isSublist(
"matrixmatrix: kernel params"))
1142 FCparams->
set(
"compute global constants", FCparams->
get(
"compute global constants",
false));
1143 std::string levelIDs =
toString(levelID);
1144 FCparams->
set(
"Timer Label", std::string(
"MueLu::TentativeP-") + levelIDs);
1148 PtentCrs->expertStaticFillComplete(coarseMap, A->getDomainMap(), dummy_i, dummy_e, FCparams);
1155 #define MUELU_TENTATIVEPFACTORY_SHORT
1156 #endif // MUELU_TENTATIVEPFACTORY_DEF_HPP
void BuildPuncoupled(RCP< Matrix > A, RCP< Aggregates > aggregates, RCP< AmalgamationInfo > amalgInfo, RCP< MultiVector > fineNullspace, RCP< const Map > coarseMap, RCP< Matrix > &Ptentative, RCP< MultiVector > &coarseNullspace, const int levelID) const
void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
Important warning messages (one line)
void reserve(size_type n)
MueLu::DefaultLocalOrdinal LocalOrdinal
int setMatrix(const RCP< SerialDenseMatrix< OrdinalType, ScalarType > > &A)
static bool MapsAreNested(const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &rowMap, const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &colMap)
void BuildPcoupled(RCP< Matrix > A, RCP< Aggregates > aggregates, RCP< AmalgamationInfo > amalgInfo, RCP< MultiVector > fineNullspace, RCP< const Map > coarseMap, RCP< Matrix > &Ptentative, RCP< MultiVector > &coarseNullspace) const
std::string toString(const T &what)
Little helper function to convert non-string types to strings.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
void DeclareInput(Level &fineLevel, Level &coarseLevel) const
Input.
KOKKOS_INLINE_FUNCTION LO GetNumAggregates() const
T & get(const std::string &name, T def_value)
void UnamalgamateAggregates(const Aggregates &aggregates, Teuchos::ArrayRCP< LocalOrdinal > &aggStart, Teuchos::ArrayRCP< GlobalOrdinal > &aggToRowMap) const
UnamalgamateAggregates.
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)
Timer to be used in factories. Similar to Monitor but with additional timers.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void UnamalgamateAggregatesLO(const Aggregates &aggregates, Teuchos::ArrayRCP< LocalOrdinal > &aggStart, Teuchos::ArrayRCP< LO > &aggToRowMap) const
static const NoFactory * get()
Print even more statistics.
#define SET_VALID_ENTRY(name)
void resize(const size_type n, const T &val=T())
bool isParameter(const std::string &name) const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Class that holds all level-specific information.
Teuchos::RCP< Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > ComputeUnamalgamatedImportDofMap(const Aggregates &aggregates) const
ComputeUnamalgamatedImportDofMap build overlapping dof row map from aggregates needed for overlapping...
bool isSublist(const std::string &name) const
Teuchos::ArrayRCP< LocalOrdinal > ComputeAggregateSizesArrayRCP(bool forceRecompute=false) const
Compute sizes of aggregates.
void resize(size_type new_size, const value_type &x=value_type())
static std::string PrintMatrixInfo(const Matrix &A, const std::string &msgTag, RCP< const Teuchos::ParameterList > params=Teuchos::null)
static bool isnaninf(const T &x)
static RCP< Vector > Build(const Teuchos::RCP< const Map > &map, bool zeroOut=true)
static magnitudeType magnitude(T a)
void push_back(const value_type &x)
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
void BuildPuncoupledBlockCrs(RCP< Matrix > A, RCP< Aggregates > aggregates, RCP< AmalgamationInfo > amalgInfo, RCP< MultiVector > fineNullspace, RCP< const Map > coarseMap, RCP< Matrix > &Ptentative, RCP< MultiVector > &coarseNullspace, const int levelID) const
int GetLevelID() const
Return level number.
RCP< SerialDenseMatrix< OrdinalType, ScalarType > > getQ() const
Exception throws to report errors in the internal logical of the program.
void BuildP(Level &fineLevel, Level &coarseLevel) const
Abstract Build method.
Description of what is happening (more verbose)
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need's value has been saved.