73 typedef Thyra::MultiVectorBase<ScalarType> TMVB;
74 typedef Teuchos::ScalarTraits<ScalarType> ST;
75 typedef typename ST::magnitudeType magType;
76#if defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS) && defined(HAVE_BELOS_TPETRA)
77 using TpMap = Tpetra::Map<Tpetra::MultiVector<>::local_ordinal_type,
78 Tpetra::MultiVector<>::global_ordinal_type,
79 Tpetra::MultiVector<>::node_type>;
80 using TpMV = Tpetra::MultiVector<ScalarType, Tpetra::MultiVector<>::local_ordinal_type,
81 Tpetra::MultiVector<>::global_ordinal_type,
82 Tpetra::MultiVector<>::node_type>;
83 using Extraction = Thyra::TpetraOperatorVectorExtraction<ScalarType,
84 Tpetra::MultiVector<>::local_ordinal_type,
85 Tpetra::MultiVector<>::global_ordinal_type,
86 Tpetra::MultiVector<>::node_type>;
89 static Teuchos::RCP<TMVB> BuildProductMultiVectorMaybe(Teuchos::RCP<const TMVB> &mv_rcp,
const int numvecs) {
90 auto pmv_rcp = Teuchos::rcp_dynamic_cast<const Thyra::DefaultProductMultiVector<ScalarType>>(mv_rcp);
91 if (!pmv_rcp.is_null()) {
92 auto ps = Teuchos::rcp_dynamic_cast<const Thyra::DefaultProductVectorSpace<ScalarType>>(pmv_rcp->range());
93 const int numBlocks = ps->numBlocks();
94 Teuchos::Array<Teuchos::RCP<Thyra::MultiVectorBase<ScalarType>>> multiVecs;
95 for (
int k = 0; k < numBlocks; ++k) {
96 auto vs = ps->getBlock(k);
97 Teuchos::RCP<const TpMap> map = Extraction::getTpetraMap(vs);
100 auto tp_mv = impl::getMultiVectorFromPool<ScalarType>(map, numvecs);
101 auto thy_mv = createMultiVector(tp_mv, vs);
102 multiVecs.push_back(thy_mv);
104 if (multiVecs.size() == numBlocks)
105 return Thyra::defaultProductMultiVector<ScalarType>(ps, multiVecs);
107 return Teuchos::null;
120 static Teuchos::RCP<TMVB>
Clone(
const TMVB& mv,
const int numvecs )
122 Teuchos::RCP<TMVB> c;
123#if defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS) && defined(HAVE_BELOS_TPETRA)
124 auto mv_rcp = Teuchos::rcpFromRef(mv);
126 Teuchos::RCP<const TpMV> X = Extraction::getConstTpetraMultiVector(mv_rcp);
128 c = Thyra::createMultiVector(X_copy);
129 }
catch (std::logic_error&)
132#if defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS) && defined(HAVE_BELOS_TPETRA)
133 c = BuildProductMultiVectorMaybe(mv_rcp, numvecs);
137 c = Thyra::createMembers(mv.range(), numvecs);
149 Teuchos::RCP< TMVB > cc;
150#if defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS) && defined(HAVE_BELOS_TPETRA)
151 auto mv_rcp = Teuchos::rcpFromRef(mv);
153 Teuchos::RCP<const TpMV> X = Extraction::getConstTpetraMultiVector(mv_rcp);
155 cc = Thyra::createMultiVector(X_copy);
156 }
catch (std::logic_error&)
159 int numvecs = mv.domain()->dim();
161#if defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS) && defined(HAVE_BELOS_TPETRA)
162 cc = BuildProductMultiVectorMaybe(mv_rcp, numvecs);
166 cc = Thyra::createMembers(mv.range(), numvecs);
169 Thyra::assign(cc.ptr(), mv);
179 static Teuchos::RCP<TMVB>
CloneCopy(
const TMVB& mv,
const std::vector<int>& index )
181 Teuchos::RCP<TMVB> cc;
182#if defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS) && defined(HAVE_BELOS_TPETRA)
183 auto mv_rcp = Teuchos::rcpFromRef(mv);
185 Teuchos::RCP<const TpMV> X = Extraction::getConstTpetraMultiVector(mv_rcp);
187 cc = Thyra::createMultiVector(X_copy);
188 }
catch (std::logic_error&)
191 int numvecs = index.size();
193#if defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS) && defined(HAVE_BELOS_TPETRA)
194 cc = BuildProductMultiVectorMaybe(mv_rcp, numvecs);
198 cc = Thyra::createMembers(mv.range(), numvecs);
201 Teuchos::RCP<const TMVB> view = mv.subView(index);
203 Thyra::assign(cc.ptr(), *view);
208 static Teuchos::RCP<TMVB>
209 CloneCopy (
const TMVB& mv,
const Teuchos::Range1D& index)
211 Teuchos::RCP<TMVB> cc;
212#if defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS) && defined(HAVE_BELOS_TPETRA)
213 auto mv_rcp = Teuchos::rcpFromRef(mv);
215 Teuchos::RCP<const TpMV> X = Extraction::getConstTpetraMultiVector(mv_rcp);
217 cc = Thyra::createMultiVector(X_copy);
218 }
catch (std::logic_error&)
221 const int numVecs = index.size();
223#if defined(HAVE_STRATIMIKOS_THYRATPETRAADAPTERS) && defined(HAVE_BELOS_TPETRA)
224 cc = BuildProductMultiVectorMaybe(mv_rcp, numVecs);
228 cc = Thyra::createMembers(mv.range(), numVecs);
231 Teuchos::RCP<const TMVB> view = mv.subView (index);
233 Thyra::assign (cc.ptr(), *view);
245 int numvecs = index.size();
261 for (
int i=0; i<numvecs; i++) {
262 if (lb+i != index[i]) contig =
false;
265 Teuchos::RCP< TMVB > cc;
267 const Thyra::Range1D rng(lb,lb+numvecs-1);
269 cc = mv.subView(rng);
273 cc = mv.subView(index);
278 static Teuchos::RCP<TMVB>
286 return mv.subView (index);
295 static Teuchos::RCP<const TMVB>
CloneView(
const TMVB& mv,
const std::vector<int>& index )
297 int numvecs = index.size();
313 for (
int i=0; i<numvecs; i++) {
314 if (lb+i != index[i]) contig =
false;
317 Teuchos::RCP< const TMVB > cc;
319 const Thyra::Range1D rng(lb,lb+numvecs-1);
321 cc = mv.subView(rng);
325 cc = mv.subView(index);
330 static Teuchos::RCP<const TMVB>
331 CloneView (
const TMVB& mv,
const Teuchos::Range1D& index)
338 return mv.subView (index);
348 return Teuchos::as<ptrdiff_t>(mv.range()->dim());
353 {
return mv.domain()->dim(); }
363 const Teuchos::SerialDenseMatrix<int,ScalarType>& B,
364 const ScalarType beta, TMVB& mv )
366 using Teuchos::arrayView;
using Teuchos::arcpFromArrayView;
367 STRATIMIKOS_TIME_MONITOR(
"Belos::MVT::MvTimesMatAddMv");
369 const int m = B.numRows();
370 const int n = B.numCols();
372 if ((m == 1) && (n == 1)) {
373 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::inoutArg;
374 const ScalarType alphaNew = alpha * B(0, 0);
375 Thyra::linear_combination<ScalarType>(tuple(alphaNew)(), tuple(ptrInArg(A))(), beta, inoutArg(mv));
378 auto vs = A.domain();
380 Teuchos::RCP< const TMVB >
381 B_thyra = vs->createCachedMembersView(
384 arcpFromArrayView(arrayView(&B(0,0), B.stride()*B.numCols())), B.stride()
387 Thyra::apply<ScalarType>(A, Thyra::NOTRANS, *B_thyra, Teuchos::outArg(mv), alpha, beta);
393 static void MvAddMv(
const ScalarType alpha,
const TMVB& A,
394 const ScalarType beta,
const TMVB& B, TMVB& mv )
396 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::inoutArg;
397 STRATIMIKOS_TIME_MONITOR(
"Belos::MVT::MvAddMv");
399 Thyra::linear_combination<ScalarType>(
400 tuple(alpha, beta)(), tuple(ptrInArg(A), ptrInArg(B))(), Teuchos::ScalarTraits<ScalarType>::zero(), inoutArg(mv));
405 static void MvScale ( TMVB& mv,
const ScalarType alpha )
407 STRATIMIKOS_TIME_MONITOR(
"Belos::MVT::MvScale");
409 Thyra::scale(alpha, Teuchos::inoutArg(mv));
414 static void MvScale (TMVB& mv,
const std::vector<ScalarType>& alpha)
416 STRATIMIKOS_TIME_MONITOR(
"Belos::MVT::MvScale");
418 for (
unsigned int i=0; i<alpha.size(); i++) {
419 Thyra::scale<ScalarType> (alpha[i], mv.col(i).ptr());
425 static void MvTransMv(
const ScalarType alpha,
const TMVB& A,
const TMVB& mv,
426 Teuchos::SerialDenseMatrix<int,ScalarType>& B )
428 using Teuchos::arrayView;
using Teuchos::arcpFromArrayView;
429 STRATIMIKOS_TIME_MONITOR(
"Belos::MVT::MvTransMv");
432 int m = A.domain()->dim();
433 int n = mv.domain()->dim();
434 auto vs = A.domain();
437 B_thyra = vs->createCachedMembersView(
440 arcpFromArrayView(arrayView(&B(0,0), B.stride()*B.numCols())), B.stride()
444 Thyra::apply<ScalarType>(A, Thyra::CONJTRANS, mv, B_thyra.ptr(), alpha);
450 static void MvDot(
const TMVB& mv,
const TMVB& A, std::vector<ScalarType>& b )
452 STRATIMIKOS_TIME_MONITOR(
"Belos::MVT::MvDot");
454 Thyra::dots(mv, A, Teuchos::arrayViewFromVector(b));
465 static void MvNorm(
const TMVB& mv, std::vector<magType>& normvec,
467 STRATIMIKOS_TIME_MONITOR(
"Belos::MVT::MvNorm");
470 Thyra::norms_2(mv, Teuchos::arrayViewFromVector(normvec));
472 Thyra::norms_1(mv, Teuchos::arrayViewFromVector(normvec));
474 Thyra::norms_inf(mv, Teuchos::arrayViewFromVector(normvec));
476 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
477 "Belos::MultiVecTraits::MvNorm (Thyra specialization): "
478 "invalid norm type. Must be either TwoNorm, OneNorm or InfNorm");
488 static void SetBlock(
const TMVB& A,
const std::vector<int>& index, TMVB& mv )
491 int numvecs = index.size();
492 std::vector<int> indexA(numvecs);
493 int numAcols = A.domain()->dim();
494 for (
int i=0; i<numvecs; i++) {
499 if ( numAcols < numvecs ) {
504 else if ( numAcols > numvecs ) {
506 indexA.resize( numAcols );
509 Teuchos::RCP< const TMVB > relsource = A.subView(indexA);
511 Teuchos::RCP< TMVB > reldest = mv.subView(index);
513 Thyra::assign(reldest.ptr(), *relsource);
517 SetBlock (
const TMVB& A,
const Teuchos::Range1D& index, TMVB& mv)
519 const int numColsA = A.domain()->dim();
520 const int numColsMv = mv.domain()->dim();
522 const bool validIndex = index.lbound() >= 0 && index.ubound() < numColsMv;
524 const bool validSource = index.size() <= numColsA;
526 if (! validIndex || ! validSource)
528 std::ostringstream os;
529 os <<
"Belos::MultiVecTraits<Scalar, Thyra::MultiVectorBase<Scalar> "
530 ">::SetBlock(A, [" << index.lbound() <<
", " << index.ubound()
532 TEUCHOS_TEST_FOR_EXCEPTION(index.lbound() < 0, std::invalid_argument,
533 os.str() <<
"Range lower bound must be nonnegative.");
534 TEUCHOS_TEST_FOR_EXCEPTION(index.ubound() >= numColsMv, std::invalid_argument,
535 os.str() <<
"Range upper bound must be less than "
536 "the number of columns " << numColsA <<
" in the "
537 "'mv' output argument.");
538 TEUCHOS_TEST_FOR_EXCEPTION(index.size() > numColsA, std::invalid_argument,
539 os.str() <<
"Range must have no more elements than"
540 " the number of columns " << numColsA <<
" in the "
541 "'A' input argument.");
542 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Should never get here!");
548 Teuchos::RCP<TMVB> mv_view;
549 if (index.lbound() == 0 && index.ubound()+1 == numColsMv)
550 mv_view = Teuchos::rcpFromRef (mv);
552 mv_view = mv.subView (index);
557 Teuchos::RCP<const TMVB> A_view;
558 if (index.size() == numColsA)
559 A_view = Teuchos::rcpFromRef (A);
561 A_view = A.subView (Teuchos::Range1D(0, index.size()-1));
564 Thyra::assign(mv_view.ptr(), *A_view);
568 Assign (
const TMVB& A, TMVB& mv)
570 STRATIMIKOS_TIME_MONITOR(
"Belos::MVT::Assign");
572 const int numColsA = A.domain()->dim();
573 const int numColsMv = mv.domain()->dim();
574 if (numColsA > numColsMv)
576 std::ostringstream os;
577 os <<
"Belos::MultiVecTraits<Scalar, Thyra::MultiVectorBase<Scalar>"
578 " >::Assign(A, mv): ";
579 TEUCHOS_TEST_FOR_EXCEPTION(numColsA > numColsMv, std::invalid_argument,
580 os.str() <<
"Input multivector 'A' has "
581 << numColsA <<
" columns, but output multivector "
582 "'mv' has only " << numColsMv <<
" columns.");
583 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Should never get here!");
586 if (numColsA == numColsMv) {
587 Thyra::assign (Teuchos::outArg (mv), A);
589 Teuchos::RCP<TMVB> mv_view =
591 Thyra::assign (mv_view.ptr(), A);
601 Thyra::randomize<ScalarType>(
602 -Teuchos::ScalarTraits<ScalarType>::one(),
603 Teuchos::ScalarTraits<ScalarType>::one(),
604 Teuchos::outArg(mv));
609 MvInit (TMVB& mv, ScalarType alpha = Teuchos::ScalarTraits<ScalarType>::zero())
611 Thyra::assign (Teuchos::outArg (mv), alpha);
621 static void MvPrint(
const TMVB& mv, std::ostream& os )
622 { os << describe(mv,Teuchos::VERB_EXTREME); }
626#ifdef HAVE_BELOS_TSQR