46 #ifndef MUELU_TENTATIVEPFACTORY_DEF_HPP 47 #define MUELU_TENTATIVEPFACTORY_DEF_HPP 49 #include <Xpetra_MapFactory.hpp> 50 #include <Xpetra_Map.hpp> 51 #include <Xpetra_CrsMatrix.hpp> 52 #include <Xpetra_Matrix.hpp> 53 #include <Xpetra_MultiVector.hpp> 54 #include <Xpetra_MultiVectorFactory.hpp> 55 #include <Xpetra_VectorFactory.hpp> 56 #include <Xpetra_Import.hpp> 57 #include <Xpetra_ImportFactory.hpp> 58 #include <Xpetra_CrsMatrixWrap.hpp> 59 #include <Xpetra_StridedMap.hpp> 60 #include <Xpetra_StridedMapFactory.hpp> 64 #include "MueLu_Aggregates.hpp" 65 #include "MueLu_AmalgamationFactory.hpp" 66 #include "MueLu_AmalgamationInfo.hpp" 67 #include "MueLu_CoarseMapFactory.hpp" 68 #include "MueLu_NullspaceFactory.hpp" 69 #include "MueLu_PerfUtils.hpp" 71 #include "MueLu_Utilities.hpp" 75 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
77 RCP<ParameterList> validParamList = rcp(
new ParameterList());
79 validParamList->set< RCP<const FactoryBase> >(
"A", Teuchos::null,
"Generating factory of the matrix A");
80 validParamList->set< RCP<const FactoryBase> >(
"Aggregates", Teuchos::null,
"Generating factory of the aggregates");
81 validParamList->set< RCP<const FactoryBase> >(
"Nullspace", Teuchos::null,
"Generating factory of the nullspace");
82 validParamList->set< RCP<const FactoryBase> >(
"UnAmalgamationInfo", Teuchos::null,
"Generating factory of UnAmalgamationInfo");
83 validParamList->set< RCP<const FactoryBase> >(
"CoarseMap", Teuchos::null,
"Generating factory of the coarse map");
84 return validParamList;
87 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
89 Input(fineLevel,
"A");
90 Input(fineLevel,
"Aggregates");
91 Input(fineLevel,
"Nullspace");
92 Input(fineLevel,
"UnAmalgamationInfo");
93 Input(fineLevel,
"CoarseMap");
96 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
98 return BuildP(fineLevel, coarseLevel);
101 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
105 RCP<Matrix> A = Get< RCP<Matrix> > (fineLevel,
"A");
106 RCP<Aggregates> aggregates = Get< RCP<Aggregates> > (fineLevel,
"Aggregates");
107 RCP<AmalgamationInfo> amalgInfo = Get< RCP<AmalgamationInfo> >(fineLevel,
"UnAmalgamationInfo");
108 RCP<MultiVector> fineNullspace = Get< RCP<MultiVector> > (fineLevel,
"Nullspace");
109 RCP<const Map> coarseMap = Get< RCP<const Map> > (fineLevel,
"CoarseMap");
111 RCP<Matrix> Ptentative;
112 RCP<MultiVector> coarseNullspace;
113 if (!aggregates->AggregatesCrossProcessors())
114 BuildPuncoupled(A, aggregates, amalgInfo, fineNullspace, coarseMap, Ptentative, coarseNullspace);
116 BuildPcoupled (A, aggregates, amalgInfo, fineNullspace, coarseMap, Ptentative, coarseNullspace);
126 if (A->IsView(
"stridedMaps") ==
true)
127 Ptentative->CreateView(
"stridedMaps", A->getRowMap(
"stridedMaps"), coarseMap);
129 Ptentative->CreateView(
"stridedMaps", Ptentative->getRangeMap(), coarseMap);
131 Set(coarseLevel,
"Nullspace", coarseNullspace);
132 Set(coarseLevel,
"P", Ptentative);
135 RCP<ParameterList> params = rcp(
new ParameterList());
136 params->set(
"printLoadBalancingInfo",
true);
141 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
143 BuildPuncoupled(RCP<Matrix> A, RCP<Aggregates> aggregates, RCP<AmalgamationInfo> amalgInfo, RCP<MultiVector> fineNullspace,
144 RCP<const Map> coarseMap, RCP<Matrix>& Ptentative, RCP<MultiVector>& coarseNullspace)
const {
145 RCP<const Map> rowMap = A->getRowMap();
146 RCP<const Map> colMap = A->getColMap();
148 const size_t numRows = rowMap->getNodeNumElements();
150 RCP<const Teuchos::Comm<int> > comm = rowMap->getComm();
152 typedef Teuchos::ScalarTraits<SC> STS;
153 typedef typename STS::magnitudeType Magnitude;
154 const SC zero = STS::zero();
155 const SC one = STS::one();
156 const LO INVALID = Teuchos::OrdinalTraits<LO>::invalid();
158 const GO numAggs = aggregates->GetNumAggregates();
159 const size_t NSDim = fineNullspace->getNumVectors();
164 bool goodMap = isGoodMap(*rowMap, *colMap);
170 ArrayRCP<LO> aggStart;
171 ArrayRCP<LO> aggToRowMapLO;
172 ArrayRCP<GO> aggToRowMapGO;
174 amalgInfo->UnamalgamateAggregatesLO(*aggregates, aggStart, aggToRowMapLO);
175 GetOStream(
Runtime1) <<
"Column map is consistent with the row map, good." << std::endl;
178 amalgInfo->UnamalgamateAggregates(*aggregates, aggStart, aggToRowMapGO);
179 GetOStream(
Warnings0) <<
"Column map is not consistent with the row map\n" 180 <<
"using GO->LO conversion with performance penalty" << std::endl;
185 for (GO i = 0; i < numAggs; i++)
186 maxAggSize = std::max(maxAggSize, aggStart[i+1] - aggStart[i]);
188 coarseNullspace = MultiVectorFactory::Build(coarseMap, NSDim);
191 ArrayRCP<ArrayRCP<const SC> > fineNS (NSDim);
192 ArrayRCP<ArrayRCP<SC> > coarseNS(NSDim);
193 for (
size_t i = 0; i < NSDim; i++) {
194 fineNS[i] = fineNullspace->getData(i);
195 if (coarseMap->getNodeNumElements() > 0)
196 coarseNS[i] = coarseNullspace->getDataNonConst(i);
199 size_t nnzEstimate = numRows * NSDim;
202 Ptentative = rcp(
new CrsMatrixWrap(rowMap, coarseMap, 0, Xpetra::StaticProfile));
203 RCP<CrsMatrix> PtentCrs = rcp_dynamic_cast<CrsMatrixWrap>(Ptentative)->getCrsMatrix();
205 ArrayRCP<size_t> iaPtent;
206 ArrayRCP<LO> jaPtent;
207 ArrayRCP<SC> valPtent;
209 PtentCrs->allocateAllValues(nnzEstimate, iaPtent, jaPtent, valPtent);
211 ArrayView<size_t> ia = iaPtent();
212 ArrayView<LO> ja = jaPtent();
213 ArrayView<SC> val = valPtent();
216 for (
size_t i = 1; i <= numRows; i++)
217 ia[i] = ia[i-1] + NSDim;
219 for (
size_t j = 0; j < nnzEstimate; j++) {
224 for (GO agg = 0; agg < numAggs; agg++) {
225 LO aggSize = aggStart[agg+1] - aggStart[agg];
227 Xpetra::global_size_t offset = agg*NSDim;
232 Teuchos::SerialDenseMatrix<LO,SC> localQR(aggSize, NSDim);
234 for (
size_t j = 0; j < NSDim; j++)
235 for (LO k = 0; k < aggSize; k++)
236 localQR(k,j) = fineNS[j][aggToRowMapLO[aggStart[agg]+k]];
238 for (
size_t j = 0; j < NSDim; j++)
239 for (LO k = 0; k < aggSize; k++)
240 localQR(k,j) = fineNS[j][rowMap->getLocalElement(aggToRowMapGO[aggStart[agg]+k])];
244 for (
size_t j = 0; j < NSDim; j++) {
245 bool bIsZeroNSColumn =
true;
247 for (LO k = 0; k < aggSize; k++)
248 if (localQR(k,j) != zero)
249 bIsZeroNSColumn =
false;
252 "MueLu::TentativePFactory::MakeTentative: fine level NS part has a zero column");
257 if (aggSize >= Teuchos::as<LO>(NSDim)) {
261 Magnitude norm = STS::magnitude(zero);
262 for (
size_t k = 0; k < Teuchos::as<size_t>(aggSize); k++)
263 norm += STS::magnitude(localQR(k,0)*localQR(k,0));
264 norm = Teuchos::ScalarTraits<Magnitude>::squareroot(norm);
267 coarseNS[0][offset] = norm;
270 for (LO i = 0; i < aggSize; i++)
271 localQR(i,0) /= norm;
274 Teuchos::SerialQRDenseSolver<LO,SC> qrSolver;
275 qrSolver.setMatrix(Teuchos::rcp(&localQR,
false));
279 for (
size_t j = 0; j < NSDim; j++)
280 for (
size_t k = 0; k <= j; k++)
281 coarseNS[j][offset+k] = localQR(k,j);
286 Teuchos::RCP<Teuchos::SerialDenseMatrix<LO,SC> > qFactor = qrSolver.getQ();
287 for (
size_t j = 0; j < NSDim; j++)
288 for (
size_t i = 0; i < Teuchos::as<size_t>(aggSize); i++)
289 localQR(i,j) = (*qFactor)(i,j);
320 for (
size_t j = 0; j < NSDim; j++)
321 for (
size_t k = 0; k < NSDim; k++)
322 if (k < as<size_t>(aggSize))
323 coarseNS[j][offset+k] = localQR(k,j);
325 coarseNS[j][offset+k] = (k == j ? one : zero);
328 for (
size_t i = 0; i < as<size_t>(aggSize); i++)
329 for (
size_t j = 0; j < NSDim; j++)
330 localQR(i,j) = (j == i ? one : zero);
335 for (LO j = 0; j < aggSize; j++) {
336 LO localRow = (goodMap ? aggToRowMapLO[aggStart[agg]+j] : rowMap->getLocalElement(aggToRowMapGO[aggStart[agg]+j]));
338 size_t rowStart = ia[localRow];
339 for (
size_t k = 0, lnnz = 0; k < NSDim; k++) {
341 if (localQR(j,k) != zero) {
342 ja [rowStart+lnnz] = offset + k;
343 val[rowStart+lnnz] = localQR(j,k);
352 size_t ia_tmp = 0, nnz = 0;
353 for (
size_t i = 0; i < numRows; i++) {
354 for (
size_t j = ia_tmp; j < ia[i+1]; j++)
355 if (ja[j] != INVALID) {
363 if (rowMap->lib() == Xpetra::UseTpetra) {
367 jaPtent .resize(nnz);
368 valPtent.resize(nnz);
371 GetOStream(
Runtime1) <<
"TentativePFactory : aggregates do not cross process boundaries" << std::endl;
373 PtentCrs->setAllValues(iaPtent, jaPtent, valPtent);
374 PtentCrs->expertStaticFillComplete(coarseMap, A->getDomainMap());
377 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
379 BuildPcoupled(RCP<Matrix> A, RCP<Aggregates> aggregates, RCP<AmalgamationInfo> amalgInfo, RCP<MultiVector> fineNullspace,
380 RCP<const Map> coarseMap, RCP<Matrix>& Ptentative, RCP<MultiVector>& coarseNullspace)
const {
381 RCP<const Teuchos::Comm<int> > comm = A->getRowMap()->getComm();
383 typedef Teuchos::ScalarTraits<SC> STS;
384 typedef typename STS::magnitudeType Magnitude;
385 const SC zero = STS::zero();
386 const SC one = STS::one();
389 GO numAggs = aggregates->GetNumAggregates();
395 ArrayRCP<LO> aggStart;
396 ArrayRCP< GO > aggToRowMap;
397 amalgInfo->UnamalgamateAggregates(*aggregates, aggStart, aggToRowMap);
401 for (GO i=0; i<numAggs; ++i) {
402 LO sizeOfThisAgg = aggStart[i+1] - aggStart[i];
403 if (sizeOfThisAgg > maxAggSize) maxAggSize = sizeOfThisAgg;
407 const size_t NSDim = fineNullspace->getNumVectors();
410 GO indexBase=A->getRowMap()->getIndexBase();
412 const RCP<const Map> nonUniqueMap = amalgInfo->ComputeUnamalgamatedImportDofMap(*aggregates);
413 const RCP<const Map> uniqueMap = A->getDomainMap();
414 RCP<const Import> importer = ImportFactory::Build(uniqueMap, nonUniqueMap);
415 RCP<MultiVector> fineNullspaceWithOverlap = MultiVectorFactory::Build(nonUniqueMap,NSDim);
416 fineNullspaceWithOverlap->doImport(*fineNullspace,*importer,Xpetra::INSERT);
419 ArrayRCP< ArrayRCP<const SC> > fineNS(NSDim);
420 for (
size_t i=0; i<NSDim; ++i)
421 fineNS[i] = fineNullspaceWithOverlap->getData(i);
424 coarseNullspace = MultiVectorFactory::Build(coarseMap, NSDim);
426 ArrayRCP< ArrayRCP<SC> > coarseNS(NSDim);
427 for (
size_t i=0; i<NSDim; ++i)
428 if (coarseMap->getNodeNumElements() > 0) coarseNS[i] = coarseNullspace->getDataNonConst(i);
433 RCP<const Map > rowMapForPtent = A->getRowMap();
434 const Map& rowMapForPtentRef = *rowMapForPtent;
438 RCP<const Map> colMap = A->getColMap();
440 RCP<const Map > ghostQMap;
441 RCP<MultiVector> ghostQvalues;
442 Array<RCP<Xpetra::Vector<GO,LO,GO,Node> > > ghostQcolumns;
443 RCP<Xpetra::Vector<GO,LO,GO,Node> > ghostQrowNums;
444 ArrayRCP< ArrayRCP<SC> > ghostQvals;
445 ArrayRCP< ArrayRCP<GO> > ghostQcols;
446 ArrayRCP< GO > ghostQrows;
449 for (LO j=0; j<numAggs; ++j) {
450 for (LO k=aggStart[j]; k<aggStart[j+1]; ++k) {
451 if (rowMapForPtentRef.isNodeGlobalElement(aggToRowMap[k]) ==
false) {
452 ghostGIDs.push_back(aggToRowMap[k]);
456 ghostQMap = MapFactory::Build(A->getRowMap()->lib(),
457 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
459 indexBase, A->getRowMap()->getComm());
461 ghostQvalues = MultiVectorFactory::Build(ghostQMap,NSDim);
465 ghostQcolumns.resize(NSDim);
466 for (
size_t i=0; i<NSDim; ++i)
467 ghostQcolumns[i] = Xpetra::VectorFactory<GO,LO,GO,Node>::Build(ghostQMap);
468 ghostQrowNums = Xpetra::VectorFactory<GO,LO,GO,Node>::Build(ghostQMap);
469 if (ghostQvalues->getLocalLength() > 0) {
470 ghostQvals.resize(NSDim);
471 ghostQcols.resize(NSDim);
472 for (
size_t i=0; i<NSDim; ++i) {
473 ghostQvals[i] = ghostQvalues->getDataNonConst(i);
474 ghostQcols[i] = ghostQcolumns[i]->getDataNonConst(0);
476 ghostQrows = ghostQrowNums->getDataNonConst(0);
480 importer = ImportFactory::Build(ghostQMap, A->getRowMap());
483 Teuchos::SerialQRDenseSolver<LO,SC> qrSolver;
486 Array<GO> globalColPtr(maxAggSize*NSDim,0);
487 Array<LO> localColPtr(maxAggSize*NSDim,0);
488 Array<SC> valPtr(maxAggSize*NSDim,0.);
491 const Map& coarseMapRef = *coarseMap;
494 ArrayRCP<size_t> ptent_rowptr;
495 ArrayRCP<LO> ptent_colind;
496 ArrayRCP<Scalar> ptent_values;
499 ArrayView<size_t> rowptr_v;
500 ArrayView<LO> colind_v;
501 ArrayView<Scalar> values_v;
504 Array<size_t> rowptr_temp;
505 Array<LO> colind_temp;
506 Array<Scalar> values_temp;
508 RCP<CrsMatrix> PtentCrs;
510 RCP<CrsMatrixWrap> PtentCrsWrap = rcp(
new CrsMatrixWrap(rowMapForPtent, NSDim, Xpetra::StaticProfile));
511 PtentCrs = PtentCrsWrap->getCrsMatrix();
512 Ptentative = PtentCrsWrap;
518 const Map& nonUniqueMapRef = *nonUniqueMap;
520 size_t total_nnz_count=0;
522 for (GO agg=0; agg<numAggs; ++agg)
524 LO myAggSize = aggStart[agg+1]-aggStart[agg];
527 Teuchos::SerialDenseMatrix<LO,SC> localQR(myAggSize, NSDim);
528 for (
size_t j=0; j<NSDim; ++j) {
529 bool bIsZeroNSColumn =
true;
530 for (LO k=0; k<myAggSize; ++k)
535 SC nsVal = fineNS[j][ nonUniqueMapRef.getLocalElement(aggToRowMap[aggStart[agg]+k]) ];
536 localQR(k,j) = nsVal;
537 if (nsVal != zero) bIsZeroNSColumn =
false;
540 GetOStream(
Runtime1,-1) <<
"length of fine level nsp: " << fineNullspace->getGlobalLength() << std::endl;
541 GetOStream(
Runtime1,-1) <<
"length of fine level nsp w overlap: " << fineNullspaceWithOverlap->getGlobalLength() << std::endl;
542 GetOStream(
Runtime1,-1) <<
"(local?) aggId=" << agg << std::endl;
543 GetOStream(
Runtime1,-1) <<
"aggSize=" << myAggSize << std::endl;
544 GetOStream(
Runtime1,-1) <<
"agg DOF=" << k << std::endl;
545 GetOStream(
Runtime1,-1) <<
"NS vector j=" << j << std::endl;
546 GetOStream(
Runtime1,-1) <<
"j*myAggSize + k = " << j*myAggSize + k << std::endl;
547 GetOStream(
Runtime1,-1) <<
"aggToRowMap["<<agg<<
"][" << k <<
"] = " << aggToRowMap[aggStart[agg]+k] << std::endl;
548 GetOStream(
Runtime1,-1) <<
"id aggToRowMap[agg][k]=" << aggToRowMap[aggStart[agg]+k] <<
" is global element in nonUniqueMap = " <<
549 nonUniqueMapRef.isNodeGlobalElement(aggToRowMap[aggStart[agg]+k]) << std::endl;
550 GetOStream(
Runtime1,-1) <<
"colMap local id aggToRowMap[agg][k]=" << nonUniqueMapRef.getLocalElement(aggToRowMap[aggStart[agg]+k]) << std::endl;
551 GetOStream(
Runtime1,-1) <<
"fineNS...=" << fineNS[j][ nonUniqueMapRef.getLocalElement(aggToRowMap[aggStart[agg]+k]) ] << std::endl;
552 GetOStream(
Errors,-1) <<
"caught an error!" << std::endl;
555 TEUCHOS_TEST_FOR_EXCEPTION(bIsZeroNSColumn ==
true,
Exceptions::RuntimeError,
"MueLu::TentativePFactory::MakeTentative: fine level NS part has a zero column. Error.");
558 Xpetra::global_size_t offset=agg*NSDim;
560 if(myAggSize >= Teuchos::as<LocalOrdinal>(NSDim)) {
565 SC tau = localQR(0,0);
570 for (
size_t k = 0; k < Teuchos::as<size_t>(myAggSize); ++k) {
571 Magnitude tmag = STS::magnitude(localQR(k,0));
574 dtemp = Teuchos::ScalarTraits<Magnitude>::squareroot(dtemp);
576 localQR(0,0) = dtemp;
578 qrSolver.setMatrix( Teuchos::rcp(&localQR,
false) );
585 for (
size_t j=0; j<NSDim; ++j) {
586 for (
size_t k=0; k<=j; ++k) {
588 if (coarseMapRef.isNodeLocalElement(offset+k)) {
589 coarseNS[j][offset+k] = localQR(k, j);
593 GetOStream(
Errors,-1) <<
"caught error in coarseNS insert, j="<<j<<
", offset+k = "<<offset+k<<std::endl;
603 Magnitude dtemp = Teuchos::ScalarTraits<SC>::magnitude(localQR(0,0));
606 for (LocalOrdinal i=0; i<myAggSize; ++i) {
607 localQR(i,0) *= dtemp ;
611 Teuchos::RCP<Teuchos::SerialDenseMatrix<LO,SC> > qFactor = qrSolver.getQ();
612 for (
size_t j=0; j<NSDim; j++) {
613 for (
size_t i = 0; i < Teuchos::as<size_t>(myAggSize); i++) {
614 localQR(i,j) = (*qFactor)(i,j);
624 for (
size_t j = 0; j < NSDim; j++)
625 for (
size_t k = 0; k < NSDim; k++) {
627 "Caught error in coarseNS insert, j=" << j <<
", offset+k = " << offset+k);
629 if (k < as<size_t>(myAggSize))
630 coarseNS[j][offset+k] = localQR(k,j);
632 coarseNS[j][offset+k] = (k == j ? one : zero);
636 for (
size_t i = 0; i < as<size_t>(myAggSize); i++)
637 for (
size_t j = 0; j < NSDim; j++)
638 localQR(i,j) = (j == i ? one : zero);
645 for (GO j=0; j<myAggSize; ++j) {
649 GO globalRow = aggToRowMap[aggStart[agg]+j];
652 if (rowMapForPtentRef.isNodeGlobalElement(globalRow) == false ) {
653 ghostQrows[qctr] = globalRow;
654 for (
size_t k=0; k<NSDim; ++k) {
655 ghostQcols[k][qctr] = coarseMapRef.getGlobalElement(agg*NSDim+k);
656 ghostQvals[k][qctr] = localQR(j,k);
661 for (
size_t k=0; k<NSDim; ++k) {
663 if (localQR(j,k) != Teuchos::ScalarTraits<SC>::zero()) {
664 localColPtr[nnz] = agg * NSDim + k;
665 globalColPtr[nnz] = coarseMapRef.getGlobalElement(localColPtr[nnz]);
666 valPtr[nnz] = localQR(j,k);
672 GetOStream(
Errors,-1) <<
"caught error in colPtr/valPtr insert, current index="<<nnz<<std::endl;
677 Ptentative->insertGlobalValues(globalRow,globalColPtr.view(0,nnz),valPtr.view(0,nnz));
680 GetOStream(
Errors,-1) <<
"pid " << A->getRowMap()->getComm()->getRank()
681 <<
"caught error during Ptent row insertion, global row " 682 << globalRow << std::endl;
693 GetOStream(
Runtime1) <<
"TentativePFactory : aggregates may cross process boundaries" << std::endl;
696 RCP<Xpetra::Vector<GO,LO,GO,Node> > targetQrowNums = Xpetra::VectorFactory<GO,LO,GO,Node>::Build(rowMapForPtent);
697 targetQrowNums->putScalar(-1);
698 targetQrowNums->doImport(*ghostQrowNums,*importer,Xpetra::INSERT);
699 ArrayRCP< GO > targetQrows = targetQrowNums->getDataNonConst(0);
702 Array<GO> gidsToImport;
703 gidsToImport.reserve(targetQrows.size());
704 for (
typename ArrayRCP<GO>::iterator r=targetQrows.begin(); r!=targetQrows.end(); ++r) {
706 gidsToImport.push_back(*r);
709 RCP<const Map > reducedMap = MapFactory::Build( A->getRowMap()->lib(),
710 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
711 gidsToImport, indexBase, A->getRowMap()->getComm() );
714 importer = ImportFactory::Build(ghostQMap, reducedMap);
716 Array<RCP<Xpetra::Vector<GO,LO,GO,Node> > > targetQcolumns(NSDim);
717 for (
size_t i=0; i<NSDim; ++i) {
718 targetQcolumns[i] = Xpetra::VectorFactory<GO,LO,GO,Node>::Build(reducedMap);
719 targetQcolumns[i]->doImport(*(ghostQcolumns[i]),*importer,Xpetra::INSERT);
721 RCP<MultiVector> targetQvalues = MultiVectorFactory::Build(reducedMap,NSDim);
722 targetQvalues->doImport(*ghostQvalues,*importer,Xpetra::INSERT);
724 ArrayRCP< ArrayRCP<SC> > targetQvals;
725 ArrayRCP<ArrayRCP<GO> > targetQcols;
726 if (targetQvalues->getLocalLength() > 0) {
727 targetQvals.resize(NSDim);
728 targetQcols.resize(NSDim);
729 for (
size_t i=0; i<NSDim; ++i) {
730 targetQvals[i] = targetQvalues->getDataNonConst(i);
731 targetQcols[i] = targetQcolumns[i]->getDataNonConst(0);
735 valPtr = Array<SC>(NSDim,0.);
736 globalColPtr = Array<GO>(NSDim,0);
737 for (
typename Array<GO>::iterator r=gidsToImport.begin(); r!=gidsToImport.end(); ++r) {
738 if (targetQvalues->getLocalLength() > 0) {
739 for (
size_t j=0; j<NSDim; ++j) {
740 valPtr[j] = targetQvals[j][reducedMap->getLocalElement(*r)];
741 globalColPtr[j] = targetQcols[j][reducedMap->getLocalElement(*r)];
743 Ptentative->insertGlobalValues(*r, globalColPtr.view(0,NSDim), valPtr.view(0,NSDim));
747 Ptentative->fillComplete(coarseMap, A->getDomainMap());
750 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
752 ArrayView<const GO> rowElements = rowMap.getNodeElementList();
753 ArrayView<const GO> colElements = colMap.getNodeElementList();
755 const size_t numElements = rowElements.size();
758 for (
size_t i = 0; i < numElements; i++)
759 if (rowElements[i] != colElements[i]) {
771 #define MUELU_TENTATIVEPFACTORY_SHORT 772 #endif // MUELU_TENTATIVEPFACTORY_DEF_HPP void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
Important warning messages (one line)
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
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.
Timer to be used in factories. Similar to Monitor but with additional timers.
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
Namespace for MueLu classes and methods.
Class that holds all level-specific information.
static std::string PrintMatrixInfo(const Matrix &A, const std::string &msgTag, RCP< const Teuchos::ParameterList > params=Teuchos::null)
bool isGoodMap(const Map &rowMap, const Map &colMap) 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)