Xpetra Version of the Day
Loading...
Searching...
No Matches
Xpetra_Helpers_def.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Xpetra: A linear algebra interface package
4//
5// Copyright 2012 NTESS and the Xpetra contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef XPETRA_HELPERS_DEF_HPP
11#define XPETRA_HELPERS_DEF_HPP
12
14
15namespace Xpetra {
16
17template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
19 // Get the underlying Tpetra Mtx
20 RCP<const CrsMatrixWrap> crsOp = Teuchos::rcp_dynamic_cast<const CrsMatrixWrap>(Op);
21 TEUCHOS_TEST_FOR_EXCEPTION(crsOp == Teuchos::null, Xpetra::Exceptions::BadCast, "Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
22
23 RCP<const CrsMatrix> tmp_CrsMtx = crsOp->getCrsMatrix();
24 const RCP<const Xpetra::TpetraCrsMatrix<SC, LO, GO, NO>>& tmp_ECrsMtx = Teuchos::rcp_dynamic_cast<const Xpetra::TpetraCrsMatrix<SC, LO, GO, NO>>(tmp_CrsMtx);
25 TEUCHOS_TEST_FOR_EXCEPTION(tmp_ECrsMtx == Teuchos::null, Xpetra::Exceptions::BadCast, "Cast from Xpetra::CrsMatrix to Xpetra::TpetraCrsMatrix failed");
26
27 return tmp_ECrsMtx->getTpetra_CrsMatrix();
28}
29
30template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
32 // Get the underlying Tpetra Mtx
33 RCP<const CrsMatrixWrap> crsOp = Teuchos::rcp_dynamic_cast<const CrsMatrixWrap>(Op);
34 TEUCHOS_TEST_FOR_EXCEPTION(crsOp == Teuchos::null, Xpetra::Exceptions::BadCast, "Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
35 RCP<const CrsMatrix> tmp_CrsMtx = crsOp->getCrsMatrix();
36 const RCP<const Xpetra::TpetraCrsMatrix<SC, LO, GO, NO>>& tmp_ECrsMtx = Teuchos::rcp_dynamic_cast<const Xpetra::TpetraCrsMatrix<SC, LO, GO, NO>>(tmp_CrsMtx);
37 TEUCHOS_TEST_FOR_EXCEPTION(tmp_ECrsMtx == Teuchos::null, Xpetra::Exceptions::BadCast, "Cast from Xpetra::CrsMatrix to Xpetra::TpetraCrsMatrix failed");
38
39 return tmp_ECrsMtx->getTpetra_CrsMatrixNonConst();
40}
41
42template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
44 // Get the underlying Tpetra Mtx
45 try {
46 const CrsMatrixWrap& crsOp = dynamic_cast<const CrsMatrixWrap&>(Op);
47 RCP<const CrsMatrix> tmp_CrsMtx = crsOp.getCrsMatrix();
48 const RCP<const Xpetra::TpetraCrsMatrix<SC, LO, GO, NO>>& tmp_TCrsMtx = Teuchos::rcp_dynamic_cast<const Xpetra::TpetraCrsMatrix<SC, LO, GO, NO>>(tmp_CrsMtx);
49 TEUCHOS_TEST_FOR_EXCEPTION(tmp_TCrsMtx == Teuchos::null, Xpetra::Exceptions::BadCast, "Cast from Xpetra::CrsMatrix to Xpetra::TpetraCrsMatrix failed");
50
51 return *tmp_TCrsMtx->getTpetra_CrsMatrix();
52
53 } catch (...) {
54 throw(Xpetra::Exceptions::BadCast("Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed"));
55 }
56}
57
58template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
60 // Get the underlying Tpetra Mtx
61 try {
62 const CrsMatrixWrap& crsOp = dynamic_cast<const CrsMatrixWrap&>(Op);
63 RCP<const CrsMatrix> tmp_CrsMtx = crsOp.getCrsMatrix();
64 const RCP<const Xpetra::TpetraCrsMatrix<SC, LO, GO, NO>>& tmp_TCrsMtx = Teuchos::rcp_dynamic_cast<const Xpetra::TpetraCrsMatrix<SC, LO, GO, NO>>(tmp_CrsMtx);
65 TEUCHOS_TEST_FOR_EXCEPTION(tmp_TCrsMtx == Teuchos::null, Xpetra::Exceptions::BadCast, "Cast from Xpetra::CrsMatrix to Xpetra::TpetraCrsMatrix failed");
66
67 return *Teuchos::rcp_const_cast<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(tmp_TCrsMtx->getTpetra_CrsMatrix());
68
69 } catch (...) {
70 throw(Xpetra::Exceptions::BadCast("Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed"));
71 }
72}
73
74template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
76 RCP<const CrsMatrixWrap> crsOp = Teuchos::rcp_dynamic_cast<const CrsMatrixWrap>(Op);
77 if (crsOp == Teuchos::null) return false;
78 RCP<const CrsMatrix> tmp_CrsMtx = crsOp->getCrsMatrix();
79 const RCP<const Xpetra::TpetraCrsMatrix<SC, LO, GO, NO>>& tmp_ECrsMtx = Teuchos::rcp_dynamic_cast<const Xpetra::TpetraCrsMatrix<SC, LO, GO, NO>>(tmp_CrsMtx);
80 if (tmp_ECrsMtx == Teuchos::null)
81 return false;
82 else
83 return true;
84}
85
86template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
88 try {
89 const CrsMatrixWrap& crsOp = dynamic_cast<const CrsMatrixWrap&>(Op);
90 RCP<const CrsMatrix> tmp_CrsMtx = crsOp.getCrsMatrix();
91 const RCP<const Xpetra::TpetraCrsMatrix<SC, LO, GO, NO>>& tmp_ECrsMtx = Teuchos::rcp_dynamic_cast<const Xpetra::TpetraCrsMatrix<SC, LO, GO, NO>>(tmp_CrsMtx);
92 if (tmp_ECrsMtx == Teuchos::null)
93 return false;
94 else
95 return true;
96 } catch (...) {
97 return false;
98 }
99}
100
101template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
103 RCP<const CrsMatrixWrap> crsOp = Teuchos::rcp_dynamic_cast<const CrsMatrixWrap>(Op);
104 TEUCHOS_TEST_FOR_EXCEPTION(crsOp == Teuchos::null, Xpetra::Exceptions::BadCast, "Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
105
106 RCP<const CrsMatrix> tmp_CrsMtx = crsOp->getCrsMatrix();
107 RCP<const TpetraBlockCrsMatrix> tmp_BlockCrs = Teuchos::rcp_dynamic_cast<const TpetraBlockCrsMatrix>(tmp_CrsMtx);
108 TEUCHOS_TEST_FOR_EXCEPTION(tmp_BlockCrs == Teuchos::null, Xpetra::Exceptions::BadCast, "Cast from Xpetra::CrsMatrix to Xpetra::TpetraBlockCrsMatrix failed");
109 return tmp_BlockCrs->getTpetra_BlockCrsMatrix();
110}
111
112template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
114 RCP<const CrsMatrixWrap> crsOp = Teuchos::rcp_dynamic_cast<const CrsMatrixWrap>(Op);
115 TEUCHOS_TEST_FOR_EXCEPTION(crsOp == Teuchos::null, Xpetra::Exceptions::BadCast, "Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
116
117 RCP<const CrsMatrix> tmp_CrsMtx = crsOp->getCrsMatrix();
118 RCP<const TpetraBlockCrsMatrix> tmp_BlockCrs = Teuchos::rcp_dynamic_cast<const TpetraBlockCrsMatrix>(tmp_CrsMtx);
119 TEUCHOS_TEST_FOR_EXCEPTION(tmp_BlockCrs == Teuchos::null, Xpetra::Exceptions::BadCast, "Cast from Xpetra::CrsMatrix to Xpetra::TpetraBlockCrsMatrix failed");
120 return tmp_BlockCrs->getTpetra_BlockCrsMatrixNonConst();
121}
122
123template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
125 try {
126 const CrsMatrixWrap& crsOp = dynamic_cast<const CrsMatrixWrap&>(Op);
127 RCP<const CrsMatrix> tmp_CrsMtx = crsOp.getCrsMatrix();
128 RCP<const TpetraBlockCrsMatrix> tmp_BlockCrs = Teuchos::rcp_dynamic_cast<const TpetraBlockCrsMatrix>(tmp_CrsMtx);
129 TEUCHOS_TEST_FOR_EXCEPTION(tmp_BlockCrs == Teuchos::null, Xpetra::Exceptions::BadCast, "Cast from Xpetra::CrsMatrix to Xpetra::TpetraBlockCrsMatrix failed");
130 return *tmp_BlockCrs->getTpetra_BlockCrsMatrix();
131 } catch (...) {
132 throw(Xpetra::Exceptions::BadCast("Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed"));
133 }
134}
135
136template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
138 try {
139 const CrsMatrixWrap& crsOp = dynamic_cast<const CrsMatrixWrap&>(Op);
140 RCP<const CrsMatrix> tmp_CrsMtx = crsOp.getCrsMatrix();
141 RCP<const TpetraBlockCrsMatrix> tmp_BlockCrs = Teuchos::rcp_dynamic_cast<const TpetraBlockCrsMatrix>(tmp_CrsMtx);
142 TEUCHOS_TEST_FOR_EXCEPTION(tmp_BlockCrs == Teuchos::null, Xpetra::Exceptions::BadCast, "Cast from Xpetra::CrsMatrix to Xpetra::TpetraBlockCrsMatrix failed");
143 return *tmp_BlockCrs->getTpetra_BlockCrsMatrixNonConst();
144 } catch (...) {
145 throw(Xpetra::Exceptions::BadCast("Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed"));
146 }
147}
148
149template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
151 RCP<const CrsMatrixWrap> crsOp = Teuchos::rcp_dynamic_cast<const CrsMatrixWrap>(Op);
152 if (crsOp == Teuchos::null) return false;
153 RCP<const CrsMatrix> tmp_CrsMtx = crsOp->getCrsMatrix();
154 RCP<const TpetraBlockCrsMatrix> tmp_BlockCrs = Teuchos::rcp_dynamic_cast<const TpetraBlockCrsMatrix>(tmp_CrsMtx);
155 if (tmp_BlockCrs == Teuchos::null)
156 return false;
157 else
158 return true;
159}
160
161template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
163 try {
164 const CrsMatrixWrap& crsOp = dynamic_cast<const CrsMatrixWrap&>(Op);
165 RCP<const CrsMatrix> tmp_CrsMtx = crsOp.getCrsMatrix();
166 RCP<const TpetraBlockCrsMatrix> tmp_BlockCrs = Teuchos::rcp_dynamic_cast<const TpetraBlockCrsMatrix>(tmp_CrsMtx);
167 if (tmp_BlockCrs == Teuchos::null)
168 return false;
169 else
170 return true;
171 } catch (...) {
172 return false;
173 }
174}
175
176template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
178 const tcrs_matrix_type& A, bool transposeA, const typename tcrs_matrix_type::scalar_type alpha,
179 const tcrs_matrix_type& B, bool transposeB, const typename tcrs_matrix_type::scalar_type beta) {
180 using Teuchos::Array;
182 using Teuchos::RCP;
183 using Teuchos::rcp;
184 using Teuchos::rcp_implicit_cast;
185 using Teuchos::rcpFromRef;
187 using CrsType = Xpetra::CrsMatrix<SC, LO, GO, NO>;
189 using transposer_type = Tpetra::RowMatrixTransposer<SC, LO, GO, NO>;
190 using import_type = Tpetra::Import<LO, GO, NO>;
191 RCP<const tcrs_matrix_type> Aprime = rcpFromRef(A);
192 if (transposeA)
193 Aprime = transposer_type(Aprime).createTranspose();
194 // Decide whether the fast code path can be taken.
195 if (A.isFillComplete() && B.isFillComplete()) {
196 RCP<tcrs_matrix_type> C = rcp(new tcrs_matrix_type(Aprime->getRowMap(), 0));
197 RCP<ParameterList> addParams = rcp(new ParameterList);
198 addParams->set("Call fillComplete", false);
199 // passing A after B means C will have the same domain/range map as A (or A^T if transposeA)
200 Tpetra::MatrixMatrix::add<SC, LO, GO, NO>(beta, transposeB, B, alpha, false, *Aprime, *C, Teuchos::null, Teuchos::null, addParams);
201 return rcp_implicit_cast<Matrix>(rcp(new CrsWrap(rcp_implicit_cast<CrsType>(rcp(new XTCrsType(C))))));
202 } else {
203 // Slow case - one or both operands are non-fill complete.
204 // TODO: deprecate this.
205 // Need to compute the explicit transpose before add if transposeA and/or transposeB.
206 // This is to count the number of entries to allocate per row in the final sum.
207 RCP<const tcrs_matrix_type> Bprime = rcpFromRef(B);
208 if (transposeB)
209 Bprime = transposer_type(Bprime).createTranspose();
210 // Use Aprime's row map as C's row map.
211 if (!(Aprime->getRowMap()->isSameAs(*(Bprime->getRowMap())))) {
212 auto import = rcp(new import_type(Bprime->getRowMap(), Aprime->getRowMap()));
213 Bprime = Tpetra::importAndFillCompleteCrsMatrix<tcrs_matrix_type>(Bprime, *import, Aprime->getDomainMap(), Aprime->getRangeMap());
214 }
215 // Count the entries to allocate for C in each local row.
216 LO numLocalRows = Aprime->getLocalNumRows();
217 Array<size_t> allocPerRow(numLocalRows);
218 // 0 is always the minimum LID
219 for (LO i = 0; i < numLocalRows; i++) {
220 allocPerRow[i] = Aprime->getNumEntriesInLocalRow(i) + Bprime->getNumEntriesInLocalRow(i);
221 }
222 // Construct C
223 RCP<tcrs_matrix_type> C = rcp(new tcrs_matrix_type(Aprime->getRowMap(), allocPerRow()));
224 // Compute the sum in C (already took care of transposes)
225 Tpetra::MatrixMatrix::Add<SC, LO, GO, NO>(
226 *Aprime, false, alpha,
227 *Bprime, false, beta,
228 C);
229 return rcp(new CrsWrap(rcp_implicit_cast<CrsType>(rcp(new XTCrsType(C)))));
230 }
231}
232
233} // namespace Xpetra
234
235#endif
LocalOrdinal LO
bool isFillComplete() const override
Concrete implementation of Xpetra::Matrix.
RCP< CrsMatrix > getCrsMatrix() const
Exception indicating invalid cast attempted.
static RCP< Tpetra::CrsMatrix< SC, LO, GO, NO > > Op2NonConstTpetraCrs(RCP< Matrix > Op)
static RCP< const Tpetra::BlockCrsMatrix< SC, LO, GO, NO > > Op2TpetraBlockCrs(RCP< Matrix > Op)
static bool isTpetraBlockCrs(RCP< Matrix > Op)
static RCP< const Tpetra::CrsMatrix< SC, LO, GO, NO > > Op2TpetraCrs(RCP< Matrix > Op)
static RCP< Tpetra::BlockCrsMatrix< SC, LO, GO, NO > > Op2NonConstTpetraBlockCrs(RCP< Matrix > Op)
static bool isTpetraCrs(RCP< Matrix > Op)
static Teuchos::RCP< Matrix > tpetraAdd(const tcrs_matrix_type &A, bool transposeA, const typename tcrs_matrix_type::scalar_type alpha, const tcrs_matrix_type &B, bool transposeB, const typename tcrs_matrix_type::scalar_type beta)
Xpetra-specific matrix class.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)