20#ifndef BELOS_THYRA_ADAPTER_HPP 
   21#define BELOS_THYRA_ADAPTER_HPP 
   23#include "Stratimikos_Config.h" 
   28#include <Thyra_DetachedMultiVectorView.hpp> 
   29#include <Thyra_MultiVectorBase.hpp> 
   30#include <Thyra_MultiVectorStdOps.hpp> 
   32#  include <Thyra_TsqrAdaptor.hpp> 
   35#ifdef HAVE_STRATIMIKOS_BELOS_TIMERS 
   36# include <Teuchos_TimeMonitor.hpp> 
   38# define STRATIMIKOS_TIME_MONITOR(NAME) \ 
   39  Teuchos::TimeMonitor tM(*Teuchos::TimeMonitor::getNewTimer(std::string(NAME))) 
   43# define STRATIMIKOS_TIME_MONITOR(NAME) 
   61  template<
class ScalarType>
 
   65    typedef Thyra::MultiVectorBase<ScalarType> TMVB;
 
   66    typedef Teuchos::ScalarTraits<ScalarType> ST;
 
   67    typedef typename ST::magnitudeType magType;
 
   78    static Teuchos::RCP<TMVB> 
Clone( 
const TMVB& mv, 
const int numvecs )
 
   80      Teuchos::RCP<TMVB> c = Thyra::createMembers( mv.range(), numvecs );
 
 
   88    static Teuchos::RCP<TMVB> 
CloneCopy( 
const TMVB& mv )
 
   90      int numvecs = mv.domain()->dim();
 
   92      Teuchos::RCP< TMVB > cc = Thyra::createMembers( mv.range(), numvecs );
 
   94      Thyra::assign(cc.ptr(), mv);
 
 
  103    static Teuchos::RCP<TMVB> 
CloneCopy( 
const TMVB& mv, 
const std::vector<int>& index )
 
  105      int numvecs = index.size();
 
  107      Teuchos::RCP<TMVB> cc = Thyra::createMembers( mv.range(), numvecs );
 
  109      Teuchos::RCP<const TMVB> view = mv.subView(index);
 
  111      Thyra::assign(cc.ptr(), *view);
 
 
  115    static Teuchos::RCP<TMVB>
 
  116    CloneCopy (
const TMVB& mv, 
const Teuchos::Range1D& index)
 
  118      const int numVecs = index.size();
 
  120      Teuchos::RCP<TMVB> cc = Thyra::createMembers (mv.range(), numVecs);
 
  122      Teuchos::RCP<const TMVB> view = mv.subView (index);
 
  124      Thyra::assign (cc.ptr(), *view);
 
  135      int numvecs = index.size();
 
  151      for (
int i=0; i<numvecs; i++) {
 
  152        if (lb+i != index[i]) contig = 
false;
 
  155      Teuchos::RCP< TMVB > cc;
 
  157        const Thyra::Range1D rng(lb,lb+numvecs-1);
 
  159        cc = mv.subView(rng);
 
  163        cc = mv.subView(index);
 
 
  168    static Teuchos::RCP<TMVB>
 
  176      return mv.subView (index);
 
  185    static Teuchos::RCP<const TMVB> 
CloneView( 
const TMVB& mv, 
const std::vector<int>& index )
 
  187      int numvecs = index.size();
 
  203      for (
int i=0; i<numvecs; i++) {
 
  204        if (lb+i != index[i]) contig = 
false;
 
  207      Teuchos::RCP< const TMVB > cc;
 
  209        const Thyra::Range1D rng(lb,lb+numvecs-1);
 
  211        cc = mv.subView(rng);
 
  215        cc = mv.subView(index);
 
 
  220    static Teuchos::RCP<const TMVB>
 
  221    CloneView (
const TMVB& mv, 
const Teuchos::Range1D& index)
 
  228      return mv.subView (index);
 
  238      return Teuchos::as<ptrdiff_t>(mv.range()->dim());
 
 
  243    { 
return mv.domain()->dim(); }
 
 
  253         const Teuchos::SerialDenseMatrix<int,ScalarType>& B,
 
  254         const ScalarType beta, TMVB& mv )
 
  256      using Teuchos::arrayView; 
using Teuchos::arcpFromArrayView;
 
  257      STRATIMIKOS_TIME_MONITOR(
"Belos::MVT::MvTimesMatAddMv");
 
  259      const int m = B.numRows();
 
  260      const int n = B.numCols();
 
  262      if ((m == 1) && (n == 1)) {
 
  263        using Teuchos::tuple; 
using Teuchos::ptrInArg; 
using Teuchos::inoutArg;
 
  264        const ScalarType alphaNew = alpha * B(0, 0);
 
  265        Thyra::linear_combination<ScalarType>(tuple(alphaNew)(), tuple(ptrInArg(A))(), beta, inoutArg(mv));
 
  268        auto vs = A.domain();
 
  270        Teuchos::RCP< const TMVB >
 
  271          B_thyra = vs->createCachedMembersView(
 
  274              arcpFromArrayView(arrayView(&B(0,0), B.stride()*B.numCols())), B.stride()
 
  277        Thyra::apply<ScalarType>(A, Thyra::NOTRANS, *B_thyra, Teuchos::outArg(mv), alpha, beta);
 
 
  283    static void MvAddMv( 
const ScalarType alpha, 
const TMVB& A,
 
  284                         const ScalarType beta,  
const TMVB& B, TMVB& mv )
 
  286      using Teuchos::tuple; 
using Teuchos::ptrInArg; 
using Teuchos::inoutArg;
 
  287      STRATIMIKOS_TIME_MONITOR(
"Belos::MVT::MvAddMv");
 
  289      Thyra::linear_combination<ScalarType>(
 
  290        tuple(alpha, beta)(), tuple(ptrInArg(A), ptrInArg(B))(), Teuchos::ScalarTraits<ScalarType>::zero(), inoutArg(mv));
 
 
  295    static void MvScale ( TMVB& mv, 
const ScalarType alpha )
 
  297        STRATIMIKOS_TIME_MONITOR(
"Belos::MVT::MvScale");
 
  299        Thyra::scale(alpha, Teuchos::inoutArg(mv));
 
 
  304    static void MvScale (TMVB& mv, 
const std::vector<ScalarType>& alpha)
 
  306      STRATIMIKOS_TIME_MONITOR(
"Belos::MVT::MvScale");
 
  308      for (
unsigned int i=0; i<alpha.size(); i++) {
 
  309        Thyra::scale<ScalarType> (alpha[i], mv.col(i).ptr());
 
 
  315    static void MvTransMv( 
const ScalarType alpha, 
const TMVB& A, 
const TMVB& mv,
 
  316      Teuchos::SerialDenseMatrix<int,ScalarType>& B )
 
  318      using Teuchos::arrayView; 
using Teuchos::arcpFromArrayView;
 
  319      STRATIMIKOS_TIME_MONITOR(
"Belos::MVT::MvTransMv");
 
  322      int m = A.domain()->dim();
 
  323      int n = mv.domain()->dim();
 
  324      auto vs = A.domain();
 
  327        B_thyra = vs->createCachedMembersView(
 
  330            arcpFromArrayView(arrayView(&B(0,0), B.stride()*B.numCols())), B.stride()
 
  334      Thyra::apply<ScalarType>(A, Thyra::CONJTRANS, mv, B_thyra.ptr(), alpha);
 
 
  340    static void MvDot( 
const TMVB& mv, 
const TMVB& A, std::vector<ScalarType>& b )
 
  342        STRATIMIKOS_TIME_MONITOR(
"Belos::MVT::MvDot");
 
  344        Thyra::dots(mv, A, Teuchos::arrayViewFromVector(b));
 
 
  355    static void MvNorm( 
const TMVB& mv, std::vector<magType>& normvec,
 
  357      STRATIMIKOS_TIME_MONITOR(
"Belos::MVT::MvNorm");
 
  360        Thyra::norms_2(mv, Teuchos::arrayViewFromVector(normvec));
 
  362        Thyra::norms_1(mv, Teuchos::arrayViewFromVector(normvec));
 
  364        Thyra::norms_inf(mv, Teuchos::arrayViewFromVector(normvec));
 
  366        TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
 
  367                           "Belos::MultiVecTraits::MvNorm (Thyra specialization): " 
  368                           "invalid norm type. Must be either TwoNorm, OneNorm or InfNorm");
 
 
  378    static void SetBlock( 
const TMVB& A, 
const std::vector<int>& index, TMVB& mv )
 
  381      int numvecs = index.size();
 
  382      std::vector<int> indexA(numvecs);
 
  383      int numAcols = A.domain()->dim();
 
  384      for (
int i=0; i<numvecs; i++) {
 
  389      if ( numAcols < numvecs ) {
 
  394      else if ( numAcols > numvecs ) {
 
  396        indexA.resize( numAcols );
 
  399      Teuchos::RCP< const TMVB > relsource = A.subView(indexA);
 
  401      Teuchos::RCP< TMVB > reldest = mv.subView(index);
 
  403      Thyra::assign(reldest.ptr(), *relsource);
 
 
  407    SetBlock (
const TMVB& A, 
const Teuchos::Range1D& index, TMVB& mv)
 
  409      const int numColsA = A.domain()->dim();
 
  410      const int numColsMv = mv.domain()->dim();
 
  412      const bool validIndex = index.lbound() >= 0 && index.ubound() < numColsMv;
 
  414      const bool validSource = index.size() <= numColsA;
 
  416      if (! validIndex || ! validSource)
 
  418          std::ostringstream os;
 
  419          os << 
"Belos::MultiVecTraits<Scalar, Thyra::MultiVectorBase<Scalar> " 
  420            ">::SetBlock(A, [" << index.lbound() << 
", " << index.ubound()
 
  422          TEUCHOS_TEST_FOR_EXCEPTION(index.lbound() < 0, std::invalid_argument,
 
  423                             os.str() << 
"Range lower bound must be nonnegative.");
 
  424          TEUCHOS_TEST_FOR_EXCEPTION(index.ubound() >= numColsMv, std::invalid_argument,
 
  425                             os.str() << 
"Range upper bound must be less than " 
  426                             "the number of columns " << numColsA << 
" in the " 
  427                             "'mv' output argument.");
 
  428          TEUCHOS_TEST_FOR_EXCEPTION(index.size() > numColsA, std::invalid_argument,
 
  429                             os.str() << 
"Range must have no more elements than" 
  430                             " the number of columns " << numColsA << 
" in the " 
  431                             "'A' input argument.");
 
  432          TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error, 
"Should never get here!");
 
  438      Teuchos::RCP<TMVB> mv_view;
 
  439      if (index.lbound() == 0 && index.ubound()+1 == numColsMv)
 
  440        mv_view = Teuchos::rcpFromRef (mv); 
 
  442        mv_view = mv.subView (index);
 
  447      Teuchos::RCP<const TMVB> A_view;
 
  448      if (index.size() == numColsA)
 
  449        A_view = Teuchos::rcpFromRef (A); 
 
  451        A_view = A.subView (Teuchos::Range1D(0, index.size()-1));
 
  454      Thyra::assign(mv_view.ptr(), *A_view);
 
  458    Assign (
const TMVB& A, TMVB& mv)
 
  460      STRATIMIKOS_TIME_MONITOR(
"Belos::MVT::Assign");
 
  462      const int numColsA = A.domain()->dim();
 
  463      const int numColsMv = mv.domain()->dim();
 
  464      if (numColsA > numColsMv)
 
  466          std::ostringstream os;
 
  467          os << 
"Belos::MultiVecTraits<Scalar, Thyra::MultiVectorBase<Scalar>" 
  468            " >::Assign(A, mv): ";
 
  469          TEUCHOS_TEST_FOR_EXCEPTION(numColsA > numColsMv, std::invalid_argument,
 
  470                             os.str() << 
"Input multivector 'A' has " 
  471                             << numColsA << 
" columns, but output multivector " 
  472                             "'mv' has only " << numColsMv << 
" columns.");
 
  473          TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error, 
"Should never get here!");
 
  476      if (numColsA == numColsMv) {
 
  477        Thyra::assign (Teuchos::outArg (mv), A);
 
  479        Teuchos::RCP<TMVB> mv_view =
 
  481        Thyra::assign (mv_view.ptr(), A);
 
  491      Thyra::randomize<ScalarType>(
 
  492        -Teuchos::ScalarTraits<ScalarType>::one(),
 
  493        Teuchos::ScalarTraits<ScalarType>::one(),
 
  494        Teuchos::outArg(mv));
 
 
  499    MvInit (TMVB& mv, ScalarType alpha = Teuchos::ScalarTraits<ScalarType>::zero())
 
  501      Thyra::assign (Teuchos::outArg (mv), alpha);
 
 
  511    static void MvPrint( 
const TMVB& mv, std::ostream& os )
 
  512      { os << describe(mv,Teuchos::VERB_EXTREME); }
 
 
  516#ifdef HAVE_BELOS_TSQR 
 
  539  template<
class ScalarType>
 
  541                        Thyra::MultiVectorBase<ScalarType>,
 
  542                        Thyra::LinearOpBase<ScalarType> >
 
  545    typedef Thyra::MultiVectorBase<ScalarType> TMVB;
 
  546    typedef Thyra::LinearOpBase<ScalarType>    TLOB;
 
  570      Thyra::EOpTransp whichOp;
 
  578        whichOp = Thyra::NOTRANS;
 
  579      else if (trans == 
TRANS)
 
  580        whichOp = Thyra::TRANS;
 
  582        whichOp = Thyra::CONJTRANS;
 
  584        TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
 
  585                           "Belos::OperatorTraits::Apply (Thyra specialization): " 
  586                           "'trans' argument must be neither NOTRANS=" << 
NOTRANS 
  588                           << 
", but instead has an invalid value of " << trans << 
".");
 
  589      Thyra::apply<ScalarType>(Op, whichOp, x, Teuchos::outArg(y));
 
 
  595      typedef Teuchos::ScalarTraits<ScalarType> STS;
 
  604      return Op.opSupported (Thyra::TRANS) &&
 
  605        (! STS::isComplex || Op.opSupported (Thyra::CONJTRANS));
 
 
 
static void MvPrint(const TMVB &mv, std::ostream &os)
Print the mv multi-std::vector to the os output stream.
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 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 > 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 > 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.
static Teuchos::RCP< MV > CloneCopy(const MV &mv)
static Teuchos::RCP< const MV > CloneView(const MV &mv, const std::vector< int > &index)
static Teuchos::RCP< MV > CloneViewNonConst(MV &mv, const std::vector< int > &index)
static void SetBlock(const MV &A, const std::vector< int > &index, MV &mv)
static void Assign(const MV &A, MV &mv)
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.