MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_IteratorOps.cpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// MueLu: A linear algebra interface package
4//
5// Copyright 2012 NTESS and the MueLu contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#include "MueLu_IteratorOps.hpp"
11
12namespace MueLu {
13
14#if defined(HAVE_MUELU_EPETRA) && !defined(XPETRA_EPETRA_NO_32BIT_GLOBAL_INDICES)
15template <>
17 const Xpetra::Vector<double, int, int, Xpetra::EpetraNode>& Dinv,
18 const Xpetra::Matrix<double, int, int, Xpetra::EpetraNode>& A,
19 const Xpetra::Matrix<double, int, int, Xpetra::EpetraNode>& B,
20 Xpetra::Matrix<double, int, int, Xpetra::EpetraNode>& C,
21 bool call_FillComplete_on_result,
22 bool doOptimizeStorage,
23 const std::string& label,
24 const Teuchos::RCP<Teuchos::ParameterList>& params) {
25 typedef double SC;
26 typedef int LO;
27 typedef int GO;
28 typedef Xpetra::EpetraNode NO;
29
30 TEUCHOS_TEST_FOR_EXCEPTION(C.getRowMap()->isSameAs(*A.getRowMap()) == false, MueLu::Exceptions::RuntimeError,
31 "MueLu::Jacobi: row map of C is not same as row map of A")
32 TEUCHOS_TEST_FOR_EXCEPTION(C.getRowMap()->isSameAs(*B.getRowMap()) == false, MueLu::Exceptions::RuntimeError,
33 "MueLu::Jacobi: row map of C is not same as row map of B");
34 TEUCHOS_TEST_FOR_EXCEPTION(!A.isFillComplete(), MueLu::Exceptions::RuntimeError, "A is not fill-completed");
35 TEUCHOS_TEST_FOR_EXCEPTION(!B.isFillComplete(), MueLu::Exceptions::RuntimeError, "B is not fill-completed");
36
37 bool haveMultiplyDoFillComplete = call_FillComplete_on_result && doOptimizeStorage;
38
39 if (C.getRowMap()->lib() == Xpetra::UseEpetra) {
40#ifndef HAVE_MUELU_EPETRAEXT
41 throw(MueLu::Exceptions::RuntimeError("MueLu::Jacobi requires EpetraExt to be compiled."));
42#else
43 Epetra_CrsMatrix& epA = Xpetra::Helpers<SC, LO, GO, NO>::Op2NonConstEpetraCrs(A);
44 Epetra_CrsMatrix& epB = Xpetra::Helpers<SC, LO, GO, NO>::Op2NonConstEpetraCrs(B);
45 Epetra_CrsMatrix& epC = Xpetra::Helpers<SC, LO, GO, NO>::Op2NonConstEpetraCrs(C);
46 // FIXME
47 XPETRA_DYNAMIC_CAST(const Xpetra::EpetraVectorT<GO XPETRA_COMMA NO>, Dinv, epD, "MueLu::Jacobi() only accepts Xpetra::EpetraVector as input argument.");
48
49 int i = EpetraExt::MatrixMatrix::Jacobi(omega, *epD.getEpetra_Vector(), epA, epB, epC, haveMultiplyDoFillComplete);
50 if (haveMultiplyDoFillComplete) {
51 // Due to Epetra wrapper intricacies, we need to explicitly call
52 // fillComplete on MueLu matrix here. Specifically, EpetraCrsMatrix
53 // only keeps an internal variable to check whether we are in resumed
54 // state or not, but never touches the underlying Epetra object. As
55 // such, we need to explicitly update the state of Xpetra matrix to
56 // that of Epetra one afterwords
57 C.fillComplete();
58 }
59
60 if (i != 0) {
61 std::ostringstream buf;
62 buf << i;
63 std::string msg = "EpetraExt::MatrixMatrix::Jacobi return value of " + buf.str();
64 throw(Exceptions::RuntimeError(msg));
65 }
66#endif
67 } else if (C.getRowMap()->lib() == Xpetra::UseTpetra) {
68#if ((defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_OPENMP) || !defined(HAVE_TPETRA_INST_INT_INT))) || \
69 (!defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_SERIAL) || !defined(HAVE_TPETRA_INST_INT_INT))))
70 throw(MueLu::Exceptions::RuntimeError("Xpetra must be compiled with Tpetra GO=<double,int,int> enabled."));
71#else
72 const Tpetra::CrsMatrix<SC, LO, GO, NO>& tpA = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraCrs(A);
73 const Tpetra::CrsMatrix<SC, LO, GO, NO>& tpB = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraCrs(B);
74 Tpetra::CrsMatrix<SC, LO, GO, NO>& tpC = Xpetra::Helpers<SC, LO, GO, NO>::Op2NonConstTpetraCrs(C);
75 const RCP<Tpetra::Vector<SC, LO, GO, NO> >& tpD = toTpetra(Dinv);
76 Tpetra::MatrixMatrix::Jacobi(omega, *tpD, tpA, tpB, tpC, haveMultiplyDoFillComplete, label, params);
77#endif
78 }
79
80 if (call_FillComplete_on_result && !haveMultiplyDoFillComplete) {
81 RCP<Teuchos::ParameterList> ppp = rcp(new Teuchos::ParameterList());
82 ppp->set("Optimize Storage", doOptimizeStorage);
83 C.fillComplete(B.getDomainMap(), B.getRangeMap(), ppp);
84 }
85
86 // transfer striding information
87 Teuchos::RCP<Xpetra::Matrix<SC, LO, GO, NO> > rcpA = Teuchos::rcp_const_cast<Xpetra::Matrix<SC, LO, GO, NO> >(Teuchos::rcpFromRef(A));
88 Teuchos::RCP<Xpetra::Matrix<SC, LO, GO, NO> > rcpB = Teuchos::rcp_const_cast<Xpetra::Matrix<SC, LO, GO, NO> >(Teuchos::rcpFromRef(B));
89 C.CreateView("stridedMaps", rcpA, false, rcpB, false); // TODO use references instead of RCPs
90}
91#endif
92
93#if defined(HAVE_MUELU_EPETRA) && !defined(XPETRA_EPETRA_NO_64BIT_GLOBAL_INDICES)
94template <>
96 const Xpetra::Vector<double, int, long long, Xpetra::EpetraNode>& Dinv,
97 const Xpetra::Matrix<double, int, long long, Xpetra::EpetraNode>& A,
98 const Xpetra::Matrix<double, int, long long, Xpetra::EpetraNode>& B,
99 Xpetra::Matrix<double, int, long long, Xpetra::EpetraNode>& C,
100 bool call_FillComplete_on_result,
101 bool doOptimizeStorage,
102 const std::string& label,
103 const Teuchos::RCP<Teuchos::ParameterList>& params) {
104 typedef double SC;
105 typedef int LO;
106 typedef long long GO;
107 typedef Xpetra::EpetraNode NO;
108
109 TEUCHOS_TEST_FOR_EXCEPTION(C.getRowMap()->isSameAs(*A.getRowMap()) == false, MueLu::Exceptions::RuntimeError,
110 "MueLu::Jacobi: row map of C is not same as row map of A")
111 TEUCHOS_TEST_FOR_EXCEPTION(C.getRowMap()->isSameAs(*B.getRowMap()) == false, MueLu::Exceptions::RuntimeError,
112 "MueLu::Jacobi: row map of C is not same as row map of B");
113 TEUCHOS_TEST_FOR_EXCEPTION(!A.isFillComplete(), MueLu::Exceptions::RuntimeError, "A is not fill-completed");
114 TEUCHOS_TEST_FOR_EXCEPTION(!B.isFillComplete(), MueLu::Exceptions::RuntimeError, "B is not fill-completed");
115
116 bool haveMultiplyDoFillComplete = call_FillComplete_on_result && doOptimizeStorage;
117
118 if (C.getRowMap()->lib() == Xpetra::UseEpetra) {
119#ifndef HAVE_MUELU_EPETRAEXT
120 throw(MueLu::Exceptions::RuntimeError("MueLu::Jacobi requires EpetraExt to be compiled."));
121#else
122 Epetra_CrsMatrix& epA = Xpetra::Helpers<SC, LO, GO, NO>::Op2NonConstEpetraCrs(A);
123 Epetra_CrsMatrix& epB = Xpetra::Helpers<SC, LO, GO, NO>::Op2NonConstEpetraCrs(B);
124 Epetra_CrsMatrix& epC = Xpetra::Helpers<SC, LO, GO, NO>::Op2NonConstEpetraCrs(C);
125 // FIXME
126 XPETRA_DYNAMIC_CAST(const Xpetra::EpetraVectorT<GO XPETRA_COMMA NO>, Dinv, epD, "MueLu::Jacobi() only accepts Xpetra::EpetraVector as input argument.");
127
128 int i = EpetraExt::MatrixMatrix::Jacobi(omega, *epD.getEpetra_Vector(), epA, epB, epC, haveMultiplyDoFillComplete);
129 if (haveMultiplyDoFillComplete) {
130 // Due to Epetra wrapper intricacies, we need to explicitly call
131 // fillComplete on Xpetra matrix here. Specifically, EpetraCrsMatrix
132 // only keeps an internal variable to check whether we are in resumed
133 // state or not, but never touches the underlying Epetra object. As
134 // such, we need to explicitly update the state of Xpetra matrix to
135 // that of Epetra one afterwords
136 C.fillComplete();
137 }
138
139 if (i != 0) {
140 std::ostringstream buf;
141 buf << i;
142 std::string msg = "EpetraExt::MatrixMatrix::Jacobi return value of " + buf.str();
143 throw(Exceptions::RuntimeError(msg));
144 }
145#endif
146 } else if (C.getRowMap()->lib() == Xpetra::UseTpetra) {
147#if ((defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_OPENMP) || !defined(HAVE_TPETRA_INST_INT_LONG_LONG))) || \
148 (!defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_SERIAL) || !defined(HAVE_TPETRA_INST_INT_LONG_LONG))))
149 throw(MueLu::Exceptions::RuntimeError("Xpetra must be compiled with Tpetra GO=<double,int,long long> enabled."));
150#else
151 const Tpetra::CrsMatrix<SC, LO, GO, NO>& tpA = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraCrs(A);
152 const Tpetra::CrsMatrix<SC, LO, GO, NO>& tpB = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraCrs(B);
153 Tpetra::CrsMatrix<SC, LO, GO, NO>& tpC = Xpetra::Helpers<SC, LO, GO, NO>::Op2NonConstTpetraCrs(C);
154 const RCP<Tpetra::Vector<SC, LO, GO, NO> >& tpD = toTpetra(Dinv);
155 Tpetra::MatrixMatrix::Jacobi(omega, *tpD, tpA, tpB, tpC, haveMultiplyDoFillComplete, label, params);
156#endif
157 }
158
159 if (call_FillComplete_on_result && !haveMultiplyDoFillComplete) {
160 RCP<Teuchos::ParameterList> ppp = rcp(new Teuchos::ParameterList());
161 ppp->set("Optimize Storage", doOptimizeStorage);
162 C.fillComplete(B.getDomainMap(), B.getRangeMap(), ppp);
163 }
164
165 // transfer striding information
166 Teuchos::RCP<Xpetra::Matrix<SC, LO, GO, NO> > rcpA = Teuchos::rcp_const_cast<Xpetra::Matrix<SC, LO, GO, NO> >(Teuchos::rcpFromRef(A));
167 Teuchos::RCP<Xpetra : Matrix<SC, LO, GO, NO> > rcpB = Teuchos::rcp_const_cast<Xpetra::Matrix<SC, LO, GO, NO> >(Teuchos::rcpFromRef(B));
168 C.CreateView("stridedMaps", rcpA, false, rcpB, false); // TODO use references instead of RCPs
169}
170#endif
171
172} // namespace MueLu
static int Jacobi(double omega, const Epetra_Vector &Dinv, const Epetra_CrsMatrix &A, const Epetra_CrsMatrix &B, Epetra_CrsMatrix &C, bool call_FillComplete_on_result=true)
Exception throws to report errors in the internal logical of the program.
Namespace for MueLu classes and methods.
void Jacobi< double, int, long long, Xpetra::EpetraNode >(double omega, const Xpetra::Vector< double, int, long long, Xpetra::EpetraNode > &Dinv, const Xpetra::Matrix< double, int, long long, Xpetra::EpetraNode > &A, const Xpetra::Matrix< double, int, long long, Xpetra::EpetraNode > &B, Xpetra::Matrix< double, int, long long, Xpetra::EpetraNode > &C, bool call_FillComplete_on_result, bool doOptimizeStorage, const std::string &label, const Teuchos::RCP< Teuchos::ParameterList > &params)
void Jacobi< double, int, int, Xpetra::EpetraNode >(double omega, const Xpetra::Vector< double, int, int, Xpetra::EpetraNode > &Dinv, const Xpetra::Matrix< double, int, int, Xpetra::EpetraNode > &A, const Xpetra::Matrix< double, int, int, Xpetra::EpetraNode > &B, Xpetra::Matrix< double, int, int, Xpetra::EpetraNode > &C, bool call_FillComplete_on_result, bool doOptimizeStorage, const std::string &label, const Teuchos::RCP< Teuchos::ParameterList > &params)