92 FactoryMonitor m(*
this,
"Prolongator smoothing (PG-AMG)", coarseLevel);
100 RCP<const FactoryBase> initialPFact =
GetFactory(
"P");
101 if (initialPFact == Teuchos::null) {
104 RCP<Matrix> Ptent = coarseLevel.
Get<RCP<Matrix> >(
"P", initialPFact.get());
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 doFillComplete =
true;
118 optimizeStorage =
false;
124 Teuchos::RCP<Vector> RowBasedOmega = Teuchos::null;
127 bool bReUseRowBasedOmegas = pL.get<
bool>(
"ReUseRowBasedOmegas");
135 RowBasedOmega = coarseLevel.
Get<Teuchos::RCP<Vector> >(
"RowBasedOmega",
this);
143 Teuchos::RCP<const Export> exporter =
144 ExportFactory::Build(RowBasedOmega->getMap(), A->getRangeMap());
146 Teuchos::RCP<Vector> noRowBasedOmega =
147 VectorFactory::Build(A->getRangeMap());
149 noRowBasedOmega->doExport(*RowBasedOmega, *exporter, Xpetra::INSERT);
154 Teuchos::RCP<const Import> importer =
155 ImportFactory::Build(A->getRangeMap(), A->getRowMap());
158 RowBasedOmega->doImport(*noRowBasedOmega, *importer, Xpetra::INSERT);
161 Teuchos::ArrayRCP<Scalar> RowBasedOmega_local = RowBasedOmega->getDataNonConst(0);
164 RCP<Matrix> P_smoothed = Teuchos::null;
167 Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::TwoMatrixAdd(*Ptent,
false, Teuchos::ScalarTraits<Scalar>::one(),
168 *DinvAP0,
false, -Teuchos::ScalarTraits<Scalar>::one(),
170 P_smoothed->fillComplete(Ptent->getDomainMap(), Ptent->getRangeMap());
174 RCP<ParameterList> params = rcp(
new ParameterList());
175 params->set(
"printLoadBalancingInfo",
true);
180 Set(coarseLevel,
"P", P_smoothed);
188 Set(coarseLevel,
"RfromPfactory", dummy);
194 if (Ptent->IsView(
"stridedMaps"))
195 P_smoothed->CreateView(
"stridedMaps", Ptent);
200 Set(coarseLevel,
"R", R);
206 if (Ptent->IsView(
"stridedMaps"))
207 R->CreateView(
"stridedMaps", Ptent,
true);
213 FactoryMonitor m(*
this,
"PgPFactory::ComputeRowBasedOmega", coarseLevel);
215 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType Magnitude;
216 Scalar sZero = Teuchos::ScalarTraits<Scalar>::zero();
217 Magnitude mZero = Teuchos::ScalarTraits<Scalar>::magnitude(sZero);
219 Teuchos::RCP<Vector> Numerator = Teuchos::null;
220 Teuchos::RCP<Vector> Denominator = Teuchos::null;
238 bool doFillComplete =
true;
239 bool optimizeStorage =
false;
240 RCP<Matrix> AP0 = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*A,
false, *P0,
false,
GetOStream(
Statistics2), doFillComplete, optimizeStorage);
243 RCP<Matrix> ADinvAP0 = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*A,
false, *DinvAP0,
false,
GetOStream(
Statistics2), doFillComplete, optimizeStorage);
245 Numerator = VectorFactory::Build(ADinvAP0->getColMap(),
true);
246 Denominator = VectorFactory::Build(ADinvAP0->getColMap(),
true);
257 Numerator = VectorFactory::Build(DinvAP0->getColMap(),
true);
258 Denominator = VectorFactory::Build(DinvAP0->getColMap(),
true);
273 bool doFillComplete =
true;
274 bool optimizeStorage =
true;
276 RCP<Matrix> DinvADinvAP0 = Xpetra::MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(*A,
false, *DinvAP0,
false,
GetOStream(
Statistics2), doFillComplete, optimizeStorage);
278 diagA = Teuchos::ArrayRCP<Scalar>();
280 Numerator = VectorFactory::Build(DinvADinvAP0->getColMap(),
true);
281 Denominator = VectorFactory::Build(DinvADinvAP0->getColMap(),
true);
286 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"MueLu::PgPFactory::Build: minimization mode not supported. error");
290 Teuchos::RCP<Vector> ColBasedOmega =
291 VectorFactory::Build(Numerator->getMap() ,
true);
293 ColBasedOmega->putScalar(-666 );
295 Teuchos::ArrayRCP<const Scalar> Numerator_local = Numerator->getData(0);
296 Teuchos::ArrayRCP<const Scalar> Denominator_local = Denominator->getData(0);
297 Teuchos::ArrayRCP<Scalar> ColBasedOmega_local = ColBasedOmega->getDataNonConst(0);
300 Magnitude min_local = 1000000.0;
301 Magnitude max_local = 0.0;
302 for (
LocalOrdinal i = 0; i < Teuchos::as<LocalOrdinal>(Numerator->getLocalLength()); i++) {
303 if (Teuchos::ScalarTraits<Scalar>::magnitude(Denominator_local[i]) == mZero) {
304 ColBasedOmega_local[i] = 0.0;
307 ColBasedOmega_local[i] = Numerator_local[i] / Denominator_local[i];
310 if (Teuchos::ScalarTraits<Scalar>::magnitude(ColBasedOmega_local[i]) < mZero) {
311 ColBasedOmega_local[i] = Teuchos::ScalarTraits<Scalar>::zero();
319 if (Teuchos::ScalarTraits<Scalar>::magnitude(ColBasedOmega_local[i]) >= 0.8) {
320 ColBasedOmega_local[i] = 0.0;
323 if (Teuchos::ScalarTraits<Scalar>::magnitude(ColBasedOmega_local[i]) < min_local) {
324 min_local = Teuchos::ScalarTraits<Scalar>::magnitude(ColBasedOmega_local[i]);
326 if (Teuchos::ScalarTraits<Scalar>::magnitude(ColBasedOmega_local[i]) > max_local) {
327 max_local = Teuchos::ScalarTraits<Scalar>::magnitude(ColBasedOmega_local[i]);
336 MueLu_sumAll(A->getRowMap()->getComm(), zero_local, zero_all);
337 MueLu_sumAll(A->getRowMap()->getComm(), nan_local, nan_all);
338 MueLu_minAll(A->getRowMap()->getComm(), min_local, min_all);
339 MueLu_maxAll(A->getRowMap()->getComm(), max_local, max_all);
348 GetOStream(
Statistics1) <<
"Damping parameter: min = " << min_all <<
", max = " << max_all << std::endl;
349 GetOStream(
Statistics) <<
"# negative omegas: " << zero_all <<
" out of " << ColBasedOmega->getGlobalLength() <<
" column-based omegas" << std::endl;
350 GetOStream(
Statistics) <<
"# NaNs: " << nan_all <<
" out of " << ColBasedOmega->getGlobalLength() <<
" column-based omegas" << std::endl;
353 if (coarseLevel.
IsRequested(
"ColBasedOmega",
this)) {
354 coarseLevel.
Set(
"ColBasedOmega", ColBasedOmega,
this);
360 VectorFactory::Build(DinvAP0->getRowMap(),
true);
362 RowBasedOmega->putScalar(-666);
364 bool bAtLeastOneDefined =
false;
365 Teuchos::ArrayRCP<Scalar> RowBasedOmega_local = RowBasedOmega->getDataNonConst(0);
366 for (
LocalOrdinal row = 0; row < Teuchos::as<LocalOrdinal>(A->getLocalNumRows()); row++) {
367 Teuchos::ArrayView<const LocalOrdinal> lindices;
368 Teuchos::ArrayView<const Scalar> lvals;
369 DinvAP0->getLocalRowView(row, lindices, lvals);
370 bAtLeastOneDefined =
false;
371 for (
size_t j = 0; j < Teuchos::as<size_t>(lindices.size()); j++) {
372 Scalar omega = ColBasedOmega_local[lindices[j]];
373 if (Teuchos::ScalarTraits<Scalar>::magnitude(omega) != -666) {
374 bAtLeastOneDefined =
true;
375 if (Teuchos::ScalarTraits<Scalar>::magnitude(RowBasedOmega_local[row]) == -666)
376 RowBasedOmega_local[row] = omega;
377 else if (Teuchos::ScalarTraits<Scalar>::magnitude(omega) < Teuchos::ScalarTraits<Scalar>::magnitude(RowBasedOmega_local[row]))
378 RowBasedOmega_local[row] = omega;
381 if (bAtLeastOneDefined ==
true) {
382 if (Teuchos::ScalarTraits<Scalar>::magnitude(RowBasedOmega_local[row]) < mZero)
383 RowBasedOmega_local[row] = sZero;
387 if (coarseLevel.
IsRequested(
"RowBasedOmega",
this)) {
388 Set(coarseLevel,
"RowBasedOmega", RowBasedOmega);
431 TEUCHOS_TEST_FOR_EXCEPTION(!left->getDomainMap()->isSameAs(*right->getDomainMap()),
Exceptions::RuntimeError,
"MueLu::PgPFactory::MultiplyAll: domain maps of left and right do not match. Error.");
432 TEUCHOS_TEST_FOR_EXCEPTION(!left->getRowMap()->isSameAs(*right->getRowMap()),
Exceptions::RuntimeError,
"MueLu::PgPFactory::MultiplyAll: row maps of left and right do not match. Error.");
435 if(InnerProdVec->getMap()->isSameAs(*left->getColMap())) {
438 std::vector<LocalOrdinal> NewRightLocal(right->getColMap()->getLocalNumElements(), Teuchos::as<LocalOrdinal>(left->getColMap()->getLocalNumElements()+1));
441 for (
size_t j=0; j < right->getColMap()->getLocalNumElements(); j++) {
442 while ( (i < Teuchos::as<LocalOrdinal>(left->getColMap()->getLocalNumElements())) &&
443 (left->getColMap()->getGlobalElement(i) < right->getColMap()->getGlobalElement(j)) ) i++;
444 if (left->getColMap()->getGlobalElement(i) == right->getColMap()->getGlobalElement(j)) {
445 NewRightLocal[j] = i;
449 Teuchos::ArrayRCP< Scalar > InnerProd_local = InnerProdVec->getDataNonConst(0);
450 std::vector<Scalar> temp_array(left->getColMap()->getLocalNumElements()+1, 0.0);
452 for(
size_t n=0; n<right->getLocalNumRows(); n++) {
453 Teuchos::ArrayView<const LocalOrdinal> lindices_left;
454 Teuchos::ArrayView<const Scalar> lvals_left;
455 Teuchos::ArrayView<const LocalOrdinal> lindices_right;
456 Teuchos::ArrayView<const Scalar> lvals_right;
458 left->getLocalRowView (n, lindices_left, lvals_left);
459 right->getLocalRowView(n, lindices_right, lvals_right);
461 for(
size_t j=0; j<Teuchos::as<size_t>(lindices_right.size()); j++) {
462 temp_array[NewRightLocal[lindices_right[j] ] ] = lvals_right[j];
464 for (
size_t j=0; j < Teuchos::as<size_t>(lindices_left.size()); j++) {
465 InnerProd_local[lindices_left[j]] += temp_array[lindices_left[j] ]*lvals_left[j];
467 for (
size_t j=0; j < Teuchos::as<size_t>(lindices_right.size()); j++) {
468 temp_array[NewRightLocal[lindices_right[j] ] ] = 0.0;
472 Teuchos::RCP<const Export> exporter =
473 ExportFactory::Build(left->getColMap(), left->getDomainMap());
475 Teuchos::RCP<Vector > nonoverlap =
476 VectorFactory::Build(left->getDomainMap());
478 nonoverlap->doExport(*InnerProdVec, *exporter, Xpetra::ADD);
483 Teuchos::RCP<const Import > importer =
484 ImportFactory::Build(left->getDomainMap(), left->getColMap());
487 InnerProdVec->doImport(*nonoverlap, *importer, Xpetra::INSERT);
492 if (InnerProdVec->getMap()->isSameAs(*right->getColMap())) {
493 size_t szNewLeftLocal = TEUCHOS_MAX(left->getColMap()->getLocalNumElements(), right->getColMap()->getLocalNumElements());
494 Teuchos::RCP<std::vector<LocalOrdinal> > NewLeftLocal = Teuchos::rcp(
new std::vector<LocalOrdinal>(szNewLeftLocal, Teuchos::as<LocalOrdinal>(right->getColMap()->getMaxLocalIndex() + 1)));
497 for (
size_t i = 0; i < left->getColMap()->getLocalNumElements(); i++) {
498 while ((j < Teuchos::as<LocalOrdinal>(right->getColMap()->getLocalNumElements())) &&
499 (right->getColMap()->getGlobalElement(j) < left->getColMap()->getGlobalElement(i))) j++;
500 if (right->getColMap()->getGlobalElement(j) == left->getColMap()->getGlobalElement(i)) {
501 (*NewLeftLocal)[i] = j;
509 Teuchos::ArrayRCP<Scalar> InnerProd_local = InnerProdVec->getDataNonConst(0);
510 Teuchos::RCP<std::vector<Scalar> > temp_array = Teuchos::rcp(
new std::vector<Scalar>(right->getColMap()->getMaxLocalIndex() + 2, 0.0));
512 for (
size_t n = 0; n < left->getLocalNumRows(); n++) {
513 Teuchos::ArrayView<const LocalOrdinal> lindices_left;
514 Teuchos::ArrayView<const Scalar> lvals_left;
515 Teuchos::ArrayView<const LocalOrdinal> lindices_right;
516 Teuchos::ArrayView<const Scalar> lvals_right;
518 left->getLocalRowView(n, lindices_left, lvals_left);
519 right->getLocalRowView(n, lindices_right, lvals_right);
521 for (
size_t i = 0; i < Teuchos::as<size_t>(lindices_left.size()); i++) {
522 (*temp_array)[(*NewLeftLocal)[lindices_left[i]]] = lvals_left[i];
524 for (
size_t i = 0; i < Teuchos::as<size_t>(lindices_right.size()); i++) {
525 InnerProd_local[lindices_right[i]] += (*temp_array)[lindices_right[i]] * lvals_right[i];
527 for (
size_t i = 0; i < Teuchos::as<size_t>(lindices_left.size()); i++) {
528 (*temp_array)[(*NewLeftLocal)[lindices_left[i]]] = 0.0;
531 InnerProd_local = Teuchos::ArrayRCP<Scalar>();
533 Teuchos::RCP<const Export> exporter =
534 ExportFactory::Build(right->getColMap(), right->getDomainMap());
536 Teuchos::RCP<Vector> nonoverlap =
537 VectorFactory::Build(right->getDomainMap());
539 nonoverlap->doExport(*InnerProdVec, *exporter, Xpetra::ADD);
544 Teuchos::RCP<const Import> importer =
545 ImportFactory::Build(right->getDomainMap(), right->getColMap());
547 InnerProdVec->doImport(*nonoverlap, *importer, Xpetra::INSERT);
549 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"MueLu::PgPFactory::MultiplyAll: map of InnerProdVec must be same as column map of left operator? Error.");
553 if (InnerProdVec->getMap()->isSameAs(*left->getColMap())) {
554 Teuchos::ArrayRCP<Scalar> InnerProd_local = InnerProdVec->getDataNonConst(0);
557 Teuchos::ArrayView<const LocalOrdinal> lindices_left;
558 Teuchos::ArrayView<const Scalar> lvals_left;
559 Teuchos::ArrayView<const LocalOrdinal> lindices_right;
560 Teuchos::ArrayView<const Scalar> lvals_right;
562 for (
size_t n = 0; n < left->getLocalNumRows(); n++) {
563 left->getLocalRowView(n, lindices_left, lvals_left);
564 right->getLocalRowView(n, lindices_right, lvals_right);
566 for (
size_t i = 0; i < Teuchos::as<size_t>(lindices_left.size()); i++) {
567 GlobalOrdinal left_gid = left->getColMap()->getGlobalElement(lindices_left[i]);
568 for (
size_t j = 0; j < Teuchos::as<size_t>(lindices_right.size()); j++) {
569 GlobalOrdinal right_gid = right->getColMap()->getGlobalElement(lindices_right[j]);
570 if (left_gid == right_gid) {
571 InnerProd_local[lindices_left[i]] += lvals_left[i] * lvals_right[j];
579 Teuchos::RCP<const Export> exporter =
580 ExportFactory::Build(left->getColMap(), left->getDomainMap());
582 Teuchos::RCP<Vector> nonoverlap =
583 VectorFactory::Build(left->getDomainMap());
585 nonoverlap->doExport(*InnerProdVec, *exporter, Xpetra::ADD);
590 Teuchos::RCP<const Import> importer =
591 ImportFactory::Build(left->getDomainMap(), left->getColMap());
594 InnerProdVec->doImport(*nonoverlap, *importer, Xpetra::INSERT);
595 }
else if (InnerProdVec->getMap()->isSameAs(*right->getColMap())) {
596 Teuchos::ArrayRCP<Scalar> InnerProd_local = InnerProdVec->getDataNonConst(0);
598 Teuchos::ArrayView<const LocalOrdinal> lindices_left;
599 Teuchos::ArrayView<const Scalar> lvals_left;
600 Teuchos::ArrayView<const LocalOrdinal> lindices_right;
601 Teuchos::ArrayView<const Scalar> lvals_right;
603 for (
size_t n = 0; n < left->getLocalNumRows(); n++) {
604 left->getLocalRowView(n, lindices_left, lvals_left);
605 right->getLocalRowView(n, lindices_right, lvals_right);
607 for (
size_t i = 0; i < Teuchos::as<size_t>(lindices_left.size()); i++) {
608 GlobalOrdinal left_gid = left->getColMap()->getGlobalElement(lindices_left[i]);
609 for (
size_t j = 0; j < Teuchos::as<size_t>(lindices_right.size()); j++) {
610 GlobalOrdinal right_gid = right->getColMap()->getGlobalElement(lindices_right[j]);
611 if (left_gid == right_gid) {
612 InnerProd_local[lindices_right[j]] += lvals_left[i] * lvals_right[j];
620 Teuchos::RCP<const Export> exporter =
621 ExportFactory::Build(right->getColMap(), right->getDomainMap());
623 Teuchos::RCP<Vector> nonoverlap =
624 VectorFactory::Build(right->getDomainMap());
626 nonoverlap->doExport(*InnerProdVec, *exporter, Xpetra::ADD);
631 Teuchos::RCP<const Import> importer =
632 ImportFactory::Build(right->getDomainMap(), right->getColMap());
635 InnerProdVec->doImport(*nonoverlap, *importer, Xpetra::INSERT);
637 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.");