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" 71 #include <Thyra_VectorSpaceBase.hpp> 72 #include <Thyra_SpmdVectorSpaceBase.hpp> 73 #include <Thyra_ProductVectorSpaceBase.hpp> 74 #include <Thyra_ProductMultiVectorBase.hpp> 75 #include <Thyra_VectorSpaceBase.hpp> 76 #include <Thyra_DefaultBlockedLinearOp.hpp> 77 #include <Thyra_LinearOpBase.hpp> 78 #include <Thyra_DetachedMultiVectorView.hpp> 80 #ifdef HAVE_XPETRA_TPETRA 81 #include <Thyra_TpetraThyraWrappers.hpp> 82 #include <Thyra_TpetraVector.hpp> 83 #include <Thyra_TpetraVectorSpace.hpp> 84 #include <Tpetra_Map.hpp> 85 #include <Tpetra_Vector.hpp> 86 #include <Tpetra_CrsMatrix.hpp> 90 #ifdef HAVE_XPETRA_EPETRA 91 #include <Thyra_EpetraLinearOp.hpp> 92 #include <Thyra_EpetraThyraWrappers.hpp> 93 #include <Thyra_SpmdVectorBase.hpp> 94 #include <Thyra_get_Epetra_Operator.hpp> 95 #include <Epetra_Map.h> 96 #include <Epetra_Vector.h> 97 #include <Epetra_CrsMatrix.h> 104 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
class BlockedCrsMatrix;
106 template <
class Scalar,
107 class LocalOrdinal = int,
108 class GlobalOrdinal = LocalOrdinal,
113 #undef XPETRA_THYRAUTILS_SHORT 122 if(stridedBlockId == -1) {
136 using Teuchos::rcp_dynamic_cast;
138 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
139 typedef Thyra::ProductVectorSpaceBase<Scalar> ThyProdVecSpaceBase;
142 typedef Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node> ThyUtils;
144 RCP<Map> resultMap = Teuchos::null;
145 RCP<const ThyProdVecSpaceBase > prodVectorSpace = rcp_dynamic_cast<
const ThyProdVecSpaceBase >(vectorSpace);
146 if(prodVectorSpace != Teuchos::null) {
149 TEUCHOS_TEST_FOR_EXCEPTION(prodVectorSpace->numBlocks()==0, std::logic_error,
"Found a product vector space with zero blocks.");
150 std::vector<RCP<Map> > maps(prodVectorSpace->numBlocks(), Teuchos::null);
151 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
152 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
158 std::vector<GlobalOrdinal> gidOffsets(prodVectorSpace->numBlocks(),0);
159 for(
int i = 1; i < prodVectorSpace->numBlocks(); ++i) {
160 gidOffsets[i] = maps[i-1]->getMaxAllGlobalIndex() + gidOffsets[i-1] + 1;
164 std::vector<GlobalOrdinal> gids;
165 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
166 for(LocalOrdinal l = 0; l < as<LocalOrdinal>(maps[b]->getNodeNumElements()); ++l) {
167 GlobalOrdinal gid = maps[b]->getGlobalElement(l) + gidOffsets[b];
175 resultMap =
MapFactory::Build(maps[0]->lib(), INVALID, gidsView, maps[0]->getIndexBase(), comm);
177 #ifdef HAVE_XPETRA_TPETRA 183 typedef Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> TpMap;
184 typedef Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpVector;
185 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
186 typedef Thyra::VectorBase<Scalar> ThyVecBase;
187 RCP<ThyVecBase> rgVec = Thyra::createMember<Scalar>(vectorSpace, std::string(
"label"));
189 RCP<const TpVector> rgTpetraVec = TOE::getTpetraVector(rgVec);
191 RCP<const TpMap> rgTpetraMap = rgTpetraVec->getMap();
195 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.");
206 using Teuchos::rcp_dynamic_cast;
208 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
209 typedef Thyra::SpmdVectorSpaceBase<Scalar> ThySpmdVecSpaceBase;
210 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
214 typedef Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node> ThyUtils;
217 RCP<MultiVector> xpMultVec = Teuchos::null;
221 if(thyProdVec != Teuchos::null) {
230 std::vector<GlobalOrdinal> lidOffsets(thyProdVec->productSpace()->numBlocks()+1,0);
231 for (
int b = 0; b < thyProdVec->productSpace()->numBlocks(); ++b){
234 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
235 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : thySubMap->dim() );
236 lidOffsets[b+1] = localSubDim + lidOffsets[b];
237 RCP<Thyra::ConstDetachedMultiVectorView<Scalar> > thyData =
238 Teuchos::rcp(
new Thyra::ConstDetachedMultiVectorView<Scalar>(thyProdVec->getMultiVectorBlock(b),
Teuchos::Range1D(localOffset,localOffset+localSubDim-1)));
239 for(
size_t vv = 0; vv < xpMultVec->getNumVectors(); ++vv) {
240 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
241 xpMultVec->replaceLocalValue(i + lidOffsets[b] , vv, (*thyData)(i,vv));
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;
407 #ifdef HAVE_XPETRA_TPETRA 410 if (tpetraMap == Teuchos::null)
411 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::TpetraMap failed");
412 RCP<Thyra::TpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node> > thyraTpetraMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tpetraMap->getTpetra_Map());
413 thyraMap = thyraTpetraMap;
417 #ifdef HAVE_XPETRA_EPETRA 431 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.");
433 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMap == Teuchos::null, std::logic_error,
"Cannot cast VectorSpaceBase to SpmdVectorSpaceBase.");
434 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.");
439 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMVec == Teuchos::null, std::logic_error,
"Cannot cast MultiVectorBase to SpmdMultiVectorBase.");
442 const LocalOrdinal localOffset = ( thSpmdMap != Teuchos::null ? thSpmdMap->localOffset() : 0 );
443 const LocalOrdinal localSubDim = ( thSpmdMap != Teuchos::null ? thSpmdMap->localSubDim() : thMap->dim() );
448 for(
size_t j = 0; j < Teuchos::as<size_t>(thSpmdMVec->domain()->dim()); ++j) {
451 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
452 (*thyData)(i,j) = vecData[i];
464 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.");
466 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMap == Teuchos::null, std::logic_error,
"Cannot cast VectorSpaceBase to SpmdVectorSpaceBase.");
467 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.");
475 const LocalOrdinal localOffset = ( thSpmdMap != Teuchos::null ? thSpmdMap->localOffset() : 0 );
476 const LocalOrdinal localSubDim = ( thSpmdMap != Teuchos::null ? thSpmdMap->localSubDim() : thMap->dim() );
481 for(
size_t j = 0; j < Teuchos::as<size_t>(thSpmdMVec->domain()->dim()); ++j) {
484 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
485 (*thyData)(i,j) = vecData[i];
497 using Teuchos::rcp_dynamic_cast;
499 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
500 typedef Thyra::SpmdVectorSpaceBase<Scalar> ThySpmdVecSpaceBase;
501 typedef Thyra::MultiVectorBase<Scalar> ThyMultVecBase;
504 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
508 RCP<ThyProdMultVecBase> prodTarget = rcp_dynamic_cast<ThyProdMultVecBase>(target);
509 if(prodTarget != Teuchos::null) {
513 TEUCHOS_TEST_FOR_EXCEPTION(mapExtractor == Teuchos::null, std::logic_error,
"Found a Thyra product vector, but user did not provide an Xpetra::MapExtractor.");
514 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.");
516 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
518 RCP<MultiVector> xpSubBlock = mapExtractor->ExtractVector(source, bbb,
false);
522 RCP<const ThyVecSpaceBase> vs = thySubBlock->range();
523 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<
const ThySpmdVecSpaceBase>(vs);
524 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
525 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : vs->dim() );
526 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
530 for(
size_t j = 0; j < xpSubBlock->getNumVectors(); ++j) {
534 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
535 (*thyData)(i,j) = xpData[i];
544 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<
const ThySpmdVecSpaceBase>(target->range());
545 TEUCHOS_TEST_FOR_EXCEPTION(mpi_vs == Teuchos::null, std::logic_error,
"Failed to cast Thyra::VectorSpaceBase to Thyra::SpmdVectorSpaceBase.");
546 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
547 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : target->range()->dim() );
548 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
552 for(
size_t j = 0; j < source->getNumVectors(); ++j) {
555 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
556 (*thyData)(i,j) = xpData[i];
567 bool bIsTpetra =
false;
569 #ifdef HAVE_XPETRA_TPETRA 571 if(tpetraMat!=Teuchos::null) {
583 thyraOp = Thyra::createConstLinearOp(tpOperator);
588 #ifdef HAVE_XPETRA_EPETRA 599 bool bIsTpetra =
false;
601 #ifdef HAVE_XPETRA_TPETRA 603 if(tpetraMat!=Teuchos::null) {
615 thyraOp = Thyra::createLinearOp(tpOperator);
620 #ifdef HAVE_XPETRA_EPETRA 629 int nRows = mat->Rows();
630 int nCols = mat->Cols();
636 bool bTpetra =
false;
637 #ifdef HAVE_XPETRA_TPETRA 639 if(tpetraMat!=Teuchos::null) bTpetra =
true;
642 #ifdef HAVE_XPETRA_EPETRA 648 Thyra::defaultBlockedLinearOp<Scalar>();
650 blockMat->beginBlockFill(nRows,nCols);
652 for (
int r=0; r<nRows; ++r) {
653 for (
int c=0; c<nCols; ++c) {
656 if(xpmat == Teuchos::null)
continue;
663 if(xpblock != Teuchos::null) {
664 if(xpblock->Rows() == 1 && xpblock->Cols() == 1) {
668 thBlock = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(xpwrap->getCrsMatrix());
671 thBlock = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(xpblock);
677 thBlock = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(xpwrap->getCrsMatrix());
680 blockMat->setBlock(r,c,thBlock);
684 blockMat->endBlockFill();
694 #ifdef HAVE_XPETRA_EPETRA 696 #ifndef XPETRA_EPETRA_NO_32BIT_GLOBAL_INDICES 698 class ThyraUtils<double, int, int,
EpetraNode> {
700 typedef double Scalar;
701 typedef int LocalOrdinal;
702 typedef int GlobalOrdinal;
706 #undef XPETRA_THYRAUTILS_SHORT 716 if(stridedBlockId == -1) {
730 using Teuchos::rcp_dynamic_cast;
732 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
733 typedef Thyra::ProductVectorSpaceBase<Scalar> ThyProdVecSpaceBase;
736 typedef Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node> ThyUtils;
738 RCP<Map> resultMap = Teuchos::null;
740 RCP<const ThyProdVecSpaceBase > prodVectorSpace = rcp_dynamic_cast<
const ThyProdVecSpaceBase >(vectorSpace);
741 if(prodVectorSpace != Teuchos::null) {
744 TEUCHOS_TEST_FOR_EXCEPTION(prodVectorSpace->numBlocks()==0, std::logic_error,
"Found a product vector space with zero blocks.");
745 std::vector<RCP<Map> > maps(prodVectorSpace->numBlocks(), Teuchos::null);
746 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
747 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
753 std::vector<GlobalOrdinal> gidOffsets(prodVectorSpace->numBlocks(),0);
754 for(
int i = 1; i < prodVectorSpace->numBlocks(); ++i) {
755 gidOffsets[i] = maps[i-1]->getMaxAllGlobalIndex() + gidOffsets[i-1] + 1;
759 std::vector<GlobalOrdinal> gids;
760 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
761 for(LocalOrdinal l = 0; l < as<LocalOrdinal>(maps[b]->getNodeNumElements()); ++l) {
762 GlobalOrdinal gid = maps[b]->getGlobalElement(l) + gidOffsets[b];
770 resultMap =
MapFactory::Build(maps[0]->lib(), INVALID, gidsView, maps[0]->getIndexBase(), comm);
776 bool bIsTpetra =
false;
777 #ifdef HAVE_XPETRA_TPETRA 778 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \ 779 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE))) 786 bool bIsEpetra = !bIsTpetra;
788 #ifdef HAVE_XPETRA_TPETRA 790 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \ 791 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE))) 792 typedef Thyra::VectorBase<Scalar> ThyVecBase;
793 typedef Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> TpMap;
794 typedef Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpVector;
795 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
796 RCP<ThyVecBase> rgVec = Thyra::createMember<Scalar>(vectorSpace, std::string(
"label"));
798 RCP<const TpVector> rgTpetraVec = TOE::getTpetraVector(rgVec);
800 RCP<const TpMap> rgTpetraMap = rgTpetraVec->getMap();
810 #ifdef HAVE_XPETRA_EPETRA 813 RCP<const Epetra_Map>
814 epetra_map = Teuchos::get_extra_data<RCP<const Epetra_Map> >(vectorSpace,
"epetra_map");
832 using Teuchos::rcp_dynamic_cast;
834 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
835 typedef Thyra::SpmdVectorSpaceBase<Scalar> ThySpmdVecSpaceBase;
838 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
843 typedef Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node> ThyUtils;
846 RCP<MultiVector> xpMultVec = Teuchos::null;
850 if(thyProdVec != Teuchos::null) {
859 std::vector<GlobalOrdinal> lidOffsets(thyProdVec->productSpace()->numBlocks()+1,0);
860 for (
int b = 0; b < thyProdVec->productSpace()->numBlocks(); ++b){
863 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
864 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : thySubMap->dim() );
865 lidOffsets[b+1] = localSubDim + lidOffsets[b];
866 RCP<Thyra::ConstDetachedMultiVectorView<Scalar> > thyData =
867 Teuchos::rcp(
new Thyra::ConstDetachedMultiVectorView<Scalar>(thyProdVec->getMultiVectorBlock(b),
Teuchos::Range1D(localOffset,localOffset+localSubDim-1)));
868 for(
size_t vv = 0; vv < xpMultVec->getNumVectors(); ++vv) {
869 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
870 xpMultVec->replaceLocalValue(i + lidOffsets[b] , vv, (*thyData)(i,vv));
879 bool bIsTpetra =
false;
880 #ifdef HAVE_XPETRA_TPETRA 881 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \ 882 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE))) 886 typedef Thyra::SpmdMultiVectorBase<Scalar> ThySpmdMultVecBase;
887 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> ConverterT;
888 typedef Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpMultVec;
890 typedef Thyra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> ThyTpMultVec;
892 RCP<const ThySpmdMultVecBase> thyraSpmdMultiVector = rcp_dynamic_cast<
const ThySpmdMultVecBase>(v);
893 RCP<const ThyTpMultVec> thyraTpetraMultiVector = rcp_dynamic_cast<
const ThyTpMultVec>(thyraSpmdMultiVector);
894 if(thyraTpetraMultiVector != Teuchos::null) {
896 const RCP<const TpMultVec> tpMultVec = ConverterT::getConstTpetraMultiVector(v);
898 RCP<TpMultVec> tpNonConstMultVec = Teuchos::rcp_const_cast<TpMultVec>(tpMultVec);
900 xpMultVec =
rcp(
new XpTpMultVec(tpNonConstMultVec));
905 #ifdef HAVE_XPETRA_EPETRA 906 if(bIsTpetra ==
false) {
912 RCP<const Epetra_Map> eMap = Teuchos::rcpFromRef(xeMap->getEpetra_Map());
916 RCP<Epetra_MultiVector> epNonConstMultVec = Teuchos::rcp_const_cast<Epetra_MultiVector>(epMultVec);
925 return Teuchos::null;
932 Teuchos::rcp_const_cast<
const Thyra::MultiVectorBase<Scalar> >(v);
938 static bool isTpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
940 bool bIsTpetra =
false;
941 #ifdef HAVE_XPETRA_TPETRA 942 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \ 943 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE))) 950 #ifdef HAVE_XPETRA_EPETRA
951 Teuchos::rcp_dynamic_cast<const Thyra::EpetraLinearOp>(op) == Teuchos::null &&
953 Teuchos::rcp_dynamic_cast<
const Thyra::DefaultBlockedLinearOp<Scalar> >(op) == Teuchos::null) {
955 typedef Thyra::TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpetraLinearOp_t;
956 if(Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op) == Teuchos::null) {
957 std::cout <<
"ATTENTION: The dynamic cast to the TpetraLinearOp failed even though it should be a TpetraLinearOp." << std::endl;
958 std::cout <<
" If you are using Panzer or Stratimikos you might check that the template parameters are " << std::endl;
959 std::cout <<
" properly set!" << std::endl;
960 std::cout << Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op,
true) << std::endl;
970 if(bIsTpetra ==
false) {
972 Teuchos::rcp_dynamic_cast<
const Thyra::BlockedLinearOpBase<Scalar> >(op);
973 if(ThyBlockedOp != Teuchos::null) {
976 ThyBlockedOp->getBlock(0,0);
978 bIsTpetra = isTpetra(b00);
986 static bool isEpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
988 bool bIsEpetra =
false;
990 #ifdef HAVE_XPETRA_EPETRA 999 if(bIsEpetra ==
false) {
1001 Teuchos::rcp_dynamic_cast<
const Thyra::BlockedLinearOpBase<Scalar> >(op,
false);
1002 if(ThyBlockedOp != Teuchos::null) {
1005 ThyBlockedOp->getBlock(0,0);
1007 bIsEpetra = isEpetra(b00);
1015 static bool isBlockedOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
1018 Teuchos::rcp_dynamic_cast<
const Thyra::BlockedLinearOpBase<Scalar> >(op);
1019 if(ThyBlockedOp != Teuchos::null) {
1028 #ifdef HAVE_XPETRA_TPETRA 1030 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \ 1031 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE))) 1033 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
1058 #ifdef HAVE_XPETRA_EPETRA 1079 return Teuchos::null;
1085 #ifdef HAVE_XPETRA_TPETRA 1087 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \ 1088 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE))) 1090 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
1101 return xTpetraCrsMat;
1108 #ifdef HAVE_XPETRA_EPETRA 1120 return xEpetraCrsMat;
1123 return Teuchos::null;
1129 #ifdef HAVE_XPETRA_TPETRA 1131 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \ 1132 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE))) 1134 if (tpetraMap == Teuchos::null)
1135 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::TpetraMap failed");
1136 RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > tpMap = tpetraMap->getTpetra_Map();
1137 RCP<Thyra::TpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node> > thyraTpetraMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tpMap);
1138 thyraMap = thyraTpetraMap;
1145 #ifdef HAVE_XPETRA_EPETRA 1148 if (epetraMap == Teuchos::null)
1149 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::EpetraMap failed");
1150 RCP<const Thyra::VectorSpaceBase<Scalar> > thyraEpetraMap = Thyra::create_VectorSpace(Teuchos::rcpFromRef(epetraMap->getEpetra_Map()));
1151 thyraMap = thyraEpetraMap;
1163 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.");
1165 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMap == Teuchos::null, std::logic_error,
"Cannot cast VectorSpaceBase to SpmdVectorSpaceBase.");
1166 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.");
1171 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMVec == Teuchos::null, std::logic_error,
"Cannot cast MultiVectorBase to SpmdMultiVectorBase.");
1174 const LocalOrdinal localOffset = ( thSpmdMap != Teuchos::null ? thSpmdMap->localOffset() : 0 );
1175 const LocalOrdinal localSubDim = ( thSpmdMap != Teuchos::null ? thSpmdMap->localSubDim() : thMap->dim() );
1180 for(
size_t j = 0; j < Teuchos::as<size_t>(thSpmdMVec->domain()->dim()); ++j) {
1183 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1184 (*thyData)(i,j) = vecData[i];
1196 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.");
1198 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMap == Teuchos::null, std::logic_error,
"Cannot cast VectorSpaceBase to SpmdVectorSpaceBase.");
1199 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.");
1207 const LocalOrdinal localOffset = ( thSpmdMap != Teuchos::null ? thSpmdMap->localOffset() : 0 );
1208 const LocalOrdinal localSubDim = ( thSpmdMap != Teuchos::null ? thSpmdMap->localSubDim() : thMap->dim() );
1213 for(
size_t j = 0; j < Teuchos::as<size_t>(thSpmdMVec->domain()->dim()); ++j) {
1216 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1217 (*thyData)(i,j) = vecData[i];
1226 using Teuchos::rcp_dynamic_cast;
1228 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
1229 typedef Thyra::SpmdVectorSpaceBase<Scalar> ThySpmdVecSpaceBase;
1230 typedef Thyra::MultiVectorBase<Scalar> ThyMultVecBase;
1233 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
1237 RCP<ThyProdMultVecBase> prodTarget = rcp_dynamic_cast<ThyProdMultVecBase>(target);
1238 if(prodTarget != Teuchos::null) {
1242 TEUCHOS_TEST_FOR_EXCEPTION(mapExtractor == Teuchos::null, std::logic_error,
"Found a Thyra product vector, but user did not provide an Xpetra::MapExtractor.");
1243 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.");
1245 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
1247 RCP<MultiVector> xpSubBlock = mapExtractor->ExtractVector(source, bbb,
false);
1251 RCP<const ThyVecSpaceBase> vs = thySubBlock->range();
1252 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<
const ThySpmdVecSpaceBase>(vs);
1253 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
1254 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : vs->dim() );
1255 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
1259 for(
size_t j = 0; j < xpSubBlock->getNumVectors(); ++j) {
1263 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1264 (*thyData)(i,j) = xpData[i];
1273 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<
const ThySpmdVecSpaceBase>(target->range());
1274 TEUCHOS_TEST_FOR_EXCEPTION(mpi_vs == Teuchos::null, std::logic_error,
"Failed to cast Thyra::VectorSpaceBase to Thyra::SpmdVectorSpaceBase.");
1275 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
1276 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : target->range()->dim() );
1277 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
1281 for(
size_t j = 0; j < source->getNumVectors(); ++j) {
1284 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1285 (*thyData)(i,j) = xpData[i];
1296 #ifdef HAVE_XPETRA_TPETRA 1298 if(tpetraMat!=Teuchos::null) {
1299 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \ 1300 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE))) 1312 thyraOp = Thyra::createConstLinearOp(tpOperator);
1320 #ifdef HAVE_XPETRA_EPETRA 1322 if(epetraMat!=Teuchos::null) {
1330 thyraOp = thyraEpOp;
1341 #ifdef HAVE_XPETRA_TPETRA 1343 if(tpetraMat!=Teuchos::null) {
1344 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \ 1345 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE))) 1357 thyraOp = Thyra::createLinearOp(tpOperator);
1365 #ifdef HAVE_XPETRA_EPETRA 1367 if(epetraMat!=Teuchos::null) {
1375 thyraOp = thyraEpOp;
1385 #endif // #ifndef XPETRA_EPETRA_NO_32BIT_GLOBAL_INDICES 1387 #ifndef XPETRA_EPETRA_NO_64BIT_GLOBAL_INDICES 1389 class ThyraUtils<double, int, long long,
EpetraNode> {
1391 typedef double Scalar;
1392 typedef int LocalOrdinal;
1393 typedef long long GlobalOrdinal;
1397 #undef XPETRA_THYRAUTILS_SHORT 1407 if(stridedBlockId == -1) {
1421 using Teuchos::rcp_dynamic_cast;
1423 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
1424 typedef Thyra::ProductVectorSpaceBase<Scalar> ThyProdVecSpaceBase;
1427 typedef Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node> ThyUtils;
1429 RCP<const ThyProdVecSpaceBase > prodVectorSpace = rcp_dynamic_cast<
const ThyProdVecSpaceBase >(vectorSpace);
1430 if(prodVectorSpace != Teuchos::null) {
1433 TEUCHOS_TEST_FOR_EXCEPTION(prodVectorSpace->numBlocks()==0, std::logic_error,
"Found a product vector space with zero blocks.");
1434 std::vector<RCP<Map> > maps(prodVectorSpace->numBlocks(), Teuchos::null);
1435 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
1436 RCP<const ThyVecSpaceBase > bv = prodVectorSpace->getBlock(b);
1442 std::vector<GlobalOrdinal> gidOffsets(prodVectorSpace->numBlocks(),0);
1443 for(
int i = 1; i < prodVectorSpace->numBlocks(); ++i) {
1444 gidOffsets[i] = maps[i-1]->getMaxAllGlobalIndex() + gidOffsets[i-1] + 1;
1448 std::vector<GlobalOrdinal> gids;
1449 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b){
1450 for(LocalOrdinal l = 0; l < as<LocalOrdinal>(maps[b]->getNodeNumElements()); ++l) {
1451 GlobalOrdinal gid = maps[b]->getGlobalElement(l) + gidOffsets[b];
1452 gids.push_back(gid);
1459 RCP<Map> fullMap =
MapFactory::Build(maps[0]->lib(), INVALID, gidsView, maps[0]->getIndexBase(), comm);
1468 bool bIsTpetra =
false;
1469 #ifdef HAVE_XPETRA_TPETRA 1470 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \ 1471 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE))) 1478 bool bIsEpetra = !bIsTpetra;
1480 #ifdef HAVE_XPETRA_TPETRA 1482 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \ 1483 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE))) 1484 typedef Thyra::VectorBase<Scalar> ThyVecBase;
1485 typedef Tpetra::Map<LocalOrdinal,GlobalOrdinal,Node> TpMap;
1486 typedef Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpVector;
1487 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
1488 RCP<ThyVecBase> rgVec = Thyra::createMember<Scalar>(vectorSpace, std::string(
"label"));
1490 RCP<const TpVector> rgTpetraVec = TOE::getTpetraVector(rgVec);
1492 RCP<const TpMap> rgTpetraMap = rgTpetraVec->getMap();
1504 #ifdef HAVE_XPETRA_EPETRA 1507 RCP<const Epetra_Map>
1508 epetra_map = Teuchos::get_extra_data<RCP<const Epetra_Map> >(vectorSpace,
"epetra_map");
1520 return Teuchos::null;
1527 using Teuchos::rcp_dynamic_cast;
1529 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
1530 typedef Thyra::SpmdVectorSpaceBase<Scalar> ThySpmdVecSpaceBase;
1533 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
1538 typedef Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node> ThyUtils;
1541 RCP<MultiVector> xpMultVec = Teuchos::null;
1545 if(thyProdVec != Teuchos::null) {
1554 std::vector<GlobalOrdinal> lidOffsets(thyProdVec->productSpace()->numBlocks()+1,0);
1555 for (
int b = 0; b < thyProdVec->productSpace()->numBlocks(); ++b){
1558 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
1559 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : thySubMap->dim() );
1560 lidOffsets[b+1] = localSubDim + lidOffsets[b];
1561 RCP<Thyra::ConstDetachedMultiVectorView<Scalar> > thyData =
1562 Teuchos::rcp(
new Thyra::ConstDetachedMultiVectorView<Scalar>(thyProdVec->getMultiVectorBlock(b),
Teuchos::Range1D(localOffset,localOffset+localSubDim-1)));
1563 for(
size_t vv = 0; vv < xpMultVec->getNumVectors(); ++vv) {
1564 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1565 xpMultVec->replaceLocalValue(i + lidOffsets[b] , vv, (*thyData)(i,vv));
1574 bool bIsTpetra =
false;
1575 #ifdef HAVE_XPETRA_TPETRA 1576 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \ 1577 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE))) 1581 typedef Thyra::SpmdMultiVectorBase<Scalar> ThySpmdMultVecBase;
1582 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> ConverterT;
1583 typedef Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpMultVec;
1585 typedef Thyra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> ThyTpMultVec;
1587 RCP<const ThySpmdMultVecBase> thyraSpmdMultiVector = rcp_dynamic_cast<
const ThySpmdMultVecBase>(v);
1588 RCP<const ThyTpMultVec> thyraTpetraMultiVector = rcp_dynamic_cast<
const ThyTpMultVec>(thyraSpmdMultiVector);
1589 if(thyraTpetraMultiVector != Teuchos::null) {
1591 const RCP<const TpMultVec> tpMultVec = ConverterT::getConstTpetraMultiVector(v);
1593 RCP<TpMultVec> tpNonConstMultVec = Teuchos::rcp_const_cast<TpMultVec>(tpMultVec);
1595 xpMultVec =
rcp(
new XpTpMultVec(tpNonConstMultVec));
1602 #ifdef HAVE_XPETRA_EPETRA 1603 if(bIsTpetra ==
false) {
1609 RCP<const Epetra_Map> eMap = Teuchos::rcpFromRef(xeMap->getEpetra_Map());
1613 RCP<Epetra_MultiVector> epNonConstMultVec = Teuchos::rcp_const_cast<Epetra_MultiVector>(epMultVec);
1622 return Teuchos::null;
1629 Teuchos::rcp_const_cast<
const Thyra::MultiVectorBase<Scalar> >(v);
1635 static bool isTpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
1637 bool bIsTpetra =
false;
1638 #ifdef HAVE_XPETRA_TPETRA 1639 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \ 1640 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE))) 1647 #ifdef HAVE_XPETRA_EPETRA
1648 Teuchos::rcp_dynamic_cast<const Thyra::EpetraLinearOp>(op) == Teuchos::null &&
1650 Teuchos::rcp_dynamic_cast<
const Thyra::DefaultBlockedLinearOp<Scalar> >(op) == Teuchos::null) {
1652 typedef Thyra::TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpetraLinearOp_t;
1653 if(Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op) == Teuchos::null) {
1654 std::cout <<
"ATTENTION: The dynamic cast to the TpetraLinearOp failed even though it should be a TpetraLinearOp." << std::endl;
1655 std::cout <<
" If you are using Panzer or Stratimikos you might check that the template parameters are " << std::endl;
1656 std::cout <<
" properly set!" << std::endl;
1657 std::cout << Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op,
true) << std::endl;
1667 if(bIsTpetra ==
false) {
1669 Teuchos::rcp_dynamic_cast<
const Thyra::BlockedLinearOpBase<Scalar> >(op);
1670 if(ThyBlockedOp != Teuchos::null) {
1673 ThyBlockedOp->getBlock(0,0);
1675 bIsTpetra = isTpetra(b00);
1683 static bool isEpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
1685 bool bIsEpetra =
false;
1687 #ifdef HAVE_XPETRA_EPETRA 1696 if(bIsEpetra ==
false) {
1698 Teuchos::rcp_dynamic_cast<
const Thyra::BlockedLinearOpBase<Scalar> >(op,
false);
1699 if(ThyBlockedOp != Teuchos::null) {
1702 ThyBlockedOp->getBlock(0,0);
1704 bIsEpetra = isEpetra(b00);
1712 static bool isBlockedOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar> > & op){
1715 Teuchos::rcp_dynamic_cast<
const Thyra::BlockedLinearOpBase<Scalar> >(op);
1716 if(ThyBlockedOp != Teuchos::null) {
1725 #ifdef HAVE_XPETRA_TPETRA 1727 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \ 1728 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE))) 1730 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
1755 #ifdef HAVE_XPETRA_EPETRA 1776 return Teuchos::null;
1782 #ifdef HAVE_XPETRA_TPETRA 1784 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \ 1785 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE))) 1787 typedef Thyra::TpetraOperatorVectorExtraction<Scalar,LocalOrdinal,GlobalOrdinal,Node> TOE;
1798 return xTpetraCrsMat;
1805 #ifdef HAVE_XPETRA_EPETRA 1817 return xEpetraCrsMat;
1820 return Teuchos::null;
1826 #ifdef HAVE_XPETRA_TPETRA 1828 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \ 1829 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE))) 1831 if (tpetraMap == Teuchos::null)
1832 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::TpetraMap failed");
1833 RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > tpMap = tpetraMap->getTpetra_Map();
1834 RCP<Thyra::TpetraVectorSpace<Scalar,LocalOrdinal,GlobalOrdinal,Node> > thyraTpetraMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(tpMap);
1835 thyraMap = thyraTpetraMap;
1842 #ifdef HAVE_XPETRA_EPETRA 1845 if (epetraMap == Teuchos::null)
1846 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::EpetraMap failed");
1847 RCP<const Thyra::VectorSpaceBase<Scalar> > thyraEpetraMap = Thyra::create_VectorSpace(Teuchos::rcpFromRef(epetraMap->getEpetra_Map()));
1848 thyraMap = thyraEpetraMap;
1860 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.");
1862 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMap == Teuchos::null, std::logic_error,
"Cannot cast VectorSpaceBase to SpmdVectorSpaceBase.");
1863 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.");
1868 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMVec == Teuchos::null, std::logic_error,
"Cannot cast MultiVectorBase to SpmdMultiVectorBase.");
1871 const LocalOrdinal localOffset = ( thSpmdMap != Teuchos::null ? thSpmdMap->localOffset() : 0 );
1872 const LocalOrdinal localSubDim = ( thSpmdMap != Teuchos::null ? thSpmdMap->localSubDim() : thMap->dim() );
1877 for(
size_t j = 0; j < Teuchos::as<size_t>(thSpmdMVec->domain()->dim()); ++j) {
1880 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1881 (*thyData)(i,j) = vecData[i];
1893 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.");
1895 TEUCHOS_TEST_FOR_EXCEPTION(thSpmdMap == Teuchos::null, std::logic_error,
"Cannot cast VectorSpaceBase to SpmdVectorSpaceBase.");
1896 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.");
1904 const LocalOrdinal localOffset = ( thSpmdMap != Teuchos::null ? thSpmdMap->localOffset() : 0 );
1905 const LocalOrdinal localSubDim = ( thSpmdMap != Teuchos::null ? thSpmdMap->localSubDim() : thMap->dim() );
1910 for(
size_t j = 0; j < Teuchos::as<size_t>(thSpmdMVec->domain()->dim()); ++j) {
1913 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1914 (*thyData)(i,j) = vecData[i];
1923 using Teuchos::rcp_dynamic_cast;
1925 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
1926 typedef Thyra::SpmdVectorSpaceBase<Scalar> ThySpmdVecSpaceBase;
1927 typedef Thyra::MultiVectorBase<Scalar> ThyMultVecBase;
1930 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
1934 RCP<ThyProdMultVecBase> prodTarget = rcp_dynamic_cast<ThyProdMultVecBase>(target);
1935 if(prodTarget != Teuchos::null) {
1939 TEUCHOS_TEST_FOR_EXCEPTION(mapExtractor == Teuchos::null, std::logic_error,
"Found a Thyra product vector, but user did not provide an Xpetra::MapExtractor.");
1940 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.");
1942 for(
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
1944 RCP<MultiVector> xpSubBlock = mapExtractor->ExtractVector(source, bbb,
false);
1948 RCP<const ThyVecSpaceBase> vs = thySubBlock->range();
1949 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<
const ThySpmdVecSpaceBase>(vs);
1950 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
1951 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : vs->dim() );
1952 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
1956 for(
size_t j = 0; j < xpSubBlock->getNumVectors(); ++j) {
1960 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1961 (*thyData)(i,j) = xpData[i];
1970 RCP<const ThySpmdVecSpaceBase> mpi_vs = rcp_dynamic_cast<
const ThySpmdVecSpaceBase>(target->range());
1971 TEUCHOS_TEST_FOR_EXCEPTION(mpi_vs == Teuchos::null, std::logic_error,
"Failed to cast Thyra::VectorSpaceBase to Thyra::SpmdVectorSpaceBase.");
1972 const LocalOrdinal localOffset = ( mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0 );
1973 const LocalOrdinal localSubDim = ( mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : target->range()->dim() );
1974 RCP<Thyra::DetachedMultiVectorView<Scalar> > thyData =
1978 for(
size_t j = 0; j < source->getNumVectors(); ++j) {
1981 for(LocalOrdinal i = 0; i < localSubDim; ++i) {
1982 (*thyData)(i,j) = xpData[i];
1993 #ifdef HAVE_XPETRA_TPETRA 1995 if(tpetraMat!=Teuchos::null) {
1996 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \ 1997 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE))) 2009 thyraOp = Thyra::createConstLinearOp(tpOperator);
2017 #ifdef HAVE_XPETRA_EPETRA 2019 if(epetraMat!=Teuchos::null) {
2027 thyraOp = thyraEpOp;
2038 #ifdef HAVE_XPETRA_TPETRA 2040 if(tpetraMat!=Teuchos::null) {
2041 #if ((defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE)) || \ 2042 (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_LONG_LONG) && defined(HAVE_TPETRA_INST_DOUBLE))) 2054 thyraOp = Thyra::createLinearOp(tpOperator);
2062 #ifdef HAVE_XPETRA_EPETRA 2064 if(epetraMat!=Teuchos::null) {
2072 thyraOp = thyraEpOp;
2082 #endif // XPETRA_EPETRA_NO_64BIT_GLOBAL_INDICES 2084 #endif // HAVE_XPETRA_EPETRA 2088 #define XPETRA_THYRAUTILS_SHORT 2089 #endif // HAVE_XPETRA_THYRA 2091 #endif // XPETRA_THYRAUTILS_HPP static Teuchos::RCP< Map< LocalOrdinal, GlobalOrdinal, Node > > Build(UnderlyingLib lib, global_size_t numGlobalElements, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalGlobal lg=Xpetra::GloballyDistributed, const Teuchos::RCP< Node > &node=defaultArgNode())
Map constructor with Xpetra-defined contiguous uniform distribution.
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.
Kokkos::Compat::KokkosSerialWrapperNode EpetraNode
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
static RCP< StridedMap > 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, const Teuchos::RCP< Node > &node=defaultArgNode())
Map constructor with Xpetra-defined contiguous uniform distribution.
const RCP< Map< LocalOrdinal, GlobalOrdinal, Node > > toXpetraNonConst(const RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > &)
RCP< const CrsGraph< int, GlobalOrdinal, Node > > toXpetra(const Epetra_CrsGraph &g)
TypeTo as(const TypeFrom &t)
Concrete implementation of Xpetra::Matrix.
Create an Xpetra::Map instance.
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.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)