47#ifndef XPETRA_THYRAUTILS_HPP
48#define XPETRA_THYRAUTILS_HPP
51#ifdef HAVE_XPETRA_THYRA
55#ifdef HAVE_XPETRA_TPETRA
56#include "Tpetra_ConfigDefs.hpp"
59#ifdef HAVE_XPETRA_EPETRA
60#include "Epetra_config.h"
61#include "Epetra_CombineMode.h"
64#include "Xpetra_Map.hpp"
65#include "Xpetra_BlockedMap.hpp"
66#include "Xpetra_BlockedMultiVector.hpp"
68#include "Xpetra_StridedMap.hpp"
69#include "Xpetra_StridedMapFactory.hpp"
70#include "Xpetra_MapExtractor.hpp"
72#include "Xpetra_CrsMatrixWrap.hpp"
73#include "Xpetra_MultiVectorFactory.hpp"
75#include <Thyra_VectorSpaceBase.hpp>
76#include <Thyra_SpmdVectorSpaceBase.hpp>
77#include <Thyra_ProductVectorSpaceBase.hpp>
78#include <Thyra_ProductMultiVectorBase.hpp>
79#include <Thyra_VectorSpaceBase.hpp>
80#include <Thyra_DefaultProductVectorSpace.hpp>
81#include <Thyra_DefaultBlockedLinearOp.hpp>
82#include <Thyra_LinearOpBase.hpp>
83#include <Thyra_DetachedMultiVectorView.hpp>
84#include <Thyra_MultiVectorStdOps.hpp>
86#ifdef HAVE_XPETRA_TPETRA
87#include <Thyra_TpetraThyraWrappers.hpp>
88#include <Thyra_TpetraVector.hpp>
89#include <Thyra_TpetraMultiVector.hpp>
90#include <Thyra_TpetraVectorSpace.hpp>
91#include <Tpetra_Map.hpp>
92#include <Tpetra_Vector.hpp>
93#include <Tpetra_CrsMatrix.hpp>
94#include <Xpetra_TpetraMap.hpp>
95#include <Xpetra_TpetraCrsMatrix.hpp>
97#ifdef HAVE_XPETRA_EPETRA
98#include <Thyra_EpetraLinearOp.hpp>
99#include <Thyra_EpetraThyraWrappers.hpp>
100#include <Thyra_SpmdVectorBase.hpp>
101#include <Thyra_get_Epetra_Operator.hpp>
102#include <Epetra_Map.h>
103#include <Epetra_Vector.h>
104#include <Epetra_CrsMatrix.h>
111template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
class BlockedCrsMatrix;
113template <
class Scalar,
114class LocalOrdinal = int,
115class GlobalOrdinal = LocalOrdinal,
120#undef XPETRA_THYRAUTILS_SHORT
129 if(stridedBlockId == -1) {
143 using Teuchos::rcp_dynamic_cast;
145 using ThyVecSpaceBase = Thyra::VectorSpaceBase<Scalar>;
146 using ThyProdVecSpaceBase = Thyra::ProductVectorSpaceBase<Scalar>;
147 using ThyUtils = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>;
150 RCP<Map> resultMap = Teuchos::null;
151 RCP<const ThyProdVecSpaceBase > prodVectorSpace = rcp_dynamic_cast<const ThyProdVecSpaceBase >(vectorSpace);
152 if(prodVectorSpace != Teuchos::null) {
155 TEUCHOS_TEST_FOR_EXCEPTION(prodVectorSpace->numBlocks()==0, std::logic_error,
"Found a product vector space with zero blocks.");
156 std::vector<RCP<const Map> > mapsThyra(prodVectorSpace->numBlocks(), Teuchos::null);
157 std::vector<RCP<const Map> > mapsXpetra(prodVectorSpace->numBlocks(), Teuchos::null);
158 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
159 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
166 std::vector<GlobalOrdinal> gidOffsets(prodVectorSpace->numBlocks(),0);
167 for(
int i = 1; i < prodVectorSpace->numBlocks(); ++i) {
168 gidOffsets[i] = mapsThyra[i-1]->getMaxAllGlobalIndex() + gidOffsets[i-1] + 1;
171 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
172 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
179#ifdef HAVE_XPETRA_TPETRA
185 typedef Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> TpMap;
186 typedef Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpVector;
187 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
188 typedef Thyra::VectorBase<Scalar> ThyVecBase;
189 RCP<ThyVecBase> rgVec = Thyra::createMember<Scalar>(vectorSpace, std::string(
"label"));
191 RCP<const TpVector> rgTpetraVec = TOE::getTpetraVector(rgVec);
193 RCP<const TpMap> rgTpetraMap = rgTpetraVec->getMap();
197 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"Cannot transform Thyra::VectorSpace to Xpetra::Map. This is the general implementation for Tpetra only, but Tpetra is disabled.");
208 using Teuchos::rcp_dynamic_cast;
211 using ThyMultVecBase = Thyra::MultiVectorBase<Scalar>;
212 using ThyProdMultVecBase = Thyra::ProductMultiVectorBase<Scalar>;
213 using ThyUtils = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>;
216 RCP<MultiVector> xpMultVec = Teuchos::null;
220 if(thyProdVec != Teuchos::null) {
229 RCP<BlockedMultiVector> xpBlockedMultVec = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(xpMultVec);
233 for (
int b = 0; b < thyProdVec->productSpace()->numBlocks(); ++b){
234 RCP<const ThyMultVecBase> thyBlockMV = thyProdVec->getMultiVectorBlock(b);
237 xpBlockedMultVec->setMultiVector(b, xpBlockMV,
true );
241#ifdef HAVE_XPETRA_TPETRA
242 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> ConverterT;
243 typedef Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpMultVec;
245 typedef Thyra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> ThyTpMultVec;
246 typedef Thyra::SpmdMultiVectorBase<Scalar> ThySpmdMultVecBase;
248 RCP<const ThySpmdMultVecBase> thyraSpmdMultiVector = rcp_dynamic_cast<const ThySpmdMultVecBase>(v);
249 RCP<const ThyTpMultVec> thyraTpetraMultiVector = rcp_dynamic_cast<const ThyTpMultVec>(thyraSpmdMultiVector);
251 const RCP<const TpMultVec> tpMultVec = ConverterT::getConstTpetraMultiVector(v);
253 RCP<TpMultVec> tpNonConstMultVec = Teuchos::rcp_const_cast<TpMultVec>(tpMultVec);
255 xpMultVec =
rcp(
new XpTpMultVec(tpNonConstMultVec));
257 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"Cannot transform Thyra::MultiVector to Xpetra::MultiVector. This is the general implementation for Tpetra only, but Teptra is disabled.");
268 Teuchos::rcp_const_cast<const Thyra::MultiVectorBase<Scalar> >(v);
271 return Teuchos::rcp_const_cast<Xpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(r);
275 static bool isTpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
279 bool bIsTpetra =
false;
280#ifdef HAVE_XPETRA_TPETRA
286#ifdef HAVE_XPETRA_EPETRA
287 Teuchos::rcp_dynamic_cast<const Thyra::EpetraLinearOp>(op) == Teuchos::null &&
289 Teuchos::rcp_dynamic_cast<
const Thyra::DefaultBlockedLinearOp<Scalar> >(op) == Teuchos::null) {
291 typedef Thyra::TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpetraLinearOp_t;
292 if(Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op) == Teuchos::null) {
293 std::cout <<
"ATTENTION: The dynamic cast to the TpetraLinearOp failed even though it should be a TpetraLinearOp." << std::endl;
294 std::cout <<
" If you are using Panzer or Stratimikos you might check that the template parameters are " << std::endl;
295 std::cout <<
" properly set!" << std::endl;
296 std::cout << Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op,
true) << std::endl;
305 if(bIsTpetra ==
false) {
307 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op);
308 if(ThyBlockedOp != Teuchos::null) {
311 ThyBlockedOp->getBlock(0,0);
313 bIsTpetra = isTpetra(b00);
321 static bool isEpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
325 static bool isBlockedOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
328 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op);
329 if(ThyBlockedOp != Teuchos::null) {
338#ifdef HAVE_XPETRA_TPETRA
340 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
357 Teuchos::rcp_dynamic_cast<const Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(xTpetraCrsMat);
362#ifdef HAVE_XPETRA_EPETRA
367 return Teuchos::null;
373#ifdef HAVE_XPETRA_TPETRA
375 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
386 return xTpetraCrsMat;
390#ifdef HAVE_XPETRA_EPETRA
395 return Teuchos::null;
403 RCP<const BlockedMap> bmap = Teuchos::rcp_dynamic_cast<const BlockedMap>(map);
404 if(bmap.is_null() ==
false) {
407 for(
size_t i = 0; i < bmap->getNumMaps(); i++) {
410 Xpetra::ThyraUtils<Scalar,LO,GO,Node>::toThyra(bmap->getMap(i,
true));
414 thyraMap = Thyra::productVectorSpace<Scalar>(vecSpaces());
419#ifdef HAVE_XPETRA_TPETRA
422 if (tpetraMap == Teuchos::null)
423 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::TpetraMap failed");
424 RCP<Thyra::TpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node> > thyraTpetraMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tpetraMap->getTpetra_Map());
425 thyraMap = thyraTpetraMap;
429#ifdef HAVE_XPETRA_EPETRA
442#ifdef HAVE_XPETRA_TPETRA
444 auto thyTpMap = Thyra::tpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node>(Teuchos::rcp_dynamic_cast<const TpetraMap>(vec->getMap())->getTpetra_Map());
445 RCP<Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpMV = Teuchos::rcp_dynamic_cast<const TpetraMultiVector>(vec)->getTpetra_MultiVector();
446 auto thyDomMap = Thyra::tpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node>(Tpetra::createLocalMapWithNode<LocalOrdinal, GlobalOrdinal, Node>(vec->getNumVectors(), vec->getMap()->getComm()));
447 auto thyMV =
rcp(
new Thyra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>());
448 thyMV->initialize(thyTpMap, thyDomMap, tpMV);
453#ifdef HAVE_XPETRA_EPETRA
466#ifdef HAVE_XPETRA_TPETRA
468 auto thyTpMap = Thyra::tpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node>(Teuchos::rcp_dynamic_cast<const TpetraMap>(vec->getMap())->getTpetra_Map());
469 RCP<Tpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpVec = Teuchos::rcp_dynamic_cast<const TpetraVector>(vec)->getTpetra_Vector();
470 auto thyVec =
rcp(
new Thyra::TpetraVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>());
471 thyVec->initialize(thyTpMap, tpVec);
476#ifdef HAVE_XPETRA_EPETRA
490 using Teuchos::rcp_dynamic_cast;
492 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
493 typedef Thyra::SpmdVectorSpaceBase<Scalar> ThySpmdVecSpaceBase;
494 typedef Thyra::MultiVectorBase<Scalar> ThyMultVecBase;
497 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
501 RCP<ThyProdMultVecBase> prodTarget = rcp_dynamic_cast<ThyProdMultVecBase>(target);
502 if(prodTarget != Teuchos::null) {
503 RCP<const BlockedMultiVector> bSourceVec = rcp_dynamic_cast<const BlockedMultiVector>(source);
504 if(bSourceVec.is_null() ==
true) {
508 TEUCHOS_TEST_FOR_EXCEPTION(mapExtractor == Teuchos::null, std::logic_error,
"Found a Thyra product vector, but user did not provide an Xpetra::MapExtractor.");
509 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.");
511 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
513 RCP<MultiVector> xpSubBlock = mapExtractor->ExtractVector(source, bbb,
false);
517 RCP<const ThyVecSpaceBase> vs = thySubBlock->range();
518 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<const ThySpmdVecSpaceBase>(vs);
519 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
520 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : vs->dim() );
521 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
525 for(
size_t j = 0; j < xpSubBlock->getNumVectors(); ++j) {
529 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
530 (*thyData)(i,j) = xpData[i];
537 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.");
539 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
541 RCP<MultiVector> xpSubBlock = bSourceVec->getMultiVector(bbb,
true);
547 Thyra::assign(thySubBlock.
ptr(), *thyXpSubBlock);
556 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<const ThySpmdVecSpaceBase>(target->range());
557 TEUCHOS_TEST_FOR_EXCEPTION(mpi_vs == Teuchos::null, std::logic_error,
"Failed to cast Thyra::VectorSpaceBase to Thyra::SpmdVectorSpaceBase.");
558 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
559 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : target->range()->dim() );
560 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
564 for(
size_t j = 0; j < source->getNumVectors(); ++j) {
567 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
568 (*thyData)(i,j) = xpData[i];
581#ifdef HAVE_XPETRA_TPETRA
583 if(tpetraMat!=Teuchos::null) {
595 thyraOp = Thyra::createConstLinearOp(tpOperator);
598#ifdef HAVE_XPETRA_EPETRA
618#ifdef HAVE_XPETRA_TPETRA
620 if(tpetraMat!=Teuchos::null) {
632 thyraOp = Thyra::createLinearOp(tpOperator);
636#ifdef HAVE_XPETRA_EPETRA
652 int nRows = mat->Rows();
653 int nCols = mat->Cols();
659#ifdef HAVE_XPETRA_TPETRA
661 if(tpetraMat!=Teuchos::null) {
665 Thyra::defaultBlockedLinearOp<Scalar>();
667 blockMat->beginBlockFill(nRows,nCols);
669 for (
int r=0; r<nRows; ++r) {
670 for (
int c=0; c<nCols; ++c) {
673 if(xpmat == Teuchos::null)
continue;
679 Teuchos::rcp_dynamic_cast<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(xpmat);
680 if(xpblock != Teuchos::null) {
681 if(xpblock->Rows() == 1 && xpblock->Cols() == 1) {
685 thBlock = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(xpwrap->getCrsMatrix());
688 thBlock = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(xpblock);
694 thBlock = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(xpwrap->getCrsMatrix());
697 blockMat->setBlock(r,c,thBlock);
701 blockMat->endBlockFill();
706#ifdef HAVE_XPETRA_EPETRA
717#if defined(HAVE_XPETRA_EPETRA) && !defined(HAVE_XPETRA_TPETRA)
728#ifdef HAVE_XPETRA_EPETRA
730#ifndef XPETRA_EPETRA_NO_32BIT_GLOBAL_INDICES
732class ThyraUtils<double, int, int,
EpetraNode> {
734 typedef double Scalar;
735 typedef int LocalOrdinal;
736 typedef int GlobalOrdinal;
740#undef XPETRA_THYRAUTILS_SHORT
750 if(stridedBlockId == -1) {
764 using Teuchos::rcp_dynamic_cast;
766 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
767 typedef Thyra::ProductVectorSpaceBase<Scalar> ThyProdVecSpaceBase;
768 typedef Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node> ThyUtils;
770 RCP<Map> resultMap = Teuchos::null;
772 RCP<const ThyProdVecSpaceBase > prodVectorSpace = rcp_dynamic_cast<const ThyProdVecSpaceBase >(vectorSpace);
773 if(prodVectorSpace != Teuchos::null) {
776 TEUCHOS_TEST_FOR_EXCEPTION(prodVectorSpace->numBlocks()==0, std::logic_error,
"Found a product vector space with zero blocks.");
777 std::vector<RCP<const Map> > mapsThyra(prodVectorSpace->numBlocks(), Teuchos::null);
778 std::vector<RCP<const Map> > mapsXpetra(prodVectorSpace->numBlocks(), Teuchos::null);
779 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
780 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
787 std::vector<GlobalOrdinal> gidOffsets(prodVectorSpace->numBlocks(),0);
788 for(
int i = 1; i < prodVectorSpace->numBlocks(); ++i) {
789 gidOffsets[i] = mapsThyra[i-1]->getMaxAllGlobalIndex() + gidOffsets[i-1] + 1;
792 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
793 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
804 bool bIsTpetra =
false;
805#ifdef HAVE_XPETRA_TPETRA
806#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
807 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
814 bool bIsEpetra = !bIsTpetra;
816#ifdef HAVE_XPETRA_TPETRA
818#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
819 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
820 typedef Thyra::VectorBase<Scalar> ThyVecBase;
821 typedef Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> TpMap;
822 typedef Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpVector;
823 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
824 RCP<ThyVecBase> rgVec = Thyra::createMember<Scalar>(vectorSpace, std::string(
"label"));
826 RCP<const TpVector> rgTpetraVec = TOE::getTpetraVector(rgVec);
828 RCP<const TpMap> rgTpetraMap = rgTpetraVec->getMap();
838#ifdef HAVE_XPETRA_EPETRA
841 RCP<const Epetra_Map>
842 epetra_map = Teuchos::get_extra_data<RCP<const Epetra_Map> >(vectorSpace,
"epetra_map");
860 using Teuchos::rcp_dynamic_cast;
863 using ThyProdMultVecBase = Thyra::ProductMultiVectorBase<Scalar>;
864 using ThyMultVecBase = Thyra::MultiVectorBase<Scalar>;
865 using ThyUtils = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>;
868 RCP<MultiVector> xpMultVec = Teuchos::null;
872 if(thyProdVec != Teuchos::null) {
881 RCP<BlockedMultiVector> xpBlockedMultVec = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(xpMultVec);
885 for (
int b = 0; b < thyProdVec->productSpace()->numBlocks(); ++b){
886 RCP<const ThyMultVecBase> thyBlockMV = thyProdVec->getMultiVectorBlock(b);
889 xpBlockedMultVec->setMultiVector(b, xpBlockMV,
true );
897 bool bIsTpetra =
false;
898#ifdef HAVE_XPETRA_TPETRA
899#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
900 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
904 typedef Thyra::SpmdMultiVectorBase<Scalar> ThySpmdMultVecBase;
905 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> ConverterT;
906 typedef Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpMultVec;
908 typedef Thyra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> ThyTpMultVec;
910 RCP<const ThySpmdMultVecBase> thyraSpmdMultiVector = rcp_dynamic_cast<const ThySpmdMultVecBase>(v);
911 RCP<const ThyTpMultVec> thyraTpetraMultiVector = rcp_dynamic_cast<const ThyTpMultVec>(thyraSpmdMultiVector);
912 if(thyraTpetraMultiVector != Teuchos::null) {
914 const RCP<const TpMultVec> tpMultVec = ConverterT::getConstTpetraMultiVector(v);
916 RCP<TpMultVec> tpNonConstMultVec = Teuchos::rcp_const_cast<TpMultVec>(tpMultVec);
918 xpMultVec =
rcp(
new XpTpMultVec(tpNonConstMultVec));
923#ifdef HAVE_XPETRA_EPETRA
924 if(bIsTpetra ==
false) {
928 RCP<Xpetra::EpetraMapT<GlobalOrdinal,Node> > xeMap = rcp_dynamic_cast<Xpetra::EpetraMapT<GlobalOrdinal,Node> >(map);
930 RCP<const Epetra_Map> eMap = xeMap->getEpetra_MapRCP();
934 RCP<Epetra_MultiVector> epNonConstMultVec = Teuchos::rcp_const_cast<Epetra_MultiVector>(epMultVec);
948 Teuchos::rcp_const_cast<const Thyra::MultiVectorBase<Scalar> >(v);
951 return Teuchos::rcp_const_cast<Xpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(r);
954 static bool isTpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
956 bool bIsTpetra =
false;
957#ifdef HAVE_XPETRA_TPETRA
958#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
959 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
966#ifdef HAVE_XPETRA_EPETRA
967 Teuchos::rcp_dynamic_cast<const Thyra::EpetraLinearOp>(op) == Teuchos::null &&
969 Teuchos::rcp_dynamic_cast<
const Thyra::DefaultBlockedLinearOp<Scalar> >(op) == Teuchos::null) {
971 typedef Thyra::TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpetraLinearOp_t;
972 if(Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op) == Teuchos::null) {
973 std::cout <<
"ATTENTION: The dynamic cast to the TpetraLinearOp failed even though it should be a TpetraLinearOp." << std::endl;
974 std::cout <<
" If you are using Panzer or Stratimikos you might check that the template parameters are " << std::endl;
975 std::cout <<
" properly set!" << std::endl;
976 std::cout << Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op,
true) << std::endl;
986 if(bIsTpetra ==
false) {
988 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op);
989 if(ThyBlockedOp != Teuchos::null) {
992 ThyBlockedOp->getBlock(0,0);
994 bIsTpetra = isTpetra(b00);
1002 static bool isEpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
1004 bool bIsEpetra =
false;
1006#ifdef HAVE_XPETRA_EPETRA
1015 if(bIsEpetra ==
false) {
1017 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op,
false);
1018 if(ThyBlockedOp != Teuchos::null) {
1021 ThyBlockedOp->getBlock(0,0);
1023 bIsEpetra = isEpetra(b00);
1031 static bool isBlockedOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
1034 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op);
1035 if(ThyBlockedOp != Teuchos::null) {
1044#ifdef HAVE_XPETRA_TPETRA
1046#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1047 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
1049 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
1065 Teuchos::rcp_dynamic_cast<const Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(xTpetraCrsMat);
1074#ifdef HAVE_XPETRA_EPETRA
1090 Teuchos::rcp_dynamic_cast<const Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(xEpetraCrsMat);
1095 return Teuchos::null;
1101#ifdef HAVE_XPETRA_TPETRA
1103#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1104 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
1106 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
1117 return xTpetraCrsMat;
1124#ifdef HAVE_XPETRA_EPETRA
1136 return xEpetraCrsMat;
1139 return Teuchos::null;
1147 RCP<const BlockedMap> bmap = Teuchos::rcp_dynamic_cast<const BlockedMap>(map);
1148 if(bmap.is_null() ==
false) {
1151 for(
size_t i = 0; i < bmap->getNumMaps(); i++) {
1154 Xpetra::ThyraUtils<Scalar,LO,GO,Node>::toThyra(bmap->getMap(i,
true));
1158 thyraMap = Thyra::productVectorSpace<Scalar>(vecSpaces());
1163#ifdef HAVE_XPETRA_TPETRA
1165#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1166 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
1168 if (tpetraMap == Teuchos::null)
1169 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::TpetraMap failed");
1170 RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > tpMap = tpetraMap->getTpetra_Map();
1171 RCP<Thyra::TpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node> > thyraTpetraMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tpMap);
1172 thyraMap = thyraTpetraMap;
1179#ifdef HAVE_XPETRA_EPETRA
1182 if (epetraMap == Teuchos::null)
1183 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::EpetraMap failed");
1184 RCP<const Thyra::VectorSpaceBase<Scalar> > thyraEpetraMap = Thyra::create_VectorSpace(epetraMap->getEpetra_MapRCP());
1185 thyraMap = thyraEpetraMap;
1196#ifdef HAVE_XPETRA_TPETRA
1198 auto thyTpMap = Thyra::tpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node>(Teuchos::rcp_dynamic_cast<const TpetraMap>(vec->getMap())->getTpetra_Map());
1199 RCP<Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpMV = Teuchos::rcp_dynamic_cast<const TpetraMultiVector>(vec)->getTpetra_MultiVector();
1200 auto thyDomMap = Thyra::tpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node>(Tpetra::createLocalMapWithNode<LocalOrdinal, GlobalOrdinal, Node>(vec->getNumVectors(), vec->getMap()->getComm()));
1201 auto thyMV =
rcp(
new Thyra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>());
1202 thyMV->initialize(thyTpMap, thyDomMap, tpMV);
1207#ifdef HAVE_XPETRA_EPETRA
1209 auto thyEpMap = Thyra::create_VectorSpace(Teuchos::rcp_dynamic_cast<
const EpetraMapT<GlobalOrdinal, Node> >(vec->getMap())->getEpetra_MapRCP());
1210 auto epMV = Teuchos::rcp_dynamic_cast<const EpetraMultiVectorT<GlobalOrdinal, Node> >(vec)->getEpetra_MultiVector();
1211 auto thyMV = Thyra::create_MultiVector(epMV, thyEpMap);
1224#ifdef HAVE_XPETRA_TPETRA
1226 auto thyTpMap = Thyra::tpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node>(Teuchos::rcp_dynamic_cast<const TpetraMap>(vec->getMap())->getTpetra_Map());
1227 RCP<Tpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpVec = Teuchos::rcp_dynamic_cast<const TpetraVector>(vec)->getTpetra_Vector();
1228 auto thyVec =
rcp(
new Thyra::TpetraVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>());
1229 thyVec->initialize(thyTpMap, tpVec);
1234#ifdef HAVE_XPETRA_EPETRA
1236 auto thyEpMap = Thyra::create_VectorSpace(Teuchos::rcp_dynamic_cast<
const EpetraMapT<GlobalOrdinal, Node> >(vec->getMap())->getEpetra_MapRCP());
1237 auto epVec =
rcp(Teuchos::rcp_dynamic_cast<
const EpetraVectorT<GlobalOrdinal, Node> >(vec)->getEpetra_Vector(),
false);
1238 auto thyVec = Thyra::create_Vector(epVec, thyEpMap);
1248 using Teuchos::rcp_dynamic_cast;
1250 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
1251 typedef Thyra::SpmdVectorSpaceBase<Scalar> ThySpmdVecSpaceBase;
1252 typedef Thyra::MultiVectorBase<Scalar> ThyMultVecBase;
1255 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
1258 RCP<ThyProdMultVecBase> prodTarget = rcp_dynamic_cast<ThyProdMultVecBase>(target);
1259 if(prodTarget != Teuchos::null) {
1261 RCP<const BlockedMultiVector> bSourceVec = rcp_dynamic_cast<const BlockedMultiVector>(source);
1262 if(bSourceVec.is_null() ==
true) {
1266 TEUCHOS_TEST_FOR_EXCEPTION(mapExtractor == Teuchos::null, std::logic_error,
"Found a Thyra product vector, but user did not provide an Xpetra::MapExtractor.");
1267 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.");
1269 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
1271 RCP<MultiVector> xpSubBlock = mapExtractor->ExtractVector(source, bbb,
false);
1275 RCP<const ThyVecSpaceBase> vs = thySubBlock->range();
1276 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<const ThySpmdVecSpaceBase>(vs);
1277 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
1278 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : vs->dim() );
1279 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
1283 for(
size_t j = 0; j < xpSubBlock->getNumVectors(); ++j) {
1287 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1288 (*thyData)(i,j) = xpData[i];
1295 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.");
1297 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
1299 RCP<MultiVector> xpSubBlock = bSourceVec->getMultiVector(bbb,
true);
1305 Thyra::assign(thySubBlock.
ptr(), *thyXpSubBlock);
1314 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<const ThySpmdVecSpaceBase>(target->range());
1315 TEUCHOS_TEST_FOR_EXCEPTION(mpi_vs == Teuchos::null, std::logic_error,
"Failed to cast Thyra::VectorSpaceBase to Thyra::SpmdVectorSpaceBase.");
1316 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
1317 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : target->range()->dim() );
1318 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
1322 for(
size_t j = 0; j < source->getNumVectors(); ++j) {
1325 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1326 (*thyData)(i,j) = xpData[i];
1337#ifdef HAVE_XPETRA_TPETRA
1339 if(tpetraMat!=Teuchos::null) {
1340#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1341 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
1353 thyraOp = Thyra::createConstLinearOp(tpOperator);
1361#ifdef HAVE_XPETRA_EPETRA
1363 if(epetraMat!=Teuchos::null) {
1371 thyraOp = thyraEpOp;
1382#ifdef HAVE_XPETRA_TPETRA
1384 if(tpetraMat!=Teuchos::null) {
1385#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1386 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
1398 thyraOp = Thyra::createLinearOp(tpOperator);
1406#ifdef HAVE_XPETRA_EPETRA
1408 if(epetraMat!=Teuchos::null) {
1416 thyraOp = thyraEpOp;
1428#ifndef XPETRA_EPETRA_NO_64BIT_GLOBAL_INDICES
1430class ThyraUtils<double, int, long long,
EpetraNode> {
1432 typedef double Scalar;
1433 typedef int LocalOrdinal;
1434 typedef long long GlobalOrdinal;
1438#undef XPETRA_THYRAUTILS_SHORT
1448 if(stridedBlockId == -1) {
1462 using Teuchos::rcp_dynamic_cast;
1464 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
1465 typedef Thyra::ProductVectorSpaceBase<Scalar> ThyProdVecSpaceBase;
1466 typedef Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node> ThyUtils;
1468 RCP<const ThyProdVecSpaceBase > prodVectorSpace = rcp_dynamic_cast<const ThyProdVecSpaceBase >(vectorSpace);
1469 if(prodVectorSpace != Teuchos::null) {
1472 TEUCHOS_TEST_FOR_EXCEPTION(prodVectorSpace->numBlocks()==0, std::logic_error,
"Found a product vector space with zero blocks.");
1473 std::vector<RCP<const Map> > mapsThyra(prodVectorSpace->numBlocks(), Teuchos::null);
1474 std::vector<RCP<const Map> > mapsXpetra(prodVectorSpace->numBlocks(), Teuchos::null);
1475 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
1476 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
1483 std::vector<GlobalOrdinal> gidOffsets(prodVectorSpace->numBlocks(),0);
1484 for(
int i = 1; i < prodVectorSpace->numBlocks(); ++i) {
1485 gidOffsets[i] = mapsThyra[i-1]->getMaxAllGlobalIndex() + gidOffsets[i-1] + 1;
1488 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
1489 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
1502 bool bIsTpetra =
false;
1503#ifdef HAVE_XPETRA_TPETRA
1504#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1505 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1512 bool bIsEpetra = !bIsTpetra;
1514#ifdef HAVE_XPETRA_TPETRA
1516#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1517 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1518 typedef Thyra::VectorBase<Scalar> ThyVecBase;
1519 typedef Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> TpMap;
1520 typedef Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpVector;
1521 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
1522 RCP<ThyVecBase> rgVec = Thyra::createMember<Scalar>(vectorSpace, std::string(
"label"));
1524 RCP<const TpVector> rgTpetraVec = TOE::getTpetraVector(rgVec);
1526 RCP<const TpMap> rgTpetraMap = rgTpetraVec->getMap();
1538#ifdef HAVE_XPETRA_EPETRA
1541 RCP<const Epetra_Map>
1542 epetra_map = Teuchos::get_extra_data<RCP<const Epetra_Map> >(vectorSpace,
"epetra_map");
1561 using Teuchos::rcp_dynamic_cast;
1563 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
1564 typedef Thyra::MultiVectorBase<Scalar> ThyMultVecBase;
1565 typedef Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node> ThyUtils;
1568 RCP<MultiVector> xpMultVec = Teuchos::null;
1572 if(thyProdVec != Teuchos::null) {
1581 RCP<BlockedMultiVector> xpBlockedMultVec = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(xpMultVec);
1585 for (
int b = 0; b < thyProdVec->productSpace()->numBlocks(); ++b){
1586 RCP<const ThyMultVecBase> thyBlockMV = thyProdVec->getMultiVectorBlock(b);
1589 xpBlockedMultVec->setMultiVector(b, xpBlockMV,
true );
1597 bool bIsTpetra =
false;
1598#ifdef HAVE_XPETRA_TPETRA
1599#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1600 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1604 typedef Thyra::SpmdMultiVectorBase<Scalar> ThySpmdMultVecBase;
1605 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> ConverterT;
1606 typedef Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpMultVec;
1608 typedef Thyra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> ThyTpMultVec;
1610 RCP<const ThySpmdMultVecBase> thyraSpmdMultiVector = rcp_dynamic_cast<const ThySpmdMultVecBase>(v);
1611 RCP<const ThyTpMultVec> thyraTpetraMultiVector = rcp_dynamic_cast<const ThyTpMultVec>(thyraSpmdMultiVector);
1612 if(thyraTpetraMultiVector != Teuchos::null) {
1614 const RCP<const TpMultVec> tpMultVec = ConverterT::getConstTpetraMultiVector(v);
1616 RCP<TpMultVec> tpNonConstMultVec = Teuchos::rcp_const_cast<TpMultVec>(tpMultVec);
1618 xpMultVec =
rcp(
new XpTpMultVec(tpNonConstMultVec));
1625#ifdef HAVE_XPETRA_EPETRA
1626 if(bIsTpetra ==
false) {
1630 RCP<Xpetra::EpetraMapT<GlobalOrdinal,Node> > xeMap = rcp_dynamic_cast<Xpetra::EpetraMapT<GlobalOrdinal,Node> >(map);
1632 RCP<const Epetra_Map> eMap = xeMap->getEpetra_MapRCP();
1636 RCP<Epetra_MultiVector> epNonConstMultVec = Teuchos::rcp_const_cast<Epetra_MultiVector>(epMultVec);
1652 Teuchos::rcp_const_cast<const Thyra::MultiVectorBase<Scalar> >(v);
1655 return Teuchos::rcp_const_cast<Xpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(r);
1658 static bool isTpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
1660 bool bIsTpetra =
false;
1661#ifdef HAVE_XPETRA_TPETRA
1662#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1663 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1670#ifdef HAVE_XPETRA_EPETRA
1671 Teuchos::rcp_dynamic_cast<const Thyra::EpetraLinearOp>(op) == Teuchos::null &&
1673 Teuchos::rcp_dynamic_cast<
const Thyra::DefaultBlockedLinearOp<Scalar> >(op) == Teuchos::null) {
1675 typedef Thyra::TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpetraLinearOp_t;
1676 if(Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op) == Teuchos::null) {
1677 std::cout <<
"ATTENTION: The dynamic cast to the TpetraLinearOp failed even though it should be a TpetraLinearOp." << std::endl;
1678 std::cout <<
" If you are using Panzer or Stratimikos you might check that the template parameters are " << std::endl;
1679 std::cout <<
" properly set!" << std::endl;
1680 std::cout << Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op,
true) << std::endl;
1690 if(bIsTpetra ==
false) {
1692 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op);
1693 if(ThyBlockedOp != Teuchos::null) {
1696 ThyBlockedOp->getBlock(0,0);
1698 bIsTpetra = isTpetra(b00);
1706 static bool isEpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
1708 bool bIsEpetra =
false;
1710#ifdef HAVE_XPETRA_EPETRA
1719 if(bIsEpetra ==
false) {
1721 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op,
false);
1722 if(ThyBlockedOp != Teuchos::null) {
1725 ThyBlockedOp->getBlock(0,0);
1727 bIsEpetra = isEpetra(b00);
1735 static bool isBlockedOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
1738 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op);
1739 if(ThyBlockedOp != Teuchos::null) {
1748#ifdef HAVE_XPETRA_TPETRA
1750#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1751 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1753 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
1769 Teuchos::rcp_dynamic_cast<const Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(xTpetraCrsMat);
1778#ifdef HAVE_XPETRA_EPETRA
1794 Teuchos::rcp_dynamic_cast<const Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(xEpetraCrsMat);
1799 return Teuchos::null;
1805#ifdef HAVE_XPETRA_TPETRA
1807#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1808 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1810 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
1821 return xTpetraCrsMat;
1828#ifdef HAVE_XPETRA_EPETRA
1840 return xEpetraCrsMat;
1843 return Teuchos::null;
1851 RCP<const BlockedMap> bmap = Teuchos::rcp_dynamic_cast<const BlockedMap>(map);
1852 if(bmap.is_null() ==
false) {
1855 for(
size_t i = 0; i < bmap->getNumMaps(); i++) {
1858 Xpetra::ThyraUtils<Scalar,LO,GO,Node>::toThyra(bmap->getMap(i,
true));
1862 thyraMap = Thyra::productVectorSpace<Scalar>(vecSpaces());
1867#ifdef HAVE_XPETRA_TPETRA
1869#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1870 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1872 if (tpetraMap == Teuchos::null)
1873 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::TpetraMap failed");
1874 RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > tpMap = tpetraMap->getTpetra_Map();
1875 RCP<Thyra::TpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node> > thyraTpetraMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tpMap);
1876 thyraMap = thyraTpetraMap;
1883#ifdef HAVE_XPETRA_EPETRA
1886 if (epetraMap == Teuchos::null)
1887 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::EpetraMap failed");
1888 RCP<const Thyra::VectorSpaceBase<Scalar> > thyraEpetraMap = Thyra::create_VectorSpace(epetraMap->getEpetra_MapRCP());
1889 thyraMap = thyraEpetraMap;
1900#ifdef HAVE_XPETRA_TPETRA
1902 auto thyTpMap = Thyra::tpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node>(Teuchos::rcp_dynamic_cast<const TpetraMap>(vec->getMap())->getTpetra_Map());
1903 RCP<Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpMV = Teuchos::rcp_dynamic_cast<const TpetraMultiVector>(vec)->getTpetra_MultiVector();
1904 auto thyDomMap = Thyra::tpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node>(Tpetra::createLocalMapWithNode<LocalOrdinal, GlobalOrdinal, Node>(vec->getNumVectors(), vec->getMap()->getComm()));
1905 auto thyMV =
rcp(
new Thyra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>());
1906 thyMV->initialize(thyTpMap, thyDomMap, tpMV);
1911#ifdef HAVE_XPETRA_EPETRA
1913 auto thyEpMap = Thyra::create_VectorSpace(Teuchos::rcp_dynamic_cast<
const EpetraMapT<GlobalOrdinal, Node> >(vec->getMap())->getEpetra_MapRCP());
1914 auto epMV = Teuchos::rcp_dynamic_cast<const EpetraMultiVectorT<GlobalOrdinal, Node> >(vec)->getEpetra_MultiVector();
1915 auto thyMV = Thyra::create_MultiVector(epMV, thyEpMap);
1927#ifdef HAVE_XPETRA_TPETRA
1929 auto thyTpMap = Thyra::tpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node>(Teuchos::rcp_dynamic_cast<const TpetraMap>(vec->getMap())->getTpetra_Map());
1930 RCP<Tpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpVec = Teuchos::rcp_dynamic_cast<const TpetraVector>(vec)->getTpetra_Vector();
1931 auto thyVec =
rcp(
new Thyra::TpetraVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>());
1932 thyVec->initialize(thyTpMap, tpVec);
1937#ifdef HAVE_XPETRA_EPETRA
1939 auto thyEpMap = Thyra::create_VectorSpace(Teuchos::rcp_dynamic_cast<
const EpetraMapT<GlobalOrdinal, Node> >(vec->getMap())->getEpetra_MapRCP());
1940 auto epVec =
rcp(Teuchos::rcp_dynamic_cast<
const EpetraVectorT<GlobalOrdinal, Node> >(vec)->getEpetra_Vector(),
false);
1941 auto thyVec = Thyra::create_Vector(epVec, thyEpMap);
1951 using Teuchos::rcp_dynamic_cast;
1953 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
1954 typedef Thyra::SpmdVectorSpaceBase<Scalar> ThySpmdVecSpaceBase;
1955 typedef Thyra::MultiVectorBase<Scalar> ThyMultVecBase;
1958 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
1961 RCP<ThyProdMultVecBase> prodTarget = rcp_dynamic_cast<ThyProdMultVecBase>(target);
1962 if(prodTarget != Teuchos::null) {
1963 RCP<const BlockedMultiVector> bSourceVec = rcp_dynamic_cast<const BlockedMultiVector>(source);
1964 if(bSourceVec.is_null() ==
true) {
1968 TEUCHOS_TEST_FOR_EXCEPTION(mapExtractor == Teuchos::null, std::logic_error,
"Found a Thyra product vector, but user did not provide an Xpetra::MapExtractor.");
1969 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.");
1971 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
1973 RCP<MultiVector> xpSubBlock = mapExtractor->ExtractVector(source, bbb,
false);
1977 RCP<const ThyVecSpaceBase> vs = thySubBlock->range();
1978 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<const ThySpmdVecSpaceBase>(vs);
1979 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
1980 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : vs->dim() );
1981 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
1985 for(
size_t j = 0; j < xpSubBlock->getNumVectors(); ++j) {
1989 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1990 (*thyData)(i,j) = xpData[i];
1997 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.");
1999 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
2001 RCP<MultiVector> xpSubBlock = bSourceVec->getMultiVector(bbb,
true);
2007 Thyra::assign(thySubBlock.
ptr(), *thyXpSubBlock);
2016 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<const ThySpmdVecSpaceBase>(target->range());
2017 TEUCHOS_TEST_FOR_EXCEPTION(mpi_vs == Teuchos::null, std::logic_error,
"Failed to cast Thyra::VectorSpaceBase to Thyra::SpmdVectorSpaceBase.");
2018 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
2019 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : target->range()->dim() );
2020 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
2024 for(
size_t j = 0; j < source->getNumVectors(); ++j) {
2027 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
2028 (*thyData)(i,j) = xpData[i];
2039#ifdef HAVE_XPETRA_TPETRA
2041 if(tpetraMat!=Teuchos::null) {
2042#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
2043 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
2055 thyraOp = Thyra::createConstLinearOp(tpOperator);
2063#ifdef HAVE_XPETRA_EPETRA
2065 if(epetraMat!=Teuchos::null) {
2073 thyraOp = thyraEpOp;
2084#ifdef HAVE_XPETRA_TPETRA
2086 if(tpetraMat!=Teuchos::null) {
2087#if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
2088 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
2100 thyraOp = Thyra::createLinearOp(tpOperator);
2108#ifdef HAVE_XPETRA_EPETRA
2110 if(epetraMat!=Teuchos::null) {
2118 thyraOp = thyraEpOp;
2134#define XPETRA_THYRAUTILS_SHORT
Exception throws to report errors in the internal logical of the program.
static Teuchos::RCP< Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > transformThyra2XpetraGIDs(const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &input, const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &nonOvlInput, const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &nonOvlReferenceInput)
replace set of global ids by new global ids
static Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Build(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &map, size_t NumVectors, bool zeroOut=true)
Constructor specifying the number of non-zeros for all rows.
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_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)
#define TEUCHOS_UNREACHABLE_RETURN(dummyReturnVal)
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)