MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_EpetraOperator.cpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// MueLu: A package for multigrid based preconditioning
4//
5// Copyright 2012 NTESS and the MueLu contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#include <Xpetra_Matrix.hpp>
11#include <Xpetra_CrsMatrixWrap.hpp>
12#include <Xpetra_BlockedCrsMatrix.hpp>
13#include <Xpetra_EpetraMultiVector.hpp>
14
16#include "MueLu_Level.hpp"
17
18#if defined(HAVE_MUELU_SERIAL) and defined(HAVE_MUELU_EPETRA)
19
20namespace MueLu {
21
22int EpetraOperator::ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const {
23 try {
24 // There is no rcpFromRef(const T&), so we need to do const_cast
25 const Xpetra::EpetraMultiVectorT<GO, NO> eX(rcpFromRef(const_cast<Epetra_MultiVector&>(X)));
26 Xpetra::EpetraMultiVectorT<GO, NO> eY(rcpFromRef(Y));
27 // Generally, we assume two different vectors, but AztecOO uses a single vector
28 if (X.Values() == Y.Values()) {
29 // X and Y point to the same memory, use an additional vector
30 RCP<Xpetra::EpetraMultiVectorT<GO, NO>> tmpY = Teuchos::rcp(new Xpetra::EpetraMultiVectorT<GO, NO>(eY.getMap(), eY.getNumVectors()));
31 // InitialGuessIsZero in MueLu::Hierarchy.Iterate() does not zero out components, it
32 // only assumes that user provided an already zeroed out vector
33 bool initialGuessZero = true;
34 tmpY->putScalar(0.0);
35 // apply one V-cycle as preconditioner
36 Hierarchy_->Iterate(eX, *tmpY, 1, initialGuessZero);
37 // deep copy solution from MueLu
38 eY.update(1.0, *tmpY, 0.0);
39 } else {
40 // X and Y point to different memory, pass the vectors through
41
42 // InitialGuessIsZero in MueLu::Hierarchy.Iterate() does not zero out components, it
43 // only assumes that user provided an already zeroed out vector
44 bool initialGuessZero = true;
45 eY.putScalar(0.0);
46 Hierarchy_->Iterate(eX, eY, 1, initialGuessZero);
47 }
48
49 } catch (std::exception& e) {
50 // TODO: error msg directly on std::cerr?
51 std::cerr << "Caught an exception in MueLu::EpetraOperator::ApplyInverse():" << std::endl
52 << e.what() << std::endl;
53 return -1;
54 }
55 return 0;
56}
57
58const Epetra_Comm& EpetraOperator::Comm() const {
59 RCP<Matrix> A = Hierarchy_->GetLevel(0)->Get<RCP<Matrix>>("A");
60
61 // TODO: This code is not pretty
62 RCP<Xpetra::BlockedCrsMatrix<SC, LO, GO, NO>> epbA = Teuchos::rcp_dynamic_cast<Xpetra::BlockedCrsMatrix<SC, LO, GO, NO>>(A);
63 if (epbA != Teuchos::null) {
64 RCP<const Xpetra::Matrix<SC, LO, GO, NO>> blockMat = epbA->getMatrix(0, 0);
65 RCP<const Xpetra::CrsMatrixWrap<SC, LO, GO, NO>> blockCrsWrap = Teuchos::rcp_dynamic_cast<const Xpetra::CrsMatrixWrap<SC, LO, GO, NO>>(blockMat);
66 if (blockCrsWrap == Teuchos::null)
67 throw Exceptions::BadCast("MueLu::EpetraOperator::Comm(): Cast from block (0,0) to CrsMatrixWrap failed. Could be a block matrix. TODO implement recursive support for block matrices.");
68 RCP<const Xpetra::EpetraCrsMatrixT<GO, NO>> tmp_ECrsMtx = rcp_dynamic_cast<const Xpetra::EpetraCrsMatrixT<GO, NO>>(blockCrsWrap->getCrsMatrix());
69 if (tmp_ECrsMtx == Teuchos::null)
70 throw Exceptions::BadCast("MueLu::EpetraOperator::Comm(): Cast from Xpetra::CrsMatrix to Xpetra::EpetraCrsMatrix failed");
71 RCP<Epetra_CrsMatrix> epA = tmp_ECrsMtx->getEpetra_CrsMatrixNonConst();
72 return epA->Comm();
73 }
74
75 RCP<const Xpetra::CrsMatrixWrap<SC, LO, GO, NO>> crsOp = rcp_dynamic_cast<const Xpetra::CrsMatrixWrap<SC, LO, GO, NO>>(A);
76 if (crsOp == Teuchos::null)
77 throw Exceptions::BadCast("Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
78 const RCP<const Xpetra::EpetraCrsMatrixT<GO, NO>>& tmp_ECrsMtx = rcp_dynamic_cast<const Xpetra::EpetraCrsMatrixT<GO, NO>>(crsOp->getCrsMatrix());
79 if (tmp_ECrsMtx == Teuchos::null)
80 throw Exceptions::BadCast("Cast from Xpetra::CrsMatrix to Xpetra::EpetraCrsMatrix failed");
81 return tmp_ECrsMtx->getEpetra_CrsMatrixNonConst()->Comm();
82}
83
84const Epetra_Map& EpetraOperator::OperatorDomainMap() const {
85 RCP<Xpetra::Matrix<SC, LO, GO, NO>> A = Hierarchy_->GetLevel(0)->Get<RCP<Matrix>>("A");
86
87 RCP<Xpetra::BlockedCrsMatrix<SC, LO, GO, NO>> epbA = Teuchos::rcp_dynamic_cast<Xpetra::BlockedCrsMatrix<SC, LO, GO, NO>>(A);
88 if (epbA != Teuchos::null)
89 return Xpetra::toEpetra(epbA->getFullDomainMap()); // TODO check me
90
91 RCP<const Xpetra::CrsMatrixWrap<SC, LO, GO, NO>> crsOp = rcp_dynamic_cast<const Xpetra::CrsMatrixWrap<SC, LO, GO, NO>>(A);
92 if (crsOp == Teuchos::null)
93 throw Exceptions::BadCast("Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
94 const RCP<const Xpetra::EpetraCrsMatrixT<GO, NO>>& tmp_ECrsMtx = rcp_dynamic_cast<const Xpetra::EpetraCrsMatrixT<GO, NO>>(crsOp->getCrsMatrix());
95 if (tmp_ECrsMtx == Teuchos::null)
96 throw Exceptions::BadCast("Cast from Xpetra::CrsMatrix to Xpetra::EpetraCrsMatrix failed");
97 return tmp_ECrsMtx->getEpetra_CrsMatrixNonConst()->DomainMap();
98}
99
100const Epetra_Map& EpetraOperator::OperatorRangeMap() const {
101 RCP<Xpetra::Matrix<SC, LO, GO, NO>> A = Hierarchy_->GetLevel(0)->Get<RCP<Matrix>>("A");
102
103 RCP<Xpetra::BlockedCrsMatrix<SC, LO, GO, NO>> epbA = Teuchos::rcp_dynamic_cast<Xpetra::BlockedCrsMatrix<SC, LO, GO, NO>>(A);
104 if (epbA != Teuchos::null)
105 return Xpetra::toEpetra(epbA->getFullRangeMap());
106
107 RCP<const Xpetra::CrsMatrixWrap<SC, LO, GO, NO>> crsOp = rcp_dynamic_cast<const Xpetra::CrsMatrixWrap<SC, LO, GO, NO>>(A);
108 if (crsOp == Teuchos::null)
109 throw Exceptions::BadCast("Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
110 const RCP<const Xpetra::EpetraCrsMatrixT<GO, NO>>& tmp_ECrsMtx = rcp_dynamic_cast<const Xpetra::EpetraCrsMatrixT<GO, NO>>(crsOp->getCrsMatrix());
111 if (tmp_ECrsMtx == Teuchos::null)
112 throw Exceptions::BadCast("Cast from Xpetra::CrsMatrix to Xpetra::EpetraCrsMatrix failed");
113 return tmp_ECrsMtx->getEpetra_CrsMatrixNonConst()->RangeMap();
114}
115
116} // namespace MueLu
117
118#endif // #if defined(HAVE_MUELU_SERIAL) and defined(HAVE_MUELU_EPETRA)
double * Values() const
Namespace for MueLu classes and methods.