10#ifndef XPETRA_THYRAUTILS_HPP
11#define XPETRA_THYRAUTILS_HPP
14#ifdef HAVE_XPETRA_THYRA
18#ifdef HAVE_XPETRA_TPETRA
19#include "Tpetra_ConfigDefs.hpp"
22#ifdef HAVE_XPETRA_EPETRA
23#include "Epetra_config.h"
27#include "Xpetra_Map.hpp"
28#include "Xpetra_BlockedMap.hpp"
29#include "Xpetra_BlockedMultiVector.hpp"
30#include "Xpetra_BlockedCrsMatrix.hpp"
32#include "Xpetra_StridedMap.hpp"
33#include "Xpetra_StridedMapFactory.hpp"
34#include "Xpetra_MapExtractor.hpp"
35#include "Xpetra_Matrix.hpp"
36#include "Xpetra_MatrixFactory.hpp"
37#include "Xpetra_CrsMatrixWrap.hpp"
38#include "Xpetra_MultiVectorFactory.hpp"
40#include <Thyra_VectorSpaceBase.hpp>
41#include <Thyra_SpmdVectorSpaceBase.hpp>
42#include <Thyra_ProductVectorSpaceBase.hpp>
43#include <Thyra_ProductMultiVectorBase.hpp>
44#include <Thyra_VectorSpaceBase.hpp>
45#include <Thyra_DefaultProductVectorSpace.hpp>
46#include <Thyra_DefaultBlockedLinearOp.hpp>
47#include <Thyra_LinearOpBase.hpp>
48#include "Thyra_DiagonalLinearOpBase.hpp"
49#include <Thyra_DetachedMultiVectorView.hpp>
50#include <Thyra_MultiVectorStdOps.hpp>
52#ifdef HAVE_XPETRA_TPETRA
53#include <Thyra_TpetraThyraWrappers.hpp>
54#include <Thyra_TpetraVector.hpp>
55#include <Thyra_TpetraMultiVector.hpp>
56#include <Thyra_TpetraVectorSpace.hpp>
57#include <Tpetra_Map.hpp>
58#include <Tpetra_Vector.hpp>
59#include <Tpetra_CrsMatrix.hpp>
60#include <Xpetra_TpetraMap.hpp>
62#include <Xpetra_TpetraCrsMatrix.hpp>
64#ifdef HAVE_XPETRA_EPETRA
65#include <Thyra_EpetraLinearOp.hpp>
66#include <Thyra_EpetraThyraWrappers.hpp>
67#include <Thyra_SpmdVectorBase.hpp>
68#include <Thyra_get_Epetra_Operator.hpp>
69#include <Epetra_Map.h>
70#include <Epetra_Vector.h>
71#include <Epetra_CrsMatrix.h>
78template <
class Scalar,
79 class LocalOrdinal = int,
80 class GlobalOrdinal = LocalOrdinal,
81 class Node = Tpetra::KokkosClassic::DefaultNode::DefaultNodeType>
84#undef XPETRA_THYRAUTILS_SHORT
88 static Teuchos::RCP<Xpetra::StridedMap<LocalOrdinal, GlobalOrdinal, Node>>
89 toXpetra(
const Teuchos::RCP<
const Thyra::VectorSpaceBase<Scalar>>& vectorSpace,
const Teuchos::RCP<
const Teuchos::Comm<int>>& comm, std::vector<size_t>& stridingInfo, LocalOrdinal stridedBlockId = -1, GlobalOrdinal offset = 0);
91 static Teuchos::RCP<Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
92 toXpetra(
const Teuchos::RCP<
const Thyra::VectorSpaceBase<Scalar>>& vectorSpace,
const Teuchos::RCP<
const Teuchos::Comm<int>>& comm);
95 static Teuchos::RCP<const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
96 toXpetra(Teuchos::RCP<
const Thyra::MultiVectorBase<Scalar>> v,
const Teuchos::RCP<
const Teuchos::Comm<int>>& comm);
99 static Teuchos::RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
100 toXpetra(Teuchos::RCP<Thyra::MultiVectorBase<Scalar>> v,
const Teuchos::RCP<
const Teuchos::Comm<int>>& comm);
102 static bool isTpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op);
104 static bool isEpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op);
106 static bool isBlockedOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op);
108 static Teuchos::RCP<const Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
109 toXpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op);
111 static Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
112 toXpetra(
const Teuchos::RCP<Thyra::LinearOpBase<Scalar>>& op);
114 static Teuchos::RCP<const Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
115 toXpetraOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op);
117 static Teuchos::RCP<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
118 toXpetraOperator(
const Teuchos::RCP<Thyra::LinearOpBase<Scalar>>& op);
120 static Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
121 toXpetra(
const Teuchos::RCP<Thyra::DiagonalLinearOpBase<Scalar>>& op);
123 static Teuchos::RCP<const Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
124 toXpetra(
const Teuchos::RCP<
const Thyra::DiagonalLinearOpBase<Scalar>>& op);
126 static Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>>
127 toThyra(Teuchos::RCP<
const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> map);
129 static Teuchos::RCP<const Thyra::MultiVectorBase<Scalar>>
130 toThyraMultiVector(Teuchos::RCP<
const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> vec);
132 static Teuchos::RCP<const Thyra::VectorBase<Scalar>>
133 toThyraVector(Teuchos::RCP<
const Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> vec);
138 updateThyra(Teuchos::RCP<
const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> source, Teuchos::RCP<
const Xpetra::MapExtractor<Scalar, LocalOrdinal, GlobalOrdinal, Node>> mapExtractor,
const Teuchos::RCP<Thyra::MultiVectorBase<Scalar>>& target);
140 static Teuchos::RCP<const Thyra::LinearOpBase<Scalar>>
141 toThyra(
const Teuchos::RCP<
const Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& mat);
143 static Teuchos::RCP<Thyra::LinearOpBase<Scalar>>
144 toThyra(
const Teuchos::RCP<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& mat);
146 static Teuchos::RCP<Thyra::LinearOpBase<Scalar>>
147 toThyra(
const Teuchos::RCP<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& mat);
153#ifdef HAVE_XPETRA_EPETRA
155#ifndef XPETRA_EPETRA_NO_32BIT_GLOBAL_INDICES
157class ThyraUtils<double, int, int,
EpetraNode> {
159 typedef double Scalar;
160 typedef int LocalOrdinal;
161 typedef int GlobalOrdinal;
165#undef XPETRA_THYRAUTILS_SHORT
169 static Teuchos::RCP<Xpetra::StridedMap<LocalOrdinal, GlobalOrdinal, Node>>
170 toXpetra(
const Teuchos::RCP<
const Thyra::VectorSpaceBase<Scalar>>& vectorSpace,
const Teuchos::RCP<
const Teuchos::Comm<int>>& comm, std::vector<size_t>& stridingInfo, LocalOrdinal stridedBlockId = -1, GlobalOrdinal offset = 0) {
171 Teuchos::RCP<Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> map = ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::toXpetra(vectorSpace, comm);
173 if (stridedBlockId == -1) {
183 static Teuchos::RCP<Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
184 toXpetra(
const Teuchos::RCP<
const Thyra::VectorSpaceBase<Scalar>>& vectorSpace,
const Teuchos::RCP<
const Teuchos::Comm<int>>& comm) {
187 using Teuchos::rcp_dynamic_cast;
188 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
189 typedef Thyra::ProductVectorSpaceBase<Scalar> ThyProdVecSpaceBase;
190 typedef Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node> ThyUtils;
192 RCP<Map> resultMap = Teuchos::null;
194 RCP<const ThyProdVecSpaceBase> prodVectorSpace = rcp_dynamic_cast<const ThyProdVecSpaceBase>(vectorSpace);
195 if (prodVectorSpace != Teuchos::null) {
198 TEUCHOS_TEST_FOR_EXCEPTION(prodVectorSpace->numBlocks() == 0, std::logic_error,
"Found a product vector space with zero blocks.");
199 std::vector<RCP<const Map>> mapsThyra(prodVectorSpace->numBlocks(), Teuchos::null);
200 std::vector<RCP<const Map>> mapsXpetra(prodVectorSpace->numBlocks(), Teuchos::null);
201 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b) {
202 RCP<const ThyVecSpaceBase> bv = prodVectorSpace->getBlock(b);
204 mapsThyra[b] = ThyUtils::toXpetra(bv, comm);
209 std::vector<GlobalOrdinal> gidOffsets(prodVectorSpace->numBlocks(), 0);
210 for (
int i = 1; i < prodVectorSpace->numBlocks(); ++i) {
211 gidOffsets[i] = mapsThyra[i - 1]->getMaxAllGlobalIndex() + gidOffsets[i - 1] + 1;
214 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b) {
215 RCP<const ThyVecSpaceBase> bv = prodVectorSpace->getBlock(b);
217 mapsXpetra[b] = MapUtils::transformThyra2XpetraGIDs(*mapsThyra[b], gidOffsets[b]);
220 resultMap =
Teuchos::rcp(
new Xpetra::BlockedMap<LocalOrdinal, GlobalOrdinal, Node>(mapsXpetra, mapsThyra));
226 bool bIsTpetra =
false;
227#ifdef HAVE_XPETRA_TPETRA
228#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
229 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
230 Teuchos::RCP<const Thyra::TpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpetra_vsc = Teuchos::rcp_dynamic_cast<const Thyra::TpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(vectorSpace);
236 bool bIsEpetra = !bIsTpetra;
238#ifdef HAVE_XPETRA_TPETRA
240#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
241 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
242 typedef Thyra::VectorBase<Scalar> ThyVecBase;
243 typedef Tpetra::Map<LocalOrdinal, GlobalOrdinal, Node> TpMap;
244 typedef Tpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpVector;
245 typedef Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node> TOE;
246 RCP<ThyVecBase> rgVec = Thyra::createMember<Scalar>(vectorSpace, std::string(
"label"));
248 RCP<const TpVector> rgTpetraVec = TOE::getTpetraVector(rgVec);
250 RCP<const TpMap> rgTpetraMap = rgTpetraVec->getMap();
255 throw Xpetra::Exceptions::RuntimeError(
"Problem AAA. Add TPETRA_INST_INT_INT:BOOL=ON in your configuration.");
260#ifdef HAVE_XPETRA_EPETRA
263 RCP<const Epetra_Map>
264 epetra_map = Teuchos::get_extra_data<RCP<const Epetra_Map>>(vectorSpace,
"epetra_map");
266 resultMap =
Teuchos::rcp(
new Xpetra::EpetraMapT<GlobalOrdinal, Node>(epetra_map));
279 static Teuchos::RCP<const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
280 toXpetra(Teuchos::RCP<
const Thyra::MultiVectorBase<Scalar>> v,
const Teuchos::RCP<
const Teuchos::Comm<int>>& comm) {
283 using Teuchos::rcp_dynamic_cast;
285 using ThyProdMultVecBase = Thyra::ProductMultiVectorBase<Scalar>;
286 using ThyMultVecBase = Thyra::MultiVectorBase<Scalar>;
287 using ThyUtils = Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
290 RCP<MultiVector> xpMultVec = Teuchos::null;
293 Teuchos::RCP<const ThyProdMultVecBase> thyProdVec = rcp_dynamic_cast<const ThyProdMultVecBase>(v);
294 if (thyProdVec != Teuchos::null) {
297 RCP<Map> fullMap = ThyUtils::toXpetra(v->range(), comm);
301 xpMultVec = MultiVectorFactory::Build(fullMap, as<size_t>(thyProdVec->domain()->dim()));
303 RCP<BlockedMultiVector> xpBlockedMultVec = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(xpMultVec,
true);
306 for (
int b = 0; b < thyProdVec->productSpace()->numBlocks(); ++b) {
307 RCP<const ThyMultVecBase> thyBlockMV = thyProdVec->getMultiVectorBlock(b);
309 RCP<const MultiVector> xpBlockMV = ThyUtils::toXpetra(thyBlockMV, comm);
310 xpBlockedMultVec->setMultiVector(b, xpBlockMV,
true );
318 bool bIsTpetra =
false;
319#ifdef HAVE_XPETRA_TPETRA
320#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
321 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
325 typedef Thyra::SpmdMultiVectorBase<Scalar> ThySpmdMultVecBase;
326 typedef Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node> ConverterT;
327 typedef Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpMultVec;
328 typedef Xpetra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> XpTpMultVec;
329 typedef Thyra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> ThyTpMultVec;
331 RCP<const ThySpmdMultVecBase> thyraSpmdMultiVector = rcp_dynamic_cast<const ThySpmdMultVecBase>(v);
332 RCP<const ThyTpMultVec> thyraTpetraMultiVector = rcp_dynamic_cast<const ThyTpMultVec>(thyraSpmdMultiVector);
333 if (thyraTpetraMultiVector != Teuchos::null) {
335 const RCP<const TpMultVec> tpMultVec = ConverterT::getConstTpetraMultiVector(v);
337 RCP<TpMultVec> tpNonConstMultVec = Teuchos::rcp_const_cast<TpMultVec>(tpMultVec);
339 xpMultVec =
rcp(
new XpTpMultVec(tpNonConstMultVec));
344#ifdef HAVE_XPETRA_EPETRA
345 if (bIsTpetra ==
false) {
347 Teuchos::RCP<Map> map = ThyUtils::toXpetra(v->range(), comm);
349 RCP<Xpetra::EpetraMapT<GlobalOrdinal, Node>> xeMap = rcp_dynamic_cast<Xpetra::EpetraMapT<GlobalOrdinal, Node>>(map,
true);
350 RCP<const Epetra_Map> eMap = xeMap->getEpetra_MapRCP();
352 Teuchos::RCP<const Epetra_MultiVector> epMultVec = Thyra::get_Epetra_MultiVector(*eMap, v);
354 RCP<Epetra_MultiVector> epNonConstMultVec = Teuchos::rcp_const_cast<Epetra_MultiVector>(epMultVec);
356 xpMultVec =
Teuchos::rcp(
new Xpetra::EpetraMultiVectorT<GlobalOrdinal, Node>(epNonConstMultVec));
365 static Teuchos::RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
366 toXpetra(Teuchos::RCP<Thyra::MultiVectorBase<Scalar>> v,
const Teuchos::RCP<
const Teuchos::Comm<int>>& comm) {
367 Teuchos::RCP<const Thyra::MultiVectorBase<Scalar>> cv =
368 Teuchos::rcp_const_cast<const Thyra::MultiVectorBase<Scalar>>(v);
369 Teuchos::RCP<const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> r =
371 return Teuchos::rcp_const_cast<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(r);
374 static bool isTpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op) {
376 bool bIsTpetra =
false;
377#ifdef HAVE_XPETRA_TPETRA
378#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
379 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
381 Teuchos::RCP<const Thyra::TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpetra_op = Teuchos::rcp_dynamic_cast<const Thyra::TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(op);
386#ifdef HAVE_XPETRA_EPETRA
387 Teuchos::rcp_dynamic_cast<const Thyra::EpetraLinearOp>(op) == Teuchos::null &&
389 Teuchos::rcp_dynamic_cast<
const Thyra::DefaultBlockedLinearOp<Scalar>>(op) == Teuchos::null) {
391 typedef Thyra::TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpetraLinearOp_t;
392 if (Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op) == Teuchos::null) {
393 std::cout <<
"ATTENTION: The dynamic cast to the TpetraLinearOp failed even though it should be a TpetraLinearOp." << std::endl;
394 std::cout <<
" If you are using Panzer or Stratimikos you might check that the template parameters are " << std::endl;
395 std::cout <<
" properly set!" << std::endl;
396 std::cout << Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op,
true) << std::endl;
406 if(bIsTpetra ==
false) {
407 Teuchos::RCP<const Thyra::BlockedLinearOpBase<Scalar> > ThyBlockedOp =
408 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op);
409 if(ThyBlockedOp != Teuchos::null) {
411 Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > b00 =
412 ThyBlockedOp->getBlock(0,0);
414 bIsTpetra = isTpetra(b00);
422 static bool isEpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op) {
424 bool bIsEpetra =
false;
426#ifdef HAVE_XPETRA_EPETRA
427 Teuchos::RCP<const Thyra::EpetraLinearOp> epetra_op = Teuchos::rcp_dynamic_cast<const Thyra::EpetraLinearOp>(op,
false);
435 if(bIsEpetra ==
false) {
436 Teuchos::RCP<const Thyra::BlockedLinearOpBase<Scalar> > ThyBlockedOp =
437 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op,
false);
438 if(ThyBlockedOp != Teuchos::null) {
440 Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > b00 =
441 ThyBlockedOp->getBlock(0,0);
443 bIsEpetra = isEpetra(b00);
451 static bool isBlockedOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op) {
453 Teuchos::RCP<const Thyra::BlockedLinearOpBase<Scalar>> ThyBlockedOp =
454 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar>>(op);
455 if (ThyBlockedOp != Teuchos::null) {
461 static Teuchos::RCP<const Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
462 toXpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op) {
463#ifdef HAVE_XPETRA_TPETRA
465#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
466 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
468 typedef Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node> TOE;
469 Teuchos::RCP<const Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraOp = TOE::getConstTpetraOperator(op);
473 Teuchos::RCP<const Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraRowMat = Teuchos::rcp_dynamic_cast<const Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(TpetraOp);
475 Teuchos::RCP<const Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraCrsMat = Teuchos::rcp_dynamic_cast<const Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(TpetraRowMat,
true);
476 Teuchos::RCP<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraNcnstCrsMat = Teuchos::rcp_const_cast<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(TpetraCrsMat);
479 Teuchos::RCP<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xTpetraCrsMat =
480 Teuchos::rcp(
new Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>(TpetraNcnstCrsMat));
482 Teuchos::RCP<const Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> ret =
483 Teuchos::rcp_dynamic_cast<const Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xTpetraCrsMat);
484 Teuchos::RCP<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpCrsMat =
485 Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xTpetraCrsMat,
true);
486 Teuchos::RCP<Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpCrsWrap =
487 Teuchos::rcp(
new Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>(xpCrsMat));
488 Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpMat =
489 Teuchos::rcp_dynamic_cast<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpCrsWrap,
true);
492 throw Xpetra::Exceptions::RuntimeError(
"Problem BBB. Add TPETRA_INST_INT_INT:BOOL=ON in your configuration.");
497#ifdef HAVE_XPETRA_EPETRA
499 Teuchos::RCP<const Epetra_Operator> epetra_op = Thyra::get_Epetra_Operator(*op);
501 Teuchos::RCP<const Epetra_RowMatrix> epetra_rowmat = Teuchos::rcp_dynamic_cast<const Epetra_RowMatrix>(epetra_op,
true);
502 Teuchos::RCP<const Epetra_CrsMatrix> epetra_crsmat = Teuchos::rcp_dynamic_cast<const Epetra_CrsMatrix>(epetra_rowmat,
true);
503 Teuchos::RCP<Epetra_CrsMatrix> epetra_ncnstcrsmat = Teuchos::rcp_const_cast<Epetra_CrsMatrix>(epetra_crsmat);
506 Teuchos::RCP<Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>> xEpetraCrsMat =
507 Teuchos::rcp(
new Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>(epetra_ncnstcrsmat));
510 Teuchos::RCP<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpCrsMat =
511 Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xEpetraCrsMat,
true);
512 Teuchos::RCP<Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpCrsWrap =
513 Teuchos::rcp(
new Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>(xpCrsMat));
514 Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpMat =
515 Teuchos::rcp_dynamic_cast<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpCrsWrap,
true);
519 return Teuchos::null;
522 static Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
523 toXpetra(
const Teuchos::RCP<Thyra::LinearOpBase<Scalar>>& op) {
524#ifdef HAVE_XPETRA_TPETRA
526#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
527 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
529 typedef Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node> TOE;
530 Teuchos::RCP<Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraOp = TOE::getTpetraOperator(op);
532 Teuchos::RCP<Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraRowMat = Teuchos::rcp_dynamic_cast<Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(TpetraOp,
true);
533 Teuchos::RCP<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraCrsMat = Teuchos::rcp_dynamic_cast<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(TpetraRowMat,
true);
535 Teuchos::RCP<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xTpetraCrsMat =
536 Teuchos::rcp(
new Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>(TpetraCrsMat));
538 Teuchos::RCP<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpCrsMat =
539 Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xTpetraCrsMat,
true);
540 Teuchos::RCP<Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpCrsWrap =
541 Teuchos::rcp(
new Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>(xpCrsMat));
542 Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpMat =
543 Teuchos::rcp_dynamic_cast<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpCrsWrap,
true);
546 throw Xpetra::Exceptions::RuntimeError(
"Problem CCC. Add TPETRA_INST_INT_INT:BOOL=ON in your configuration.");
551#ifdef HAVE_XPETRA_EPETRA
553 Teuchos::RCP<Epetra_Operator> epetra_op = Thyra::get_Epetra_Operator(*op);
555 Teuchos::RCP<Epetra_RowMatrix> epetra_rowmat = Teuchos::rcp_dynamic_cast<Epetra_RowMatrix>(epetra_op,
true);
556 Teuchos::RCP<Epetra_CrsMatrix> epetra_crsmat = Teuchos::rcp_dynamic_cast<Epetra_CrsMatrix>(epetra_rowmat,
true);
558 Teuchos::RCP<Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>> xEpetraCrsMat =
559 Teuchos::rcp(
new Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>(epetra_crsmat));
561 Teuchos::RCP<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpCrsMat =
562 Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xEpetraCrsMat,
true);
563 Teuchos::RCP<Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpCrsWrap =
564 Teuchos::rcp(
new Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>(xpCrsMat));
565 Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpMat =
566 Teuchos::rcp_dynamic_cast<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpCrsWrap,
true);
570 return Teuchos::null;
573 static Teuchos::RCP<const Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
574 toXpetraOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op) {
575 return toXpetraOperator(Teuchos::rcp_const_cast<Thyra::LinearOpBase<Scalar>>(op));
603 static Teuchos::RCP<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
604 toXpetraOperator(
const Teuchos::RCP<Thyra::LinearOpBase<Scalar>>& op) {
605#ifdef HAVE_XPETRA_TPETRA
607 typedef Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node> TOE;
608 Teuchos::RCP<Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraOp = TOE::getTpetraOperator(op);
610 Teuchos::RCP<Xpetra::TpetraOperator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xTpetraOp =
611 Teuchos::rcp(
new Xpetra::TpetraOperator<Scalar, LocalOrdinal, GlobalOrdinal, Node>(TpetraOp));
614 Teuchos::RCP<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpOp =
615 Teuchos::rcp_dynamic_cast<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xTpetraOp,
true);
620#ifdef HAVE_XPETRA_EPETRA
622 TEUCHOS_TEST_FOR_EXCEPTION(
true, Xpetra::Exceptions::RuntimeError,
"Epetra needs SC=double, LO=int, and GO=int or GO=long long");
625 return Teuchos::null;
628 static Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
629 toXpetra(
const Teuchos::RCP<Thyra::DiagonalLinearOpBase<Scalar>>& op) {
630 using Teuchos::rcp_const_cast;
631 using Teuchos::rcp_dynamic_cast;
633 RCP<const Thyra::VectorBase<Scalar>> diag = op->getDiag();
635 RCP<const Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpDiag;
636#ifdef HAVE_XPETRA_TPETRA
637 using thyTpV = Thyra::TpetraVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
638 using tV = Tpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
639 if (!rcp_dynamic_cast<const thyTpV>(diag).
is_null()) {
640 RCP<const tV> tDiag = Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node>::getConstTpetraVector(diag);
641 if (!tDiag.is_null())
645#ifdef HAVE_XPETRA_EPETRA
646 using ThyVSBase = Thyra::SpmdVectorSpaceBase<Scalar>;
647 if (xpDiag.is_null()) {
648 RCP<const Epetra_Comm> comm = Thyra::get_Epetra_Comm(*rcp_dynamic_cast<const ThyVSBase>(op->range())->getComm());
649 RCP<const Epetra_Map> map = Thyra::get_Epetra_Map(*(op->range()), comm);
650 if (!map.is_null()) {
651 RCP<const Epetra_Vector> eDiag = Thyra::get_Epetra_Vector(*map, diag);
652 RCP<Epetra_Vector> nceDiag = rcp_const_cast<Epetra_Vector>(eDiag);
653 RCP<Xpetra::EpetraVectorT<int, Node>> xpEpDiag =
rcp(
new Xpetra::EpetraVectorT<int, Node>(nceDiag));
654 xpDiag = rcp_dynamic_cast<Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpEpDiag,
true);
659 RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> M = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(xpDiag);
663 static Teuchos::RCP<const Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
664 toXpetra(
const Teuchos::RCP<
const Thyra::DiagonalLinearOpBase<Scalar>>& op) {
665 return toXpetra(Teuchos::rcp_const_cast<Thyra::DiagonalLinearOpBase<Scalar>>(op));
668 static Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>>
669 toThyra(Teuchos::RCP<
const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> map) {
670 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>> thyraMap = Teuchos::null;
673 RCP<const BlockedMap> bmap = Teuchos::rcp_dynamic_cast<const BlockedMap>(map);
674 if (bmap.is_null() ==
false) {
675 Teuchos::Array<Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>>> vecSpaces(bmap->getNumMaps());
676 for (
size_t i = 0; i < bmap->getNumMaps(); i++) {
678 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>> vs =
679 Xpetra::ThyraUtils<Scalar, LO, GO, Node>::toThyra(bmap->getMap(i,
true));
683 thyraMap = Thyra::productVectorSpace<Scalar>(vecSpaces());
688#ifdef HAVE_XPETRA_TPETRA
690#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
691 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
692 Teuchos::RCP<const Xpetra::TpetraMap<LocalOrdinal, GlobalOrdinal, Node>> tpetraMap = Teuchos::rcp_dynamic_cast<const Xpetra::TpetraMap<LocalOrdinal, GlobalOrdinal, Node>>(map);
693 if (tpetraMap == Teuchos::null)
694 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::TpetraMap failed");
695 RCP<const Tpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> tpMap = tpetraMap->getTpetra_Map();
696 RCP<Thyra::TpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>> thyraTpetraMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tpMap);
697 thyraMap = thyraTpetraMap;
699 throw Xpetra::Exceptions::RuntimeError(
"Problem DDD. Add TPETRA_INST_INT_INT:BOOL=ON in your configuration.");
704#ifdef HAVE_XPETRA_EPETRA
706 Teuchos::RCP<const Xpetra::EpetraMapT<GlobalOrdinal, Node>> epetraMap = Teuchos::rcp_dynamic_cast<const Xpetra::EpetraMapT<GlobalOrdinal, Node>>(map);
707 if (epetraMap == Teuchos::null)
708 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::EpetraMap failed");
709 RCP<const Thyra::VectorSpaceBase<Scalar>> thyraEpetraMap = Thyra::create_VectorSpace(epetraMap->getEpetra_MapRCP());
710 thyraMap = thyraEpetraMap;
717 static Teuchos::RCP<const Thyra::MultiVectorBase<Scalar>>
718 toThyraMultiVector(Teuchos::RCP<
const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> vec) {
720#ifdef HAVE_XPETRA_TPETRA
722 auto thyTpMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(Teuchos::rcp_dynamic_cast<const TpetraMap>(vec->getMap())->getTpetra_Map());
723 RCP<Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpMV = Teuchos::rcp_dynamic_cast<const TpetraMultiVector>(vec)->getTpetra_MultiVector();
724 auto thyDomMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(Tpetra::createLocalMapWithNode<LocalOrdinal, GlobalOrdinal, Node>(vec->getNumVectors(), vec->getMap()->getComm()));
725 auto thyMV =
rcp(
new Thyra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>());
726 thyMV->initialize(thyTpMap, thyDomMap, tpMV);
731#ifdef HAVE_XPETRA_EPETRA
733 auto thyEpMap = Thyra::create_VectorSpace(Teuchos::rcp_dynamic_cast<
const EpetraMapT<GlobalOrdinal, Node>>(vec->getMap())->getEpetra_MapRCP());
734 auto epMV = Teuchos::rcp_dynamic_cast<const EpetraMultiVectorT<GlobalOrdinal, Node>>(vec)->getEpetra_MultiVector();
735 auto thyMV = Thyra::create_MultiVector(epMV, thyEpMap);
743 static Teuchos::RCP<const Thyra::VectorBase<Scalar>>
744 toThyraVector(Teuchos::RCP<
const Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> vec) {
746#ifdef HAVE_XPETRA_TPETRA
748 auto thyTpMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(Teuchos::rcp_dynamic_cast<const TpetraMap>(vec->getMap())->getTpetra_Map());
749 RCP<Tpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpVec = Teuchos::rcp_dynamic_cast<const TpetraVector>(vec)->getTpetra_Vector();
750 auto thyVec =
rcp(
new Thyra::TpetraVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>());
751 thyVec->initialize(thyTpMap, tpVec);
756#ifdef HAVE_XPETRA_EPETRA
758 auto thyEpMap = Thyra::create_VectorSpace(Teuchos::rcp_dynamic_cast<
const EpetraMapT<GlobalOrdinal, Node>>(vec->getMap())->getEpetra_MapRCP());
759 auto epVec =
rcp(Teuchos::rcp_dynamic_cast<
const EpetraVectorT<GlobalOrdinal, Node>>(vec)->getEpetra_Vector(),
false);
760 auto thyVec = Thyra::create_Vector(epVec, thyEpMap);
768 static void updateThyra(Teuchos::RCP<
const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> source, Teuchos::RCP<
const Xpetra::MapExtractor<Scalar, LocalOrdinal, GlobalOrdinal, Node>> mapExtractor,
const Teuchos::RCP<Thyra::MultiVectorBase<Scalar>>& target) {
771 using Teuchos::rcp_dynamic_cast;
772 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
773 typedef Thyra::SpmdVectorSpaceBase<Scalar> ThySpmdVecSpaceBase;
774 typedef Thyra::MultiVectorBase<Scalar> ThyMultVecBase;
777 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
780 RCP<ThyProdMultVecBase> prodTarget = rcp_dynamic_cast<ThyProdMultVecBase>(target);
781 if (prodTarget != Teuchos::null) {
782 RCP<const BlockedMultiVector> bSourceVec = rcp_dynamic_cast<const BlockedMultiVector>(source);
783 if (bSourceVec.is_null() ==
true) {
787 TEUCHOS_TEST_FOR_EXCEPTION(mapExtractor == Teuchos::null, std::logic_error,
"Found a Thyra product vector, but user did not provide an Xpetra::MapExtractor.");
788 TEUCHOS_TEST_FOR_EXCEPTION(prodTarget->productSpace()->numBlocks() != as<int>(mapExtractor->NumMaps()), std::logic_error,
"Inconsistent numbers of sub maps in Thyra::ProductVectorSpace and Xpetra::MapExtractor.");
790 for (
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
792 RCP<MultiVector> xpSubBlock = mapExtractor->ExtractVector(source, bbb,
false);
795 Teuchos::RCP<ThyMultVecBase> thySubBlock = prodTarget->getNonconstMultiVectorBlock(bbb);
796 RCP<const ThyVecSpaceBase> vs = thySubBlock->range();
797 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<const ThySpmdVecSpaceBase>(vs);
798 const LocalOrdinal localOffset = (mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0);
799 const LocalOrdinal localSubDim = (mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : vs->dim());
800 RCP<Thyra::DetachedMultiVectorView<Scalar>> thyData =
801 Teuchos::rcp(
new Thyra::DetachedMultiVectorView<Scalar>(*thySubBlock, Teuchos::Range1D(localOffset, localOffset + localSubDim - 1)));
804 for (
size_t j = 0; j < xpSubBlock->getNumVectors(); ++j) {
805 Teuchos::ArrayRCP<const Scalar> xpData = xpSubBlock->getData(j);
808 for (LocalOrdinal i = 0; i < localSubDim; ++i) {
809 (*thyData)(i, j) = xpData[i];
816 TEUCHOS_TEST_FOR_EXCEPTION(prodTarget->productSpace()->numBlocks() != as<int>(bSourceVec->getBlockedMap()->getNumMaps()), std::logic_error,
"Inconsistent numbers of sub maps in Thyra::ProductVectorSpace and Xpetra::BlockedMultiVector.");
818 for (
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
820 RCP<MultiVector> xpSubBlock = bSourceVec->getMultiVector(bbb,
true);
822 Teuchos::RCP<const ThyMultVecBase> thyXpSubBlock = toThyraMultiVector(xpSubBlock);
825 Teuchos::RCP<ThyMultVecBase> thySubBlock = prodTarget->getNonconstMultiVectorBlock(bbb);
826 Thyra::assign(thySubBlock.
ptr(), *thyXpSubBlock);
834 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<const ThySpmdVecSpaceBase>(target->range());
835 TEUCHOS_TEST_FOR_EXCEPTION(mpi_vs == Teuchos::null, std::logic_error,
"Failed to cast Thyra::VectorSpaceBase to Thyra::SpmdVectorSpaceBase.");
836 const LocalOrdinal localOffset = (mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0);
837 const LocalOrdinal localSubDim = (mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : target->range()->dim());
838 RCP<Thyra::DetachedMultiVectorView<Scalar>> thyData =
839 Teuchos::rcp(
new Thyra::DetachedMultiVectorView<Scalar>(*target, Teuchos::Range1D(localOffset, localOffset + localSubDim - 1)));
842 for (
size_t j = 0; j < source->getNumVectors(); ++j) {
843 Teuchos::ArrayRCP<const Scalar> xpData = source->getData(j);
845 for (LocalOrdinal i = 0; i < localSubDim; ++i) {
846 (*thyData)(i, j) = xpData[i];
852 static Teuchos::RCP<const Thyra::LinearOpBase<Scalar>>
853 toThyra(
const Teuchos::RCP<
const Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& mat) {
855 Teuchos::RCP<const Thyra::LinearOpBase<Scalar>> thyraOp = Teuchos::null;
857#ifdef HAVE_XPETRA_TPETRA
858 Teuchos::RCP<const Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpetraMat = Teuchos::rcp_dynamic_cast<const Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(mat);
859 if (tpetraMat != Teuchos::null) {
860#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
861 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
863 Teuchos::RCP<const Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xTpCrsMat = Teuchos::rcp_dynamic_cast<const Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(mat,
true);
864 Teuchos::RCP<const Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpCrsMat = xTpCrsMat->getTpetra_CrsMatrix();
867 Teuchos::RCP<const Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpRowMat = Teuchos::rcp_dynamic_cast<const Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(tpCrsMat,
true);
868 Teuchos::RCP<const Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpOperator = Teuchos::rcp_dynamic_cast<const Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(tpRowMat,
true);
870 thyraOp = Thyra::createConstLinearOp(tpOperator);
873 throw Xpetra::Exceptions::RuntimeError(
"Add TPETRA_INST_INT_INT:BOOL=ON in your configuration.");
878#ifdef HAVE_XPETRA_EPETRA
879 Teuchos::RCP<const Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>> epetraMat = Teuchos::rcp_dynamic_cast<const Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>>(mat);
880 if (epetraMat != Teuchos::null) {
881 Teuchos::RCP<const Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>> xEpCrsMat = Teuchos::rcp_dynamic_cast<const Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>>(mat);
883 Teuchos::RCP<const Epetra_CrsMatrix> epCrsMat = xEpCrsMat->getEpetra_CrsMatrix();
886 Teuchos::RCP<const Thyra::EpetraLinearOp> thyraEpOp = Thyra::epetraLinearOp(epCrsMat,
"op");
894 static Teuchos::RCP<Thyra::LinearOpBase<Scalar>>
895 toThyra(
const Teuchos::RCP<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& mat) {
897 Teuchos::RCP<Thyra::LinearOpBase<Scalar>> thyraOp = Teuchos::null;
899#ifdef HAVE_XPETRA_TPETRA
900 Teuchos::RCP<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpetraMat = Teuchos::rcp_dynamic_cast<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(mat);
901 if (tpetraMat != Teuchos::null) {
902#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
903 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
905 Teuchos::RCP<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xTpCrsMat = Teuchos::rcp_dynamic_cast<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(mat,
true);
906 Teuchos::RCP<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpCrsMat = xTpCrsMat->getTpetra_CrsMatrixNonConst();
909 Teuchos::RCP<Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpRowMat = Teuchos::rcp_dynamic_cast<Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(tpCrsMat,
true);
910 Teuchos::RCP<Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpOperator = Teuchos::rcp_dynamic_cast<Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(tpRowMat,
true);
912 thyraOp = Thyra::createLinearOp(tpOperator);
915 throw Xpetra::Exceptions::RuntimeError(
"Add TPETRA_INST_INT_INT:BOOL=ON in your configuration.");
920#ifdef HAVE_XPETRA_EPETRA
921 Teuchos::RCP<Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>> epetraMat = Teuchos::rcp_dynamic_cast<Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>>(mat);
922 if (epetraMat != Teuchos::null) {
923 Teuchos::RCP<Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>> xEpCrsMat = Teuchos::rcp_dynamic_cast<Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>>(mat,
true);
924 Teuchos::RCP<Epetra_CrsMatrix> epCrsMat = xEpCrsMat->getEpetra_CrsMatrixNonConst();
927 Teuchos::RCP<Thyra::EpetraLinearOp> thyraEpOp = Thyra::nonconstEpetraLinearOp(epCrsMat,
"op");
935 static Teuchos::RCP<Thyra::LinearOpBase<Scalar>>
936 toThyra(
const Teuchos::RCP<Xpetra::BlockedCrsMatrix<double, int, int, EpetraNode>>& mat);
941#ifndef XPETRA_EPETRA_NO_64BIT_GLOBAL_INDICES
943class ThyraUtils<double, int, long long,
EpetraNode> {
945 typedef double Scalar;
946 typedef int LocalOrdinal;
947 typedef long long GlobalOrdinal;
951#undef XPETRA_THYRAUTILS_SHORT
955 static Teuchos::RCP<Xpetra::StridedMap<LocalOrdinal, GlobalOrdinal, Node>>
956 toXpetra(
const Teuchos::RCP<
const Thyra::VectorSpaceBase<Scalar>>& vectorSpace,
const Teuchos::RCP<
const Teuchos::Comm<int>>& comm, std::vector<size_t>& stridingInfo, LocalOrdinal stridedBlockId = -1, GlobalOrdinal offset = 0) {
957 Teuchos::RCP<Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> map = ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::toXpetra(vectorSpace, comm);
959 if (stridedBlockId == -1) {
969 static Teuchos::RCP<Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
970 toXpetra(
const Teuchos::RCP<
const Thyra::VectorSpaceBase<Scalar>>& vectorSpace,
const Teuchos::RCP<
const Teuchos::Comm<int>>& comm) {
973 using Teuchos::rcp_dynamic_cast;
974 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
975 typedef Thyra::ProductVectorSpaceBase<Scalar> ThyProdVecSpaceBase;
976 typedef Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node> ThyUtils;
978 RCP<const ThyProdVecSpaceBase> prodVectorSpace = rcp_dynamic_cast<const ThyProdVecSpaceBase>(vectorSpace);
979 if (prodVectorSpace != Teuchos::null) {
982 TEUCHOS_TEST_FOR_EXCEPTION(prodVectorSpace->numBlocks() == 0, std::logic_error,
"Found a product vector space with zero blocks.");
983 std::vector<RCP<const Map>> mapsThyra(prodVectorSpace->numBlocks(), Teuchos::null);
984 std::vector<RCP<const Map>> mapsXpetra(prodVectorSpace->numBlocks(), Teuchos::null);
985 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b) {
986 RCP<const ThyVecSpaceBase> bv = prodVectorSpace->getBlock(b);
988 mapsThyra[b] = ThyUtils::toXpetra(bv, comm);
993 std::vector<GlobalOrdinal> gidOffsets(prodVectorSpace->numBlocks(), 0);
994 for (
int i = 1; i < prodVectorSpace->numBlocks(); ++i) {
995 gidOffsets[i] = mapsThyra[i - 1]->getMaxAllGlobalIndex() + gidOffsets[i - 1] + 1;
998 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b) {
999 RCP<const ThyVecSpaceBase> bv = prodVectorSpace->getBlock(b);
1001 mapsXpetra[b] = MapUtils::transformThyra2XpetraGIDs(*mapsThyra[b], gidOffsets[b]);
1004 Teuchos::RCP<Map> resultMap =
Teuchos::rcp(
new Xpetra::BlockedMap<LocalOrdinal, GlobalOrdinal, Node>(mapsXpetra, mapsThyra));
1012 bool bIsTpetra =
false;
1013#ifdef HAVE_XPETRA_TPETRA
1014#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1015 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1016 Teuchos::RCP<const Thyra::TpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpetra_vsc = Teuchos::rcp_dynamic_cast<const Thyra::TpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(vectorSpace);
1022 bool bIsEpetra = !bIsTpetra;
1024#ifdef HAVE_XPETRA_TPETRA
1026#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1027 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1028 typedef Thyra::VectorBase<Scalar> ThyVecBase;
1029 typedef Tpetra::Map<LocalOrdinal, GlobalOrdinal, Node> TpMap;
1030 typedef Tpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpVector;
1031 typedef Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node> TOE;
1032 RCP<ThyVecBase> rgVec = Thyra::createMember<Scalar>(vectorSpace, std::string(
"label"));
1034 RCP<const TpVector> rgTpetraVec = TOE::getTpetraVector(rgVec);
1036 RCP<const TpMap> rgTpetraMap = rgTpetraVec->getMap();
1043 throw Xpetra::Exceptions::RuntimeError(
"Add TPETRA_INST_INT_LONG_LONG:BOOL=ON in your configuration.");
1048#ifdef HAVE_XPETRA_EPETRA
1051 RCP<const Epetra_Map>
1052 epetra_map = Teuchos::get_extra_data<RCP<const Epetra_Map>>(vectorSpace,
"epetra_map");
1054 Teuchos::RCP<Map> rgXpetraMap =
Teuchos::rcp(
new Xpetra::EpetraMapT<GlobalOrdinal, Node>(epetra_map));
1068 static Teuchos::RCP<const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
1069 toXpetra(Teuchos::RCP<
const Thyra::MultiVectorBase<Scalar>> v,
const Teuchos::RCP<
const Teuchos::Comm<int>>& comm) {
1072 using Teuchos::rcp_dynamic_cast;
1073 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
1074 typedef Thyra::MultiVectorBase<Scalar> ThyMultVecBase;
1075 typedef Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node> ThyUtils;
1078 RCP<MultiVector> xpMultVec = Teuchos::null;
1081 Teuchos::RCP<const ThyProdMultVecBase> thyProdVec = rcp_dynamic_cast<const ThyProdMultVecBase>(v);
1082 if (thyProdVec != Teuchos::null) {
1085 RCP<Map> fullMap = ThyUtils::toXpetra(v->range(), comm);
1089 xpMultVec = MultiVectorFactory::Build(fullMap, as<size_t>(thyProdVec->domain()->dim()));
1091 RCP<BlockedMultiVector> xpBlockedMultVec = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(xpMultVec);
1095 for (
int b = 0; b < thyProdVec->productSpace()->numBlocks(); ++b) {
1096 RCP<const ThyMultVecBase> thyBlockMV = thyProdVec->getMultiVectorBlock(b);
1098 RCP<const MultiVector> xpBlockMV = ThyUtils::toXpetra(thyBlockMV, comm);
1099 xpBlockedMultVec->setMultiVector(b, xpBlockMV,
true );
1107 bool bIsTpetra =
false;
1108#ifdef HAVE_XPETRA_TPETRA
1109#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1110 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1114 typedef Thyra::SpmdMultiVectorBase<Scalar> ThySpmdMultVecBase;
1115 typedef Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node> ConverterT;
1116 typedef Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpMultVec;
1117 typedef Xpetra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> XpTpMultVec;
1118 typedef Thyra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> ThyTpMultVec;
1120 RCP<const ThySpmdMultVecBase> thyraSpmdMultiVector = rcp_dynamic_cast<const ThySpmdMultVecBase>(v);
1121 RCP<const ThyTpMultVec> thyraTpetraMultiVector = rcp_dynamic_cast<const ThyTpMultVec>(thyraSpmdMultiVector);
1122 if (thyraTpetraMultiVector != Teuchos::null) {
1124 const RCP<const TpMultVec> tpMultVec = ConverterT::getConstTpetraMultiVector(v);
1126 RCP<TpMultVec> tpNonConstMultVec = Teuchos::rcp_const_cast<TpMultVec>(tpMultVec);
1128 xpMultVec =
rcp(
new XpTpMultVec(tpNonConstMultVec));
1135#ifdef HAVE_XPETRA_EPETRA
1136 if (bIsTpetra ==
false) {
1138 Teuchos::RCP<Map> map = ThyUtils::toXpetra(v->range(), comm);
1140 RCP<Xpetra::EpetraMapT<GlobalOrdinal, Node>> xeMap = rcp_dynamic_cast<Xpetra::EpetraMapT<GlobalOrdinal, Node>>(map,
true);
1141 RCP<const Epetra_Map> eMap = xeMap->getEpetra_MapRCP();
1143 Teuchos::RCP<const Epetra_MultiVector> epMultVec = Thyra::get_Epetra_MultiVector(*eMap, v);
1145 RCP<Epetra_MultiVector> epNonConstMultVec = Teuchos::rcp_const_cast<Epetra_MultiVector>(epMultVec);
1147 xpMultVec =
Teuchos::rcp(
new Xpetra::EpetraMultiVectorT<GlobalOrdinal, Node>(epNonConstMultVec));
1158 static Teuchos::RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
1159 toXpetra(Teuchos::RCP<Thyra::MultiVectorBase<Scalar>> v,
const Teuchos::RCP<
const Teuchos::Comm<int>>& comm) {
1160 Teuchos::RCP<const Thyra::MultiVectorBase<Scalar>> cv =
1161 Teuchos::rcp_const_cast<const Thyra::MultiVectorBase<Scalar>>(v);
1162 Teuchos::RCP<const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> r =
1164 return Teuchos::rcp_const_cast<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(r);
1167 static bool isTpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op) {
1169 bool bIsTpetra =
false;
1170#ifdef HAVE_XPETRA_TPETRA
1171#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1172 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1174 Teuchos::RCP<const Thyra::TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpetra_op = Teuchos::rcp_dynamic_cast<const Thyra::TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(op);
1179#ifdef HAVE_XPETRA_EPETRA
1180 Teuchos::rcp_dynamic_cast<const Thyra::EpetraLinearOp>(op) == Teuchos::null &&
1182 Teuchos::rcp_dynamic_cast<
const Thyra::DefaultBlockedLinearOp<Scalar>>(op) == Teuchos::null) {
1184 typedef Thyra::TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpetraLinearOp_t;
1185 if (Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op) == Teuchos::null) {
1186 std::cout <<
"ATTENTION: The dynamic cast to the TpetraLinearOp failed even though it should be a TpetraLinearOp." << std::endl;
1187 std::cout <<
" If you are using Panzer or Stratimikos you might check that the template parameters are " << std::endl;
1188 std::cout <<
" properly set!" << std::endl;
1189 std::cout << Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op,
true) << std::endl;
1199 if(bIsTpetra ==
false) {
1200 Teuchos::RCP<const Thyra::BlockedLinearOpBase<Scalar> > ThyBlockedOp =
1201 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op);
1202 if(ThyBlockedOp != Teuchos::null) {
1204 Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > b00 =
1205 ThyBlockedOp->getBlock(0,0);
1207 bIsTpetra = isTpetra(b00);
1215 static bool isEpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op) {
1217 bool bIsEpetra =
false;
1219#ifdef HAVE_XPETRA_EPETRA
1220 Teuchos::RCP<const Thyra::EpetraLinearOp> epetra_op = Teuchos::rcp_dynamic_cast<const Thyra::EpetraLinearOp>(op,
false);
1228 if(bIsEpetra ==
false) {
1229 Teuchos::RCP<const Thyra::BlockedLinearOpBase<Scalar> > ThyBlockedOp =
1230 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op,
false);
1231 if(ThyBlockedOp != Teuchos::null) {
1233 Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > b00 =
1234 ThyBlockedOp->getBlock(0,0);
1236 bIsEpetra = isEpetra(b00);
1244 static bool isBlockedOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op) {
1246 Teuchos::RCP<const Thyra::BlockedLinearOpBase<Scalar>> ThyBlockedOp =
1247 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar>>(op);
1248 if (ThyBlockedOp != Teuchos::null) {
1254 static Teuchos::RCP<const Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
1255 toXpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op) {
1256#ifdef HAVE_XPETRA_TPETRA
1258#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1259 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1261 typedef Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node> TOE;
1262 Teuchos::RCP<const Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraOp = TOE::getConstTpetraOperator(op);
1266 Teuchos::RCP<const Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraRowMat = Teuchos::rcp_dynamic_cast<const Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(TpetraOp,
true);
1267 Teuchos::RCP<const Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraCrsMat = Teuchos::rcp_dynamic_cast<const Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(TpetraRowMat,
true);
1268 Teuchos::RCP<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraNcnstCrsMat = Teuchos::rcp_const_cast<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(TpetraCrsMat);
1271 Teuchos::RCP<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xTpetraCrsMat =
1272 Teuchos::rcp(
new Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>(TpetraNcnstCrsMat));
1275 Teuchos::RCP<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpCrsMat =
1276 Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xTpetraCrsMat,
true);
1277 Teuchos::RCP<Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpCrsWrap =
1278 Teuchos::rcp(
new Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>(xpCrsMat));
1279 Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpMat =
1280 Teuchos::rcp_dynamic_cast<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpCrsWrap,
true);
1283 throw Xpetra::Exceptions::RuntimeError(
"Add TPETRA_INST_INT_LONG_LONG:BOOL=ON in your configuration.");
1288#ifdef HAVE_XPETRA_EPETRA
1290 Teuchos::RCP<const Epetra_Operator> epetra_op = Thyra::get_Epetra_Operator(*op);
1292 Teuchos::RCP<const Epetra_RowMatrix> epetra_rowmat = Teuchos::rcp_dynamic_cast<const Epetra_RowMatrix>(epetra_op,
true);
1293 Teuchos::RCP<const Epetra_CrsMatrix> epetra_crsmat = Teuchos::rcp_dynamic_cast<const Epetra_CrsMatrix>(epetra_rowmat,
true);
1294 Teuchos::RCP<Epetra_CrsMatrix> epetra_ncnstcrsmat = Teuchos::rcp_const_cast<Epetra_CrsMatrix>(epetra_crsmat);
1297 Teuchos::RCP<Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>> xEpetraCrsMat =
1298 Teuchos::rcp(
new Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>(epetra_ncnstcrsmat));
1301 Teuchos::RCP<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpCrsMat =
1302 Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xEpetraCrsMat,
true);
1303 Teuchos::RCP<Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpCrsWrap =
1304 Teuchos::rcp(
new Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>(xpCrsMat));
1305 Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpMat =
1306 Teuchos::rcp_dynamic_cast<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpCrsWrap,
true);
1310 return Teuchos::null;
1313 static Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
1314 toXpetra(
const Teuchos::RCP<Thyra::LinearOpBase<Scalar>>& op) {
1315#ifdef HAVE_XPETRA_TPETRA
1317#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1318 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1320 typedef Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node> TOE;
1321 Teuchos::RCP<Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraOp = TOE::getTpetraOperator(op);
1323 Teuchos::RCP<Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraRowMat = Teuchos::rcp_dynamic_cast<Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(TpetraOp,
true);
1324 Teuchos::RCP<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraCrsMat = Teuchos::rcp_dynamic_cast<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(TpetraRowMat,
true);
1326 Teuchos::RCP<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xTpetraCrsMat =
1327 Teuchos::rcp(
new Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>(TpetraCrsMat));
1330 Teuchos::RCP<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpCrsMat =
1331 Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xTpetraCrsMat,
true);
1332 Teuchos::RCP<Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpCrsWrap =
1333 Teuchos::rcp(
new Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>(xpCrsMat));
1334 Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpMat =
1335 Teuchos::rcp_dynamic_cast<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpCrsWrap,
true);
1338 throw Xpetra::Exceptions::RuntimeError(
"Add TPETRA_INST_INT_LONG_LONG:BOOL=ON in your configuration.");
1343#ifdef HAVE_XPETRA_EPETRA
1345 Teuchos::RCP<Epetra_Operator> epetra_op = Thyra::get_Epetra_Operator(*op);
1347 Teuchos::RCP<Epetra_RowMatrix> epetra_rowmat = Teuchos::rcp_dynamic_cast<Epetra_RowMatrix>(epetra_op,
true);
1348 Teuchos::RCP<Epetra_CrsMatrix> epetra_crsmat = Teuchos::rcp_dynamic_cast<Epetra_CrsMatrix>(epetra_rowmat,
true);
1350 Teuchos::RCP<Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>> xEpetraCrsMat =
1351 Teuchos::rcp(
new Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>(epetra_crsmat));
1354 Teuchos::RCP<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpCrsMat =
1355 Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xEpetraCrsMat,
true);
1356 Teuchos::RCP<Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpCrsWrap =
1357 Teuchos::rcp(
new Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>(xpCrsMat));
1358 Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpMat =
1359 Teuchos::rcp_dynamic_cast<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpCrsWrap,
true);
1363 return Teuchos::null;
1366 static Teuchos::RCP<const Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
1367 toXpetraOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op) {
1368#ifdef HAVE_XPETRA_TPETRA
1370 typedef Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node> TOE;
1371 Teuchos::RCP<const Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraOp = TOE::getConstTpetraOperator(op);
1373 Teuchos::RCP<Xpetra::TpetraOperator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xTpetraOp =
1374 Teuchos::rcp(
new Xpetra::TpetraOperator<Scalar, LocalOrdinal, GlobalOrdinal, Node>(TpetraOp));
1377 Teuchos::RCP<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpOp =
1378 Teuchos::rcp_dynamic_cast<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xTpetraOp,
true);
1383#ifdef HAVE_XPETRA_EPETRA
1385 TEUCHOS_TEST_FOR_EXCEPTION(
true, Xpetra::Exceptions::RuntimeError,
"Epetra needs SC=double, LO=int, and GO=int or GO=long long");
1388 return Teuchos::null;
1391 static Teuchos::RCP<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
1392 toXpetraOperator(
const Teuchos::RCP<Thyra::LinearOpBase<Scalar>>& op) {
1393#ifdef HAVE_XPETRA_TPETRA
1395 typedef Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node> TOE;
1396 Teuchos::RCP<Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraOp = TOE::getTpetraOperator(op);
1398 Teuchos::RCP<Xpetra::TpetraOperator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xTpetraOp =
1399 Teuchos::rcp(
new Xpetra::TpetraOperator<Scalar, LocalOrdinal, GlobalOrdinal, Node>(TpetraOp));
1402 Teuchos::RCP<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpOp =
1403 Teuchos::rcp_dynamic_cast<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xTpetraOp,
true);
1408#ifdef HAVE_XPETRA_EPETRA
1410 TEUCHOS_TEST_FOR_EXCEPTION(
true, Xpetra::Exceptions::RuntimeError,
"Epetra needs SC=double, LO=int, and GO=int or GO=long long");
1413 return Teuchos::null;
1416 static Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
1417 toXpetra(
const Teuchos::RCP<Thyra::DiagonalLinearOpBase<Scalar>>& op) {
1418 using Teuchos::rcp_const_cast;
1419 using Teuchos::rcp_dynamic_cast;
1420 using ThyVSBase = Thyra::SpmdVectorSpaceBase<Scalar>;
1421 using thyTpV = Thyra::TpetraVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
1422 using tV = Tpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
1424 RCP<const Thyra::VectorBase<Scalar>> diag = op->getDiag();
1426 RCP<const Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpDiag;
1427#ifdef HAVE_XPETRA_TPETRA
1428 if (!rcp_dynamic_cast<const thyTpV>(diag).
is_null()) {
1429 RCP<const tV> tDiag = Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node>::getConstTpetraVector(diag);
1430 if (!tDiag.is_null())
1434#ifdef HAVE_XPETRA_EPETRA
1435 if (xpDiag.is_null()) {
1436 RCP<const Epetra_Comm> comm = Thyra::get_Epetra_Comm(*rcp_dynamic_cast<const ThyVSBase>(op->range())->getComm());
1437 RCP<const Epetra_Map> map = Thyra::get_Epetra_Map(*(op->range()), comm);
1438 if (!map.is_null()) {
1439 RCP<const Epetra_Vector> eDiag = Thyra::get_Epetra_Vector(*map, diag);
1440 RCP<Epetra_Vector> nceDiag = rcp_const_cast<Epetra_Vector>(eDiag);
1441 RCP<Xpetra::EpetraVectorT<int, Node>> xpEpDiag =
rcp(
new Xpetra::EpetraVectorT<int, Node>(nceDiag));
1442 xpDiag = rcp_dynamic_cast<Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpEpDiag,
true);
1447 RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> M = Xpetra::MatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(xpDiag);
1451 static Teuchos::RCP<const Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
1452 toXpetra(
const Teuchos::RCP<
const Thyra::DiagonalLinearOpBase<Scalar>>& op) {
1453 return toXpetra(Teuchos::rcp_const_cast<Thyra::DiagonalLinearOpBase<Scalar>>(op));
1456 static Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>>
1457 toThyra(Teuchos::RCP<
const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> map) {
1458 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>> thyraMap = Teuchos::null;
1461 RCP<const BlockedMap> bmap = Teuchos::rcp_dynamic_cast<const BlockedMap>(map);
1462 if (bmap.is_null() ==
false) {
1463 Teuchos::Array<Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>>> vecSpaces(bmap->getNumMaps());
1464 for (
size_t i = 0; i < bmap->getNumMaps(); i++) {
1466 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>> vs =
1467 Xpetra::ThyraUtils<Scalar, LO, GO, Node>::toThyra(bmap->getMap(i,
true));
1471 thyraMap = Thyra::productVectorSpace<Scalar>(vecSpaces());
1476#ifdef HAVE_XPETRA_TPETRA
1478#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1479 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1480 Teuchos::RCP<const Xpetra::TpetraMap<LocalOrdinal, GlobalOrdinal, Node>> tpetraMap = Teuchos::rcp_dynamic_cast<const Xpetra::TpetraMap<LocalOrdinal, GlobalOrdinal, Node>>(map);
1481 if (tpetraMap == Teuchos::null)
1482 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::TpetraMap failed");
1483 RCP<const Tpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> tpMap = tpetraMap->getTpetra_Map();
1484 RCP<Thyra::TpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>> thyraTpetraMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tpMap);
1485 thyraMap = thyraTpetraMap;
1487 throw Xpetra::Exceptions::RuntimeError(
"Problem DDD. Add TPETRA_INST_INT_LONG_LONG:BOOL=ON in your configuration.");
1492#ifdef HAVE_XPETRA_EPETRA
1494 Teuchos::RCP<const Xpetra::EpetraMapT<GlobalOrdinal, Node>> epetraMap = Teuchos::rcp_dynamic_cast<const Xpetra::EpetraMapT<GlobalOrdinal, Node>>(map);
1495 if (epetraMap == Teuchos::null)
1496 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::EpetraMap failed");
1497 RCP<const Thyra::VectorSpaceBase<Scalar>> thyraEpetraMap = Thyra::create_VectorSpace(epetraMap->getEpetra_MapRCP());
1498 thyraMap = thyraEpetraMap;
1505 static Teuchos::RCP<const Thyra::MultiVectorBase<Scalar>>
1506 toThyraMultiVector(Teuchos::RCP<
const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> vec) {
1508#ifdef HAVE_XPETRA_TPETRA
1510 auto thyTpMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(Teuchos::rcp_dynamic_cast<const TpetraMap>(vec->getMap())->getTpetra_Map());
1511 RCP<Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpMV = Teuchos::rcp_dynamic_cast<const TpetraMultiVector>(vec)->getTpetra_MultiVector();
1512 auto thyDomMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(Tpetra::createLocalMapWithNode<LocalOrdinal, GlobalOrdinal, Node>(vec->getNumVectors(), vec->getMap()->getComm()));
1513 auto thyMV =
rcp(
new Thyra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>());
1514 thyMV->initialize(thyTpMap, thyDomMap, tpMV);
1519#ifdef HAVE_XPETRA_EPETRA
1521 auto thyEpMap = Thyra::create_VectorSpace(Teuchos::rcp_dynamic_cast<
const EpetraMapT<GlobalOrdinal, Node>>(vec->getMap())->getEpetra_MapRCP());
1522 auto epMV = Teuchos::rcp_dynamic_cast<const EpetraMultiVectorT<GlobalOrdinal, Node>>(vec)->getEpetra_MultiVector();
1523 auto thyMV = Thyra::create_MultiVector(epMV, thyEpMap);
1531 static Teuchos::RCP<const Thyra::VectorBase<Scalar>>
1532 toThyraVector(Teuchos::RCP<
const Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> vec) {
1534#ifdef HAVE_XPETRA_TPETRA
1536 auto thyTpMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(Teuchos::rcp_dynamic_cast<const TpetraMap>(vec->getMap())->getTpetra_Map());
1537 RCP<Tpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpVec = Teuchos::rcp_dynamic_cast<const TpetraVector>(vec)->getTpetra_Vector();
1538 auto thyVec =
rcp(
new Thyra::TpetraVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>());
1539 thyVec->initialize(thyTpMap, tpVec);
1544#ifdef HAVE_XPETRA_EPETRA
1546 auto thyEpMap = Thyra::create_VectorSpace(Teuchos::rcp_dynamic_cast<
const EpetraMapT<GlobalOrdinal, Node>>(vec->getMap())->getEpetra_MapRCP());
1547 auto epVec =
rcp(Teuchos::rcp_dynamic_cast<
const EpetraVectorT<GlobalOrdinal, Node>>(vec)->getEpetra_Vector(),
false);
1548 auto thyVec = Thyra::create_Vector(epVec, thyEpMap);
1556 static void updateThyra(Teuchos::RCP<
const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> source, Teuchos::RCP<
const Xpetra::MapExtractor<Scalar, LocalOrdinal, GlobalOrdinal, Node>> mapExtractor,
const Teuchos::RCP<Thyra::MultiVectorBase<Scalar>>& target) {
1559 using Teuchos::rcp_dynamic_cast;
1560 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
1561 typedef Thyra::SpmdVectorSpaceBase<Scalar> ThySpmdVecSpaceBase;
1562 typedef Thyra::MultiVectorBase<Scalar> ThyMultVecBase;
1565 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
1568 RCP<ThyProdMultVecBase> prodTarget = rcp_dynamic_cast<ThyProdMultVecBase>(target);
1569 if (prodTarget != Teuchos::null) {
1570 RCP<const BlockedMultiVector> bSourceVec = rcp_dynamic_cast<const BlockedMultiVector>(source);
1571 if (bSourceVec.is_null() ==
true) {
1575 TEUCHOS_TEST_FOR_EXCEPTION(mapExtractor == Teuchos::null, std::logic_error,
"Found a Thyra product vector, but user did not provide an Xpetra::MapExtractor.");
1576 TEUCHOS_TEST_FOR_EXCEPTION(prodTarget->productSpace()->numBlocks() != as<int>(mapExtractor->NumMaps()), std::logic_error,
"Inconsistent numbers of sub maps in Thyra::ProductVectorSpace and Xpetra::MapExtractor.");
1578 for (
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
1580 RCP<MultiVector> xpSubBlock = mapExtractor->ExtractVector(source, bbb,
false);
1583 Teuchos::RCP<ThyMultVecBase> thySubBlock = prodTarget->getNonconstMultiVectorBlock(bbb);
1584 RCP<const ThyVecSpaceBase> vs = thySubBlock->range();
1585 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<const ThySpmdVecSpaceBase>(vs);
1586 const LocalOrdinal localOffset = (mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0);
1587 const LocalOrdinal localSubDim = (mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : vs->dim());
1588 RCP<Thyra::DetachedMultiVectorView<Scalar>> thyData =
1589 Teuchos::rcp(
new Thyra::DetachedMultiVectorView<Scalar>(*thySubBlock, Teuchos::Range1D(localOffset, localOffset + localSubDim - 1)));
1592 for (
size_t j = 0; j < xpSubBlock->getNumVectors(); ++j) {
1593 Teuchos::ArrayRCP<const Scalar> xpData = xpSubBlock->getData(j);
1596 for (LocalOrdinal i = 0; i < localSubDim; ++i) {
1597 (*thyData)(i, j) = xpData[i];
1604 TEUCHOS_TEST_FOR_EXCEPTION(prodTarget->productSpace()->numBlocks() != as<int>(bSourceVec->getBlockedMap()->getNumMaps()), std::logic_error,
"Inconsistent numbers of sub maps in Thyra::ProductVectorSpace and Xpetra::BlockedMultiVector.");
1606 for (
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
1608 RCP<MultiVector> xpSubBlock = bSourceVec->getMultiVector(bbb,
true);
1610 Teuchos::RCP<const ThyMultVecBase> thyXpSubBlock = toThyraMultiVector(xpSubBlock);
1613 Teuchos::RCP<ThyMultVecBase> thySubBlock = prodTarget->getNonconstMultiVectorBlock(bbb);
1614 Thyra::assign(thySubBlock.
ptr(), *thyXpSubBlock);
1622 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<const ThySpmdVecSpaceBase>(target->range());
1623 TEUCHOS_TEST_FOR_EXCEPTION(mpi_vs == Teuchos::null, std::logic_error,
"Failed to cast Thyra::VectorSpaceBase to Thyra::SpmdVectorSpaceBase.");
1624 const LocalOrdinal localOffset = (mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0);
1625 const LocalOrdinal localSubDim = (mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : target->range()->dim());
1626 RCP<Thyra::DetachedMultiVectorView<Scalar>> thyData =
1627 Teuchos::rcp(
new Thyra::DetachedMultiVectorView<Scalar>(*target, Teuchos::Range1D(localOffset, localOffset + localSubDim - 1)));
1630 for (
size_t j = 0; j < source->getNumVectors(); ++j) {
1631 Teuchos::ArrayRCP<const Scalar> xpData = source->getData(j);
1633 for (LocalOrdinal i = 0; i < localSubDim; ++i) {
1634 (*thyData)(i, j) = xpData[i];
1640 static Teuchos::RCP<const Thyra::LinearOpBase<Scalar>>
1641 toThyra(
const Teuchos::RCP<
const Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& mat) {
1643 Teuchos::RCP<const Thyra::LinearOpBase<Scalar>> thyraOp = Teuchos::null;
1645#ifdef HAVE_XPETRA_TPETRA
1646 Teuchos::RCP<const Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpetraMat = Teuchos::rcp_dynamic_cast<const Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(mat);
1647 if (tpetraMat != Teuchos::null) {
1648#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1649 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1651 Teuchos::RCP<const Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xTpCrsMat = Teuchos::rcp_dynamic_cast<const Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(mat,
true);
1652 Teuchos::RCP<const Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpCrsMat = xTpCrsMat->getTpetra_CrsMatrix();
1655 Teuchos::RCP<const Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpRowMat = Teuchos::rcp_dynamic_cast<const Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(tpCrsMat,
true);
1656 Teuchos::RCP<const Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpOperator = Teuchos::rcp_dynamic_cast<const Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(tpRowMat,
true);
1658 thyraOp = Thyra::createConstLinearOp(tpOperator);
1661 throw Xpetra::Exceptions::RuntimeError(
"Add TPETRA_INST_INT_LONG_LONG:BOOL=ON in your configuration.");
1666#ifdef HAVE_XPETRA_EPETRA
1667 Teuchos::RCP<const Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>> epetraMat = Teuchos::rcp_dynamic_cast<const Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>>(mat);
1668 if (epetraMat != Teuchos::null) {
1669 Teuchos::RCP<const Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>> xEpCrsMat = Teuchos::rcp_dynamic_cast<const Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>>(mat,
true);
1670 Teuchos::RCP<const Epetra_CrsMatrix> epCrsMat = xEpCrsMat->getEpetra_CrsMatrix();
1673 Teuchos::RCP<const Thyra::EpetraLinearOp> thyraEpOp = Thyra::epetraLinearOp(epCrsMat,
"op");
1675 thyraOp = thyraEpOp;
1681 static Teuchos::RCP<Thyra::LinearOpBase<Scalar>>
1682 toThyra(
const Teuchos::RCP<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& mat) {
1684 Teuchos::RCP<Thyra::LinearOpBase<Scalar>> thyraOp = Teuchos::null;
1686#ifdef HAVE_XPETRA_TPETRA
1687 Teuchos::RCP<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpetraMat = Teuchos::rcp_dynamic_cast<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(mat);
1688 if (tpetraMat != Teuchos::null) {
1689#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1690 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1692 Teuchos::RCP<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xTpCrsMat = Teuchos::rcp_dynamic_cast<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(mat,
true);
1693 Teuchos::RCP<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpCrsMat = xTpCrsMat->getTpetra_CrsMatrixNonConst();
1696 Teuchos::RCP<Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpRowMat = Teuchos::rcp_dynamic_cast<Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(tpCrsMat,
true);
1697 Teuchos::RCP<Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpOperator = Teuchos::rcp_dynamic_cast<Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(tpRowMat,
true);
1699 thyraOp = Thyra::createLinearOp(tpOperator);
1702 throw Xpetra::Exceptions::RuntimeError(
"Add TPETRA_INST_INT_LONG_LONG:BOOL=ON in your configuration.");
1707#ifdef HAVE_XPETRA_EPETRA
1708 Teuchos::RCP<Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>> epetraMat = Teuchos::rcp_dynamic_cast<Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>>(mat);
1709 if (epetraMat != Teuchos::null) {
1710 Teuchos::RCP<Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>> xEpCrsMat = Teuchos::rcp_dynamic_cast<Xpetra::EpetraCrsMatrixT<GlobalOrdinal, Node>>(mat,
true);
1711 Teuchos::RCP<Epetra_CrsMatrix> epCrsMat = xEpCrsMat->getEpetra_CrsMatrixNonConst();
1714 Teuchos::RCP<Thyra::EpetraLinearOp> thyraEpOp = Thyra::nonconstEpetraLinearOp(epCrsMat,
"op");
1716 thyraOp = thyraEpOp;
1722 static Teuchos::RCP<Thyra::LinearOpBase<Scalar>>
1723 toThyra(
const Teuchos::RCP<Xpetra::BlockedCrsMatrix<double, int, long long, EpetraNode>>& mat);
1732#define XPETRA_THYRAUTILS_SHORT
static RCP< Xpetra::StridedMap< LocalOrdinal, GlobalOrdinal, Node > > Build(UnderlyingLib lib, global_size_t numGlobalElements, GlobalOrdinal indexBase, std::vector< size_t > &stridingInfo, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalOrdinal stridedBlockId=-1, GlobalOrdinal offset=0, LocalGlobal lg=Xpetra::GloballyDistributed)
Map constructor with Xpetra-defined contiguous uniform distribution.
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
bool is_null(const std::shared_ptr< T > &p)
TypeTo as(const TypeFrom &t)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
const RCP< Map< LocalOrdinal, GlobalOrdinal, Node > > toXpetraNonConst(const RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > &map)
Tpetra::KokkosCompat::KokkosSerialWrapperNode EpetraNode
RCP< const CrsGraph< int, GlobalOrdinal, Node > > toXpetra(const Epetra_CrsGraph &g)