10#ifndef HAVE_XPETRA_THYRAUTILS_DEF_HPP
11#define HAVE_XPETRA_THYRAUTILS_DEF_HPP
13#ifdef HAVE_XPETRA_THYRA
15#include "Xpetra_BlockedCrsMatrix.hpp"
21template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
22Teuchos::RCP<Xpetra::StridedMap<LocalOrdinal, GlobalOrdinal, Node>>
23Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
24 toXpetra(
const Teuchos::RCP<
const Thyra::VectorSpaceBase<Scalar>>& vectorSpace,
const Teuchos::RCP<
const Teuchos::Comm<int>>& comm, std::vector<size_t>& stridingInfo, LocalOrdinal stridedBlockId, GlobalOrdinal offset) {
25 Teuchos::RCP<Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> map =
toXpetra(vectorSpace, comm);
27 if (stridedBlockId == -1) {
37template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
38Teuchos::RCP<Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>
39Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
40 toXpetra(
const Teuchos::RCP<
const Thyra::VectorSpaceBase<Scalar>>& vectorSpace,
const Teuchos::RCP<
const Teuchos::Comm<int>>& comm) {
43 using Teuchos::rcp_dynamic_cast;
44 using ThyVecSpaceBase = Thyra::VectorSpaceBase<Scalar>;
45 using ThyProdVecSpaceBase = Thyra::ProductVectorSpaceBase<Scalar>;
46 using ThyUtils = Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
50 if (prodVectorSpace != Teuchos::null) {
53 TEUCHOS_TEST_FOR_EXCEPTION(prodVectorSpace->numBlocks() == 0, std::logic_error,
"Found a product vector space with zero blocks.");
54 std::vector<RCP<const Map>> mapsThyra(prodVectorSpace->numBlocks(), Teuchos::null);
55 std::vector<RCP<const Map>> mapsXpetra(prodVectorSpace->numBlocks(), Teuchos::null);
56 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b) {
59 mapsThyra[b] = ThyUtils::toXpetra(bv, comm);
64 std::vector<GlobalOrdinal> gidOffsets(prodVectorSpace->numBlocks(), 0);
65 for (
int i = 1; i < prodVectorSpace->numBlocks(); ++i) {
66 gidOffsets[i] = mapsThyra[i - 1]->getMaxAllGlobalIndex() + gidOffsets[i - 1] + 1;
69 for (
int b = 0; b < prodVectorSpace->numBlocks(); ++b) {
75 resultMap =
Teuchos::rcp(
new Xpetra::BlockedMap<LocalOrdinal, GlobalOrdinal, Node>(mapsXpetra, mapsThyra));
79 Teuchos::RCP<const Thyra::TpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpetra_vsc = Teuchos::rcp_dynamic_cast<const Thyra::TpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(vectorSpace);
80 TEUCHOS_TEST_FOR_EXCEPTION(
Teuchos::is_null(tpetra_vsc) ==
true, Xpetra::Exceptions::RuntimeError,
"toXpetra failed to convert provided vector space to Thyra::TpetraVectorSpace. This is the general implementation for Tpetra only.");
82 typedef Tpetra::Map<LocalOrdinal, GlobalOrdinal, Node> TpMap;
83 typedef Tpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpVector;
84 typedef Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node> TOE;
85 typedef Thyra::VectorBase<Scalar> ThyVecBase;
86 RCP<ThyVecBase> rgVec = Thyra::createMember<Scalar>(vectorSpace, std::string(
"label"));
98template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
99Teuchos::RCP<const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
100Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
101 toXpetra(Teuchos::RCP<
const Thyra::MultiVectorBase<Scalar>> v,
const Teuchos::RCP<
const Teuchos::Comm<int>>& comm) {
104 using Teuchos::rcp_dynamic_cast;
106 using ThyMultVecBase = Thyra::MultiVectorBase<Scalar>;
107 using ThyProdMultVecBase = Thyra::ProductMultiVectorBase<Scalar>;
108 using ThyUtils = Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
114 Teuchos::RCP<const ThyProdMultVecBase> thyProdVec = rcp_dynamic_cast<const ThyProdMultVecBase>(v);
115 if (thyProdVec != Teuchos::null) {
118 RCP<Map> fullMap = ThyUtils::toXpetra(v->range(), comm);
127 for (
int b = 0; b < thyProdVec->productSpace()->numBlocks(); ++b) {
131 xpBlockedMultVec->setMultiVector(b, xpBlockMV,
true );
135 typedef Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node> ConverterT;
136 typedef Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpMultVec;
137 typedef Xpetra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> XpTpMultVec;
138 typedef Thyra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> ThyTpMultVec;
139 typedef Thyra::SpmdMultiVectorBase<Scalar> ThySpmdMultVecBase;
143 TEUCHOS_TEST_FOR_EXCEPTION(thyraTpetraMultiVector == Teuchos::null, Xpetra::Exceptions::RuntimeError,
"toXpetra failed to convert provided multi vector to Thyra::TpetraMultiVector. This is the general implementation for Tpetra only.");
146 RCP<TpMultVec> tpNonConstMultVec = Teuchos::rcp_const_cast<TpMultVec>(tpMultVec);
148 xpMultVec =
rcp(
new XpTpMultVec(tpNonConstMultVec));
154template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
155Teuchos::RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
156Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
157 toXpetra(Teuchos::RCP<Thyra::MultiVectorBase<Scalar>> v,
const Teuchos::RCP<
const Teuchos::Comm<int>>& comm) {
158 Teuchos::RCP<const Thyra::MultiVectorBase<Scalar>> cv =
159 Teuchos::rcp_const_cast<const Thyra::MultiVectorBase<Scalar>>(v);
160 Teuchos::RCP<const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> r =
162 return Teuchos::rcp_const_cast<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(r);
165template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
166bool Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
167 isTpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op) {
171 bool bIsTpetra =
false;
172 Teuchos::RCP<const Thyra::TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpetra_op = Teuchos::rcp_dynamic_cast<const Thyra::TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(op);
177 Teuchos::rcp_dynamic_cast<
const Thyra::DefaultBlockedLinearOp<Scalar>>(op) == Teuchos::null) {
179 typedef Thyra::TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpetraLinearOp_t;
180 if (Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op) == Teuchos::null) {
181 std::cout <<
"ATTENTION: The dynamic cast to the TpetraLinearOp failed even though it should be a TpetraLinearOp." << std::endl;
182 std::cout <<
" If you are using Panzer or Stratimikos you might check that the template parameters are " << std::endl;
183 std::cout <<
" properly set!" << std::endl;
184 std::cout << Teuchos::rcp_dynamic_cast<const TpetraLinearOp_t>(op,
true) << std::endl;
192 if(bIsTpetra ==
false) {
193 Teuchos::RCP<const Thyra::BlockedLinearOpBase<Scalar> > ThyBlockedOp =
194 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(op);
195 if(ThyBlockedOp != Teuchos::null) {
197 Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > b00 =
198 ThyBlockedOp->getBlock(0,0);
200 bIsTpetra = isTpetra(b00);
208template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
209bool Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
210 isBlockedOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op) {
212 Teuchos::RCP<const Thyra::BlockedLinearOpBase<Scalar>> ThyBlockedOp =
213 Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar>>(op);
214 if (ThyBlockedOp != Teuchos::null) {
220template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
221Teuchos::RCP<const Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
222Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
223 toXpetra(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op) {
225 typedef Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node> TOE;
226 Teuchos::RCP<const Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraOp = TOE::getConstTpetraOperator(op);
230 Teuchos::RCP<const Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraRowMat = Teuchos::rcp_dynamic_cast<const Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(TpetraOp,
true);
231 Teuchos::RCP<const Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraCrsMat = Teuchos::rcp_dynamic_cast<const Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(TpetraRowMat,
true);
232 Teuchos::RCP<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraNcnstCrsMat = Teuchos::rcp_const_cast<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(TpetraCrsMat);
235 Teuchos::RCP<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xTpetraCrsMat =
236 Teuchos::rcp(
new Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>(TpetraNcnstCrsMat));
239 Teuchos::RCP<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpCrsMat =
240 Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xTpetraCrsMat,
true);
241 Teuchos::RCP<Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpCrsWrap =
242 Teuchos::rcp(
new Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>(xpCrsMat));
243 Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpMat =
244 Teuchos::rcp_dynamic_cast<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpCrsWrap,
true);
248 return Teuchos::null;
251template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
252Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
253Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
254 toXpetra(
const Teuchos::RCP<Thyra::LinearOpBase<Scalar>>& op) {
257 using Teuchos::rcp_const_cast;
258 using Teuchos::rcp_dynamic_cast;
261 typedef Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node> TOE;
262 typedef Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpetraOperator_t;
266 rcp_dynamic_cast<const Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(TpetraOp,
true);
268 rcp_dynamic_cast<const Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(TpetraRowMat,
true);
271 rcp(
new Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>(
272 rcp_const_cast<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(TpetraCrsMat)));
275 rcp_dynamic_cast<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xTpetraCrsMat,
true);
277 rcp(
new Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>(xpCrsMat));
279 rcp_dynamic_cast<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpCrsWrap,
true);
283 return Teuchos::null;
286template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
287Teuchos::RCP<const Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
288Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
289 toXpetraOperator(
const Teuchos::RCP<
const Thyra::LinearOpBase<Scalar>>& op) {
291 typedef Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node> TOE;
292 Teuchos::RCP<const Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraOp = TOE::getConstTpetraOperator(op);
294 auto nonConstTpetraOp = Teuchos::rcp_const_cast<Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(TpetraOp);
296 Teuchos::RCP<Xpetra::TpetraOperator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xTpetraOp =
297 Teuchos::rcp(
new Xpetra::TpetraOperator<Scalar, LocalOrdinal, GlobalOrdinal, Node>(nonConstTpetraOp));
300 Teuchos::RCP<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpOp =
301 Teuchos::rcp_dynamic_cast<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xTpetraOp,
true);
305 return Teuchos::null;
308template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
309Teuchos::RCP<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
310Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
311 toXpetraOperator(
const Teuchos::RCP<Thyra::LinearOpBase<Scalar>>& op) {
313 typedef Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node> TOE;
314 Teuchos::RCP<Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> TpetraOp = TOE::getTpetraOperator(op);
316 Teuchos::RCP<Xpetra::TpetraOperator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xTpetraOp =
317 Teuchos::rcp(
new Xpetra::TpetraOperator<Scalar, LocalOrdinal, GlobalOrdinal, Node>(TpetraOp));
320 Teuchos::RCP<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpOp =
321 Teuchos::rcp_dynamic_cast<Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xTpetraOp,
true);
325 return Teuchos::null;
328template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
329Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
330Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
331 toXpetra(
const Teuchos::RCP<Thyra::DiagonalLinearOpBase<Scalar>>& op) {
332 using Teuchos::rcp_const_cast;
333 using Teuchos::rcp_dynamic_cast;
338 using thyTpV = Thyra::TpetraVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
339 using tV = Tpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
340 if (!rcp_dynamic_cast<const thyTpV>(diag).
is_null()) {
341 RCP<const tV> tDiag = Thyra::TpetraOperatorVectorExtraction<Scalar, LocalOrdinal, GlobalOrdinal, Node>::getConstTpetraVector(diag);
342 if (!tDiag.is_null())
350template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
351Teuchos::RCP<const Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
352Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
353 toXpetra(
const Teuchos::RCP<
const Thyra::DiagonalLinearOpBase<Scalar>>& op) {
354 return toXpetra(Teuchos::rcp_const_cast<Thyra::DiagonalLinearOpBase<Scalar>>(op));
357template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
358Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>>
359Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
360 toThyra(Teuchos::RCP<
const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> map) {
361 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>> thyraMap = Teuchos::null;
365 if (bmap.is_null() ==
false) {
366 Teuchos::Array<Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>>> vecSpaces(bmap->getNumMaps());
367 for (
size_t i = 0; i < bmap->getNumMaps(); i++) {
369 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar>> vs =
370 Xpetra::ThyraUtils<Scalar, LO, GO, Node>::toThyra(bmap->getMap(i,
true));
374 thyraMap = Thyra::productVectorSpace<Scalar>(vecSpaces());
380 Teuchos::RCP<const Xpetra::TpetraMap<LocalOrdinal, GlobalOrdinal, Node>> tpetraMap = Teuchos::rcp_dynamic_cast<const Xpetra::TpetraMap<LocalOrdinal, GlobalOrdinal, Node>>(map);
381 if (tpetraMap == Teuchos::null)
382 throw Exceptions::BadCast(
"Xpetra::ThyraUtils::toThyra: Cast from Xpetra::Map to Xpetra::TpetraMap failed");
384 thyraMap = thyraTpetraMap;
390template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
391Teuchos::RCP<const Thyra::MultiVectorBase<Scalar>>
392Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
393 toThyraMultiVector(Teuchos::RCP<
const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> vec) {
396 auto thyTpMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(Teuchos::rcp_dynamic_cast<const TpetraMap>(vec->getMap())->getTpetra_Map());
399 auto thyMV =
rcp(
new Thyra::TpetraMultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>());
400 thyMV->initialize(thyTpMap, thyDomMap, tpMV);
407template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
408Teuchos::RCP<const Thyra::VectorBase<Scalar>>
409Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
410 toThyraVector(Teuchos::RCP<
const Xpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> vec) {
413 auto thyTpMap = Thyra::tpetraVectorSpace<Scalar, LocalOrdinal, GlobalOrdinal, Node>(Teuchos::rcp_dynamic_cast<const TpetraMap>(vec->getMap())->getTpetra_Map());
415 auto thyVec =
rcp(
new Thyra::TpetraVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>());
416 thyVec->initialize(thyTpMap, tpVec);
423template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
424void Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
425 updateThyra(Teuchos::RCP<
const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> source, Teuchos::RCP<
const Xpetra::MapExtractor<Scalar, LocalOrdinal, GlobalOrdinal, Node>> mapExtractor,
const Teuchos::RCP<Thyra::MultiVectorBase<Scalar>>& target) {
428 using Teuchos::rcp_dynamic_cast;
429 typedef Thyra::VectorSpaceBase<Scalar> ThyVecSpaceBase;
430 typedef Thyra::SpmdVectorSpaceBase<Scalar> ThySpmdVecSpaceBase;
431 typedef Thyra::MultiVectorBase<Scalar> ThyMultVecBase;
434 typedef Thyra::ProductMultiVectorBase<Scalar> ThyProdMultVecBase;
438 if (prodTarget != Teuchos::null) {
440 if (bSourceVec.is_null() ==
true) {
444 TEUCHOS_TEST_FOR_EXCEPTION(mapExtractor == Teuchos::null, std::logic_error,
"Found a Thyra product vector, but user did not provide an Xpetra::MapExtractor.");
445 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.");
447 for (
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
449 RCP<MultiVector> xpSubBlock = mapExtractor->ExtractVector(source, bbb,
false);
452 Teuchos::RCP<ThyMultVecBase> thySubBlock = prodTarget->getNonconstMultiVectorBlock(bbb);
455 const LocalOrdinal localOffset = (mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0);
456 const LocalOrdinal localSubDim = (mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : vs->dim());
458 Teuchos::rcp(
new Thyra::DetachedMultiVectorView<Scalar>(*thySubBlock, Teuchos::Range1D(localOffset, localOffset + localSubDim - 1)));
461 for (
size_t j = 0; j < xpSubBlock->getNumVectors(); ++j) {
462 Teuchos::ArrayRCP<const Scalar> xpData = xpSubBlock->getData(j);
465 for (LocalOrdinal i = 0; i < localSubDim; ++i) {
466 (*thyData)(i, j) = xpData[i];
473 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.");
475 for (
int bbb = 0; bbb < prodTarget->productSpace()->numBlocks(); ++bbb) {
479 Teuchos::RCP<const ThyMultVecBase> thyXpSubBlock = toThyraMultiVector(xpSubBlock);
482 Teuchos::RCP<ThyMultVecBase> thySubBlock = prodTarget->getNonconstMultiVectorBlock(bbb);
483 Thyra::assign(thySubBlock.
ptr(), *thyXpSubBlock);
492 TEUCHOS_TEST_FOR_EXCEPTION(mpi_vs == Teuchos::null, std::logic_error,
"Failed to cast Thyra::VectorSpaceBase to Thyra::SpmdVectorSpaceBase.");
493 const LocalOrdinal localOffset = (mpi_vs != Teuchos::null ? mpi_vs->localOffset() : 0);
494 const LocalOrdinal localSubDim = (mpi_vs != Teuchos::null ? mpi_vs->localSubDim() : target->range()->dim());
496 Teuchos::rcp(
new Thyra::DetachedMultiVectorView<Scalar>(*target, Teuchos::Range1D(localOffset, localOffset + localSubDim - 1)));
499 for (
size_t j = 0; j < source->getNumVectors(); ++j) {
500 Teuchos::ArrayRCP<const Scalar> xpData = source->getData(j);
502 for (LocalOrdinal i = 0; i < localSubDim; ++i) {
503 (*thyData)(i, j) = xpData[i];
509template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
510Teuchos::RCP<const Thyra::LinearOpBase<Scalar>>
511Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
512 toThyra(
const Teuchos::RCP<
const Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& mat) {
514 Teuchos::RCP<const Thyra::LinearOpBase<Scalar>> thyraOp = Teuchos::null;
518 Teuchos::RCP<const Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpetraMat = Teuchos::rcp_dynamic_cast<const Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(mat);
519 if (tpetraMat != Teuchos::null) {
521 Teuchos::RCP<const Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xTpCrsMat = Teuchos::rcp_dynamic_cast<const Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(mat,
true);
522 Teuchos::RCP<const Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpCrsMat = xTpCrsMat->getTpetra_CrsMatrix();
525 Teuchos::RCP<const Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpRowMat = Teuchos::rcp_dynamic_cast<const Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(tpCrsMat,
true);
526 Teuchos::RCP<const Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpOperator = Teuchos::rcp_dynamic_cast<const Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(tpRowMat,
true);
528 thyraOp = Thyra::createConstLinearOp(tpOperator);
531 TEUCHOS_TEST_FOR_EXCEPTION(
true, Xpetra::Exceptions::RuntimeError,
"Cast to Tpetra::CrsMatrix failed. Assume matrix should be Epetra then. No Epetra available");
536template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
537Teuchos::RCP<Thyra::LinearOpBase<Scalar>>
538Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
539 toThyra(
const Teuchos::RCP<Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& mat) {
541 Teuchos::RCP<Thyra::LinearOpBase<Scalar>> thyraOp = Teuchos::null;
545 Teuchos::RCP<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpetraMat = Teuchos::rcp_dynamic_cast<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(mat);
546 if (tpetraMat != Teuchos::null) {
548 Teuchos::RCP<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xTpCrsMat = Teuchos::rcp_dynamic_cast<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(mat,
true);
549 Teuchos::RCP<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpCrsMat = xTpCrsMat->getTpetra_CrsMatrixNonConst();
552 Teuchos::RCP<Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpRowMat = Teuchos::rcp_dynamic_cast<Tpetra::RowMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(tpCrsMat,
true);
553 Teuchos::RCP<Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpOperator = Teuchos::rcp_dynamic_cast<Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(tpRowMat,
true);
555 thyraOp = Thyra::createLinearOp(tpOperator);
559 TEUCHOS_TEST_FOR_EXCEPTION(
true, Xpetra::Exceptions::RuntimeError,
"Cast to TpetraCrsMatrix failed. Guess, matrix should be Epetra then, but no Epetra available.");
564template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
565Teuchos::RCP<Thyra::LinearOpBase<Scalar>>
566Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
567 toThyra(
const Teuchos::RCP<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& mat) {
568 int nRows = mat->Rows();
569 int nCols = mat->Cols();
571 Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> Ablock = mat->getInnermostCrsMatrix();
572 Teuchos::RCP<Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>> Ablock_wrap = Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(Ablock);
575 Teuchos::RCP<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> tpetraMat = Teuchos::rcp_dynamic_cast<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(Ablock_wrap->getCrsMatrix());
576 if (tpetraMat != Teuchos::null) {
578 Teuchos::RCP<Thyra::PhysicallyBlockedLinearOpBase<Scalar>> blockMat =
579 Thyra::defaultBlockedLinearOp<Scalar>();
581 blockMat->beginBlockFill(nRows, nCols);
583 for (
int r = 0; r < nRows; ++r) {
584 for (
int c = 0; c < nCols; ++c) {
585 Teuchos::RCP<Matrix> xpmat = mat->getMatrix(r, c);
587 if (xpmat == Teuchos::null)
continue;
589 Teuchos::RCP<Thyra::LinearOpBase<Scalar>> thBlock = Teuchos::null;
592 Teuchos::RCP<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> xpblock =
593 Teuchos::rcp_dynamic_cast<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(xpmat);
594 if (xpblock != Teuchos::null) {
595 if (xpblock->Rows() == 1 && xpblock->Cols() == 1) {
597 Teuchos::RCP<CrsMatrixWrap> xpwrap = Teuchos::rcp_dynamic_cast<CrsMatrixWrap>(xpblock->getCrsMatrix());
599 thBlock = Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::toThyra(xpwrap->getCrsMatrix());
602 thBlock = Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::toThyra(xpblock);
606 Teuchos::RCP<CrsMatrixWrap> xpwrap = Teuchos::rcp_dynamic_cast<CrsMatrixWrap>(xpmat);
608 thBlock = Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::toThyra(xpwrap->getCrsMatrix());
611 blockMat->setBlock(r, c, thBlock);
615 blockMat->endBlockFill();
620 TEUCHOS_TEST_FOR_EXCEPTION(
true, Xpetra::Exceptions::RuntimeError,
"Cast to TpetraCrsMatrix failed. Guess, matrix should be Epetra then, but no Epetra available.");
Exception indicating invalid cast attempted.
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_ASSERT(assertion_test)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
bool is_null(const std::shared_ptr< T > &p)
TypeTo as(const TypeFrom &t)
#define TEUCHOS_UNREACHABLE_RETURN(dummyReturnVal)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > createLocalMapWithNode(const size_t numElements, const Teuchos::RCP< const Teuchos::Comm< int > > &comm)
const RCP< Map< LocalOrdinal, GlobalOrdinal, Node > > toXpetraNonConst(const RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > &map)
RCP< const CrsGraph< LocalOrdinal, GlobalOrdinal, Node > > toXpetra(RCP< const Tpetra::CrsGraph< LocalOrdinal, GlobalOrdinal, Node > > graph)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)