44 BuildPermutation(
const Teuchos::RCP<Matrix>& A,
const Teuchos::RCP<const Map>& permRowMap,
46 const Scalar SC_ZERO = Teuchos::ScalarTraits<Scalar>::zero();
47 const Scalar SC_ONE = Teuchos::ScalarTraits<Scalar>::one();
49 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType MT;
50 const MT MT_ZERO = Teuchos::ScalarTraits<MT>::zero();
51 const MT MT_ONE = Teuchos::ScalarTraits<MT>::one();
53 const Teuchos::RCP<const Teuchos::Comm<int> > comm = A->getRowMap()->getComm();
54 int numProcs = comm->getSize();
55 int myRank = comm->getRank();
57 size_t nDofsPerNode = 1;
58 if (A->IsView(
"stridedMaps")) {
59 Teuchos::RCP<const Map> permRowMapStrided = A->getRowMap(
"stridedMaps");
60 nDofsPerNode = Teuchos::rcp_dynamic_cast<const StridedMap>(permRowMapStrided)->getFixedBlockSize();
63 std::vector<std::pair<GlobalOrdinal, GlobalOrdinal> > permutedDiagCandidates;
64 std::vector<std::pair<GlobalOrdinal, GlobalOrdinal> > keepDiagonalEntries;
65 std::vector<MT> Weights;
69 for (
size_t row = 0; row < A->getRowMap()->getLocalNumElements(); row++) {
72 if (permRowMap->isNodeGlobalElement(grow) ==
true)
continue;
74 size_t nnz = A->getNumEntriesInLocalRow(row);
77 Teuchos::ArrayView<const LocalOrdinal> indices;
78 Teuchos::ArrayView<const Scalar> vals;
79 A->getLocalRowView(row, indices, vals);
82 "MueLu::PermutationFactory::Build: number of nonzeros not equal to number of indices? Error.");
88 for (
size_t j = 0; j < Teuchos::as<size_t>(indices.size()); j++) {
89 norm1 += Teuchos::ScalarTraits<Scalar>::magnitude(vals[j]);
90 if (Teuchos::ScalarTraits<Scalar>::magnitude(vals[j]) > maxVal) {
91 maxVal = Teuchos::ScalarTraits<Scalar>::magnitude(vals[j]);
92 gMaxValIdx = A->getColMap()->getGlobalElement(indices[j]);
96 if (grow == gMaxValIdx)
97 keepDiagonalEntries.push_back(std::make_pair(grow, grow));
102 for (
size_t row = 0; row < permRowMap->getLocalNumElements(); row++) {
104 LocalOrdinal lArow = A->getRowMap()->getLocalElement(grow);
105 size_t nnz = A->getNumEntriesInLocalRow(lArow);
108 Teuchos::ArrayView<const LocalOrdinal> indices;
109 Teuchos::ArrayView<const Scalar> vals;
110 A->getLocalRowView(lArow, indices, vals);
113 "MueLu::PermutationFactory::Build: number of nonzeros not equal to number of indices? Error.");
119 for (
size_t j = 0; j < Teuchos::as<size_t>(indices.size()); j++) {
120 norm1 += Teuchos::ScalarTraits<Scalar>::magnitude(vals[j]);
121 if (Teuchos::ScalarTraits<Scalar>::magnitude(vals[j]) > maxVal) {
122 maxVal = Teuchos::ScalarTraits<Scalar>::magnitude(vals[j]);
123 gMaxValIdx = A->getColMap()->getGlobalElement(indices[j]);
127 if (maxVal > Teuchos::ScalarTraits<MT>::zero()) {
128 permutedDiagCandidates.push_back(std::make_pair(grow, gMaxValIdx));
129 Weights.push_back(maxVal / (norm1 * Teuchos::as<MT>(nnz)));
131 std::cout <<
"ATTENTION: row " << grow <<
" has only zero entries -> singular matrix!" << std::endl;
136 std::vector<int> permutation;
145 Teuchos::RCP<Vector> gColVec = VectorFactory::Build(A->getColMap());
146 Teuchos::RCP<Vector> gDomVec = VectorFactory::Build(A->getDomainMap());
147 gColVec->putScalar(SC_ZERO);
148 gDomVec->putScalar(SC_ZERO);
151 for (
typename std::vector<std::pair<GlobalOrdinal, GlobalOrdinal> >::const_iterator p = keepDiagonalEntries.begin(); p != keepDiagonalEntries.end(); ++p) {
152 gColVec->sumIntoGlobalValue((*p).second, 1.0);
155 Teuchos::RCP<Export> exporter = ExportFactory::Build(gColVec->getMap(), gDomVec->getMap());
156 gDomVec->doExport(*gColVec, *exporter, Xpetra::ADD);
157 gColVec->doImport(*gDomVec, *exporter, Xpetra::INSERT);
159 std::vector<std::pair<GlobalOrdinal, GlobalOrdinal> > permutedDiagCandidatesFiltered;
160 std::map<GlobalOrdinal, MT> gColId2Weight;
163 Teuchos::ArrayRCP<Scalar> ddata = gColVec->getDataNonConst(0);
164 for (
size_t i = 0; i < permutedDiagCandidates.size(); ++i) {
166 std::pair<GlobalOrdinal, GlobalOrdinal> pp = permutedDiagCandidates[permutation[i]];
170 LocalOrdinal lcol = A->getColMap()->getLocalElement(gcol);
171 if (Teuchos::ScalarTraits<Scalar>::real(ddata[lcol]) > MT_ZERO) {
176 ddata[lcol] += SC_ONE;
178 permutedDiagCandidatesFiltered.push_back(std::make_pair(grow, gcol));
179 gColId2Weight[gcol] = Weights[permutation[i]];
184 gDomVec->doExport(*gColVec, *exporter, Xpetra::ADD);
185 gColVec->doImport(*gDomVec, *exporter, Xpetra::INSERT);
192 std::vector<GlobalOrdinal> multipleColRequests;
196 std::queue<GlobalOrdinal> unusedColIdx;
198 for (
size_t sz = 0; sz < gDomVec->getLocalLength(); ++sz) {
199 Teuchos::ArrayRCP<const Scalar> arrDomVec = gDomVec->getData(0);
205 if (Teuchos::ScalarTraits<Scalar>::real(arrDomVec[sz]) > MT_ONE) {
206 multipleColRequests.push_back(gDomVec->getMap()->getGlobalElement(sz));
207 }
else if (Teuchos::ScalarTraits<Scalar>::real(arrDomVec[sz]) == MT_ZERO) {
208 unusedColIdx.push(gDomVec->getMap()->getGlobalElement(sz));
213 LocalOrdinal localMultColRequests = Teuchos::as<LocalOrdinal>(multipleColRequests.size());
223 if (globalMultColRequests > 0) {
229 std::vector<GlobalOrdinal> numMyMultColRequests(numProcs, 0);
230 std::vector<GlobalOrdinal> numGlobalMultColRequests(numProcs, 0);
231 numMyMultColRequests[myRank] = localMultColRequests;
232 Teuchos::reduceAll(*comm, Teuchos::REDUCE_MAX, numProcs,
233 numMyMultColRequests.data(),
234 numGlobalMultColRequests.data());
238 for (
int i = 0; i < myRank - 1; i++)
239 nMyOffset += numGlobalMultColRequests[i];
242 std::vector<GlobalOrdinal> procMultRequestedColIds(globalMultColRequests, zero);
243 std::vector<GlobalOrdinal> global_procMultRequestedColIds(globalMultColRequests, zero);
246 for (
size_t i = 0; i < multipleColRequests.size(); i++) {
247 procMultRequestedColIds[nMyOffset + i] = multipleColRequests[i];
251 Teuchos::reduceAll(*comm, Teuchos::REDUCE_MAX, Teuchos::as<int>(globalMultColRequests),
252 procMultRequestedColIds.data(),
253 global_procMultRequestedColIds.data());
256 for (
size_t k = 0; k < global_procMultRequestedColIds.size(); k++) {
259 std::vector<MT> MyWeightForColId(numProcs, MT_ZERO);
260 std::vector<MT> GlobalWeightForColId(numProcs, MT_ZERO);
262 if (gColVec->getMap()->isNodeGlobalElement(globColId)) {
263 MyWeightForColId[myRank] = gColId2Weight[globColId];
265 MyWeightForColId[myRank] = MT_ZERO;
268 Teuchos::reduceAll(*comm, Teuchos::REDUCE_MAX, numProcs,
269 MyWeightForColId.data(),
270 GlobalWeightForColId.data());
272 if (gColVec->getMap()->isNodeGlobalElement(globColId)) {
275 MT winnerValue = MT_ZERO;
276 int winnerProcRank = 0;
277 for (
int proc = 0; proc < numProcs; proc++) {
278 if (GlobalWeightForColId[proc] > winnerValue) {
279 winnerValue = GlobalWeightForColId[proc];
280 winnerProcRank = proc;
287 if (myRank != winnerProcRank) {
289 typename std::vector<std::pair<GlobalOrdinal, GlobalOrdinal> >::iterator p = permutedDiagCandidatesFiltered.begin();
290 while (p != permutedDiagCandidatesFiltered.end()) {
291 if ((*p).second == globColId)
292 p = permutedDiagCandidatesFiltered.erase(p);
304 std::vector<std::pair<GlobalOrdinal, GlobalOrdinal> > RowColPairs;
305 RowColPairs.insert(RowColPairs.end(), keepDiagonalEntries.begin(), keepDiagonalEntries.end());
306 RowColPairs.insert(RowColPairs.end(), permutedDiagCandidatesFiltered.begin(), permutedDiagCandidatesFiltered.end());
311 gColVec->putScalar(SC_ZERO);
312 gDomVec->putScalar(SC_ZERO);
313 typename std::vector<std::pair<GlobalOrdinal, GlobalOrdinal> >::iterator pl = RowColPairs.begin();
314 while (pl != RowColPairs.end()) {
318 gColVec->sumIntoGlobalValue(jk, 1.0);
321 gDomVec->doExport(*gColVec, *exporter, Xpetra::ADD);
322 for (
size_t sz = 0; sz < gDomVec->getLocalLength(); ++sz) {
323 Teuchos::ArrayRCP<const Scalar> arrDomVec = gDomVec->getData(0);
324 if (arrDomVec[sz] > 1.0) {
325 GetOStream(
Runtime0) <<
"RowColPairs has multiple column [" << sz <<
"]=" << arrDomVec[sz] << std::endl;
326 }
else if (arrDomVec[sz] == SC_ZERO) {
327 GetOStream(
Runtime0) <<
"RowColPairs has empty column [" << sz <<
"]=" << arrDomVec[sz] << std::endl;
360 Teuchos::RCP<Vector> Pperm = VectorFactory::Build(A->getRowMap());
361 Teuchos::RCP<Vector> Qperm = VectorFactory::Build(A->getDomainMap());
362 Teuchos::RCP<Vector> lQperm = VectorFactory::Build(A->getColMap());
364 Pperm->putScalar(SC_ZERO);
365 Qperm->putScalar(SC_ZERO);
366 lQperm->putScalar(SC_ZERO);
369 Teuchos::RCP<Export> QpermExporter = ExportFactory::Build(lQperm->getMap(), Qperm->getMap());
371 Teuchos::RCP<Vector> RowIdStatus = VectorFactory::Build(A->getRowMap());
372 Teuchos::RCP<Vector> ColIdStatus = VectorFactory::Build(A->getDomainMap());
373 Teuchos::RCP<Vector> lColIdStatus = VectorFactory::Build(A->getColMap());
374 Teuchos::RCP<Vector> ColIdUsed = VectorFactory::Build(A->getDomainMap());
375 RowIdStatus->putScalar(SC_ZERO);
376 ColIdStatus->putScalar(SC_ZERO);
377 lColIdStatus->putScalar(SC_ZERO);
378 ColIdUsed->putScalar(SC_ZERO);
390 Teuchos::ArrayRCP<Scalar> RowIdStatusArray = RowIdStatus->getDataNonConst(0);
391 Teuchos::ArrayRCP<Scalar> lColIdStatusArray = lColIdStatus->getDataNonConst(0);
393 typename std::vector<std::pair<GlobalOrdinal, GlobalOrdinal> >::iterator p = RowColPairs.begin();
394 while (p != RowColPairs.end()) {
401 if (RowIdStatusArray[lik] == SC_ZERO) {
402 RowIdStatusArray[lik] = SC_ONE;
403 lColIdStatusArray[ljk] = SC_ONE;
404 Pperm->replaceLocalValue(lik, ik);
405 lQperm->replaceLocalValue(ljk, ik);
406 ColIdUsed->replaceGlobalValue(ik, SC_ONE);
407 p = RowColPairs.erase(p);
410 if (floor(ik / nDofsPerNode) != floor(jk / nDofsPerNode)) {
411 lWideRangeColPermutations++;
418 Qperm->doExport(*lQperm, *QpermExporter, Xpetra::ABSMAX);
419 ColIdStatus->doExport(*lColIdStatus, *QpermExporter, Xpetra::ABSMAX);
422 if (RowColPairs.size() > 0) GetOStream(
Warnings0) <<
"MueLu::PermutationFactory: There are Row/Col pairs left!!!" << std::endl;
427 size_t cntFreeRowIdx = 0;
428 std::queue<GlobalOrdinal> qFreeGRowIdx;
429 for (
size_t lik = 0; lik < RowIdStatus->getLocalLength(); ++lik) {
430 if (RowIdStatusArray[lik] == SC_ZERO) {
432 qFreeGRowIdx.push(RowIdStatus->getMap()->getGlobalElement(lik));
437 for (
size_t lik = 0; lik < RowIdStatus->getLocalLength(); ++lik) {
438 if (RowIdStatusArray[lik] == SC_ZERO) {
439 RowIdStatusArray[lik] = SC_ONE;
440 Pperm->replaceLocalValue(lik, qFreeGRowIdx.front());
442 if (floor(qFreeGRowIdx.front() / nDofsPerNode) != floor(RowIdStatus->getMap()->getGlobalElement(lik) / nDofsPerNode)) {
443 lWideRangeRowPermutations++;
450 size_t cntUnusedColIdx = 0;
451 std::queue<GlobalOrdinal> qUnusedGColIdx;
452 size_t cntFreeColIdx = 0;
453 std::queue<GlobalOrdinal> qFreeGColIdx;
455 Teuchos::ArrayRCP<Scalar> ColIdStatusArray = ColIdStatus->getDataNonConst(0);
456 Teuchos::ArrayRCP<Scalar> ColIdUsedArray = ColIdUsed->getDataNonConst(0);
459 for (
size_t ljk = 0; ljk < ColIdStatus->getLocalLength(); ++ljk) {
460 if (ColIdStatusArray[ljk] == SC_ZERO) {
462 qFreeGColIdx.push(ColIdStatus->getMap()->getGlobalElement(ljk));
466 for (
size_t ljk = 0; ljk < ColIdUsed->getLocalLength(); ++ljk) {
467 if (ColIdUsedArray[ljk] == SC_ZERO) {
469 qUnusedGColIdx.push(ColIdUsed->getMap()->getGlobalElement(ljk));
474 for (
size_t ljk = 0; ljk < ColIdStatus->getLocalLength(); ++ljk) {
476 if (cntUnusedColIdx == 0)
break;
478 if (ColIdStatusArray[ljk] == SC_ZERO) {
479 ColIdStatusArray[ljk] = SC_ONE;
480 Qperm->replaceLocalValue(ljk, qUnusedGColIdx.front());
481 ColIdUsed->replaceGlobalValue(qUnusedGColIdx.front(), SC_ONE);
483 if (floor(qUnusedGColIdx.front() / nDofsPerNode) != floor(ColIdStatus->getMap()->getGlobalElement(ljk) / nDofsPerNode)) {
484 lWideRangeColPermutations++;
486 qUnusedGColIdx.pop();
498 for (
size_t ljk = 0; ljk < ColIdStatus->getLocalLength(); ++ljk) {
499 if (ColIdStatusArray[ljk] == SC_ZERO) {
507 MueLu_sumAll(comm, Teuchos::as<GlobalOrdinal>(local_cntFreeColIdx), global_cntFreeColIdx);
509 std::cout <<
"global # of empty column idx entries in Qperm: " << global_cntFreeColIdx << std::endl;
513 if (global_cntFreeColIdx > 0) {
517 MueLu_sumAll(comm, Teuchos::as<GlobalOrdinal>(local_cntUnusedColIdx), global_cntUnusedColIdx);
519 std::cout <<
"global # of unused column idx: " << global_cntUnusedColIdx << std::endl;
523 std::vector<LocalOrdinal> local_UnusedColIdxOnProc(numProcs);
524 std::vector<LocalOrdinal> global_UnusedColIdxOnProc(numProcs);
525 local_UnusedColIdxOnProc[myRank] = local_cntUnusedColIdx;
526 Teuchos::reduceAll(*comm, Teuchos::REDUCE_MAX, numProcs,
527 local_UnusedColIdxOnProc.data(),
528 global_UnusedColIdxOnProc.data());
531 std::cout <<
"PROC " << myRank <<
" global num unused indices per proc: ";
532 for (
size_t ljk = 0; ljk < global_UnusedColIdxOnProc.size(); ++ljk) {
533 std::cout <<
" " << global_UnusedColIdxOnProc[ljk];
535 std::cout << std::endl;
539 std::vector<GlobalOrdinal> local_UnusedColIdxVector(Teuchos::as<size_t>(global_cntUnusedColIdx));
540 std::vector<GlobalOrdinal> global_UnusedColIdxVector(Teuchos::as<size_t>(global_cntUnusedColIdx));
542 for (
int proc = 0; proc < myRank; proc++) {
543 global_cntUnusedColIdxStartIter += global_UnusedColIdxOnProc[proc];
545 for (
GlobalOrdinal k = global_cntUnusedColIdxStartIter; k < global_cntUnusedColIdxStartIter + local_cntUnusedColIdx; k++) {
546 local_UnusedColIdxVector[k] = qUnusedGColIdx.front();
547 qUnusedGColIdx.pop();
549 Teuchos::reduceAll(*comm, Teuchos::REDUCE_MAX, Teuchos::as<int>(global_cntUnusedColIdx),
550 local_UnusedColIdxVector.data(),
551 global_UnusedColIdxVector.data());
553 std::cout <<
"PROC " << myRank <<
" global UnusedGColIdx: ";
554 for (
size_t ljk = 0; ljk < global_UnusedColIdxVector.size(); ++ljk) {
555 std::cout <<
" " << global_UnusedColIdxVector[ljk];
557 std::cout << std::endl;
562 std::vector<LocalOrdinal> local_EmptyColIdxOnProc(numProcs);
563 std::vector<LocalOrdinal> global_EmptyColIdxOnProc(numProcs);
564 local_EmptyColIdxOnProc[myRank] = local_cntFreeColIdx;
565 Teuchos::reduceAll(*comm, Teuchos::REDUCE_MAX, numProcs,
566 local_EmptyColIdxOnProc.data(),
567 global_EmptyColIdxOnProc.data());
570 std::cout <<
"PROC " << myRank <<
" global num of needed column indices: ";
571 for (
size_t ljk = 0; ljk < global_EmptyColIdxOnProc.size(); ++ljk) {
572 std::cout <<
" " << global_EmptyColIdxOnProc[ljk];
574 std::cout << std::endl;
580 for (
int proc = 0; proc < myRank; proc++) {
581 global_UnusedColStartIdx += global_EmptyColIdxOnProc[proc];
585 GetOStream(
Statistics0) <<
"PROC " << myRank <<
" is allowd to use the following column gids: ";
586 for (
GlobalOrdinal k = global_UnusedColStartIdx; k < global_UnusedColStartIdx + Teuchos::as<GlobalOrdinal>(cntFreeColIdx); k++) {
587 GetOStream(
Statistics0) << global_UnusedColIdxVector[k] <<
" ";
594 Teuchos::ArrayRCP<Scalar> ColIdStatusArray = ColIdStatus->getDataNonConst(0);
596 for (
size_t ljk = 0; ljk < ColIdStatus->getLocalLength(); ++ljk) {
597 if (ColIdStatusArray[ljk] == SC_ZERO) {
598 ColIdStatusArray[ljk] = SC_ONE;
599 Qperm->replaceLocalValue(ljk, global_UnusedColIdxVector[global_UnusedColStartIdx + array_iter]);
600 ColIdUsed->replaceGlobalValue(global_UnusedColIdxVector[global_UnusedColStartIdx + array_iter], SC_ONE);
602 if (floor(global_UnusedColIdxVector[global_UnusedColStartIdx + array_iter] / nDofsPerNode) != floor(ColIdStatus->getMap()->getGlobalElement(ljk) / nDofsPerNode)) {
603 lWideRangeColPermutations++;
614 Teuchos::RCP<CrsMatrixWrap> permPTmatrix = Teuchos::rcp(
new CrsMatrixWrap(A->getRowMap(), 1));
615 Teuchos::RCP<CrsMatrixWrap> permQTmatrix = Teuchos::rcp(
new CrsMatrixWrap(A->getRowMap(), 1));
618 Teuchos::ArrayRCP<Scalar> PpermData = Pperm->getDataNonConst(0);
619 Teuchos::ArrayRCP<Scalar> QpermData = Qperm->getDataNonConst(0);
621 for (
size_t row = 0; row < A->getLocalNumRows(); row++) {
625 Teuchos::ArrayRCP<GlobalOrdinal> indoutP(1, Teuchos::as<GO>(Teuchos::ScalarTraits<Scalar>::real(PpermData[row])));
626 Teuchos::ArrayRCP<GlobalOrdinal> indoutQ(1, Teuchos::as<GO>(Teuchos::ScalarTraits<Scalar>::real(QpermData[row])));
627 Teuchos::ArrayRCP<Scalar> valout(1, SC_ONE);
628 permPTmatrix->insertGlobalValues(A->getRowMap()->getGlobalElement(row), indoutP.view(0, indoutP.size()), valout.view(0, valout.size()));
629 permQTmatrix->insertGlobalValues(A->getRowMap()->getGlobalElement(row), indoutQ.view(0, indoutQ.size()), valout.view(0, valout.size()));
633 permPTmatrix->fillComplete();
634 permQTmatrix->fillComplete();
638 for (
size_t row = 0; row < permPTmatrix->getLocalNumRows(); row++) {
639 if (permPTmatrix->getNumEntriesInLocalRow(row) != 1)
640 GetOStream(
Warnings0) <<
"#entries in row " << row <<
" of permPTmatrix is " << permPTmatrix->getNumEntriesInLocalRow(row) << std::endl;
641 if (permPmatrix->getNumEntriesInLocalRow(row) != 1)
642 GetOStream(
Warnings0) <<
"#entries in row " << row <<
" of permPmatrix is " << permPmatrix->getNumEntriesInLocalRow(row) << std::endl;
643 if (permQTmatrix->getNumEntriesInLocalRow(row) != 1)
644 GetOStream(
Warnings0) <<
"#entries in row " << row <<
" of permQmatrix is " << permQTmatrix->getNumEntriesInLocalRow(row) << std::endl;
648 Teuchos::RCP<Matrix> ApermQt = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*A,
false, *permQTmatrix,
false, GetOStream(
Statistics2));
649 Teuchos::RCP<Matrix> permPApermQt = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*permPmatrix,
false, *ApermQt,
false, GetOStream(
Statistics2));
658 Teuchos::RCP<Vector> diagVec = VectorFactory::Build(permPApermQt->getRowMap(),
true);
659 Teuchos::RCP<Vector> invDiagVec = VectorFactory::Build(permPApermQt->getRowMap(),
true);
660 Teuchos::RCP<CrsMatrixWrap> diagScalingOp = Teuchos::rcp(
new CrsMatrixWrap(permPApermQt->getRowMap(), 1));
662 permPApermQt->getLocalDiagCopy(*diagVec);
663 Teuchos::ArrayRCP<const Scalar> diagVecData = diagVec->getData(0);
664 Teuchos::ArrayRCP<Scalar> invDiagVecData = invDiagVec->getDataNonConst(0);
665 for (
size_t i = 0; i < diagVec->getMap()->getLocalNumElements(); ++i) {
666 if (diagVecData[i] != SC_ZERO)
667 invDiagVecData[i] = SC_ONE / diagVecData[i];
669 invDiagVecData[i] = SC_ONE;
670 GetOStream(
Statistics0) <<
"MueLu::PermutationFactory: found zero on diagonal in row " << i << std::endl;
674 for (
size_t row = 0; row < A->getLocalNumRows(); row++) {
675 Teuchos::ArrayRCP<GlobalOrdinal> indout(1, permPApermQt->getRowMap()->getGlobalElement(row));
676 Teuchos::ArrayRCP<Scalar> valout(1, invDiagVecData[row]);
677 diagScalingOp->insertGlobalValues(A->getRowMap()->getGlobalElement(row), indout.view(0, indout.size()), valout.view(0, valout.size()));
680 diagScalingOp->fillComplete();
682 Teuchos::RCP<Matrix> scaledA = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*diagScalingOp,
false, *permPApermQt,
false, GetOStream(
Statistics2));
683 currentLevel.
Set(
"A", Teuchos::rcp_dynamic_cast<Matrix>(scaledA), genFactory );
685 currentLevel.
Set(
"permA", Teuchos::rcp_dynamic_cast<Matrix>(permPApermQt), genFactory );
686 currentLevel.
Set(
"permP", Teuchos::rcp_dynamic_cast<Matrix>(permPmatrix), genFactory );
687 currentLevel.
Set(
"permQT", Teuchos::rcp_dynamic_cast<Matrix>(permQTmatrix), genFactory );
688 currentLevel.
Set(
"permScaling", Teuchos::rcp_dynamic_cast<Matrix>(diagScalingOp), genFactory );
692 Teuchos::RCP<Vector> diagPVec = VectorFactory::Build(permPmatrix->getRowMap(),
true);
693 permPmatrix->getLocalDiagCopy(*diagPVec);
697 Teuchos::ArrayRCP<const Scalar> diagPVecData = diagPVec->getData(0);
698 for (
size_t i = 0; i < diagPVec->getMap()->getLocalNumElements(); ++i) {
699 if (diagPVecData[i] == SC_ZERO) {
700 lNumRowPermutations++;
706 MueLu_sumAll(diagPVec->getMap()->getComm(), Teuchos::as<GlobalOrdinal>(lNumRowPermutations), gNumRowPermutations);
710 Teuchos::RCP<Vector> diagQTVec = VectorFactory::Build(permQTmatrix->getRowMap(),
true);
711 permQTmatrix->getLocalDiagCopy(*diagQTVec);
715 Teuchos::ArrayRCP<const Scalar> diagQTVecData = diagQTVec->getData(0);
716 for (
size_t i = 0; i < diagQTVec->getMap()->getLocalNumElements(); ++i) {
717 if (diagQTVecData[i] == SC_ZERO) {
718 lNumColPermutations++;
724 MueLu_sumAll(diagQTVec->getMap()->getComm(), Teuchos::as<GlobalOrdinal>(lNumColPermutations), gNumColPermutations);
726 currentLevel.
Set(
"#RowPermutations", gNumRowPermutations, genFactory );
727 currentLevel.
Set(
"#ColPermutations", gNumColPermutations, genFactory );
728 currentLevel.
Set(
"#WideRangeRowPermutations", gWideRangeRowPermutations, genFactory );
729 currentLevel.
Set(
"#WideRangeColPermutations", gWideRangeColPermutations, genFactory );
731 GetOStream(
Statistics0) <<
"#Row permutations/max possible permutations: " << gNumRowPermutations <<
"/" << diagPVec->getMap()->getGlobalNumElements() << std::endl;
732 GetOStream(
Statistics0) <<
"#Column permutations/max possible permutations: " << gNumColPermutations <<
"/" << diagQTVec->getMap()->getGlobalNumElements() << std::endl;
733 GetOStream(
Runtime1) <<
"#wide range row permutations: " << gWideRangeRowPermutations <<
" #wide range column permutations: " << gWideRangeColPermutations << std::endl;