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_TpetraVectorSpace.hpp>
90 #include <Tpetra_Map.hpp>
91 #include <Tpetra_Vector.hpp>
92 #include <Tpetra_CrsMatrix.hpp>
93 #include <Xpetra_TpetraMap.hpp>
94 #include <Xpetra_TpetraCrsMatrix.hpp>
96 #ifdef HAVE_XPETRA_EPETRA
97 #include <Thyra_EpetraLinearOp.hpp>
98 #include <Thyra_EpetraThyraWrappers.hpp>
99 #include <Thyra_SpmdVectorBase.hpp>
100 #include <Thyra_get_Epetra_Operator.hpp>
101 #include <Epetra_Map.h>
102 #include <Epetra_Vector.h>
103 #include <Epetra_CrsMatrix.h>
110 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
class BlockedCrsMatrix;
112 template <
class Scalar,
113 class LocalOrdinal = int,
114 class GlobalOrdinal = LocalOrdinal,
119 #undef XPETRA_THYRAUTILS_SHORT
128 if(stridedBlockId == -1) {
142 using Teuchos::rcp_dynamic_cast;
144 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
145 typedef Thyra::ProductVectorSpaceBase<Scalar> ThyProdVecSpaceBase;
148 using ThyUtils = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>;
151 RCP<Map> resultMap = Teuchos::null;
152 RCP<const ThyProdVecSpaceBase > prodVectorSpace = rcp_dynamic_cast<
const ThyProdVecSpaceBase >(vectorSpace);
153 if(prodVectorSpace != Teuchos::null) {
156 TEUCHOS_TEST_FOR_EXCEPTION(prodVectorSpace->numBlocks()==0, std::logic_error,
"Found a product vector space with zero blocks.");
157 std::vector<RCP<const Map> > mapsThyra(prodVectorSpace->numBlocks(), Teuchos::null);
158 std::vector<RCP<const Map> > mapsXpetra(prodVectorSpace->numBlocks(), Teuchos::null);
159 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
160 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
167 std::vector<GlobalOrdinal> gidOffsets(prodVectorSpace->numBlocks(),0);
168 for(
int i = 1; i < prodVectorSpace->numBlocks(); ++i) {
169 gidOffsets[i] = mapsThyra[i-1]->getMaxAllGlobalIndex() + gidOffsets[i-1] + 1;
172 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
173 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
180 #ifdef HAVE_XPETRA_TPETRA
186 typedef Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> TpMap;
187 typedef Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpVector;
188 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
189 typedef Thyra::VectorBase<Scalar> ThyVecBase;
190 RCP<ThyVecBase> rgVec = Thyra::createMember<Scalar>(vectorSpace, std::string(
"label"));
192 RCP<const TpVector> rgTpetraVec = TOE::getTpetraVector(rgVec);
194 RCP<const TpMap> rgTpetraMap = rgTpetraVec->getMap();
198 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.");
209 using Teuchos::rcp_dynamic_cast;
212 using ThyMultVecBase = Thyra::MultiVectorBase<Scalar>;
213 using ThyProdMultVecBase = Thyra::ProductMultiVectorBase<Scalar>;
218 using ThyUtils = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>;
222 RCP<MultiVector> xpMultVec = Teuchos::null;
226 if(thyProdVec != Teuchos::null) {
235 RCP<BlockedMultiVector> xpBlockedMultVec = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(xpMultVec);
239 for (
int b = 0; b < thyProdVec->productSpace()->numBlocks(); ++b){
240 RCP<const ThyMultVecBase> thyBlockMV = thyProdVec->getMultiVectorBlock(b);
243 xpBlockedMultVec->setMultiVector(b, xpBlockMV,
true );
247 #ifdef HAVE_XPETRA_TPETRA
248 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> ConverterT;
249 typedef Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpMultVec;
251 typedef Thyra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> ThyTpMultVec;
252 typedef Thyra::SpmdMultiVectorBase<Scalar> ThySpmdMultVecBase;
254 RCP<const ThySpmdMultVecBase> thyraSpmdMultiVector = rcp_dynamic_cast<
const ThySpmdMultVecBase>(v);
255 RCP<const ThyTpMultVec> thyraTpetraMultiVector = rcp_dynamic_cast<
const ThyTpMultVec>(thyraSpmdMultiVector);
257 const RCP<const TpMultVec> tpMultVec = ConverterT::getConstTpetraMultiVector(v);
259 RCP<TpMultVec> tpNonConstMultVec = Teuchos::rcp_const_cast<TpMultVec>(tpMultVec);
261 xpMultVec =
rcp(
new XpTpMultVec(tpNonConstMultVec));
263 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.");
274 Teuchos::rcp_const_cast<
const Thyra::MultiVectorBase<Scalar> >(v);
281 static bool isTpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
285 bool bIsTpetra =
false;
286 #ifdef HAVE_XPETRA_TPETRA
292 #ifdef HAVE_XPETRA_EPETRA
293 Teuchos::rcp_dynamic_cast<const Thyra::EpetraLinearOp>(op) == Teuchos::null &&
295 Teuchos::rcp_dynamic_cast<
const Thyra::DefaultBlockedLinearOp<Scalar> >(op) == Teuchos::null) {
297 typedef Thyra::TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpetraLinearOp_t;
298 if(Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op) == Teuchos::null) {
299 std::cout <<
"ATTENTION: The dynamic cast to the TpetraLinearOp failed even though it should be a TpetraLinearOp." << std::endl;
300 std::cout <<
" If you are using Panzer or Stratimikos you might check that the template parameters are " << std::endl;
301 std::cout <<
" properly set!" << std::endl;
302 std::cout << Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op,
true) << std::endl;
311 if(bIsTpetra ==
false) {
313 Teuchos::rcp_dynamic_cast<
const Thyra::BlockedLinearOpBase<Scalar> >(op);
314 if(ThyBlockedOp != Teuchos::null) {
317 ThyBlockedOp->getBlock(0,0);
319 bIsTpetra = isTpetra(b00);
327 static bool isEpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
331 static bool isBlockedOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
334 Teuchos::rcp_dynamic_cast<
const Thyra::BlockedLinearOpBase<Scalar> >(op);
335 if(ThyBlockedOp != Teuchos::null) {
344 #ifdef HAVE_XPETRA_TPETRA
346 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
368 #ifdef HAVE_XPETRA_EPETRA
373 return Teuchos::null;
379 #ifdef HAVE_XPETRA_TPETRA
381 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
392 return xTpetraCrsMat;
396 #ifdef HAVE_XPETRA_EPETRA
401 return Teuchos::null;
409 RCP<const BlockedMap> bmap = Teuchos::rcp_dynamic_cast<
const BlockedMap>(map);
410 if(bmap.is_null() ==
false) {
413 for(
size_t i = 0; i < bmap->getNumMaps(); i++) {
416 Xpetra::ThyraUtils<Scalar,LO,GO,Node>::toThyra(bmap->getMap(i,
true));
420 thyraMap = Thyra::productVectorSpace<Scalar>(vecSpaces());
425 #ifdef HAVE_XPETRA_TPETRA
428 if (tpetraMap == Teuchos::null)
429 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::TpetraMap failed");
430 RCP<Thyra::TpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node> > thyraTpetraMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tpetraMap->getTpetra_Map());
431 thyraMap = thyraTpetraMap;
435 #ifdef HAVE_XPETRA_EPETRA
449 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::as<Teuchos::Ordinal>(vec->getMap()->getGlobalNumElements())!=thMap->dim(), std::logic_error,
"Global dimension of Xpetra map and Thyra VectorSpaceBase are different.");
451 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMap == Teuchos::null, std::logic_error,
"Cannot cast VectorSpaceBase to SpmdVectorSpaceBase.");
452 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::as<Teuchos::Ordinal>(vec->getMap()->getNodeNumElements())!=thSpmdMap->localSubDim(), std::logic_error,
"Local dimension of Xpetra map and Thyra VectorSpaceBase on one (or more) processor(s) are different.");
457 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMVec == Teuchos::null, std::logic_error,
"Cannot cast MultiVectorBase to SpmdMultiVectorBase.");
460 const LocalOrdinal localOffset = ( thSpmdMap != Teuchos::null ? thSpmdMap->localOffset() : 0 );
461 const LocalOrdinal localSubDim = ( thSpmdMap != Teuchos::null ? thSpmdMap->localSubDim() : thMap->dim() );
466 for(
size_t j = 0; j < Teuchos::as<size_t>(thSpmdMVec->domain()->dim()); ++j) {
469 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
470 (*thyData)(i,j) = vecData[i];
482 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::as<Teuchos::Ordinal>(vec->getMap()->getGlobalNumElements())!=thMap->dim(), std::logic_error,
"Global dimension of Xpetra map and Thyra VectorSpaceBase are different.");
484 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMap == Teuchos::null, std::logic_error,
"Cannot cast VectorSpaceBase to SpmdVectorSpaceBase.");
485 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::as<Teuchos::Ordinal>(vec->getMap()->getNodeNumElements())!=thSpmdMap->localSubDim(), std::logic_error,
"Local dimension of Xpetra map and Thyra VectorSpaceBase on one (or more) processor(s) are different.");
493 const LocalOrdinal localOffset = ( thSpmdMap != Teuchos::null ? thSpmdMap->localOffset() : 0 );
494 const LocalOrdinal localSubDim = ( thSpmdMap != Teuchos::null ? thSpmdMap->localSubDim() : thMap->dim() );
499 for(
size_t j = 0; j < Teuchos::as<size_t>(thSpmdMVec->domain()->dim()); ++j) {
502 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
503 (*thyData)(i,j) = vecData[i];
515 using Teuchos::rcp_dynamic_cast;
517 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
518 typedef Thyra::SpmdVectorSpaceBase<Scalar> ThySpmdVecSpaceBase;
519 typedef Thyra::MultiVectorBase<Scalar> ThyMultVecBase;
522 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
529 RCP<ThyProdMultVecBase> prodTarget = rcp_dynamic_cast<ThyProdMultVecBase>(target);
530 if(prodTarget != Teuchos::null) {
531 RCP<const BlockedMultiVector> bSourceVec = rcp_dynamic_cast<
const BlockedMultiVector>(source);
532 if(bSourceVec.is_null() ==
true) {
536 TEUCHOS_TEST_FOR_EXCEPTION(mapExtractor == Teuchos::null, std::logic_error,
"Found a Thyra product vector, but user did not provide an Xpetra::MapExtractor.");
537 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.");
539 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
541 RCP<MultiVector> xpSubBlock = mapExtractor->ExtractVector(source, bbb,
false);
545 RCP<const ThyVecSpaceBase> vs = thySubBlock->range();
546 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<
const ThySpmdVecSpaceBase>(vs);
547 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
548 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : vs->dim() );
549 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
553 for(
size_t j = 0; j < xpSubBlock->getNumVectors(); ++j) {
557 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
558 (*thyData)(i,j) = xpData[i];
565 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.");
567 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
569 RCP<MultiVector> xpSubBlock = bSourceVec->getMultiVector(bbb,
true);
575 Thyra::assign(thySubBlock.
ptr(), *thyXpSubBlock);
584 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<
const ThySpmdVecSpaceBase>(target->range());
585 TEUCHOS_TEST_FOR_EXCEPTION(mpi_vs == Teuchos::null, std::logic_error,
"Failed to cast Thyra::VectorSpaceBase to Thyra::SpmdVectorSpaceBase.");
586 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
587 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : target->range()->dim() );
588 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
592 for(
size_t j = 0; j < source->getNumVectors(); ++j) {
595 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
596 (*thyData)(i,j) = xpData[i];
609 #ifdef HAVE_XPETRA_TPETRA
611 if(tpetraMat!=Teuchos::null) {
623 thyraOp = Thyra::createConstLinearOp(tpOperator);
626 #ifdef HAVE_XPETRA_EPETRA
646 #ifdef HAVE_XPETRA_TPETRA
648 if(tpetraMat!=Teuchos::null) {
660 thyraOp = Thyra::createLinearOp(tpOperator);
664 #ifdef HAVE_XPETRA_EPETRA
680 int nRows = mat->Rows();
681 int nCols = mat->Cols();
687 #ifdef HAVE_XPETRA_TPETRA
689 if(tpetraMat!=Teuchos::null) {
693 Thyra::defaultBlockedLinearOp<Scalar>();
695 blockMat->beginBlockFill(nRows,nCols);
697 for (
int r=0; r<nRows; ++r) {
698 for (
int c=0; c<nCols; ++c) {
701 if(xpmat == Teuchos::null)
continue;
708 if(xpblock != Teuchos::null) {
709 if(xpblock->Rows() == 1 && xpblock->Cols() == 1) {
713 thBlock = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(xpwrap->getCrsMatrix());
716 thBlock = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(xpblock);
722 thBlock = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(xpwrap->getCrsMatrix());
725 blockMat->setBlock(r,c,thBlock);
729 blockMat->endBlockFill();
734 #ifdef HAVE_XPETRA_EPETRA
741 #endif // endif HAVE_XPETRA_TPETRA
745 #if defined(HAVE_XPETRA_EPETRA) && !defined(HAVE_XPETRA_TPETRA)
748 #endif // endif HAVE_XPETRA_EPETRA
756 #ifdef HAVE_XPETRA_EPETRA
758 #ifndef XPETRA_EPETRA_NO_32BIT_GLOBAL_INDICES
760 class ThyraUtils<double, int, int,
EpetraNode> {
762 typedef double Scalar;
763 typedef int LocalOrdinal;
764 typedef int GlobalOrdinal;
768 #undef XPETRA_THYRAUTILS_SHORT
778 if(stridedBlockId == -1) {
792 using Teuchos::rcp_dynamic_cast;
794 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
795 typedef Thyra::ProductVectorSpaceBase<Scalar> ThyProdVecSpaceBase;
798 typedef Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node> ThyUtils;
800 RCP<Map> resultMap = Teuchos::null;
802 RCP<const ThyProdVecSpaceBase > prodVectorSpace = rcp_dynamic_cast<
const ThyProdVecSpaceBase >(vectorSpace);
803 if(prodVectorSpace != Teuchos::null) {
806 TEUCHOS_TEST_FOR_EXCEPTION(prodVectorSpace->numBlocks()==0, std::logic_error,
"Found a product vector space with zero blocks.");
807 std::vector<RCP<const Map> > mapsThyra(prodVectorSpace->numBlocks(), Teuchos::null);
808 std::vector<RCP<const Map> > mapsXpetra(prodVectorSpace->numBlocks(), Teuchos::null);
809 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
810 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
817 std::vector<GlobalOrdinal> gidOffsets(prodVectorSpace->numBlocks(),0);
818 for(
int i = 1; i < prodVectorSpace->numBlocks(); ++i) {
819 gidOffsets[i] = mapsThyra[i-1]->getMaxAllGlobalIndex() + gidOffsets[i-1] + 1;
822 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
823 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
834 bool bIsTpetra =
false;
835 #ifdef HAVE_XPETRA_TPETRA
836 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
837 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
844 bool bIsEpetra = !bIsTpetra;
846 #ifdef HAVE_XPETRA_TPETRA
848 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
849 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
850 typedef Thyra::VectorBase<Scalar> ThyVecBase;
851 typedef Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> TpMap;
852 typedef Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpVector;
853 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
854 RCP<ThyVecBase> rgVec = Thyra::createMember<Scalar>(vectorSpace, std::string(
"label"));
856 RCP<const TpVector> rgTpetraVec = TOE::getTpetraVector(rgVec);
858 RCP<const TpMap> rgTpetraMap = rgTpetraVec->getMap();
868 #ifdef HAVE_XPETRA_EPETRA
871 RCP<const Epetra_Map>
872 epetra_map = Teuchos::get_extra_data<RCP<const Epetra_Map> >(vectorSpace,
"epetra_map");
890 using Teuchos::rcp_dynamic_cast;
893 using ThyProdMultVecBase = Thyra::ProductMultiVectorBase<Scalar>;
894 using ThyMultVecBase = Thyra::MultiVectorBase<Scalar>;
898 using ThyUtils = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>;
902 RCP<MultiVector> xpMultVec = Teuchos::null;
906 if(thyProdVec != Teuchos::null) {
915 RCP<BlockedMultiVector> xpBlockedMultVec = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(xpMultVec);
919 for (
int b = 0; b < thyProdVec->productSpace()->numBlocks(); ++b){
920 RCP<const ThyMultVecBase> thyBlockMV = thyProdVec->getMultiVectorBlock(b);
923 xpBlockedMultVec->setMultiVector(b, xpBlockMV,
true );
931 bool bIsTpetra =
false;
932 #ifdef HAVE_XPETRA_TPETRA
933 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
934 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
938 typedef Thyra::SpmdMultiVectorBase<Scalar> ThySpmdMultVecBase;
939 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> ConverterT;
940 typedef Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpMultVec;
942 typedef Thyra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> ThyTpMultVec;
944 RCP<const ThySpmdMultVecBase> thyraSpmdMultiVector = rcp_dynamic_cast<
const ThySpmdMultVecBase>(v);
945 RCP<const ThyTpMultVec> thyraTpetraMultiVector = rcp_dynamic_cast<
const ThyTpMultVec>(thyraSpmdMultiVector);
946 if(thyraTpetraMultiVector != Teuchos::null) {
948 const RCP<const TpMultVec> tpMultVec = ConverterT::getConstTpetraMultiVector(v);
950 RCP<TpMultVec> tpNonConstMultVec = Teuchos::rcp_const_cast<TpMultVec>(tpMultVec);
952 xpMultVec =
rcp(
new XpTpMultVec(tpNonConstMultVec));
957 #ifdef HAVE_XPETRA_EPETRA
958 if(bIsTpetra ==
false) {
964 RCP<const Epetra_Map> eMap = Teuchos::rcpFromRef(xeMap->getEpetra_Map());
968 RCP<Epetra_MultiVector> epNonConstMultVec = Teuchos::rcp_const_cast<
Epetra_MultiVector>(epMultVec);
983 Teuchos::rcp_const_cast<
const Thyra::MultiVectorBase<Scalar> >(v);
989 static bool isTpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
991 bool bIsTpetra =
false;
992 #ifdef HAVE_XPETRA_TPETRA
993 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
994 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
1001 #ifdef HAVE_XPETRA_EPETRA
1002 Teuchos::rcp_dynamic_cast<const Thyra::EpetraLinearOp>(op) == Teuchos::null &&
1004 Teuchos::rcp_dynamic_cast<
const Thyra::DefaultBlockedLinearOp<Scalar> >(op) == Teuchos::null) {
1006 typedef Thyra::TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpetraLinearOp_t;
1007 if(Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op) == Teuchos::null) {
1008 std::cout <<
"ATTENTION: The dynamic cast to the TpetraLinearOp failed even though it should be a TpetraLinearOp." << std::endl;
1009 std::cout <<
" If you are using Panzer or Stratimikos you might check that the template parameters are " << std::endl;
1010 std::cout <<
" properly set!" << std::endl;
1011 std::cout << Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op,
true) << std::endl;
1021 if(bIsTpetra ==
false) {
1023 Teuchos::rcp_dynamic_cast<
const Thyra::BlockedLinearOpBase<Scalar> >(op);
1024 if(ThyBlockedOp != Teuchos::null) {
1027 ThyBlockedOp->getBlock(0,0);
1029 bIsTpetra = isTpetra(b00);
1037 static bool isEpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
1039 bool bIsEpetra =
false;
1041 #ifdef HAVE_XPETRA_EPETRA
1050 if(bIsEpetra ==
false) {
1052 Teuchos::rcp_dynamic_cast<
const Thyra::BlockedLinearOpBase<Scalar> >(op,
false);
1053 if(ThyBlockedOp != Teuchos::null) {
1056 ThyBlockedOp->getBlock(0,0);
1058 bIsEpetra = isEpetra(b00);
1066 static bool isBlockedOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
1069 Teuchos::rcp_dynamic_cast<
const Thyra::BlockedLinearOpBase<Scalar> >(op);
1070 if(ThyBlockedOp != Teuchos::null) {
1079 #ifdef HAVE_XPETRA_TPETRA
1081 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1082 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
1084 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
1109 #ifdef HAVE_XPETRA_EPETRA
1130 return Teuchos::null;
1136 #ifdef HAVE_XPETRA_TPETRA
1138 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1139 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
1141 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
1152 return xTpetraCrsMat;
1159 #ifdef HAVE_XPETRA_EPETRA
1171 return xEpetraCrsMat;
1174 return Teuchos::null;
1182 RCP<const BlockedMap> bmap = Teuchos::rcp_dynamic_cast<
const BlockedMap>(map);
1183 if(bmap.is_null() ==
false) {
1186 for(
size_t i = 0; i < bmap->getNumMaps(); i++) {
1189 Xpetra::ThyraUtils<Scalar,LO,GO,Node>::toThyra(bmap->getMap(i,
true));
1193 thyraMap = Thyra::productVectorSpace<Scalar>(vecSpaces());
1198 #ifdef HAVE_XPETRA_TPETRA
1200 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1201 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
1203 if (tpetraMap == Teuchos::null)
1204 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::TpetraMap failed");
1205 RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > tpMap = tpetraMap->getTpetra_Map();
1206 RCP<Thyra::TpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node> > thyraTpetraMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tpMap);
1207 thyraMap = thyraTpetraMap;
1214 #ifdef HAVE_XPETRA_EPETRA
1217 if (epetraMap == Teuchos::null)
1218 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::EpetraMap failed");
1219 RCP<const Thyra::VectorSpaceBase<Scalar> > thyraEpetraMap = Thyra::create_VectorSpace(Teuchos::rcpFromRef(epetraMap->getEpetra_Map()));
1220 thyraMap = thyraEpetraMap;
1232 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::as<Teuchos::Ordinal>(vec->getMap()->getGlobalNumElements())!=thMap->dim(), std::logic_error,
"Global dimension of Xpetra map and Thyra VectorSpaceBase are different.");
1234 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMap == Teuchos::null, std::logic_error,
"Cannot cast VectorSpaceBase to SpmdVectorSpaceBase.");
1235 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::as<Teuchos::Ordinal>(vec->getMap()->getNodeNumElements())!=thSpmdMap->localSubDim(), std::logic_error,
"Local dimension of Xpetra map and Thyra VectorSpaceBase on one (or more) processor(s) are different.");
1240 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMVec == Teuchos::null, std::logic_error,
"Cannot cast MultiVectorBase to SpmdMultiVectorBase.");
1243 const LocalOrdinal localOffset = ( thSpmdMap != Teuchos::null ? thSpmdMap->localOffset() : 0 );
1244 const LocalOrdinal localSubDim = ( thSpmdMap != Teuchos::null ? thSpmdMap->localSubDim() : thMap->dim() );
1249 for(
size_t j = 0; j < Teuchos::as<size_t>(thSpmdMVec->domain()->dim()); ++j) {
1252 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1253 (*thyData)(i,j) = vecData[i];
1265 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::as<Teuchos::Ordinal>(vec->getMap()->getGlobalNumElements())!=thMap->dim(), std::logic_error,
"Global dimension of Xpetra map and Thyra VectorSpaceBase are different.");
1267 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMap == Teuchos::null, std::logic_error,
"Cannot cast VectorSpaceBase to SpmdVectorSpaceBase.");
1268 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::as<Teuchos::Ordinal>(vec->getMap()->getNodeNumElements())!=thSpmdMap->localSubDim(), std::logic_error,
"Local dimension of Xpetra map and Thyra VectorSpaceBase on one (or more) processor(s) are different.");
1276 const LocalOrdinal localOffset = ( thSpmdMap != Teuchos::null ? thSpmdMap->localOffset() : 0 );
1277 const LocalOrdinal localSubDim = ( thSpmdMap != Teuchos::null ? thSpmdMap->localSubDim() : thMap->dim() );
1282 for(
size_t j = 0; j < Teuchos::as<size_t>(thSpmdMVec->domain()->dim()); ++j) {
1285 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1286 (*thyData)(i,j) = vecData[i];
1295 using Teuchos::rcp_dynamic_cast;
1297 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
1298 typedef Thyra::SpmdVectorSpaceBase<Scalar> ThySpmdVecSpaceBase;
1299 typedef Thyra::MultiVectorBase<Scalar> ThyMultVecBase;
1302 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
1306 RCP<ThyProdMultVecBase> prodTarget = rcp_dynamic_cast<ThyProdMultVecBase>(target);
1307 if(prodTarget != Teuchos::null) {
1309 RCP<const BlockedMultiVector> bSourceVec = rcp_dynamic_cast<
const BlockedMultiVector>(source);
1310 if(bSourceVec.is_null() ==
true) {
1314 TEUCHOS_TEST_FOR_EXCEPTION(mapExtractor == Teuchos::null, std::logic_error,
"Found a Thyra product vector, but user did not provide an Xpetra::MapExtractor.");
1315 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.");
1317 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
1319 RCP<MultiVector> xpSubBlock = mapExtractor->ExtractVector(source, bbb,
false);
1323 RCP<const ThyVecSpaceBase> vs = thySubBlock->range();
1324 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<
const ThySpmdVecSpaceBase>(vs);
1325 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
1326 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : vs->dim() );
1327 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
1331 for(
size_t j = 0; j < xpSubBlock->getNumVectors(); ++j) {
1335 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1336 (*thyData)(i,j) = xpData[i];
1343 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.");
1345 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
1347 RCP<MultiVector> xpSubBlock = bSourceVec->getMultiVector(bbb,
true);
1353 Thyra::assign(thySubBlock.
ptr(), *thyXpSubBlock);
1362 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<
const ThySpmdVecSpaceBase>(target->range());
1363 TEUCHOS_TEST_FOR_EXCEPTION(mpi_vs == Teuchos::null, std::logic_error,
"Failed to cast Thyra::VectorSpaceBase to Thyra::SpmdVectorSpaceBase.");
1364 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
1365 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : target->range()->dim() );
1366 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
1370 for(
size_t j = 0; j < source->getNumVectors(); ++j) {
1373 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1374 (*thyData)(i,j) = xpData[i];
1385 #ifdef HAVE_XPETRA_TPETRA
1387 if(tpetraMat!=Teuchos::null) {
1388 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1389 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
1401 thyraOp = Thyra::createConstLinearOp(tpOperator);
1409 #ifdef HAVE_XPETRA_EPETRA
1411 if(epetraMat!=Teuchos::null) {
1419 thyraOp = thyraEpOp;
1430 #ifdef HAVE_XPETRA_TPETRA
1432 if(tpetraMat!=Teuchos::null) {
1433 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1434 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
1446 thyraOp = Thyra::createLinearOp(tpOperator);
1454 #ifdef HAVE_XPETRA_EPETRA
1456 if(epetraMat!=Teuchos::null) {
1464 thyraOp = thyraEpOp;
1474 #endif // #ifndef XPETRA_EPETRA_NO_32BIT_GLOBAL_INDICES
1476 #ifndef XPETRA_EPETRA_NO_64BIT_GLOBAL_INDICES
1478 class ThyraUtils<double, int, long long,
EpetraNode> {
1480 typedef double Scalar;
1481 typedef int LocalOrdinal;
1482 typedef long long GlobalOrdinal;
1486 #undef XPETRA_THYRAUTILS_SHORT
1496 if(stridedBlockId == -1) {
1510 using Teuchos::rcp_dynamic_cast;
1512 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
1513 typedef Thyra::ProductVectorSpaceBase<Scalar> ThyProdVecSpaceBase;
1515 typedef Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node> ThyUtils;
1517 RCP<const ThyProdVecSpaceBase > prodVectorSpace = rcp_dynamic_cast<
const ThyProdVecSpaceBase >(vectorSpace);
1518 if(prodVectorSpace != Teuchos::null) {
1521 TEUCHOS_TEST_FOR_EXCEPTION(prodVectorSpace->numBlocks()==0, std::logic_error,
"Found a product vector space with zero blocks.");
1522 std::vector<RCP<const Map> > mapsThyra(prodVectorSpace->numBlocks(), Teuchos::null);
1523 std::vector<RCP<const Map> > mapsXpetra(prodVectorSpace->numBlocks(), Teuchos::null);
1524 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
1525 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
1532 std::vector<GlobalOrdinal> gidOffsets(prodVectorSpace->numBlocks(),0);
1533 for(
int i = 1; i < prodVectorSpace->numBlocks(); ++i) {
1534 gidOffsets[i] = mapsThyra[i-1]->getMaxAllGlobalIndex() + gidOffsets[i-1] + 1;
1537 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
1538 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
1551 bool bIsTpetra =
false;
1552 #ifdef HAVE_XPETRA_TPETRA
1553 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1554 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1561 bool bIsEpetra = !bIsTpetra;
1563 #ifdef HAVE_XPETRA_TPETRA
1565 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1566 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1567 typedef Thyra::VectorBase<Scalar> ThyVecBase;
1568 typedef Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> TpMap;
1569 typedef Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpVector;
1570 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
1571 RCP<ThyVecBase> rgVec = Thyra::createMember<Scalar>(vectorSpace, std::string(
"label"));
1573 RCP<const TpVector> rgTpetraVec = TOE::getTpetraVector(rgVec);
1575 RCP<const TpMap> rgTpetraMap = rgTpetraVec->getMap();
1587 #ifdef HAVE_XPETRA_EPETRA
1590 RCP<const Epetra_Map>
1591 epetra_map = Teuchos::get_extra_data<RCP<const Epetra_Map> >(vectorSpace,
"epetra_map");
1610 using Teuchos::rcp_dynamic_cast;
1612 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
1613 typedef Thyra::MultiVectorBase<Scalar> ThyMultVecBase;
1617 typedef Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node> ThyUtils;
1620 RCP<MultiVector> xpMultVec = Teuchos::null;
1624 if(thyProdVec != Teuchos::null) {
1633 RCP<BlockedMultiVector> xpBlockedMultVec = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(xpMultVec);
1637 for (
int b = 0; b < thyProdVec->productSpace()->numBlocks(); ++b){
1638 RCP<const ThyMultVecBase> thyBlockMV = thyProdVec->getMultiVectorBlock(b);
1641 xpBlockedMultVec->setMultiVector(b, xpBlockMV,
true );
1649 bool bIsTpetra =
false;
1650 #ifdef HAVE_XPETRA_TPETRA
1651 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1652 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1656 typedef Thyra::SpmdMultiVectorBase<Scalar> ThySpmdMultVecBase;
1657 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> ConverterT;
1658 typedef Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpMultVec;
1660 typedef Thyra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> ThyTpMultVec;
1662 RCP<const ThySpmdMultVecBase> thyraSpmdMultiVector = rcp_dynamic_cast<
const ThySpmdMultVecBase>(v);
1663 RCP<const ThyTpMultVec> thyraTpetraMultiVector = rcp_dynamic_cast<
const ThyTpMultVec>(thyraSpmdMultiVector);
1664 if(thyraTpetraMultiVector != Teuchos::null) {
1666 const RCP<const TpMultVec> tpMultVec = ConverterT::getConstTpetraMultiVector(v);
1668 RCP<TpMultVec> tpNonConstMultVec = Teuchos::rcp_const_cast<TpMultVec>(tpMultVec);
1670 xpMultVec =
rcp(
new XpTpMultVec(tpNonConstMultVec));
1677 #ifdef HAVE_XPETRA_EPETRA
1678 if(bIsTpetra ==
false) {
1684 RCP<const Epetra_Map> eMap = Teuchos::rcpFromRef(xeMap->getEpetra_Map());
1688 RCP<Epetra_MultiVector> epNonConstMultVec = Teuchos::rcp_const_cast<
Epetra_MultiVector>(epMultVec);
1704 Teuchos::rcp_const_cast<
const Thyra::MultiVectorBase<Scalar> >(v);
1710 static bool isTpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
1712 bool bIsTpetra =
false;
1713 #ifdef HAVE_XPETRA_TPETRA
1714 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1715 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1722 #ifdef HAVE_XPETRA_EPETRA
1723 Teuchos::rcp_dynamic_cast<const Thyra::EpetraLinearOp>(op) == Teuchos::null &&
1725 Teuchos::rcp_dynamic_cast<
const Thyra::DefaultBlockedLinearOp<Scalar> >(op) == Teuchos::null) {
1727 typedef Thyra::TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpetraLinearOp_t;
1728 if(Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op) == Teuchos::null) {
1729 std::cout <<
"ATTENTION: The dynamic cast to the TpetraLinearOp failed even though it should be a TpetraLinearOp." << std::endl;
1730 std::cout <<
" If you are using Panzer or Stratimikos you might check that the template parameters are " << std::endl;
1731 std::cout <<
" properly set!" << std::endl;
1732 std::cout << Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op,
true) << std::endl;
1742 if(bIsTpetra ==
false) {
1744 Teuchos::rcp_dynamic_cast<
const Thyra::BlockedLinearOpBase<Scalar> >(op);
1745 if(ThyBlockedOp != Teuchos::null) {
1748 ThyBlockedOp->getBlock(0,0);
1750 bIsTpetra = isTpetra(b00);
1758 static bool isEpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
1760 bool bIsEpetra =
false;
1762 #ifdef HAVE_XPETRA_EPETRA
1771 if(bIsEpetra ==
false) {
1773 Teuchos::rcp_dynamic_cast<
const Thyra::BlockedLinearOpBase<Scalar> >(op,
false);
1774 if(ThyBlockedOp != Teuchos::null) {
1777 ThyBlockedOp->getBlock(0,0);
1779 bIsEpetra = isEpetra(b00);
1787 static bool isBlockedOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
1790 Teuchos::rcp_dynamic_cast<
const Thyra::BlockedLinearOpBase<Scalar> >(op);
1791 if(ThyBlockedOp != Teuchos::null) {
1800 #ifdef HAVE_XPETRA_TPETRA
1802 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1803 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1805 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
1830 #ifdef HAVE_XPETRA_EPETRA
1851 return Teuchos::null;
1857 #ifdef HAVE_XPETRA_TPETRA
1859 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1860 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1862 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
1873 return xTpetraCrsMat;
1880 #ifdef HAVE_XPETRA_EPETRA
1892 return xEpetraCrsMat;
1895 return Teuchos::null;
1903 RCP<const BlockedMap> bmap = Teuchos::rcp_dynamic_cast<
const BlockedMap>(map);
1904 if(bmap.is_null() ==
false) {
1907 for(
size_t i = 0; i < bmap->getNumMaps(); i++) {
1910 Xpetra::ThyraUtils<Scalar,LO,GO,Node>::toThyra(bmap->getMap(i,
true));
1914 thyraMap = Thyra::productVectorSpace<Scalar>(vecSpaces());
1919 #ifdef HAVE_XPETRA_TPETRA
1921 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1922 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1924 if (tpetraMap == Teuchos::null)
1925 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::TpetraMap failed");
1926 RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > tpMap = tpetraMap->getTpetra_Map();
1927 RCP<Thyra::TpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node> > thyraTpetraMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tpMap);
1928 thyraMap = thyraTpetraMap;
1935 #ifdef HAVE_XPETRA_EPETRA
1938 if (epetraMap == Teuchos::null)
1939 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::EpetraMap failed");
1940 RCP<const Thyra::VectorSpaceBase<Scalar> > thyraEpetraMap = Thyra::create_VectorSpace(Teuchos::rcpFromRef(epetraMap->getEpetra_Map()));
1941 thyraMap = thyraEpetraMap;
1953 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::as<Teuchos::Ordinal>(vec->getMap()->getGlobalNumElements())!=thMap->dim(), std::logic_error,
"Global dimension of Xpetra map and Thyra VectorSpaceBase are different.");
1955 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMap == Teuchos::null, std::logic_error,
"Cannot cast VectorSpaceBase to SpmdVectorSpaceBase.");
1956 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::as<Teuchos::Ordinal>(vec->getMap()->getNodeNumElements())!=thSpmdMap->localSubDim(), std::logic_error,
"Local dimension of Xpetra map and Thyra VectorSpaceBase on one (or more) processor(s) are different.");
1961 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMVec == Teuchos::null, std::logic_error,
"Cannot cast MultiVectorBase to SpmdMultiVectorBase.");
1964 const LocalOrdinal localOffset = ( thSpmdMap != Teuchos::null ? thSpmdMap->localOffset() : 0 );
1965 const LocalOrdinal localSubDim = ( thSpmdMap != Teuchos::null ? thSpmdMap->localSubDim() : thMap->dim() );
1970 for(
size_t j = 0; j < Teuchos::as<size_t>(thSpmdMVec->domain()->dim()); ++j) {
1973 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1974 (*thyData)(i,j) = vecData[i];
1986 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::as<Teuchos::Ordinal>(vec->getMap()->getGlobalNumElements())!=thMap->dim(), std::logic_error,
"Global dimension of Xpetra map and Thyra VectorSpaceBase are different.");
1988 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMap == Teuchos::null, std::logic_error,
"Cannot cast VectorSpaceBase to SpmdVectorSpaceBase.");
1989 TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::as<Teuchos::Ordinal>(vec->getMap()->getNodeNumElements())!=thSpmdMap->localSubDim(), std::logic_error,
"Local dimension of Xpetra map and Thyra VectorSpaceBase on one (or more) processor(s) are different.");
1997 const LocalOrdinal localOffset = ( thSpmdMap != Teuchos::null ? thSpmdMap->localOffset() : 0 );
1998 const LocalOrdinal localSubDim = ( thSpmdMap != Teuchos::null ? thSpmdMap->localSubDim() : thMap->dim() );
2003 for(
size_t j = 0; j < Teuchos::as<size_t>(thSpmdMVec->domain()->dim()); ++j) {
2006 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
2007 (*thyData)(i,j) = vecData[i];
2016 using Teuchos::rcp_dynamic_cast;
2018 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
2019 typedef Thyra::SpmdVectorSpaceBase<Scalar> ThySpmdVecSpaceBase;
2020 typedef Thyra::MultiVectorBase<Scalar> ThyMultVecBase;
2023 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
2027 RCP<ThyProdMultVecBase> prodTarget = rcp_dynamic_cast<ThyProdMultVecBase>(target);
2028 if(prodTarget != Teuchos::null) {
2029 RCP<const BlockedMultiVector> bSourceVec = rcp_dynamic_cast<
const BlockedMultiVector>(source);
2030 if(bSourceVec.is_null() ==
true) {
2034 TEUCHOS_TEST_FOR_EXCEPTION(mapExtractor == Teuchos::null, std::logic_error,
"Found a Thyra product vector, but user did not provide an Xpetra::MapExtractor.");
2035 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.");
2037 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
2039 RCP<MultiVector> xpSubBlock = mapExtractor->ExtractVector(source, bbb,
false);
2043 RCP<const ThyVecSpaceBase> vs = thySubBlock->range();
2044 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<
const ThySpmdVecSpaceBase>(vs);
2045 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
2046 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : vs->dim() );
2047 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
2051 for(
size_t j = 0; j < xpSubBlock->getNumVectors(); ++j) {
2055 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
2056 (*thyData)(i,j) = xpData[i];
2063 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.");
2065 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
2067 RCP<MultiVector> xpSubBlock = bSourceVec->getMultiVector(bbb,
true);
2073 Thyra::assign(thySubBlock.
ptr(), *thyXpSubBlock);
2082 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<
const ThySpmdVecSpaceBase>(target->range());
2083 TEUCHOS_TEST_FOR_EXCEPTION(mpi_vs == Teuchos::null, std::logic_error,
"Failed to cast Thyra::VectorSpaceBase to Thyra::SpmdVectorSpaceBase.");
2084 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
2085 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : target->range()->dim() );
2086 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
2090 for(
size_t j = 0; j < source->getNumVectors(); ++j) {
2093 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
2094 (*thyData)(i,j) = xpData[i];
2105 #ifdef HAVE_XPETRA_TPETRA
2107 if(tpetraMat!=Teuchos::null) {
2108 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
2109 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
2121 thyraOp = Thyra::createConstLinearOp(tpOperator);
2129 #ifdef HAVE_XPETRA_EPETRA
2131 if(epetraMat!=Teuchos::null) {
2139 thyraOp = thyraEpOp;
2150 #ifdef HAVE_XPETRA_TPETRA
2152 if(tpetraMat!=Teuchos::null) {
2153 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
2154 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
2166 thyraOp = Thyra::createLinearOp(tpOperator);
2174 #ifdef HAVE_XPETRA_EPETRA
2176 if(epetraMat!=Teuchos::null) {
2184 thyraOp = thyraEpOp;
2194 #endif // XPETRA_EPETRA_NO_64BIT_GLOBAL_INDICES
2196 #endif // HAVE_XPETRA_EPETRA
2200 #define XPETRA_THYRAUTILS_SHORT
2201 #endif // HAVE_XPETRA_THYRA
2203 #endif // XPETRA_THYRAUTILS_HPP
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.
bool is_null(const std::shared_ptr< T > &p)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Exception throws to report errors in the internal logical of the program.
Xpetra utility class for common map-related routines.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
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
RCP< const CrsGraph< int, GlobalOrdinal, Node > > toXpetra(const Epetra_CrsGraph &g)
#define TEUCHOS_UNREACHABLE_RETURN(dummyReturnVal)
TypeTo as(const TypeFrom &t)
Concrete implementation of Xpetra::Matrix.
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)
const RCP< Map< LocalOrdinal, GlobalOrdinal, Node > > toXpetraNonConst(const RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > &map)