126 FactoryMonitor m(*
this,
"Prolongator smoothing (PG-AMG)", coarseLevel);
134 RCP<const FactoryBase> initialPFact =
GetFactory(
"P");
135 if (initialPFact == Teuchos::null) { initialPFact = coarseLevel.
GetFactoryManager()->GetFactory(
"Ptent"); }
136 RCP<Matrix> Ptent = coarseLevel.
Get< RCP<Matrix> >(
"P", initialPFact.get());
145 bool doFillComplete=
true;
146 bool optimizeStorage=
true;
147 RCP<Matrix> DinvAP0 = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*A,
false, *Ptent,
false,
GetOStream(
Statistics2), doFillComplete, optimizeStorage);
150 optimizeStorage=
false;
156 Teuchos::RCP<Vector > RowBasedOmega = Teuchos::null;
159 bool bReUseRowBasedOmegas = pL.get<
bool>(
"ReUseRowBasedOmegas");
167 RowBasedOmega = coarseLevel.
Get<Teuchos::RCP<Vector > >(
"RowBasedOmega",
this);
175 Teuchos::RCP<const Export> exporter =
176 ExportFactory::Build(RowBasedOmega->getMap(), A->getRangeMap());
178 Teuchos::RCP<Vector > noRowBasedOmega =
179 VectorFactory::Build(A->getRangeMap());
181 noRowBasedOmega->doExport(*RowBasedOmega, *exporter, Xpetra::INSERT);
186 Teuchos::RCP<const Import > importer =
187 ImportFactory::Build(A->getRangeMap(), A->getRowMap());
190 RowBasedOmega->doImport(*noRowBasedOmega, *importer, Xpetra::INSERT);
193 Teuchos::ArrayRCP< Scalar > RowBasedOmega_local = RowBasedOmega->getDataNonConst(0);
196 RCP<Matrix> P_smoothed = Teuchos::null;
199 Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::TwoMatrixAdd(*Ptent,
false, Teuchos::ScalarTraits<Scalar>::one(),
200 *DinvAP0,
false, -Teuchos::ScalarTraits<Scalar>::one(),
202 P_smoothed->fillComplete(Ptent->getDomainMap(), Ptent->getRangeMap());
206 RCP<ParameterList> params = rcp(
new ParameterList());
207 params->set(
"printLoadBalancingInfo",
true);
212 Set(coarseLevel,
"P", P_smoothed);
220 Set(coarseLevel,
"RfromPfactory", dummy);
226 if (Ptent->IsView(
"stridedMaps"))
227 P_smoothed->CreateView(
"stridedMaps", Ptent);
232 Set(coarseLevel,
"R", R);
238 if (Ptent->IsView(
"stridedMaps"))
239 R->CreateView(
"stridedMaps", Ptent,
true);
246 FactoryMonitor m(*
this,
"PgPFactory::ComputeRowBasedOmega", coarseLevel);
248 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType Magnitude;
249 Scalar sZero = Teuchos::ScalarTraits<Scalar>::zero();
250 Magnitude mZero = Teuchos::ScalarTraits<Scalar>::magnitude(sZero);
252 Teuchos::RCP<Vector > Numerator = Teuchos::null;
253 Teuchos::RCP<Vector > Denominator = Teuchos::null;
272 bool doFillComplete=
true;
273 bool optimizeStorage=
false;
274 RCP<Matrix> AP0 = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*A,
false, *P0,
false,
GetOStream(
Statistics2), doFillComplete, optimizeStorage);
277 RCP<Matrix> ADinvAP0 = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*A,
false, *DinvAP0,
false,
GetOStream(
Statistics2), doFillComplete, optimizeStorage);
279 Numerator = VectorFactory::Build(ADinvAP0->getColMap(),
true);
280 Denominator = VectorFactory::Build(ADinvAP0->getColMap(),
true);
293 Numerator = VectorFactory::Build(DinvAP0->getColMap(),
true);
294 Denominator = VectorFactory::Build(DinvAP0->getColMap(),
true);
310 bool doFillComplete=
true;
311 bool optimizeStorage=
true;
313 RCP<Matrix> DinvADinvAP0 = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*A,
false, *DinvAP0,
false,
GetOStream(
Statistics2), doFillComplete, optimizeStorage);
315 diagA = Teuchos::ArrayRCP<Scalar>();
317 Numerator = VectorFactory::Build(DinvADinvAP0->getColMap(),
true);
318 Denominator = VectorFactory::Build(DinvADinvAP0->getColMap(),
true);
324 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"MueLu::PgPFactory::Build: minimization mode not supported. error");
329 Teuchos::RCP<Vector > ColBasedOmega =
330 VectorFactory::Build(Numerator->getMap(),
true);
332 ColBasedOmega->putScalar(-666);
334 Teuchos::ArrayRCP< const Scalar > Numerator_local = Numerator->getData(0);
335 Teuchos::ArrayRCP< const Scalar > Denominator_local = Denominator->getData(0);
336 Teuchos::ArrayRCP< Scalar > ColBasedOmega_local = ColBasedOmega->getDataNonConst(0);
339 Magnitude min_local = 1000000.0;
340 Magnitude max_local = 0.0;
341 for(
LocalOrdinal i = 0; i < Teuchos::as<LocalOrdinal>(Numerator->getLocalLength()); i++) {
342 if(Teuchos::ScalarTraits<Scalar>::magnitude(Denominator_local[i]) == mZero)
344 ColBasedOmega_local[i] = 0.0;
349 ColBasedOmega_local[i] = Numerator_local[i] / Denominator_local[i];
352 if(Teuchos::ScalarTraits<Scalar>::magnitude(ColBasedOmega_local[i]) < mZero) {
353 ColBasedOmega_local[i] = Teuchos::ScalarTraits<Scalar>::zero();
361 if(Teuchos::ScalarTraits<Scalar>::magnitude(ColBasedOmega_local[i]) >= 0.8) {
362 ColBasedOmega_local[i] = 0.0;
365 if(Teuchos::ScalarTraits<Scalar>::magnitude(ColBasedOmega_local[i]) < min_local)
366 { min_local = Teuchos::ScalarTraits<Scalar>::magnitude(ColBasedOmega_local[i]); }
367 if(Teuchos::ScalarTraits<Scalar>::magnitude(ColBasedOmega_local[i]) > max_local)
368 { max_local = Teuchos::ScalarTraits<Scalar>::magnitude(ColBasedOmega_local[i]); }
376 MueLu_sumAll(A->getRowMap()->getComm(), zero_local, zero_all);
377 MueLu_sumAll(A->getRowMap()->getComm(), nan_local, nan_all);
378 MueLu_minAll(A->getRowMap()->getComm(), min_local, min_all);
379 MueLu_maxAll(A->getRowMap()->getComm(), max_local, max_all);
388 GetOStream(
Statistics1) <<
"Damping parameter: min = " << min_all <<
", max = " << max_all << std::endl;
389 GetOStream(
Statistics) <<
"# negative omegas: " << zero_all <<
" out of " << ColBasedOmega->getGlobalLength() <<
" column-based omegas" << std::endl;
390 GetOStream(
Statistics) <<
"# NaNs: " << nan_all <<
" out of " << ColBasedOmega->getGlobalLength() <<
" column-based omegas" << std::endl;
393 if(coarseLevel.
IsRequested(
"ColBasedOmega",
this)) {
394 coarseLevel.
Set(
"ColBasedOmega", ColBasedOmega,
this);
400 VectorFactory::Build(DinvAP0->getRowMap(),
true);
402 RowBasedOmega->putScalar(-666);
404 bool bAtLeastOneDefined =
false;
405 Teuchos::ArrayRCP< Scalar > RowBasedOmega_local = RowBasedOmega->getDataNonConst(0);
406 for(
LocalOrdinal row = 0; row<Teuchos::as<LocalOrdinal>(A->getLocalNumRows()); row++) {
407 Teuchos::ArrayView<const LocalOrdinal> lindices;
408 Teuchos::ArrayView<const Scalar> lvals;
409 DinvAP0->getLocalRowView(row, lindices, lvals);
410 bAtLeastOneDefined =
false;
411 for(
size_t j=0; j<Teuchos::as<size_t>(lindices.size()); j++) {
412 Scalar omega = ColBasedOmega_local[lindices[j]];
413 if (Teuchos::ScalarTraits<Scalar>::magnitude(omega) != -666) {
414 bAtLeastOneDefined =
true;
415 if(Teuchos::ScalarTraits<Scalar>::magnitude(RowBasedOmega_local[row]) == -666) RowBasedOmega_local[row] = omega;
416 else if(Teuchos::ScalarTraits<Scalar>::magnitude(omega) < Teuchos::ScalarTraits<Scalar>::magnitude(RowBasedOmega_local[row])) RowBasedOmega_local[row] = omega;
419 if(bAtLeastOneDefined ==
true) {
420 if(Teuchos::ScalarTraits<Scalar>::magnitude(RowBasedOmega_local[row]) < mZero)
421 RowBasedOmega_local[row] = sZero;
425 if(coarseLevel.
IsRequested(
"RowBasedOmega",
this)) {
426 Set(coarseLevel,
"RowBasedOmega", RowBasedOmega);
472 TEUCHOS_TEST_FOR_EXCEPTION(!left->getDomainMap()->isSameAs(*right->getDomainMap()),
Exceptions::RuntimeError,
"MueLu::PgPFactory::MultiplyAll: domain maps of left and right do not match. Error.");
473 TEUCHOS_TEST_FOR_EXCEPTION(!left->getRowMap()->isSameAs(*right->getRowMap()),
Exceptions::RuntimeError,
"MueLu::PgPFactory::MultiplyAll: row maps of left and right do not match. Error.");
476 if(InnerProdVec->getMap()->isSameAs(*left->getColMap())) {
479 std::vector<LocalOrdinal> NewRightLocal(right->getColMap()->getLocalNumElements(), Teuchos::as<LocalOrdinal>(left->getColMap()->getLocalNumElements()+1));
482 for (
size_t j=0; j < right->getColMap()->getLocalNumElements(); j++) {
483 while ( (i < Teuchos::as<LocalOrdinal>(left->getColMap()->getLocalNumElements())) &&
484 (left->getColMap()->getGlobalElement(i) < right->getColMap()->getGlobalElement(j)) ) i++;
485 if (left->getColMap()->getGlobalElement(i) == right->getColMap()->getGlobalElement(j)) {
486 NewRightLocal[j] = i;
490 Teuchos::ArrayRCP< Scalar > InnerProd_local = InnerProdVec->getDataNonConst(0);
491 std::vector<Scalar> temp_array(left->getColMap()->getLocalNumElements()+1, 0.0);
493 for(
size_t n=0; n<right->getLocalNumRows(); n++) {
494 Teuchos::ArrayView<const LocalOrdinal> lindices_left;
495 Teuchos::ArrayView<const Scalar> lvals_left;
496 Teuchos::ArrayView<const LocalOrdinal> lindices_right;
497 Teuchos::ArrayView<const Scalar> lvals_right;
499 left->getLocalRowView (n, lindices_left, lvals_left);
500 right->getLocalRowView(n, lindices_right, lvals_right);
502 for(
size_t j=0; j<Teuchos::as<size_t>(lindices_right.size()); j++) {
503 temp_array[NewRightLocal[lindices_right[j] ] ] = lvals_right[j];
505 for (
size_t j=0; j < Teuchos::as<size_t>(lindices_left.size()); j++) {
506 InnerProd_local[lindices_left[j]] += temp_array[lindices_left[j] ]*lvals_left[j];
508 for (
size_t j=0; j < Teuchos::as<size_t>(lindices_right.size()); j++) {
509 temp_array[NewRightLocal[lindices_right[j] ] ] = 0.0;
513 Teuchos::RCP<const Export> exporter =
514 ExportFactory::Build(left->getColMap(), left->getDomainMap());
516 Teuchos::RCP<Vector > nonoverlap =
517 VectorFactory::Build(left->getDomainMap());
519 nonoverlap->doExport(*InnerProdVec, *exporter, Xpetra::ADD);
524 Teuchos::RCP<const Import > importer =
525 ImportFactory::Build(left->getDomainMap(), left->getColMap());
528 InnerProdVec->doImport(*nonoverlap, *importer, Xpetra::INSERT);
533 if(InnerProdVec->getMap()->isSameAs(*right->getColMap())) {
534 size_t szNewLeftLocal = TEUCHOS_MAX(left->getColMap()->getLocalNumElements(), right->getColMap()->getLocalNumElements());
535 Teuchos::RCP<std::vector<LocalOrdinal> > NewLeftLocal = Teuchos::rcp(
new std::vector<LocalOrdinal>(szNewLeftLocal, Teuchos::as<LocalOrdinal>(right->getColMap()->getMaxLocalIndex()+1)));
538 for (
size_t i=0; i < left->getColMap()->getLocalNumElements(); i++) {
539 while ( (j < Teuchos::as<LocalOrdinal>(right->getColMap()->getLocalNumElements())) &&
540 (right->getColMap()->getGlobalElement(j) < left->getColMap()->getGlobalElement(i)) ) j++;
541 if (right->getColMap()->getGlobalElement(j) == left->getColMap()->getGlobalElement(i)) {
542 (*NewLeftLocal)[i] = j;
550 Teuchos::ArrayRCP< Scalar > InnerProd_local = InnerProdVec->getDataNonConst(0);
551 Teuchos::RCP<std::vector<Scalar> > temp_array = Teuchos::rcp(
new std::vector<Scalar>(right->getColMap()->getMaxLocalIndex()+2, 0.0));
553 for(
size_t n=0; n<left->getLocalNumRows(); n++) {
554 Teuchos::ArrayView<const LocalOrdinal> lindices_left;
555 Teuchos::ArrayView<const Scalar> lvals_left;
556 Teuchos::ArrayView<const LocalOrdinal> lindices_right;
557 Teuchos::ArrayView<const Scalar> lvals_right;
559 left->getLocalRowView (n, lindices_left, lvals_left);
560 right->getLocalRowView(n, lindices_right, lvals_right);
562 for(
size_t i=0; i<Teuchos::as<size_t>(lindices_left.size()); i++) {
563 (*temp_array)[(*NewLeftLocal)[lindices_left[i] ] ] = lvals_left[i];
565 for (
size_t i=0; i < Teuchos::as<size_t>(lindices_right.size()); i++) {
566 InnerProd_local[lindices_right[i]] += (*temp_array)[lindices_right[i] ] * lvals_right[i];
568 for (
size_t i=0; i < Teuchos::as<size_t>(lindices_left.size()); i++) {
569 (*temp_array)[(*NewLeftLocal)[lindices_left[i] ] ] = 0.0;
572 InnerProd_local = Teuchos::ArrayRCP< Scalar >();
574 Teuchos::RCP<const Export> exporter =
575 ExportFactory::Build(right->getColMap(), right->getDomainMap());
577 Teuchos::RCP<Vector> nonoverlap =
578 VectorFactory::Build(right->getDomainMap());
580 nonoverlap->doExport(*InnerProdVec, *exporter, Xpetra::ADD);
585 Teuchos::RCP<const Import > importer =
586 ImportFactory::Build(right->getDomainMap(), right->getColMap());
588 InnerProdVec->doImport(*nonoverlap, *importer, Xpetra::INSERT);
590 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"MueLu::PgPFactory::MultiplyAll: map of InnerProdVec must be same as column map of left operator? Error.");
594 if(InnerProdVec->getMap()->isSameAs(*left->getColMap())) {
596 Teuchos::ArrayRCP< Scalar > InnerProd_local = InnerProdVec->getDataNonConst(0);
599 Teuchos::ArrayView<const LocalOrdinal> lindices_left;
600 Teuchos::ArrayView<const Scalar> lvals_left;
601 Teuchos::ArrayView<const LocalOrdinal> lindices_right;
602 Teuchos::ArrayView<const Scalar> lvals_right;
604 for(
size_t n=0; n<left->getLocalNumRows(); n++)
607 left->getLocalRowView (n, lindices_left, lvals_left);
608 right->getLocalRowView(n, lindices_right, lvals_right);
610 for(
size_t i=0; i<Teuchos::as<size_t>(lindices_left.size()); i++)
612 GlobalOrdinal left_gid = left->getColMap()->getGlobalElement(lindices_left[i]);
613 for(
size_t j=0; j<Teuchos::as<size_t>(lindices_right.size()); j++)
615 GlobalOrdinal right_gid= right->getColMap()->getGlobalElement(lindices_right[j]);
616 if(left_gid == right_gid)
618 InnerProd_local[lindices_left[i]] += lvals_left[i]*lvals_right[j];
626 Teuchos::RCP<const Export> exporter =
627 ExportFactory::Build(left->getColMap(), left->getDomainMap());
629 Teuchos::RCP<Vector > nonoverlap =
630 VectorFactory::Build(left->getDomainMap());
632 nonoverlap->doExport(*InnerProdVec, *exporter, Xpetra::ADD);
637 Teuchos::RCP<const Import > importer =
638 ImportFactory::Build(left->getDomainMap(), left->getColMap());
641 InnerProdVec->doImport(*nonoverlap, *importer, Xpetra::INSERT);
643 else if(InnerProdVec->getMap()->isSameAs(*right->getColMap())) {
644 Teuchos::ArrayRCP< Scalar > InnerProd_local = InnerProdVec->getDataNonConst(0);
646 Teuchos::ArrayView<const LocalOrdinal> lindices_left;
647 Teuchos::ArrayView<const Scalar> lvals_left;
648 Teuchos::ArrayView<const LocalOrdinal> lindices_right;
649 Teuchos::ArrayView<const Scalar> lvals_right;
651 for(
size_t n=0; n<left->getLocalNumRows(); n++)
653 left->getLocalRowView(n, lindices_left, lvals_left);
654 right->getLocalRowView(n, lindices_right, lvals_right);
656 for(
size_t i=0; i<Teuchos::as<size_t>(lindices_left.size()); i++)
658 GlobalOrdinal left_gid = left->getColMap()->getGlobalElement(lindices_left[i]);
659 for(
size_t j=0; j<Teuchos::as<size_t>(lindices_right.size()); j++)
661 GlobalOrdinal right_gid= right->getColMap()->getGlobalElement(lindices_right[j]);
662 if(left_gid == right_gid)
664 InnerProd_local[lindices_right[j]] += lvals_left[i]*lvals_right[j];
672 Teuchos::RCP<const Export> exporter =
673 ExportFactory::Build(right->getColMap(), right->getDomainMap());
675 Teuchos::RCP<Vector> nonoverlap =
676 VectorFactory::Build(right->getDomainMap());
678 nonoverlap->doExport(*InnerProdVec, *exporter, Xpetra::ADD);
683 Teuchos::RCP<const Import > importer =
684 ImportFactory::Build(right->getDomainMap(), right->getColMap());
687 InnerProdVec->doImport(*nonoverlap, *importer, Xpetra::INSERT);
690 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"MueLu::PgPFactory::MultiplyAll: map of InnerProdVec must be same as column map of left or right operator? Error.");