52#ifndef BELOS_THYRA_ADAPTER_HPP
53#define BELOS_THYRA_ADAPTER_HPP
55#include "Stratimikos_Config.h"
56#include "BelosConfigDefs.hpp"
57#include "BelosMultiVecTraits.hpp"
58#include "BelosOperatorTraits.hpp"
60#include <Thyra_DetachedMultiVectorView.hpp>
61#include <Thyra_MultiVectorBase.hpp>
62#include <Thyra_MultiVectorStdOps.hpp>
67#ifdef HAVE_STRATIMIKOS_BELOS_TIMERS
68# include <Teuchos_TimeMonitor.hpp>
70# define STRATIMIKOS_TIME_MONITOR(NAME) \
71 Teuchos::TimeMonitor tM(*Teuchos::TimeMonitor::getNewTimer(std::string(NAME)))
75# define STRATIMIKOS_TIME_MONITOR(NAME)
93 template<
class ScalarType>
94 class MultiVecTraits< ScalarType,
Thyra::MultiVectorBase<ScalarType> >
97 typedef Thyra::MultiVectorBase<ScalarType>
TMVB;
98 typedef Teuchos::ScalarTraits<ScalarType>
ST;
99 typedef typename ST::magnitudeType
magType;
110 static Teuchos::RCP<TMVB>
Clone(
const TMVB& mv,
const int numvecs )
112 Teuchos::RCP<TMVB> c = Thyra::createMembers( mv.range(), numvecs );
122 int numvecs = mv.domain()->dim();
124 Teuchos::RCP< TMVB > cc = Thyra::createMembers( mv.range(), numvecs );
126 Thyra::assign(cc.ptr(), mv);
135 static Teuchos::RCP<TMVB>
CloneCopy(
const TMVB& mv,
const std::vector<int>& index )
137 int numvecs = index.size();
139 Teuchos::RCP<TMVB> cc = Thyra::createMembers( mv.range(), numvecs );
141 Teuchos::RCP<const TMVB> view = mv.subView(index);
143 Thyra::assign(cc.ptr(), *view);
147 static Teuchos::RCP<TMVB>
150 const int numVecs = index.size();
152 Teuchos::RCP<TMVB> cc = Thyra::createMembers (mv.range(), numVecs);
154 Teuchos::RCP<const TMVB> view = mv.subView (index);
156 Thyra::assign (cc.ptr(), *view);
167 int numvecs = index.size();
183 for (
int i=0; i<numvecs; i++) {
184 if (lb+i != index[i]) contig =
false;
187 Teuchos::RCP< TMVB > cc;
189 const Thyra::Range1D rng(lb,lb+numvecs-1);
191 cc = mv.subView(rng);
195 cc = mv.subView(index);
200 static Teuchos::RCP<TMVB>
208 return mv.subView (index);
217 static Teuchos::RCP<const TMVB>
CloneView(
const TMVB& mv,
const std::vector<int>& index )
219 int numvecs = index.size();
235 for (
int i=0; i<numvecs; i++) {
236 if (lb+i != index[i]) contig =
false;
239 Teuchos::RCP< const TMVB > cc;
241 const Thyra::Range1D rng(lb,lb+numvecs-1);
243 cc = mv.subView(rng);
247 cc = mv.subView(index);
252 static Teuchos::RCP<const TMVB>
260 return mv.subView (index);
270 return Teuchos::as<ptrdiff_t>(mv.range()->dim());
275 {
return mv.domain()->dim(); }
285 const Teuchos::SerialDenseMatrix<int,ScalarType>& B,
286 const ScalarType beta,
TMVB& mv )
288 using Teuchos::arrayView;
using Teuchos::arcpFromArrayView;
291 const int m = B.numRows();
292 const int n = B.numCols();
293 auto vs = A.domain();
295 Teuchos::RCP< const TMVB >
296 B_thyra = vs->createCachedMembersView(
299 arcpFromArrayView(arrayView(&B(0,0), B.stride()*B.numCols())), B.stride()
303 Thyra::apply<ScalarType>(A, Thyra::NOTRANS, *B_thyra, Teuchos::outArg(mv), alpha, beta);
309 const ScalarType beta,
const TMVB& B,
TMVB& mv )
311 using Teuchos::tuple;
using Teuchos::ptrInArg;
using Teuchos::inoutArg;
314 Thyra::linear_combination<ScalarType>(
315 tuple(alpha, beta)(), tuple(ptrInArg(A), ptrInArg(B))(), Teuchos::ScalarTraits<ScalarType>::zero(), inoutArg(mv));
324 Thyra::scale(alpha, Teuchos::inoutArg(mv));
329 static void MvScale (
TMVB& mv,
const std::vector<ScalarType>& alpha)
333 for (
unsigned int i=0; i<alpha.size(); i++) {
334 Thyra::scale<ScalarType> (alpha[i], mv.col(i).ptr());
341 Teuchos::SerialDenseMatrix<int,ScalarType>& B )
343 using Teuchos::arrayView;
using Teuchos::arcpFromArrayView;
347 int m = A.domain()->dim();
348 int n = mv.domain()->dim();
349 auto vs = A.domain();
352 B_thyra = vs->createCachedMembersView(
355 arcpFromArrayView(arrayView(&B(0,0), B.stride()*B.numCols())), B.stride()
358 Thyra::apply<ScalarType>(A, Thyra::CONJTRANS, mv, B_thyra.ptr(), alpha);
364 static void MvDot(
const TMVB& mv,
const TMVB& A, std::vector<ScalarType>& b )
368 Thyra::dots(mv, A, Teuchos::arrayViewFromVector(b));
379 static void MvNorm(
const TMVB& mv, std::vector<magType>& normvec,
380 NormType type = TwoNorm ) {
384 Thyra::norms_2(mv, Teuchos::arrayViewFromVector(normvec));
385 else if(type == OneNorm)
386 Thyra::norms_1(mv, Teuchos::arrayViewFromVector(normvec));
387 else if(type == InfNorm)
388 Thyra::norms_inf(mv, Teuchos::arrayViewFromVector(normvec));
390 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
391 "Belos::MultiVecTraits::MvNorm (Thyra specialization): "
392 "invalid norm type. Must be either TwoNorm, OneNorm or InfNorm");
405 int numvecs = index.size();
406 std::vector<int> indexA(numvecs);
407 int numAcols = A.domain()->dim();
408 for (
int i=0; i<numvecs; i++) {
413 if ( numAcols < numvecs ) {
418 else if ( numAcols > numvecs ) {
420 indexA.resize( numAcols );
423 Teuchos::RCP< const TMVB > relsource = A.subView(indexA);
425 Teuchos::RCP< TMVB > reldest = mv.subView(index);
427 Thyra::assign(reldest.ptr(), *relsource);
433 const int numColsA = A.domain()->dim();
434 const int numColsMv = mv.domain()->dim();
436 const bool validIndex = index.lbound() >= 0 && index.ubound() < numColsMv;
438 const bool validSource = index.size() <= numColsA;
440 if (! validIndex || ! validSource)
442 std::ostringstream os;
443 os <<
"Belos::MultiVecTraits<Scalar, Thyra::MultiVectorBase<Scalar> "
444 ">::SetBlock(A, [" << index.lbound() <<
", " << index.ubound()
446 TEUCHOS_TEST_FOR_EXCEPTION(index.lbound() < 0, std::invalid_argument,
447 os.str() <<
"Range lower bound must be nonnegative.");
448 TEUCHOS_TEST_FOR_EXCEPTION(index.ubound() >= numColsMv, std::invalid_argument,
449 os.str() <<
"Range upper bound must be less than "
450 "the number of columns " << numColsA <<
" in the "
451 "'mv' output argument.");
452 TEUCHOS_TEST_FOR_EXCEPTION(index.size() > numColsA, std::invalid_argument,
453 os.str() <<
"Range must have no more elements than"
454 " the number of columns " << numColsA <<
" in the "
455 "'A' input argument.");
456 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Should never get here!");
462 Teuchos::RCP<TMVB> mv_view;
463 if (index.lbound() == 0 && index.ubound()+1 == numColsMv)
464 mv_view = Teuchos::rcpFromRef (mv);
466 mv_view = mv.subView (index);
471 Teuchos::RCP<const TMVB> A_view;
472 if (index.size() == numColsA)
473 A_view = Teuchos::rcpFromRef (A);
475 A_view = A.subView (Teuchos::Range1D(0, index.size()-1));
478 Thyra::assign(mv_view.ptr(), *A_view);
486 const int numColsA = A.domain()->dim();
487 const int numColsMv = mv.domain()->dim();
488 if (numColsA > numColsMv)
490 std::ostringstream os;
491 os <<
"Belos::MultiVecTraits<Scalar, Thyra::MultiVectorBase<Scalar>"
492 " >::Assign(A, mv): ";
493 TEUCHOS_TEST_FOR_EXCEPTION(numColsA > numColsMv, std::invalid_argument,
494 os.str() <<
"Input multivector 'A' has "
495 << numColsA <<
" columns, but output multivector "
496 "'mv' has only " << numColsMv <<
" columns.");
497 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Should never get here!");
500 if (numColsA == numColsMv) {
501 Thyra::assign (Teuchos::outArg (mv), A);
503 Teuchos::RCP<TMVB> mv_view =
505 Thyra::assign (mv_view.ptr(), A);
515 Thyra::randomize<ScalarType>(
516 -Teuchos::ScalarTraits<ScalarType>::one(),
517 Teuchos::ScalarTraits<ScalarType>::one(),
518 Teuchos::outArg(mv));
523 MvInit (
TMVB& mv, ScalarType alpha = Teuchos::ScalarTraits<ScalarType>::zero())
525 Thyra::assign (Teuchos::outArg (mv), alpha);
536 { os << describe(mv,Teuchos::VERB_EXTREME); }
540#ifdef HAVE_BELOS_TSQR
563 template<
class ScalarType>
564 class OperatorTraits <ScalarType,
565 Thyra::MultiVectorBase<ScalarType>,
566 Thyra::LinearOpBase<ScalarType> >
569 typedef Thyra::MultiVectorBase<ScalarType>
TMVB;
570 typedef Thyra::LinearOpBase<ScalarType>
TLOB;
592 ETrans trans = NOTRANS)
594 Thyra::EOpTransp whichOp;
601 if (trans == NOTRANS)
602 whichOp = Thyra::NOTRANS;
603 else if (trans == TRANS)
604 whichOp = Thyra::TRANS;
605 else if (trans == CONJTRANS)
606 whichOp = Thyra::CONJTRANS;
608 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
609 "Belos::OperatorTraits::Apply (Thyra specialization): "
610 "'trans' argument must be neither NOTRANS=" << NOTRANS
611 <<
", TRANS=" << TRANS <<
", or CONJTRANS=" << CONJTRANS
612 <<
", but instead has an invalid value of " << trans <<
".");
613 Thyra::apply<ScalarType>(Op, whichOp, x, Teuchos::outArg(y));
619 typedef Teuchos::ScalarTraits<ScalarType> STS;
628 return Op.opSupported (Thyra::TRANS) &&
629 (! STS::isComplex || Op.opSupported (Thyra::CONJTRANS));
#define STRATIMIKOS_TIME_MONITOR(NAME)
static void MvPrint(const TMVB &mv, std::ostream &os)
Print the mv multi-stdvector to the os output stream.
Thyra::MultiVectorBase< ScalarType > TMVB
ST::magnitudeType magType
static void SetBlock(const TMVB &A, const std::vector< int > &index, TMVB &mv)
Copy the vectors in A to a set of vectors in mv indicated by the indices given in index.
static void MvAddMv(const ScalarType alpha, const TMVB &A, const ScalarType beta, const TMVB &B, TMVB &mv)
Replace mv with .
static int GetNumberVecs(const TMVB &mv)
Obtain the number of vectors in mv.
static Teuchos::RCP< TMVB > CloneCopy(const TMVB &mv)
Creates a new MultiVectorBase and copies contents of mv into the new std::vector (deep copy).
static Teuchos::RCP< const TMVB > CloneView(const TMVB &mv, const Teuchos::Range1D &index)
static void SetBlock(const TMVB &A, const Teuchos::Range1D &index, TMVB &mv)
Teuchos::ScalarTraits< ScalarType > ST
static void Assign(const TMVB &A, TMVB &mv)
static ptrdiff_t GetGlobalLength(const TMVB &mv)
Obtain the std::vector length of mv.
static void MvDot(const TMVB &mv, const TMVB &A, std::vector< ScalarType > &b)
Compute a std::vector b where the components are the individual dot-products of the i-th columns of A...
static Teuchos::RCP< TMVB > CloneCopy(const TMVB &mv, const std::vector< int > &index)
Creates a new MultiVectorBase and copies the selected contents of mv into the new std::vector (deep c...
static Teuchos::RCP< TMVB > CloneCopy(const TMVB &mv, const Teuchos::Range1D &index)
static Teuchos::RCP< TMVB > CloneViewNonConst(TMVB &mv, const std::vector< int > &index)
Creates a new MultiVectorBase that shares the selected contents of mv (shallow copy).
static Teuchos::RCP< TMVB > CloneViewNonConst(TMVB &mv, const Teuchos::Range1D &index)
static Teuchos::RCP< TMVB > Clone(const TMVB &mv, const int numvecs)
Creates a new empty MultiVectorBase containing numvecs columns.
static Teuchos::RCP< const TMVB > CloneView(const TMVB &mv, const std::vector< int > &index)
Creates a new const MultiVectorBase that shares the selected contents of mv (shallow copy).
static void MvScale(TMVB &mv, const ScalarType alpha)
Scale each element of the vectors in *this with alpha.
static void MvTransMv(const ScalarType alpha, const TMVB &A, const TMVB &mv, Teuchos::SerialDenseMatrix< int, ScalarType > &B)
Compute a dense matrix B through the matrix-matrix multiply .
static void MvScale(TMVB &mv, const std::vector< ScalarType > &alpha)
Scale each element of the i-th vector in *this with alpha[i].
static void MvTimesMatAddMv(const ScalarType alpha, const TMVB &A, const Teuchos::SerialDenseMatrix< int, ScalarType > &B, const ScalarType beta, TMVB &mv)
Update mv with .
static void MvRandom(TMVB &mv)
Replace the vectors in mv with random vectors.
static void MvNorm(const TMVB &mv, std::vector< magType > &normvec, NormType type=TwoNorm)
Compute the 2-norm of each individual std::vector of mv. Upon return, normvec[i] holds the value of ,...
static void MvInit(TMVB &mv, ScalarType alpha=Teuchos::ScalarTraits< ScalarType >::zero())
Replace each element of the vectors in mv with alpha.
Thyra::LinearOpBase< ScalarType > TLOB
Thyra::MultiVectorBase< ScalarType > TMVB
static bool HasApplyTranspose(const TLOB &Op)
Whether the operator implements applying the transpose.
static void Apply(const TLOB &Op, const TMVB &x, TMVB &y, ETrans trans=NOTRANS)
Apply Op to x, storing the result in y.
Stub adaptor from Thyra::MultiVectorBase to TSQR.