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 using ThyVecSpaceBase = Thyra::VectorSpaceBase<Scalar>;
145 using ThyProdVecSpaceBase = Thyra::ProductVectorSpaceBase<Scalar>;
146 using ThyUtils = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>;
149 RCP<Map> resultMap = Teuchos::null;
150 RCP<const ThyProdVecSpaceBase > prodVectorSpace = rcp_dynamic_cast<const ThyProdVecSpaceBase >(vectorSpace);
151 if(prodVectorSpace != Teuchos::null) {
154 TEUCHOS_TEST_FOR_EXCEPTION(prodVectorSpace->numBlocks()==0, std::logic_error,
"Found a product vector space with zero blocks.");
155 std::vector<RCP<const Map> > mapsThyra(prodVectorSpace->numBlocks(), Teuchos::null);
156 std::vector<RCP<const Map> > mapsXpetra(prodVectorSpace->numBlocks(), Teuchos::null);
157 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
158 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
165 std::vector<GlobalOrdinal> gidOffsets(prodVectorSpace->numBlocks(),0);
166 for(
int i = 1; i < prodVectorSpace->numBlocks(); ++i) {
167 gidOffsets[i] = mapsThyra[i-1]->getMaxAllGlobalIndex() + gidOffsets[i-1] + 1;
170 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
171 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
178 #ifdef HAVE_XPETRA_TPETRA
184 typedef Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> TpMap;
185 typedef Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpVector;
186 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
187 typedef Thyra::VectorBase<Scalar> ThyVecBase;
188 RCP<ThyVecBase> rgVec = Thyra::createMember<Scalar>(vectorSpace, std::string(
"label"));
190 RCP<const TpVector> rgTpetraVec = TOE::getTpetraVector(rgVec);
192 RCP<const TpMap> rgTpetraMap = rgTpetraVec->getMap();
196 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.");
207 using Teuchos::rcp_dynamic_cast;
210 using ThyMultVecBase = Thyra::MultiVectorBase<Scalar>;
211 using ThyProdMultVecBase = Thyra::ProductMultiVectorBase<Scalar>;
212 using ThyUtils = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>;
215 RCP<MultiVector> xpMultVec = Teuchos::null;
219 if(thyProdVec != Teuchos::null) {
228 RCP<BlockedMultiVector> xpBlockedMultVec = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(xpMultVec);
232 for (
int b = 0; b < thyProdVec->productSpace()->numBlocks(); ++b){
233 RCP<const ThyMultVecBase> thyBlockMV = thyProdVec->getMultiVectorBlock(b);
236 xpBlockedMultVec->setMultiVector(b, xpBlockMV,
true );
240 #ifdef HAVE_XPETRA_TPETRA
241 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> ConverterT;
242 typedef Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpMultVec;
244 typedef Thyra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> ThyTpMultVec;
245 typedef Thyra::SpmdMultiVectorBase<Scalar> ThySpmdMultVecBase;
247 RCP<const ThySpmdMultVecBase> thyraSpmdMultiVector = rcp_dynamic_cast<const ThySpmdMultVecBase>(v);
248 RCP<const ThyTpMultVec> thyraTpetraMultiVector = rcp_dynamic_cast<const ThyTpMultVec>(thyraSpmdMultiVector);
250 const RCP<const TpMultVec> tpMultVec = ConverterT::getConstTpetraMultiVector(v);
252 RCP<TpMultVec> tpNonConstMultVec = Teuchos::rcp_const_cast<TpMultVec>(tpMultVec);
254 xpMultVec =
rcp(
new XpTpMultVec(tpNonConstMultVec));
256 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.");
267 Teuchos::rcp_const_cast<const Thyra::MultiVectorBase<Scalar> >(v);
270 return Teuchos::rcp_const_cast<Xpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(r);
274 static bool isTpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
278 bool bIsTpetra =
false;
279 #ifdef HAVE_XPETRA_TPETRA
285 #ifdef HAVE_XPETRA_EPETRA
286 Teuchos::rcp_dynamic_cast<const Thyra::EpetraLinearOp>(op) == Teuchos::null &&
288 Teuchos::rcp_dynamic_cast<
const Thyra::DefaultBlockedLinearOp<Scalar> >(op) == Teuchos::null) {
290 typedef Thyra::TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpetraLinearOp_t;
291 if(Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op) == Teuchos::null) {
292 std::cout <<
"ATTENTION: The dynamic cast to the TpetraLinearOp failed even though it should be a TpetraLinearOp." << std::endl;
293 std::cout <<
" If you are using Panzer or Stratimikos you might check that the template parameters are " << std::endl;
294 std::cout <<
" properly set!" << std::endl;
295 std::cout << Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op,
true) << std::endl;
304 if(bIsTpetra ==
false) {
306 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op);
307 if(ThyBlockedOp != Teuchos::null) {
310 ThyBlockedOp->getBlock(0,0);
312 bIsTpetra = isTpetra(b00);
320 static bool isEpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
324 static bool isBlockedOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
327 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op);
328 if(ThyBlockedOp != Teuchos::null) {
337 #ifdef HAVE_XPETRA_TPETRA
339 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
356 Teuchos::rcp_dynamic_cast<const Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(xTpetraCrsMat);
361 #ifdef HAVE_XPETRA_EPETRA
366 return Teuchos::null;
372 #ifdef HAVE_XPETRA_TPETRA
374 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
385 return xTpetraCrsMat;
389 #ifdef HAVE_XPETRA_EPETRA
394 return Teuchos::null;
402 RCP<const BlockedMap> bmap = Teuchos::rcp_dynamic_cast<const BlockedMap>(map);
403 if(bmap.is_null() ==
false) {
406 for(
size_t i = 0; i < bmap->getNumMaps(); i++) {
409 Xpetra::ThyraUtils<Scalar,LO,GO,Node>::toThyra(bmap->getMap(i,
true));
413 thyraMap = Thyra::productVectorSpace<Scalar>(vecSpaces());
418 #ifdef HAVE_XPETRA_TPETRA
421 if (tpetraMap == Teuchos::null)
422 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::TpetraMap failed");
423 RCP<Thyra::TpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node> > thyraTpetraMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tpetraMap->getTpetra_Map());
424 thyraMap = thyraTpetraMap;
428 #ifdef HAVE_XPETRA_EPETRA
442 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.");
444 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMap == Teuchos::null, std::logic_error,
"Cannot cast VectorSpaceBase to SpmdVectorSpaceBase.");
445 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.");
450 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMVec == Teuchos::null, std::logic_error,
"Cannot cast MultiVectorBase to SpmdMultiVectorBase.");
453 const LocalOrdinal localOffset = ( thSpmdMap != Teuchos::null ? thSpmdMap->localOffset() : 0 );
454 const LocalOrdinal localSubDim = ( thSpmdMap != Teuchos::null ? thSpmdMap->localSubDim() : thMap->dim() );
459 for(
size_t j = 0; j < Teuchos::as<size_t>(thSpmdMVec->domain()->dim()); ++j) {
462 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
463 (*thyData)(i,j) = vecData[i];
475 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.");
477 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMap == Teuchos::null, std::logic_error,
"Cannot cast VectorSpaceBase to SpmdVectorSpaceBase.");
478 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.");
486 const LocalOrdinal localOffset = ( thSpmdMap != Teuchos::null ? thSpmdMap->localOffset() : 0 );
487 const LocalOrdinal localSubDim = ( thSpmdMap != Teuchos::null ? thSpmdMap->localSubDim() : thMap->dim() );
492 for(
size_t j = 0; j < Teuchos::as<size_t>(thSpmdMVec->domain()->dim()); ++j) {
495 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
496 (*thyData)(i,j) = vecData[i];
508 using Teuchos::rcp_dynamic_cast;
510 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
511 typedef Thyra::SpmdVectorSpaceBase<Scalar> ThySpmdVecSpaceBase;
512 typedef Thyra::MultiVectorBase<Scalar> ThyMultVecBase;
515 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
519 RCP<ThyProdMultVecBase> prodTarget = rcp_dynamic_cast<ThyProdMultVecBase>(target);
520 if(prodTarget != Teuchos::null) {
521 RCP<const BlockedMultiVector> bSourceVec = rcp_dynamic_cast<const BlockedMultiVector>(source);
522 if(bSourceVec.is_null() ==
true) {
526 TEUCHOS_TEST_FOR_EXCEPTION(mapExtractor == Teuchos::null, std::logic_error,
"Found a Thyra product vector, but user did not provide an Xpetra::MapExtractor.");
527 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.");
529 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
531 RCP<MultiVector> xpSubBlock = mapExtractor->ExtractVector(source, bbb,
false);
535 RCP<const ThyVecSpaceBase> vs = thySubBlock->range();
536 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<const ThySpmdVecSpaceBase>(vs);
537 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
538 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : vs->dim() );
539 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
543 for(
size_t j = 0; j < xpSubBlock->getNumVectors(); ++j) {
547 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
548 (*thyData)(i,j) = xpData[i];
555 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.");
557 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
559 RCP<MultiVector> xpSubBlock = bSourceVec->getMultiVector(bbb,
true);
565 Thyra::assign(thySubBlock.
ptr(), *thyXpSubBlock);
574 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<const ThySpmdVecSpaceBase>(target->range());
575 TEUCHOS_TEST_FOR_EXCEPTION(mpi_vs == Teuchos::null, std::logic_error,
"Failed to cast Thyra::VectorSpaceBase to Thyra::SpmdVectorSpaceBase.");
576 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
577 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : target->range()->dim() );
578 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
582 for(
size_t j = 0; j < source->getNumVectors(); ++j) {
585 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
586 (*thyData)(i,j) = xpData[i];
599 #ifdef HAVE_XPETRA_TPETRA
601 if(tpetraMat!=Teuchos::null) {
613 thyraOp = Thyra::createConstLinearOp(tpOperator);
616 #ifdef HAVE_XPETRA_EPETRA
636 #ifdef HAVE_XPETRA_TPETRA
638 if(tpetraMat!=Teuchos::null) {
650 thyraOp = Thyra::createLinearOp(tpOperator);
654 #ifdef HAVE_XPETRA_EPETRA
670 int nRows = mat->Rows();
671 int nCols = mat->Cols();
677 #ifdef HAVE_XPETRA_TPETRA
679 if(tpetraMat!=Teuchos::null) {
683 Thyra::defaultBlockedLinearOp<Scalar>();
685 blockMat->beginBlockFill(nRows,nCols);
687 for (
int r=0; r<nRows; ++r) {
688 for (
int c=0; c<nCols; ++c) {
691 if(xpmat == Teuchos::null)
continue;
697 Teuchos::rcp_dynamic_cast<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(xpmat);
698 if(xpblock != Teuchos::null) {
699 if(xpblock->Rows() == 1 && xpblock->Cols() == 1) {
703 thBlock = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(xpwrap->getCrsMatrix());
706 thBlock = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(xpblock);
712 thBlock = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(xpwrap->getCrsMatrix());
715 blockMat->setBlock(r,c,thBlock);
719 blockMat->endBlockFill();
724 #ifdef HAVE_XPETRA_EPETRA
735 #if defined(HAVE_XPETRA_EPETRA) && !defined(HAVE_XPETRA_TPETRA)
746 #ifdef HAVE_XPETRA_EPETRA
748 #ifndef XPETRA_EPETRA_NO_32BIT_GLOBAL_INDICES
750 class ThyraUtils<double, int, int,
EpetraNode> {
752 typedef double Scalar;
753 typedef int LocalOrdinal;
754 typedef int GlobalOrdinal;
758 #undef XPETRA_THYRAUTILS_SHORT
768 if(stridedBlockId == -1) {
782 using Teuchos::rcp_dynamic_cast;
784 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
785 typedef Thyra::ProductVectorSpaceBase<Scalar> ThyProdVecSpaceBase;
786 typedef Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node> ThyUtils;
788 RCP<Map> resultMap = Teuchos::null;
790 RCP<const ThyProdVecSpaceBase > prodVectorSpace = rcp_dynamic_cast<const ThyProdVecSpaceBase >(vectorSpace);
791 if(prodVectorSpace != Teuchos::null) {
794 TEUCHOS_TEST_FOR_EXCEPTION(prodVectorSpace->numBlocks()==0, std::logic_error,
"Found a product vector space with zero blocks.");
795 std::vector<RCP<const Map> > mapsThyra(prodVectorSpace->numBlocks(), Teuchos::null);
796 std::vector<RCP<const Map> > mapsXpetra(prodVectorSpace->numBlocks(), Teuchos::null);
797 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
798 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
805 std::vector<GlobalOrdinal> gidOffsets(prodVectorSpace->numBlocks(),0);
806 for(
int i = 1; i < prodVectorSpace->numBlocks(); ++i) {
807 gidOffsets[i] = mapsThyra[i-1]->getMaxAllGlobalIndex() + gidOffsets[i-1] + 1;
810 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
811 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
822 bool bIsTpetra =
false;
823 #ifdef HAVE_XPETRA_TPETRA
824 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
825 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
832 bool bIsEpetra = !bIsTpetra;
834 #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)))
838 typedef Thyra::VectorBase<Scalar> ThyVecBase;
839 typedef Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> TpMap;
840 typedef Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpVector;
841 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
842 RCP<ThyVecBase> rgVec = Thyra::createMember<Scalar>(vectorSpace, std::string(
"label"));
844 RCP<const TpVector> rgTpetraVec = TOE::getTpetraVector(rgVec);
846 RCP<const TpMap> rgTpetraMap = rgTpetraVec->getMap();
856 #ifdef HAVE_XPETRA_EPETRA
859 RCP<const Epetra_Map>
860 epetra_map = Teuchos::get_extra_data<RCP<const Epetra_Map> >(vectorSpace,
"epetra_map");
878 using Teuchos::rcp_dynamic_cast;
881 using ThyProdMultVecBase = Thyra::ProductMultiVectorBase<Scalar>;
882 using ThyMultVecBase = Thyra::MultiVectorBase<Scalar>;
883 using ThyUtils = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>;
886 RCP<MultiVector> xpMultVec = Teuchos::null;
890 if(thyProdVec != Teuchos::null) {
899 RCP<BlockedMultiVector> xpBlockedMultVec = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(xpMultVec);
903 for (
int b = 0; b < thyProdVec->productSpace()->numBlocks(); ++b){
904 RCP<const ThyMultVecBase> thyBlockMV = thyProdVec->getMultiVectorBlock(b);
907 xpBlockedMultVec->setMultiVector(b, xpBlockMV,
true );
915 bool bIsTpetra =
false;
916 #ifdef HAVE_XPETRA_TPETRA
917 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
918 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
922 typedef Thyra::SpmdMultiVectorBase<Scalar> ThySpmdMultVecBase;
923 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> ConverterT;
924 typedef Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpMultVec;
926 typedef Thyra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> ThyTpMultVec;
928 RCP<const ThySpmdMultVecBase> thyraSpmdMultiVector = rcp_dynamic_cast<const ThySpmdMultVecBase>(v);
929 RCP<const ThyTpMultVec> thyraTpetraMultiVector = rcp_dynamic_cast<const ThyTpMultVec>(thyraSpmdMultiVector);
930 if(thyraTpetraMultiVector != Teuchos::null) {
932 const RCP<const TpMultVec> tpMultVec = ConverterT::getConstTpetraMultiVector(v);
934 RCP<TpMultVec> tpNonConstMultVec = Teuchos::rcp_const_cast<TpMultVec>(tpMultVec);
936 xpMultVec =
rcp(
new XpTpMultVec(tpNonConstMultVec));
941 #ifdef HAVE_XPETRA_EPETRA
942 if(bIsTpetra ==
false) {
946 RCP<Xpetra::EpetraMapT<GlobalOrdinal,Node> > xeMap = rcp_dynamic_cast<Xpetra::EpetraMapT<GlobalOrdinal,Node> >(map);
948 RCP<const Epetra_Map> eMap = Teuchos::rcpFromRef(xeMap->getEpetra_Map());
952 RCP<Epetra_MultiVector> epNonConstMultVec = Teuchos::rcp_const_cast<Epetra_MultiVector>(epMultVec);
967 Teuchos::rcp_const_cast<const Thyra::MultiVectorBase<Scalar> >(v);
970 return Teuchos::rcp_const_cast<Xpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(r);
973 static bool isTpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
975 bool bIsTpetra =
false;
976 #ifdef HAVE_XPETRA_TPETRA
977 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
978 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
985 #ifdef HAVE_XPETRA_EPETRA
986 Teuchos::rcp_dynamic_cast<const Thyra::EpetraLinearOp>(op) == Teuchos::null &&
988 Teuchos::rcp_dynamic_cast<
const Thyra::DefaultBlockedLinearOp<Scalar> >(op) == Teuchos::null) {
990 typedef Thyra::TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpetraLinearOp_t;
991 if(Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op) == Teuchos::null) {
992 std::cout <<
"ATTENTION: The dynamic cast to the TpetraLinearOp failed even though it should be a TpetraLinearOp." << std::endl;
993 std::cout <<
" If you are using Panzer or Stratimikos you might check that the template parameters are " << std::endl;
994 std::cout <<
" properly set!" << std::endl;
995 std::cout << Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op,
true) << std::endl;
1005 if(bIsTpetra ==
false) {
1007 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op);
1008 if(ThyBlockedOp != Teuchos::null) {
1011 ThyBlockedOp->getBlock(0,0);
1013 bIsTpetra = isTpetra(b00);
1021 static bool isEpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
1023 bool bIsEpetra =
false;
1025 #ifdef HAVE_XPETRA_EPETRA
1034 if(bIsEpetra ==
false) {
1036 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op,
false);
1037 if(ThyBlockedOp != Teuchos::null) {
1040 ThyBlockedOp->getBlock(0,0);
1042 bIsEpetra = isEpetra(b00);
1050 static bool isBlockedOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
1053 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op);
1054 if(ThyBlockedOp != Teuchos::null) {
1063 #ifdef HAVE_XPETRA_TPETRA
1065 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1066 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
1068 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
1084 Teuchos::rcp_dynamic_cast<const Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(xTpetraCrsMat);
1093 #ifdef HAVE_XPETRA_EPETRA
1109 Teuchos::rcp_dynamic_cast<const Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(xEpetraCrsMat);
1114 return Teuchos::null;
1120 #ifdef HAVE_XPETRA_TPETRA
1122 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1123 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
1125 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
1136 return xTpetraCrsMat;
1143 #ifdef HAVE_XPETRA_EPETRA
1155 return xEpetraCrsMat;
1158 return Teuchos::null;
1166 RCP<const BlockedMap> bmap = Teuchos::rcp_dynamic_cast<const BlockedMap>(map);
1167 if(bmap.is_null() ==
false) {
1170 for(
size_t i = 0; i < bmap->getNumMaps(); i++) {
1173 Xpetra::ThyraUtils<Scalar,LO,GO,Node>::toThyra(bmap->getMap(i,
true));
1177 thyraMap = Thyra::productVectorSpace<Scalar>(vecSpaces());
1182 #ifdef HAVE_XPETRA_TPETRA
1184 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1185 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
1187 if (tpetraMap == Teuchos::null)
1188 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::TpetraMap failed");
1189 RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > tpMap = tpetraMap->getTpetra_Map();
1190 RCP<Thyra::TpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node> > thyraTpetraMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tpMap);
1191 thyraMap = thyraTpetraMap;
1198 #ifdef HAVE_XPETRA_EPETRA
1201 if (epetraMap == Teuchos::null)
1202 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::EpetraMap failed");
1203 RCP<const Thyra::VectorSpaceBase<Scalar> > thyraEpetraMap = Thyra::create_VectorSpace(Teuchos::rcpFromRef(epetraMap->getEpetra_Map()));
1204 thyraMap = thyraEpetraMap;
1216 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.");
1218 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMap == Teuchos::null, std::logic_error,
"Cannot cast VectorSpaceBase to SpmdVectorSpaceBase.");
1219 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.");
1224 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMVec == Teuchos::null, std::logic_error,
"Cannot cast MultiVectorBase to SpmdMultiVectorBase.");
1227 const LocalOrdinal localOffset = ( thSpmdMap != Teuchos::null ? thSpmdMap->localOffset() : 0 );
1228 const LocalOrdinal localSubDim = ( thSpmdMap != Teuchos::null ? thSpmdMap->localSubDim() : thMap->dim() );
1233 for(
size_t j = 0; j < Teuchos::as<size_t>(thSpmdMVec->domain()->dim()); ++j) {
1236 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1237 (*thyData)(i,j) = vecData[i];
1249 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.");
1251 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMap == Teuchos::null, std::logic_error,
"Cannot cast VectorSpaceBase to SpmdVectorSpaceBase.");
1252 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.");
1260 const LocalOrdinal localOffset = ( thSpmdMap != Teuchos::null ? thSpmdMap->localOffset() : 0 );
1261 const LocalOrdinal localSubDim = ( thSpmdMap != Teuchos::null ? thSpmdMap->localSubDim() : thMap->dim() );
1266 for(
size_t j = 0; j < Teuchos::as<size_t>(thSpmdMVec->domain()->dim()); ++j) {
1269 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1270 (*thyData)(i,j) = vecData[i];
1279 using Teuchos::rcp_dynamic_cast;
1281 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
1282 typedef Thyra::SpmdVectorSpaceBase<Scalar> ThySpmdVecSpaceBase;
1283 typedef Thyra::MultiVectorBase<Scalar> ThyMultVecBase;
1286 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
1289 RCP<ThyProdMultVecBase> prodTarget = rcp_dynamic_cast<ThyProdMultVecBase>(target);
1290 if(prodTarget != Teuchos::null) {
1292 RCP<const BlockedMultiVector> bSourceVec = rcp_dynamic_cast<const BlockedMultiVector>(source);
1293 if(bSourceVec.is_null() ==
true) {
1297 TEUCHOS_TEST_FOR_EXCEPTION(mapExtractor == Teuchos::null, std::logic_error,
"Found a Thyra product vector, but user did not provide an Xpetra::MapExtractor.");
1298 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.");
1300 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
1302 RCP<MultiVector> xpSubBlock = mapExtractor->ExtractVector(source, bbb,
false);
1306 RCP<const ThyVecSpaceBase> vs = thySubBlock->range();
1307 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<const ThySpmdVecSpaceBase>(vs);
1308 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
1309 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : vs->dim() );
1310 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
1314 for(
size_t j = 0; j < xpSubBlock->getNumVectors(); ++j) {
1318 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1319 (*thyData)(i,j) = xpData[i];
1326 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.");
1328 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
1330 RCP<MultiVector> xpSubBlock = bSourceVec->getMultiVector(bbb,
true);
1336 Thyra::assign(thySubBlock.
ptr(), *thyXpSubBlock);
1345 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<const ThySpmdVecSpaceBase>(target->range());
1346 TEUCHOS_TEST_FOR_EXCEPTION(mpi_vs == Teuchos::null, std::logic_error,
"Failed to cast Thyra::VectorSpaceBase to Thyra::SpmdVectorSpaceBase.");
1347 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
1348 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : target->range()->dim() );
1349 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
1353 for(
size_t j = 0; j < source->getNumVectors(); ++j) {
1356 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1357 (*thyData)(i,j) = xpData[i];
1368 #ifdef HAVE_XPETRA_TPETRA
1370 if(tpetraMat!=Teuchos::null) {
1371 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1372 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
1384 thyraOp = Thyra::createConstLinearOp(tpOperator);
1392 #ifdef HAVE_XPETRA_EPETRA
1394 if(epetraMat!=Teuchos::null) {
1402 thyraOp = thyraEpOp;
1413 #ifdef HAVE_XPETRA_TPETRA
1415 if(tpetraMat!=Teuchos::null) {
1416 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1417 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
1429 thyraOp = Thyra::createLinearOp(tpOperator);
1437 #ifdef HAVE_XPETRA_EPETRA
1439 if(epetraMat!=Teuchos::null) {
1447 thyraOp = thyraEpOp;
1459 #ifndef XPETRA_EPETRA_NO_64BIT_GLOBAL_INDICES
1461 class ThyraUtils<double, int, long long,
EpetraNode> {
1463 typedef double Scalar;
1464 typedef int LocalOrdinal;
1465 typedef long long GlobalOrdinal;
1469 #undef XPETRA_THYRAUTILS_SHORT
1479 if(stridedBlockId == -1) {
1493 using Teuchos::rcp_dynamic_cast;
1495 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
1496 typedef Thyra::ProductVectorSpaceBase<Scalar> ThyProdVecSpaceBase;
1497 typedef Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node> ThyUtils;
1499 RCP<const ThyProdVecSpaceBase > prodVectorSpace = rcp_dynamic_cast<const ThyProdVecSpaceBase >(vectorSpace);
1500 if(prodVectorSpace != Teuchos::null) {
1503 TEUCHOS_TEST_FOR_EXCEPTION(prodVectorSpace->numBlocks()==0, std::logic_error,
"Found a product vector space with zero blocks.");
1504 std::vector<RCP<const Map> > mapsThyra(prodVectorSpace->numBlocks(), Teuchos::null);
1505 std::vector<RCP<const Map> > mapsXpetra(prodVectorSpace->numBlocks(), Teuchos::null);
1506 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
1507 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
1514 std::vector<GlobalOrdinal> gidOffsets(prodVectorSpace->numBlocks(),0);
1515 for(
int i = 1; i < prodVectorSpace->numBlocks(); ++i) {
1516 gidOffsets[i] = mapsThyra[i-1]->getMaxAllGlobalIndex() + gidOffsets[i-1] + 1;
1519 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
1520 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
1533 bool bIsTpetra =
false;
1534 #ifdef HAVE_XPETRA_TPETRA
1535 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1536 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1543 bool bIsEpetra = !bIsTpetra;
1545 #ifdef HAVE_XPETRA_TPETRA
1547 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1548 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1549 typedef Thyra::VectorBase<Scalar> ThyVecBase;
1550 typedef Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> TpMap;
1551 typedef Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpVector;
1552 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
1553 RCP<ThyVecBase> rgVec = Thyra::createMember<Scalar>(vectorSpace, std::string(
"label"));
1555 RCP<const TpVector> rgTpetraVec = TOE::getTpetraVector(rgVec);
1557 RCP<const TpMap> rgTpetraMap = rgTpetraVec->getMap();
1569 #ifdef HAVE_XPETRA_EPETRA
1572 RCP<const Epetra_Map>
1573 epetra_map = Teuchos::get_extra_data<RCP<const Epetra_Map> >(vectorSpace,
"epetra_map");
1592 using Teuchos::rcp_dynamic_cast;
1594 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
1595 typedef Thyra::MultiVectorBase<Scalar> ThyMultVecBase;
1596 typedef Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node> ThyUtils;
1599 RCP<MultiVector> xpMultVec = Teuchos::null;
1603 if(thyProdVec != Teuchos::null) {
1612 RCP<BlockedMultiVector> xpBlockedMultVec = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(xpMultVec);
1616 for (
int b = 0; b < thyProdVec->productSpace()->numBlocks(); ++b){
1617 RCP<const ThyMultVecBase> thyBlockMV = thyProdVec->getMultiVectorBlock(b);
1620 xpBlockedMultVec->setMultiVector(b, xpBlockMV,
true );
1628 bool bIsTpetra =
false;
1629 #ifdef HAVE_XPETRA_TPETRA
1630 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1631 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1635 typedef Thyra::SpmdMultiVectorBase<Scalar> ThySpmdMultVecBase;
1636 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> ConverterT;
1637 typedef Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpMultVec;
1639 typedef Thyra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> ThyTpMultVec;
1641 RCP<const ThySpmdMultVecBase> thyraSpmdMultiVector = rcp_dynamic_cast<const ThySpmdMultVecBase>(v);
1642 RCP<const ThyTpMultVec> thyraTpetraMultiVector = rcp_dynamic_cast<const ThyTpMultVec>(thyraSpmdMultiVector);
1643 if(thyraTpetraMultiVector != Teuchos::null) {
1645 const RCP<const TpMultVec> tpMultVec = ConverterT::getConstTpetraMultiVector(v);
1647 RCP<TpMultVec> tpNonConstMultVec = Teuchos::rcp_const_cast<TpMultVec>(tpMultVec);
1649 xpMultVec =
rcp(
new XpTpMultVec(tpNonConstMultVec));
1656 #ifdef HAVE_XPETRA_EPETRA
1657 if(bIsTpetra ==
false) {
1661 RCP<Xpetra::EpetraMapT<GlobalOrdinal,Node> > xeMap = rcp_dynamic_cast<Xpetra::EpetraMapT<GlobalOrdinal,Node> >(map);
1663 RCP<const Epetra_Map> eMap = Teuchos::rcpFromRef(xeMap->getEpetra_Map());
1667 RCP<Epetra_MultiVector> epNonConstMultVec = Teuchos::rcp_const_cast<Epetra_MultiVector>(epMultVec);
1683 Teuchos::rcp_const_cast<const Thyra::MultiVectorBase<Scalar> >(v);
1686 return Teuchos::rcp_const_cast<Xpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(r);
1689 static bool isTpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
1691 bool bIsTpetra =
false;
1692 #ifdef HAVE_XPETRA_TPETRA
1693 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1694 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1701 #ifdef HAVE_XPETRA_EPETRA
1702 Teuchos::rcp_dynamic_cast<const Thyra::EpetraLinearOp>(op) == Teuchos::null &&
1704 Teuchos::rcp_dynamic_cast<
const Thyra::DefaultBlockedLinearOp<Scalar> >(op) == Teuchos::null) {
1706 typedef Thyra::TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpetraLinearOp_t;
1707 if(Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op) == Teuchos::null) {
1708 std::cout <<
"ATTENTION: The dynamic cast to the TpetraLinearOp failed even though it should be a TpetraLinearOp." << std::endl;
1709 std::cout <<
" If you are using Panzer or Stratimikos you might check that the template parameters are " << std::endl;
1710 std::cout <<
" properly set!" << std::endl;
1711 std::cout << Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op,
true) << std::endl;
1721 if(bIsTpetra ==
false) {
1723 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op);
1724 if(ThyBlockedOp != Teuchos::null) {
1727 ThyBlockedOp->getBlock(0,0);
1729 bIsTpetra = isTpetra(b00);
1737 static bool isEpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
1739 bool bIsEpetra =
false;
1741 #ifdef HAVE_XPETRA_EPETRA
1750 if(bIsEpetra ==
false) {
1752 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op,
false);
1753 if(ThyBlockedOp != Teuchos::null) {
1756 ThyBlockedOp->getBlock(0,0);
1758 bIsEpetra = isEpetra(b00);
1766 static bool isBlockedOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
1769 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op);
1770 if(ThyBlockedOp != Teuchos::null) {
1779 #ifdef HAVE_XPETRA_TPETRA
1781 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1782 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1784 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
1800 Teuchos::rcp_dynamic_cast<const Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(xTpetraCrsMat);
1809 #ifdef HAVE_XPETRA_EPETRA
1825 Teuchos::rcp_dynamic_cast<const Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(xEpetraCrsMat);
1830 return Teuchos::null;
1836 #ifdef HAVE_XPETRA_TPETRA
1838 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1839 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1841 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
1852 return xTpetraCrsMat;
1859 #ifdef HAVE_XPETRA_EPETRA
1871 return xEpetraCrsMat;
1874 return Teuchos::null;
1882 RCP<const BlockedMap> bmap = Teuchos::rcp_dynamic_cast<const BlockedMap>(map);
1883 if(bmap.is_null() ==
false) {
1886 for(
size_t i = 0; i < bmap->getNumMaps(); i++) {
1889 Xpetra::ThyraUtils<Scalar,LO,GO,Node>::toThyra(bmap->getMap(i,
true));
1893 thyraMap = Thyra::productVectorSpace<Scalar>(vecSpaces());
1898 #ifdef HAVE_XPETRA_TPETRA
1900 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
1901 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
1903 if (tpetraMap == Teuchos::null)
1904 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::TpetraMap failed");
1905 RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > tpMap = tpetraMap->getTpetra_Map();
1906 RCP<Thyra::TpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node> > thyraTpetraMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tpMap);
1907 thyraMap = thyraTpetraMap;
1914 #ifdef HAVE_XPETRA_EPETRA
1917 if (epetraMap == Teuchos::null)
1918 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::EpetraMap failed");
1919 RCP<const Thyra::VectorSpaceBase<Scalar> > thyraEpetraMap = Thyra::create_VectorSpace(Teuchos::rcpFromRef(epetraMap->getEpetra_Map()));
1920 thyraMap = thyraEpetraMap;
1932 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.");
1934 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMap == Teuchos::null, std::logic_error,
"Cannot cast VectorSpaceBase to SpmdVectorSpaceBase.");
1935 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.");
1940 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMVec == Teuchos::null, std::logic_error,
"Cannot cast MultiVectorBase to SpmdMultiVectorBase.");
1943 const LocalOrdinal localOffset = ( thSpmdMap != Teuchos::null ? thSpmdMap->localOffset() : 0 );
1944 const LocalOrdinal localSubDim = ( thSpmdMap != Teuchos::null ? thSpmdMap->localSubDim() : thMap->dim() );
1949 for(
size_t j = 0; j < Teuchos::as<size_t>(thSpmdMVec->domain()->dim()); ++j) {
1952 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1953 (*thyData)(i,j) = vecData[i];
1965 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.");
1967 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMap == Teuchos::null, std::logic_error,
"Cannot cast VectorSpaceBase to SpmdVectorSpaceBase.");
1968 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.");
1976 const LocalOrdinal localOffset = ( thSpmdMap != Teuchos::null ? thSpmdMap->localOffset() : 0 );
1977 const LocalOrdinal localSubDim = ( thSpmdMap != Teuchos::null ? thSpmdMap->localSubDim() : thMap->dim() );
1982 for(
size_t j = 0; j < Teuchos::as<size_t>(thSpmdMVec->domain()->dim()); ++j) {
1985 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1986 (*thyData)(i,j) = vecData[i];
1995 using Teuchos::rcp_dynamic_cast;
1997 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
1998 typedef Thyra::SpmdVectorSpaceBase<Scalar> ThySpmdVecSpaceBase;
1999 typedef Thyra::MultiVectorBase<Scalar> ThyMultVecBase;
2002 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
2005 RCP<ThyProdMultVecBase> prodTarget = rcp_dynamic_cast<ThyProdMultVecBase>(target);
2006 if(prodTarget != Teuchos::null) {
2007 RCP<const BlockedMultiVector> bSourceVec = rcp_dynamic_cast<const BlockedMultiVector>(source);
2008 if(bSourceVec.is_null() ==
true) {
2012 TEUCHOS_TEST_FOR_EXCEPTION(mapExtractor == Teuchos::null, std::logic_error,
"Found a Thyra product vector, but user did not provide an Xpetra::MapExtractor.");
2013 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.");
2015 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
2017 RCP<MultiVector> xpSubBlock = mapExtractor->ExtractVector(source, bbb,
false);
2021 RCP<const ThyVecSpaceBase> vs = thySubBlock->range();
2022 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<const ThySpmdVecSpaceBase>(vs);
2023 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
2024 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : vs->dim() );
2025 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
2029 for(
size_t j = 0; j < xpSubBlock->getNumVectors(); ++j) {
2033 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
2034 (*thyData)(i,j) = xpData[i];
2041 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.");
2043 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
2045 RCP<MultiVector> xpSubBlock = bSourceVec->getMultiVector(bbb,
true);
2051 Thyra::assign(thySubBlock.
ptr(), *thyXpSubBlock);
2060 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<const ThySpmdVecSpaceBase>(target->range());
2061 TEUCHOS_TEST_FOR_EXCEPTION(mpi_vs == Teuchos::null, std::logic_error,
"Failed to cast Thyra::VectorSpaceBase to Thyra::SpmdVectorSpaceBase.");
2062 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
2063 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : target->range()->dim() );
2064 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
2068 for(
size_t j = 0; j < source->getNumVectors(); ++j) {
2071 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
2072 (*thyData)(i,j) = xpData[i];
2083 #ifdef HAVE_XPETRA_TPETRA
2085 if(tpetraMat!=Teuchos::null) {
2086 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
2087 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
2099 thyraOp = Thyra::createConstLinearOp(tpOperator);
2107 #ifdef HAVE_XPETRA_EPETRA
2109 if(epetraMat!=Teuchos::null) {
2117 thyraOp = thyraEpOp;
2128 #ifdef HAVE_XPETRA_TPETRA
2130 if(tpetraMat!=Teuchos::null) {
2131 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
2132 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)))
2144 thyraOp = Thyra::createLinearOp(tpOperator);
2152 #ifdef HAVE_XPETRA_EPETRA
2154 if(epetraMat!=Teuchos::null) {
2162 thyraOp = thyraEpOp;
2178 #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)