MueLu Version of the Day
Loading...
Searching...
No Matches
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
13#include "Xpetra_EpetraMultiVector.hpp"
14#include "Xpetra_CrsMatrixWrap.hpp"
15#include "Xpetra_EpetraCrsMatrix.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
25namespace MueLu {
26
27int 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
35 Teuchos::RCP<Xpetra::EpetraMultiVectorT<GO, NO>> tmpY = Teuchos::rcp(new Xpetra::EpetraMultiVectorT<GO, NO>(eY.getMap(), eY.getNumVectors()));
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
55const Epetra_Comm& AztecEpetraOperator::Comm() const {
56 const Epetra_Map emap = Xpetra::toEpetra(xOp_->getDomainMap());
57 return emap.Comm();
58}
59
60const 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
78const 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_ */
const Epetra_Comm & Comm() const
double * Values() const
Preconditioner (wrapped as a Xpetra::Operator) for Maxwell's equations in curl-curl form.
Namespace for MueLu classes and methods.