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"
24#include "Epetra_CombineMode.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
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);
115 toXpetraOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op);
118 toXpetraOperator(
const Teuchos::RCP<Thyra::LinearOpBase<Scalar>>& op);
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
173 if (stridedBlockId == -1) {
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]);
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)))
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();
260#ifdef HAVE_XPETRA_EPETRA
263 RCP<const Epetra_Map>
264 epetra_map = Teuchos::get_extra_data<RCP<const Epetra_Map>>(vectorSpace,
"epetra_map");
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;
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;
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) {
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();
354 RCP<Epetra_MultiVector> epNonConstMultVec = Teuchos::rcp_const_cast<Epetra_MultiVector>(epMultVec);
368 Teuchos::rcp_const_cast<const Thyra::MultiVectorBase<Scalar>>(v);
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)))
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) {
408 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op);
409 if(ThyBlockedOp != Teuchos::null) {
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
435 if(bIsEpetra ==
false) {
437 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op,
false);
438 if(ThyBlockedOp != Teuchos::null) {
441 ThyBlockedOp->getBlock(0,0);
443 bIsEpetra = isEpetra(b00);
451 static bool isBlockedOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op) {
454 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar>>(op);
455 if (ThyBlockedOp != Teuchos::null) {
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;
483 Teuchos::rcp_dynamic_cast<const Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xTpetraCrsMat);
485 Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xTpetraCrsMat,
true);
489 Teuchos::rcp_dynamic_cast<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpCrsWrap,
true);
497#ifdef HAVE_XPETRA_EPETRA
511 Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xEpetraCrsMat,
true);
515 Teuchos::rcp_dynamic_cast<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpCrsWrap,
true);
519 return Teuchos::null;
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;
539 Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xTpetraCrsMat,
true);
543 Teuchos::rcp_dynamic_cast<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpCrsWrap,
true);
551#ifdef HAVE_XPETRA_EPETRA
562 Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xEpetraCrsMat,
true);
566 Teuchos::rcp_dynamic_cast<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpCrsWrap,
true);
570 return Teuchos::null;
574 toXpetraOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op) {
575 return toXpetraOperator(Teuchos::rcp_const_cast<Thyra::LinearOpBase<Scalar>>(op));
604 toXpetraOperator(
const Teuchos::RCP<Thyra::LinearOpBase<Scalar>>& op) {
605#ifdef HAVE_XPETRA_TPETRA
607 typedef Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node> TOE;
615 Teuchos::rcp_dynamic_cast<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xTpetraOp,
true);
620#ifdef HAVE_XPETRA_EPETRA
625 return Teuchos::null;
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);
654 xpDiag = rcp_dynamic_cast<Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpEpDiag,
true);
665 return toXpetra(Teuchos::rcp_const_cast<Thyra::DiagonalLinearOpBase<Scalar>>(op));
673 RCP<const BlockedMap> bmap = Teuchos::rcp_dynamic_cast<const BlockedMap>(map);
674 if (bmap.is_null() ==
false) {
676 for (
size_t i = 0; i < bmap->getNumMaps(); i++) {
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)))
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;
704#ifdef HAVE_XPETRA_EPETRA
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;
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);
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);
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);
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 =
804 for (
size_t j = 0; j < xpSubBlock->getNumVectors(); ++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);
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 =
842 for (
size_t j = 0; j < source->getNumVectors(); ++j) {
845 for (LocalOrdinal i = 0; i < localSubDim; ++i) {
846 (*thyData)(i, j) = xpData[i];
857#ifdef HAVE_XPETRA_TPETRA
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)))
870 thyraOp = Thyra::createConstLinearOp(tpOperator);
878#ifdef HAVE_XPETRA_EPETRA
880 if (epetraMat != Teuchos::null) {
899#ifdef HAVE_XPETRA_TPETRA
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)))
912 thyraOp = Thyra::createLinearOp(tpOperator);
920#ifdef HAVE_XPETRA_EPETRA
922 if (epetraMat != Teuchos::null) {
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
959 if (stridedBlockId == -1) {
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]);
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)))
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();
1048#ifdef HAVE_XPETRA_EPETRA
1051 RCP<const Epetra_Map>
1052 epetra_map = Teuchos::get_extra_data<RCP<const Epetra_Map>>(vectorSpace,
"epetra_map");
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;
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;
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) {
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();
1145 RCP<Epetra_MultiVector> epNonConstMultVec = Teuchos::rcp_const_cast<Epetra_MultiVector>(epMultVec);
1161 Teuchos::rcp_const_cast<const Thyra::MultiVectorBase<Scalar>>(v);
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)))
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) {
1201 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op);
1202 if(ThyBlockedOp != Teuchos::null) {
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
1228 if(bIsEpetra ==
false) {
1230 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op,
false);
1231 if(ThyBlockedOp != Teuchos::null) {
1234 ThyBlockedOp->getBlock(0,0);
1236 bIsEpetra = isEpetra(b00);
1244 static bool isBlockedOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op) {
1247 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar>>(op);
1248 if (ThyBlockedOp != Teuchos::null) {
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;
1276 Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xTpetraCrsMat,
true);
1280 Teuchos::rcp_dynamic_cast<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpCrsWrap,
true);
1288#ifdef HAVE_XPETRA_EPETRA
1302 Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xEpetraCrsMat,
true);
1306 Teuchos::rcp_dynamic_cast<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpCrsWrap,
true);
1310 return Teuchos::null;
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;
1331 Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xTpetraCrsMat,
true);
1335 Teuchos::rcp_dynamic_cast<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpCrsWrap,
true);
1343#ifdef HAVE_XPETRA_EPETRA
1355 Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xEpetraCrsMat,
true);
1359 Teuchos::rcp_dynamic_cast<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpCrsWrap,
true);
1363 return Teuchos::null;
1367 toXpetraOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op) {
1368#ifdef HAVE_XPETRA_TPETRA
1370 typedef Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node> TOE;
1378 Teuchos::rcp_dynamic_cast<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xTpetraOp,
true);
1383#ifdef HAVE_XPETRA_EPETRA
1388 return Teuchos::null;
1392 toXpetraOperator(
const Teuchos::RCP<Thyra::LinearOpBase<Scalar>>& op) {
1393#ifdef HAVE_XPETRA_TPETRA
1395 typedef Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node> TOE;
1403 Teuchos::rcp_dynamic_cast<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xTpetraOp,
true);
1408#ifdef HAVE_XPETRA_EPETRA
1413 return Teuchos::null;
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);
1442 xpDiag = rcp_dynamic_cast<Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpEpDiag,
true);
1453 return toXpetra(Teuchos::rcp_const_cast<Thyra::DiagonalLinearOpBase<Scalar>>(op));
1461 RCP<const BlockedMap> bmap = Teuchos::rcp_dynamic_cast<const BlockedMap>(map);
1462 if (bmap.is_null() ==
false) {
1464 for (
size_t i = 0; i < bmap->getNumMaps(); i++) {
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)))
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;
1492#ifdef HAVE_XPETRA_EPETRA
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;
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);
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);
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);
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 =
1592 for (
size_t j = 0; j < xpSubBlock->getNumVectors(); ++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);
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 =
1630 for (
size_t j = 0; j < source->getNumVectors(); ++j) {
1633 for (LocalOrdinal i = 0; i < localSubDim; ++i) {
1634 (*thyData)(i, j) = xpData[i];
1645#ifdef HAVE_XPETRA_TPETRA
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)))
1658 thyraOp = Thyra::createConstLinearOp(tpOperator);
1666#ifdef HAVE_XPETRA_EPETRA
1668 if (epetraMat != Teuchos::null) {
1675 thyraOp = thyraEpOp;
1686#ifdef HAVE_XPETRA_TPETRA
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)))
1699 thyraOp = Thyra::createLinearOp(tpOperator);
1707#ifdef HAVE_XPETRA_EPETRA
1709 if (epetraMat != Teuchos::null) {
1716 thyraOp = thyraEpOp;
1732#define XPETRA_THYRAUTILS_SHORT
Tpetra::KokkosCompat::KokkosSerialWrapperNode EpetraNode
Concrete implementation of Xpetra::Matrix.
Exception throws to report errors in the internal logical of the program.
static RCP< Matrix > Build(const RCP< const Map > &rowMap)
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)
RCP< const CrsGraph< int, GlobalOrdinal, Node > > toXpetra(const Epetra_CrsGraph &g)