92 FactoryMonitor m(*
this,
"Prolongator smoothing (PG-AMG)", coarseLevel);
95 RCP<Matrix> A = Get<RCP<Matrix> >(fineLevel,
"A");
100 RCP<const FactoryBase> initialPFact = GetFactory(
"P");
101 if (initialPFact == Teuchos::null) {
104 RCP<Matrix> Ptent = coarseLevel.
Get<RCP<Matrix> >(
"P", initialPFact.get());
107 if (restrictionMode_) {
113 bool doFillComplete =
true;
114 bool optimizeStorage =
true;
115 RCP<Matrix> DinvAP0 = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*A,
false, *Ptent,
false, GetOStream(
Statistics2), doFillComplete, optimizeStorage);
117 const auto rowMap = A->getRowMap();
118 auto diag = Xpetra::VectorFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(rowMap,
true);
119 A->getLocalDiagCopy(*diag);
120 diag->reciprocal(*diag);
121 DinvAP0->leftScale(*diag);
125 Teuchos::RCP<Vector> RowBasedOmega = Teuchos::null;
127 const ParameterList& pL = GetParameterList();
128 bool bReUseRowBasedOmegas = pL.get<
bool>(
"ReUseRowBasedOmegas");
129 if (restrictionMode_ ==
false || bReUseRowBasedOmegas ==
false) {
132 ComputeRowBasedOmega(fineLevel, coarseLevel, A, Ptent, DinvAP0, RowBasedOmega);
136 RowBasedOmega = coarseLevel.
Get<Teuchos::RCP<Vector> >(
"RowBasedOmega",
this);
144 Teuchos::RCP<const Export> exporter =
145 ExportFactory::Build(RowBasedOmega->getMap(), A->getRangeMap());
147 Teuchos::RCP<Vector> noRowBasedOmega =
148 VectorFactory::Build(A->getRangeMap());
150 noRowBasedOmega->doExport(*RowBasedOmega, *exporter, Xpetra::INSERT);
155 Teuchos::RCP<const Import> importer =
156 ImportFactory::Build(A->getRangeMap(), A->getRowMap());
159 RowBasedOmega->doImport(*noRowBasedOmega, *importer, Xpetra::INSERT);
162 DinvAP0->leftScale(*RowBasedOmega);
164 RCP<Matrix> P_smoothed = Teuchos::null;
166 Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::TwoMatrixAdd(*Ptent,
false, Teuchos::ScalarTraits<Scalar>::one(),
167 *DinvAP0,
false, -Teuchos::ScalarTraits<Scalar>::one(),
169 P_smoothed->fillComplete(Ptent->getDomainMap(), Ptent->getRangeMap());
173 RCP<ParameterList> params = rcp(
new ParameterList());
174 params->set(
"printLoadBalancingInfo",
true);
177 if (!restrictionMode_) {
179 Set(coarseLevel,
"P", P_smoothed);
187 Set(coarseLevel,
"RfromPfactory", dummy);
193 if (Ptent->IsView(
"stridedMaps"))
194 P_smoothed->CreateView(
"stridedMaps", Ptent);
199 Set(coarseLevel,
"R", R);
205 if (Ptent->IsView(
"stridedMaps"))
206 R->CreateView(
"stridedMaps", Ptent,
true);
212 FactoryMonitor m(*
this,
"PgPFactory::ComputeRowBasedOmega", coarseLevel);
214 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType Magnitude;
215 Scalar sZero = Teuchos::ScalarTraits<Scalar>::zero();
216 Magnitude mZero = Teuchos::ScalarTraits<Scalar>::magnitude(sZero);
218 Teuchos::RCP<Vector> Numerator = Teuchos::null;
219 Teuchos::RCP<Vector> Denominator = Teuchos::null;
221 const ParameterList& pL = GetParameterList();
237 bool doFillComplete =
true;
238 bool optimizeStorage =
false;
239 RCP<Matrix> AP0 = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*A,
false, *P0,
false, GetOStream(
Statistics2), doFillComplete, optimizeStorage);
242 RCP<Matrix> ADinvAP0 = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*A,
false, *DinvAP0,
false, GetOStream(
Statistics2), doFillComplete, optimizeStorage);
244 Numerator = VectorFactory::Build(ADinvAP0->getColMap(),
true);
245 Denominator = VectorFactory::Build(ADinvAP0->getColMap(),
true);
246 MultiplyAll(AP0, ADinvAP0, Numerator);
247 MultiplySelfAll(ADinvAP0, Denominator);
256 Numerator = VectorFactory::Build(DinvAP0->getColMap(),
true);
257 Denominator = VectorFactory::Build(DinvAP0->getColMap(),
true);
258 MultiplyAll(P0, DinvAP0, Numerator);
259 MultiplySelfAll(DinvAP0, Denominator);
272 bool doFillComplete =
true;
273 bool optimizeStorage =
true;
275 RCP<Matrix> DinvADinvAP0 = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*A,
false, *DinvAP0,
false, GetOStream(
Statistics2), doFillComplete, optimizeStorage);
277 const auto rowMap = A->getRowMap();
278 auto diag = Xpetra::VectorFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(rowMap,
true);
279 A->getLocalDiagCopy(*diag);
280 diag->reciprocal(*diag);
281 DinvADinvAP0->leftScale(*diag);
283 Numerator = VectorFactory::Build(DinvADinvAP0->getColMap(),
true);
284 Denominator = VectorFactory::Build(DinvADinvAP0->getColMap(),
true);
285 MultiplyAll(DinvAP0, DinvADinvAP0, Numerator);
286 MultiplySelfAll(DinvADinvAP0, Denominator);
289 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"MueLu::PgPFactory::Build: minimization mode not supported. error");
293 Teuchos::RCP<Vector> ColBasedOmega =
294 VectorFactory::Build(Numerator->getMap() ,
true);
296 ColBasedOmega->putScalar(-666 );
298 Teuchos::ArrayRCP<const Scalar> Numerator_local = Numerator->getData(0);
299 Teuchos::ArrayRCP<const Scalar> Denominator_local = Denominator->getData(0);
300 Teuchos::ArrayRCP<Scalar> ColBasedOmega_local = ColBasedOmega->getDataNonConst(0);
303 Magnitude min_local = 1000000.0;
304 Magnitude max_local = 0.0;
305 for (
LocalOrdinal i = 0; i < Teuchos::as<LocalOrdinal>(Numerator->getLocalLength()); i++) {
306 if (Teuchos::ScalarTraits<Scalar>::magnitude(Denominator_local[i]) == mZero) {
307 ColBasedOmega_local[i] = 0.0;
310 ColBasedOmega_local[i] = Numerator_local[i] / Denominator_local[i];
313 if (Teuchos::ScalarTraits<Scalar>::magnitude(ColBasedOmega_local[i]) < mZero) {
314 ColBasedOmega_local[i] = Teuchos::ScalarTraits<Scalar>::zero();
322 if (Teuchos::ScalarTraits<Scalar>::magnitude(ColBasedOmega_local[i]) >= 0.8) {
323 ColBasedOmega_local[i] = 0.0;
326 if (Teuchos::ScalarTraits<Scalar>::magnitude(ColBasedOmega_local[i]) < min_local) {
327 min_local = Teuchos::ScalarTraits<Scalar>::magnitude(ColBasedOmega_local[i]);
329 if (Teuchos::ScalarTraits<Scalar>::magnitude(ColBasedOmega_local[i]) > max_local) {
330 max_local = Teuchos::ScalarTraits<Scalar>::magnitude(ColBasedOmega_local[i]);
339 MueLu_sumAll(A->getRowMap()->getComm(), zero_local, zero_all);
340 MueLu_sumAll(A->getRowMap()->getComm(), nan_local, nan_all);
341 MueLu_minAll(A->getRowMap()->getComm(), min_local, min_all);
342 MueLu_maxAll(A->getRowMap()->getComm(), max_local, max_all);
349 default: GetOStream(
Statistics1) <<
"unknown)" << std::endl;
break;
351 GetOStream(
Statistics1) <<
"Damping parameter: min = " << min_all <<
", max = " << max_all << std::endl;
352 GetOStream(
Statistics) <<
"# negative omegas: " << zero_all <<
" out of " << ColBasedOmega->getGlobalLength() <<
" column-based omegas" << std::endl;
353 GetOStream(
Statistics) <<
"# NaNs: " << nan_all <<
" out of " << ColBasedOmega->getGlobalLength() <<
" column-based omegas" << std::endl;
356 if (coarseLevel.
IsRequested(
"ColBasedOmega",
this)) {
357 coarseLevel.
Set(
"ColBasedOmega", ColBasedOmega,
this);
363 VectorFactory::Build(DinvAP0->getRowMap(),
true);
365 RowBasedOmega->putScalar(-666);
367 bool bAtLeastOneDefined =
false;
368 Teuchos::ArrayRCP<Scalar> RowBasedOmega_local = RowBasedOmega->getDataNonConst(0);
369 for (
LocalOrdinal row = 0; row < Teuchos::as<LocalOrdinal>(A->getLocalNumRows()); row++) {
370 Teuchos::ArrayView<const LocalOrdinal> lindices;
371 Teuchos::ArrayView<const Scalar> lvals;
372 DinvAP0->getLocalRowView(row, lindices, lvals);
373 bAtLeastOneDefined =
false;
374 for (
size_t j = 0; j < Teuchos::as<size_t>(lindices.size()); j++) {
375 Scalar omega = ColBasedOmega_local[lindices[j]];
376 if (Teuchos::ScalarTraits<Scalar>::magnitude(omega) != -666) {
377 bAtLeastOneDefined =
true;
378 if (Teuchos::ScalarTraits<Scalar>::magnitude(RowBasedOmega_local[row]) == -666)
379 RowBasedOmega_local[row] = omega;
380 else if (Teuchos::ScalarTraits<Scalar>::magnitude(omega) < Teuchos::ScalarTraits<Scalar>::magnitude(RowBasedOmega_local[row]))
381 RowBasedOmega_local[row] = omega;
384 if (bAtLeastOneDefined ==
true) {
385 if (Teuchos::ScalarTraits<Scalar>::magnitude(RowBasedOmega_local[row]) < mZero)
386 RowBasedOmega_local[row] = sZero;
390 if (coarseLevel.
IsRequested(
"RowBasedOmega",
this)) {
391 Set(coarseLevel,
"RowBasedOmega", RowBasedOmega);
434 TEUCHOS_TEST_FOR_EXCEPTION(!left->getDomainMap()->isSameAs(*right->getDomainMap()),
Exceptions::RuntimeError,
"MueLu::PgPFactory::MultiplyAll: domain maps of left and right do not match. Error.");
435 TEUCHOS_TEST_FOR_EXCEPTION(!left->getRowMap()->isSameAs(*right->getRowMap()),
Exceptions::RuntimeError,
"MueLu::PgPFactory::MultiplyAll: row maps of left and right do not match. Error.");
438 if(InnerProdVec->getMap()->isSameAs(*left->getColMap())) {
441 std::vector<LocalOrdinal> NewRightLocal(right->getColMap()->getLocalNumElements(), Teuchos::as<LocalOrdinal>(left->getColMap()->getLocalNumElements()+1));
444 for (
size_t j=0; j < right->getColMap()->getLocalNumElements(); j++) {
445 while ( (i < Teuchos::as<LocalOrdinal>(left->getColMap()->getLocalNumElements())) &&
446 (left->getColMap()->getGlobalElement(i) < right->getColMap()->getGlobalElement(j)) ) i++;
447 if (left->getColMap()->getGlobalElement(i) == right->getColMap()->getGlobalElement(j)) {
448 NewRightLocal[j] = i;
452 Teuchos::ArrayRCP< Scalar > InnerProd_local = InnerProdVec->getDataNonConst(0);
453 std::vector<Scalar> temp_array(left->getColMap()->getLocalNumElements()+1, 0.0);
455 for(
size_t n=0; n<right->getLocalNumRows(); n++) {
456 Teuchos::ArrayView<const LocalOrdinal> lindices_left;
457 Teuchos::ArrayView<const Scalar> lvals_left;
458 Teuchos::ArrayView<const LocalOrdinal> lindices_right;
459 Teuchos::ArrayView<const Scalar> lvals_right;
461 left->getLocalRowView (n, lindices_left, lvals_left);
462 right->getLocalRowView(n, lindices_right, lvals_right);
464 for(
size_t j=0; j<Teuchos::as<size_t>(lindices_right.size()); j++) {
465 temp_array[NewRightLocal[lindices_right[j] ] ] = lvals_right[j];
467 for (
size_t j=0; j < Teuchos::as<size_t>(lindices_left.size()); j++) {
468 InnerProd_local[lindices_left[j]] += temp_array[lindices_left[j] ]*lvals_left[j];
470 for (
size_t j=0; j < Teuchos::as<size_t>(lindices_right.size()); j++) {
471 temp_array[NewRightLocal[lindices_right[j] ] ] = 0.0;
475 Teuchos::RCP<const Export> exporter =
476 ExportFactory::Build(left->getColMap(), left->getDomainMap());
478 Teuchos::RCP<Vector > nonoverlap =
479 VectorFactory::Build(left->getDomainMap());
481 nonoverlap->doExport(*InnerProdVec, *exporter, Xpetra::ADD);
486 Teuchos::RCP<const Import > importer =
487 ImportFactory::Build(left->getDomainMap(), left->getColMap());
490 InnerProdVec->doImport(*nonoverlap, *importer, Xpetra::INSERT);
495 if (InnerProdVec->getMap()->isSameAs(*right->getColMap())) {
496 size_t szNewLeftLocal = TEUCHOS_MAX(left->getColMap()->getLocalNumElements(), right->getColMap()->getLocalNumElements());
497 Teuchos::RCP<std::vector<LocalOrdinal> > NewLeftLocal = Teuchos::rcp(
new std::vector<LocalOrdinal>(szNewLeftLocal, Teuchos::as<LocalOrdinal>(right->getColMap()->getMaxLocalIndex() + 1)));
500 for (
size_t i = 0; i < left->getColMap()->getLocalNumElements(); i++) {
501 while ((j < Teuchos::as<LocalOrdinal>(right->getColMap()->getLocalNumElements())) &&
502 (right->getColMap()->getGlobalElement(j) < left->getColMap()->getGlobalElement(i))) j++;
503 if (right->getColMap()->getGlobalElement(j) == left->getColMap()->getGlobalElement(i)) {
504 (*NewLeftLocal)[i] = j;
512 Teuchos::ArrayRCP<Scalar> InnerProd_local = InnerProdVec->getDataNonConst(0);
513 Teuchos::RCP<std::vector<Scalar> > temp_array = Teuchos::rcp(
new std::vector<Scalar>(right->getColMap()->getMaxLocalIndex() + 2, 0.0));
515 for (
size_t n = 0; n < left->getLocalNumRows(); n++) {
516 Teuchos::ArrayView<const LocalOrdinal> lindices_left;
517 Teuchos::ArrayView<const Scalar> lvals_left;
518 Teuchos::ArrayView<const LocalOrdinal> lindices_right;
519 Teuchos::ArrayView<const Scalar> lvals_right;
521 left->getLocalRowView(n, lindices_left, lvals_left);
522 right->getLocalRowView(n, lindices_right, lvals_right);
524 for (
size_t i = 0; i < Teuchos::as<size_t>(lindices_left.size()); i++) {
525 (*temp_array)[(*NewLeftLocal)[lindices_left[i]]] = lvals_left[i];
527 for (
size_t i = 0; i < Teuchos::as<size_t>(lindices_right.size()); i++) {
528 InnerProd_local[lindices_right[i]] += (*temp_array)[lindices_right[i]] * lvals_right[i];
530 for (
size_t i = 0; i < Teuchos::as<size_t>(lindices_left.size()); i++) {
531 (*temp_array)[(*NewLeftLocal)[lindices_left[i]]] = 0.0;
534 InnerProd_local = Teuchos::ArrayRCP<Scalar>();
536 Teuchos::RCP<const Export> exporter =
537 ExportFactory::Build(right->getColMap(), right->getDomainMap());
539 Teuchos::RCP<Vector> nonoverlap =
540 VectorFactory::Build(right->getDomainMap());
542 nonoverlap->doExport(*InnerProdVec, *exporter, Xpetra::ADD);
547 Teuchos::RCP<const Import> importer =
548 ImportFactory::Build(right->getDomainMap(), right->getColMap());
550 InnerProdVec->doImport(*nonoverlap, *importer, Xpetra::INSERT);
552 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"MueLu::PgPFactory::MultiplyAll: map of InnerProdVec must be same as column map of left operator? Error.");
556 if (InnerProdVec->getMap()->isSameAs(*left->getColMap())) {
557 Teuchos::ArrayRCP<Scalar> InnerProd_local = InnerProdVec->getDataNonConst(0);
560 Teuchos::ArrayView<const LocalOrdinal> lindices_left;
561 Teuchos::ArrayView<const Scalar> lvals_left;
562 Teuchos::ArrayView<const LocalOrdinal> lindices_right;
563 Teuchos::ArrayView<const Scalar> lvals_right;
565 for (
size_t n = 0; n < left->getLocalNumRows(); n++) {
566 left->getLocalRowView(n, lindices_left, lvals_left);
567 right->getLocalRowView(n, lindices_right, lvals_right);
569 for (
size_t i = 0; i < Teuchos::as<size_t>(lindices_left.size()); i++) {
570 GlobalOrdinal left_gid = left->getColMap()->getGlobalElement(lindices_left[i]);
571 for (
size_t j = 0; j < Teuchos::as<size_t>(lindices_right.size()); j++) {
572 GlobalOrdinal right_gid = right->getColMap()->getGlobalElement(lindices_right[j]);
573 if (left_gid == right_gid) {
574 InnerProd_local[lindices_left[i]] += lvals_left[i] * lvals_right[j];
582 Teuchos::RCP<const Export> exporter =
583 ExportFactory::Build(left->getColMap(), left->getDomainMap());
585 Teuchos::RCP<Vector> nonoverlap =
586 VectorFactory::Build(left->getDomainMap());
588 nonoverlap->doExport(*InnerProdVec, *exporter, Xpetra::ADD);
593 Teuchos::RCP<const Import> importer =
594 ImportFactory::Build(left->getDomainMap(), left->getColMap());
597 InnerProdVec->doImport(*nonoverlap, *importer, Xpetra::INSERT);
598 }
else if (InnerProdVec->getMap()->isSameAs(*right->getColMap())) {
599 Teuchos::ArrayRCP<Scalar> InnerProd_local = InnerProdVec->getDataNonConst(0);
601 Teuchos::ArrayView<const LocalOrdinal> lindices_left;
602 Teuchos::ArrayView<const Scalar> lvals_left;
603 Teuchos::ArrayView<const LocalOrdinal> lindices_right;
604 Teuchos::ArrayView<const Scalar> lvals_right;
606 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++) {
611 GlobalOrdinal left_gid = left->getColMap()->getGlobalElement(lindices_left[i]);
612 for (
size_t j = 0; j < Teuchos::as<size_t>(lindices_right.size()); j++) {
613 GlobalOrdinal right_gid = right->getColMap()->getGlobalElement(lindices_right[j]);
614 if (left_gid == right_gid) {
615 InnerProd_local[lindices_right[j]] += lvals_left[i] * lvals_right[j];
623 Teuchos::RCP<const Export> exporter =
624 ExportFactory::Build(right->getColMap(), right->getDomainMap());
626 Teuchos::RCP<Vector> nonoverlap =
627 VectorFactory::Build(right->getDomainMap());
629 nonoverlap->doExport(*InnerProdVec, *exporter, Xpetra::ADD);
634 Teuchos::RCP<const Import> importer =
635 ImportFactory::Build(right->getDomainMap(), right->getColMap());
638 InnerProdVec->doImport(*nonoverlap, *importer, Xpetra::INSERT);
640 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.");