MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_AztecEpetraOperator.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 #ifndef PACKAGES_MUELU_ADAPTERS_AZTECOO_MUELU_AZTECEPETRAOPERATOR_CPP_
11 #define PACKAGES_MUELU_ADAPTERS_AZTECOO_MUELU_AZTECEPETRAOPERATOR_CPP_
12 
14 #include "Xpetra_CrsMatrixWrap.hpp"
16 
17 #include "MueLu_config.hpp" // for HAVE_MUELU_DEBUG
18 #include "MueLu_RefMaxwell.hpp"
19 #include "MueLu_Exceptions.hpp"
20 
22 
23 #if defined(HAVE_MUELU_SERIAL) and defined(HAVE_MUELU_EPETRA)
24 
25 namespace MueLu {
26 
27 int AztecEpetraOperator::ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const {
28  try {
29  // There is no rcpFromRef(const T&), so we need to do const_cast
30  const Xpetra::EpetraMultiVectorT<GO, NO> eX(Teuchos::rcpFromRef(const_cast<Epetra_MultiVector&>(X)));
31  Xpetra::EpetraMultiVectorT<GO, NO> eY(Teuchos::rcpFromRef(Y));
32  // Generally, we assume two different vectors, but AztecOO uses a single vector
33  if (X.Values() == Y.Values()) {
34  // X and Y point to the same memory, use an additional vector
36  tmpY->putScalar(0.0);
37  xOp_->apply(eX, *tmpY);
38  // deep copy solution from MueLu
39  eY.update(1.0, *tmpY, 0.0);
40  } else {
41  // X and Y point to different memory, pass the vectors through
42  eY.putScalar(0.0);
43  xOp_->apply(eX, eY);
44  }
45 
46  } catch (std::exception& e) {
47  // TODO: error msg directly on std::cerr?
48  std::cerr << "Caught an exception in MueLu::AztecEpetraOperator::ApplyInverse():" << std::endl
49  << e.what() << std::endl;
50  return -1;
51  }
52  return 0;
53 }
54 
55 const Epetra_Comm& AztecEpetraOperator::Comm() const {
56  const Epetra_Map emap = Xpetra::toEpetra(xOp_->getDomainMap());
57  return emap.Comm();
58 }
59 
60 const Epetra_Map& AztecEpetraOperator::OperatorDomainMap() const {
61  if (Teuchos::rcp_dynamic_cast<MueLu::RefMaxwell<SC, LO, GO, NO>>(xOp_) != Teuchos::null) {
62  RCP<Xpetra::Matrix<SC, LO, GO, NO>> A = Teuchos::rcp_dynamic_cast<MueLu::RefMaxwell<SC, LO, GO, NO>>(xOp_)->getJacobian();
63  RCP<const Xpetra::CrsMatrixWrap<SC, LO, GO, NO>> crsOp = rcp_dynamic_cast<const Xpetra::CrsMatrixWrap<SC, LO, GO, NO>>(A);
64  if (crsOp == Teuchos::null)
65  throw Exceptions::BadCast("Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
66  const RCP<const Xpetra::EpetraCrsMatrixT<GO, NO>>& tmp_ECrsMtx = rcp_dynamic_cast<const Xpetra::EpetraCrsMatrixT<GO, NO>>(crsOp->getCrsMatrix());
67  if (tmp_ECrsMtx == Teuchos::null)
68  throw Exceptions::BadCast("Cast from Xpetra::CrsMatrix to Xpetra::EpetraCrsMatrix failed");
69  return tmp_ECrsMtx->getEpetra_CrsMatrixNonConst()->DomainMap();
70  }
71 
72  // TAW there is a problem with the Map version of toEeptra leading to code crashes
73  // we probably need to create a new copy of the Epetra_Map
74  Teuchos::RCP<const Map> map = xOp_->getDomainMap();
75  return Xpetra::toEpetra(map);
76 }
77 
78 const Epetra_Map& AztecEpetraOperator::OperatorRangeMap() const {
79  if (Teuchos::rcp_dynamic_cast<MueLu::RefMaxwell<SC, LO, GO, NO>>(xOp_) != Teuchos::null) {
80  RCP<Xpetra::Matrix<SC, LO, GO, NO>> A = Teuchos::rcp_dynamic_cast<MueLu::RefMaxwell<SC, LO, GO, NO>>(xOp_)->getJacobian();
81  RCP<const Xpetra::CrsMatrixWrap<SC, LO, GO, NO>> crsOp = rcp_dynamic_cast<const Xpetra::CrsMatrixWrap<SC, LO, GO, NO>>(A);
82  if (crsOp == Teuchos::null)
83  throw Exceptions::BadCast("Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
84  const RCP<const Xpetra::EpetraCrsMatrixT<GO, NO>>& tmp_ECrsMtx = rcp_dynamic_cast<const Xpetra::EpetraCrsMatrixT<GO, NO>>(crsOp->getCrsMatrix());
85  if (tmp_ECrsMtx == Teuchos::null)
86  throw Exceptions::BadCast("Cast from Xpetra::CrsMatrix to Xpetra::EpetraCrsMatrix failed");
87  return tmp_ECrsMtx->getEpetra_CrsMatrixNonConst()->RangeMap();
88  }
89 
90  // TAW there is a problem with the Map version of toEeptra leading to code crashes
91  // we probably need to create a new copy of the Epetra_Map
92  Teuchos::RCP<const Map> map = xOp_->getRangeMap();
93  return Xpetra::toEpetra(map);
94 }
95 
96 } // namespace MueLu
97 
98 #endif /*#if defined(HAVE_MUELU_SERIAL) and defined(HAVE_MUELU_EPETRA)*/
99 
100 #endif /* PACKAGES_MUELU_ADAPTERS_AZTECOO_MUELU_AZTECEPETRAOPERATOR_CPP_ */
void update(const Scalar &alpha, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, const Scalar &beta)
void putScalar(const Scalar &value)
const Epetra_CrsGraph & toEpetra(const RCP< const CrsGraph< int, GlobalOrdinal, Node > > &graph)
Preconditioner (wrapped as a Xpetra::Operator) for Maxwell&#39;s equations in curl-curl form...
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
size_t getNumVectors() const
const Epetra_Comm & Comm() const
Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getMap() const