10 #ifndef ANASAZI_TPETRA_ADAPTER_HPP 
   11 #define ANASAZI_TPETRA_ADAPTER_HPP 
   50 #include <Tpetra_MultiVector.hpp> 
   51 #include <Tpetra_Operator.hpp> 
   54 #include <Teuchos_Assert.hpp> 
   55 #include <Teuchos_DefaultSerialComm.hpp> 
   56 #include <Teuchos_CommHelpers.hpp> 
   58 #include <Teuchos_FancyOStream.hpp> 
   66 #ifdef HAVE_ANASAZI_TSQR 
   67 #  include <Tpetra_TsqrAdaptor.hpp> 
   68 #endif // HAVE_ANASAZI_TSQR 
   84   template<
class Scalar, 
class LO, 
class GO, 
class Node>
 
   86     typedef Tpetra::MultiVector<Scalar, LO, GO, Node> MV;
 
  130 #ifdef HAVE_TPETRA_DEBUG 
  131       const char fnName[] = 
"Anasazi::MultiVecTraits::CloneCopy(mv,index)";
 
  132       const size_t inNumVecs = mv.getNumVectors ();
 
  134         index.size () > 0 && *std::min_element (index.begin (), index.end ()) < 0,
 
  135         std::runtime_error, fnName << 
": All indices must be nonnegative.");
 
  138         static_cast<size_t> (*std::max_element (index.begin (), index.end ())) >= inNumVecs,
 
  140         fnName << 
": All indices must be strictly less than the number of " 
  141         "columns " << inNumVecs << 
" of the input multivector mv.");
 
  142 #endif // HAVE_TPETRA_DEBUG 
  146       for (std::vector<int>::size_type j = 0; j < index.size (); ++j) {
 
  147         columns[j] = index[j];
 
  166       const bool validRange = index.
size() > 0 &&
 
  170         std::ostringstream os;
 
  171         os << 
"Anasazi::MultiVecTraits::CloneCopy(mv,index=[" 
  174           index.
size() == 0, std::invalid_argument,
 
  175           os.str() << 
"Empty index range is not allowed.");
 
  177           index.
lbound() < 0, std::invalid_argument,
 
  178           os.str() << 
"Index range includes negative index/ices, which is not " 
  182           os.str() << 
"Index range exceeds number of vectors " 
  183           << mv.getNumVectors() << 
" in the input multivector.");
 
  185           os.str() << 
"Should never get here!");
 
  195 #ifdef HAVE_TPETRA_DEBUG 
  196       const char fnName[] = 
"Anasazi::MultiVecTraits::CloneViewNonConst(mv,index)";
 
  197       const size_t numVecs = mv.getNumVectors ();
 
  199         index.size () > 0 && *std::min_element (index.begin (), index.end ()) < 0,
 
  200         std::invalid_argument,
 
  201         fnName << 
": All indices must be nonnegative.");
 
  204         static_cast<size_t> (*std::max_element (index.begin (), index.end ())) >= numVecs,
 
  205         std::invalid_argument,
 
  206         fnName << 
": All indices must be strictly less than the number of " 
  207         "columns " << numVecs << 
" in the input MultiVector mv.");
 
  208 #endif // HAVE_TPETRA_DEBUG 
  212       for (std::vector<int>::size_type j = 0; j < index.size (); ++j) {
 
  213         columns[j] = index[j];
 
  229       const int numCols = 
static_cast<int> (mv.getNumVectors());
 
  230       const bool validRange = index.
size() > 0 &&
 
  233         std::ostringstream os;
 
  234         os << 
"Belos::MultiVecTraits::CloneViewNonConst(mv,index=[" 
  237           index.
size() == 0, std::invalid_argument,
 
  238           os.str() << 
"Empty index range is not allowed.");
 
  240           index.
lbound() < 0, std::invalid_argument,
 
  241           os.str() << 
"Index range includes negative inde{x,ices}, which is " 
  244           index.
ubound() >= numCols, std::invalid_argument,
 
  245           os.str() << 
"Index range exceeds number of vectors " << numCols
 
  246           << 
" in the input multivector.");
 
  248           true, std::logic_error,
 
  249           os.str() << 
"Should never get here!");
 
  257     CloneView (
const MV& mv, 
const std::vector<int>& index)
 
  259 #ifdef HAVE_TPETRA_DEBUG 
  260       const char fnName[] = 
"Belos::MultiVecTraits<Scalar, " 
  261         "Tpetra::MultiVector<...> >::CloneView(mv,index)";
 
  262       const size_t numVecs = mv.getNumVectors ();
 
  264         *std::min_element (index.begin (), index.end ()) < 0,
 
  265         std::invalid_argument,
 
  266         fnName << 
": All indices must be nonnegative.");
 
  268         static_cast<size_t> (*std::max_element (index.begin (), index.end ())) >= numVecs,
 
  269         std::invalid_argument,
 
  270         fnName << 
": All indices must be strictly less than the number of " 
  271         "columns " << numVecs << 
" in the input MultiVector mv.");
 
  272 #endif // HAVE_TPETRA_DEBUG 
  276       for (std::vector<int>::size_type j = 0; j < index.size (); ++j) {
 
  277         columns[j] = index[j];
 
  283       Teuchos::rcp_const_cast<MV> (X_view)->setCopyOrView (
Teuchos::View);
 
  293       const int numCols = 
static_cast<int> (mv.getNumVectors());
 
  294       const bool validRange = index.
size() > 0 &&
 
  297         std::ostringstream os;
 
  298         os << 
"Anasazi::MultiVecTraits::CloneView(mv, index=[" 
  301           os.str() << 
"Empty index range is not allowed.");
 
  303           os.str() << 
"Index range includes negative index/ices, which is not " 
  306           index.
ubound() >= numCols, std::invalid_argument,
 
  307           os.str() << 
"Index range exceeds number of vectors " << numCols
 
  308           << 
" in the input multivector.");
 
  310           os.str() << 
"Should never get here!");
 
  313       Teuchos::rcp_const_cast<MV> (X_view)->setCopyOrView (
Teuchos::View);
 
  318       return static_cast<ptrdiff_t
> (mv.getGlobalLength ());
 
  322       return static_cast<int> (mv.getNumVectors ());
 
  334       using Teuchos::rcpFromRef;
 
  335       typedef Tpetra::Map<LO, GO, Node> map_type;
 
  337 #ifdef HAVE_ANASAZI_TPETRA_TIMERS 
  338       const std::string timerName (
"Anasazi::MVT::MvTimesMatAddMv");
 
  345         timer.
is_null (), std::logic_error,
 
  346         "Anasazi::MultiVecTraits::MvTimesMatAddMv: " 
  347         "Failed to look up timer \"" << timerName << 
"\".  " 
  348         "Please report this bug to the Belos developers.");
 
  356         mv.update (alpha*B(0,0), A, beta);
 
  362       map_type LocalMap (B.
numRows (), A.getMap ()->getIndexBase (),
 
  363                          rcpFromRef<const Comm<int> > (serialComm),
 
  364                          Tpetra::LocallyReplicated);
 
  368       MV B_mv (rcpFromRef (LocalMap), Bvalues, B.
stride (), B.
numCols ());
 
  389     static void MvScale (MV& mv, Scalar alpha) {
 
  393     static void MvScale (MV& mv, 
const std::vector<Scalar>& alphas) {
 
  403       using Tpetra::LocallyReplicated;
 
  408       typedef Tpetra::Map<LO,GO,Node> map_type;
 
  410 #ifdef HAVE_ANASAZI_TPETRA_TIMERS 
  411       const std::string timerName (
"Anasazi::MVT::MvTransMv");
 
  412       RCP<Teuchos::Time> timer = TimeMonitor::lookupCounter (timerName);
 
  413       if (timer.is_null ()) {
 
  414         timer = TimeMonitor::getNewCounter (timerName);
 
  417         timer.is_null (), std::logic_error, 
"Anasazi::MvTransMv: " 
  418         "Failed to look up timer \"" << timerName << 
"\".  " 
  419         "Please report this bug to the Belos developers.");
 
  422       TimeMonitor timeMon (*timer);
 
  423 #endif // HAVE_ANASAZI_TPETRA_TIMERS 
  433       const int numRowsC = C.
numRows ();
 
  434       const int numColsC = C.
numCols ();
 
  435       const int strideC  = C.
stride ();
 
  438       if (numRowsC == 1 && numColsC == 1) {
 
  452       RCP<const Comm<int> > pcomm = A.getMap ()->getComm ();
 
  455       RCP<const map_type> LocalMap =
 
  456         rcp (
new map_type (numRowsC, 0, pcomm, LocallyReplicated));
 
  458       const bool INIT_TO_ZERO = 
true;
 
  459       MV C_mv (LocalMap, numColsC, INIT_TO_ZERO);
 
  471       C_mv.get1dCopy (C_view, strideC);
 
  476     MvDot (
const MV& A, 
const MV& B, std::vector<Scalar> &dots)
 
  478       const size_t numVecs = A.getNumVectors ();
 
  480         numVecs != B.getNumVectors (), std::invalid_argument,
 
  481         "Anasazi::MultiVecTraits::MvDot(A,B,dots): " 
  482         "A and B must have the same number of columns.  " 
  483         "A has " << numVecs << 
" column(s), " 
  484         "but B has " << B.getNumVectors () << 
" column(s).");
 
  485 #ifdef HAVE_TPETRA_DEBUG 
  487         dots.size() < numVecs, std::invalid_argument,
 
  488         "Anasazi::MultiVecTraits::MvDot(A,B,dots): " 
  489         "The output array 'dots' must have room for all dot products.  " 
  490         "A and B each have " << numVecs << 
" column(s), " 
  491         "but 'dots' only has " << dots.size() << 
" entry(/ies).");
 
  492 #endif // HAVE_TPETRA_DEBUG 
  495       A.dot (B, av (0, numVecs));
 
  504 #ifdef HAVE_TPETRA_DEBUG 
  506         normvec.size () < 
static_cast<std::vector<int>::size_type
> (mv.getNumVectors ()),
 
  507         std::invalid_argument,
 
  508         "Anasazi::MultiVecTraits::MvNorm(mv,normvec): The normvec output " 
  509         "argument must have at least as many entries as the number of vectors " 
  510         "(columns) in the MultiVector mv.  normvec.size() = " << normvec.size ()
 
  511         << 
" < mv.getNumVectors() = " << mv.getNumVectors () << 
".");
 
  512 #endif // HAVE_TPETRA_DEBUG 
  514       mv.norm2 (av (0, mv.getNumVectors ()));
 
  518     SetBlock (
const MV& A, 
const std::vector<int>& index, MV& mv)
 
  522       const size_t inNumVecs = A.getNumVectors ();
 
  523 #ifdef HAVE_TPETRA_DEBUG 
  525         inNumVecs < static_cast<size_t> (index.size ()), std::invalid_argument,
 
  526         "Anasazi::MultiVecTraits::SetBlock(A,index,mv): 'index' argument must " 
  527         "have no more entries as the number of columns in the input MultiVector" 
  528         " A.  A.getNumVectors() = " << inNumVecs << 
" < index.size () = " 
  529         << index.size () << 
".");
 
  530 #endif // HAVE_TPETRA_DEBUG 
  532       if (inNumVecs > static_cast<size_t> (index.size ())) {
 
  533         RCP<const MV> Asub = A.subView (Range1D (0, index.size () - 1));
 
  534         Tpetra::deep_copy (*mvsub, *Asub);
 
  536         Tpetra::deep_copy (*mvsub, A);
 
  550       const size_t maxInt =
 
  552       const bool overflow =
 
  553         maxInt < A.getNumVectors () && maxInt < mv.getNumVectors ();
 
  555         std::ostringstream os;
 
  556         os << 
"Anasazi::MultiVecTraits::SetBlock(A, index=[" << index.
lbound ()
 
  557            << 
", " << index.
ubound () << 
"], mv): ";
 
  559           maxInt < A.getNumVectors (), std::range_error, os.str () << 
"Number " 
  560           "of columns (size_t) in the input MultiVector 'A' overflows int.");
 
  562           maxInt < mv.getNumVectors (), std::range_error, os.str () << 
"Number " 
  563           "of columns (size_t) in the output MultiVector 'mv' overflows int.");
 
  566       const int numColsA = 
static_cast<int> (A.getNumVectors ());
 
  567       const int numColsMv = 
static_cast<int> (mv.getNumVectors ());
 
  569       const bool validIndex =
 
  572       const bool validSource = index.
size () <= numColsA;
 
  574       if (! validIndex || ! validSource) {
 
  575         std::ostringstream os;
 
  576         os << 
"Anasazi::MultiVecTraits::SetBlock(A, index=[" << index.
lbound ()
 
  577            << 
", " << index.
ubound () << 
"], mv): ";
 
  579           index.
lbound() < 0, std::invalid_argument,
 
  580           os.str() << 
"Range lower bound must be nonnegative.");
 
  582           index.
ubound() >= numColsMv, std::invalid_argument,
 
  583           os.str() << 
"Range upper bound must be less than the number of " 
  584           "columns " << numColsA << 
" in the 'mv' output argument.");
 
  586           index.
size() > numColsA, std::invalid_argument,
 
  587           os.str() << 
"Range must have no more elements than the number of " 
  588           "columns " << numColsA << 
" in the 'A' input argument.");
 
  590           true, std::logic_error, 
"Should never get here!");
 
  597       if (index.
lbound () == 0 && index.
ubound () + 1 == numColsMv) {
 
  598         mv_view = Teuchos::rcpFromRef (mv); 
 
  607       if (index.
size () == numColsA) {
 
  608         A_view = Teuchos::rcpFromRef (A); 
 
  613       Tpetra::deep_copy (*mv_view, *A_view);
 
  616     static void Assign (
const MV& A, MV& mv)
 
  618       const char errPrefix[] = 
"Anasazi::MultiVecTraits::Assign(A, mv): ";
 
  627       const size_t maxInt =
 
  629       const bool overflow =
 
  630         maxInt < A.getNumVectors () && maxInt < mv.getNumVectors ();
 
  633           maxInt < A.getNumVectors(), std::range_error,
 
  634           errPrefix << 
"Number of columns in the input multivector 'A' " 
  635           "(a size_t) overflows int.");
 
  637           maxInt < mv.getNumVectors(), std::range_error,
 
  638           errPrefix << 
"Number of columns in the output multivector 'mv' " 
  639           "(a size_t) overflows int.");
 
  641           true, std::logic_error, 
"Should never get here!");
 
  644       const int numColsA = 
static_cast<int> (A.getNumVectors ());
 
  645       const int numColsMv = 
static_cast<int> (mv.getNumVectors ());
 
  646       if (numColsA > numColsMv) {
 
  648           numColsA > numColsMv, std::invalid_argument,
 
  649           errPrefix << 
"Input multivector 'A' has " << numColsA << 
" columns, " 
  650           "but output multivector 'mv' has only " << numColsMv << 
" columns.");
 
  653       if (numColsA == numColsMv) {
 
  654         Tpetra::deep_copy (mv, A);
 
  658         Tpetra::deep_copy (*mv_view, A);
 
  669       mv.putScalar (alpha);
 
  672     static void MvPrint (
const MV& mv, std::ostream& os) {
 
  677 #ifdef HAVE_ANASAZI_TSQR 
  678     typedef Tpetra::TsqrAdaptor<Tpetra::MultiVector<Scalar, LO, GO, Node> > tsqr_adaptor_type;
 
  681 #endif // HAVE_ANASAZI_TSQR 
  686   template <
class Scalar, 
class LO, 
class GO, 
class Node>
 
  688                        Tpetra::MultiVector<Scalar,LO,GO,Node>,
 
  689                        Tpetra::Operator<Scalar,LO,GO,Node> >
 
  693     Apply (
const Tpetra::Operator<Scalar,LO,GO,Node>& Op,
 
  694            const Tpetra::MultiVector<Scalar,LO,GO,Node>& X,
 
  695            Tpetra::MultiVector<Scalar,LO,GO,Node>& Y)
 
  702 template<
class ST, 
class LO, 
class GO, 
class NT>
 
  704   typedef Tpetra::Operator<ST, LO, GO, NT> operator_type;
 
  707   getOutputStream (
const operator_type& op, 
int rootRank = 0)
 
  713     const int myRank = comm.
is_null () ? 0 : comm->getRank ();
 
  714     const int numProcs = comm.
is_null () ? 1 : comm->getSize ();
 
ScalarType * values() const 
 
static ptrdiff_t GetGlobalLength(const MV &mv)
Return the number of rows in the given multivector mv. 
 
basic_FancyOStream & setProcRankAndSize(const int procRank, const int numProcs)
 
static void MvDot(const MV &A, const MV &B, std::vector< Scalar > &dots)
For all columns j of A, set dots[j] := A[j]^T * B[j]. 
 
static void MvInit(MV &mv, const ScalarType alpha=Teuchos::ScalarTraits< ScalarType >::zero())
Replace each element of the vectors in mv with alpha. 
 
static void MvRandom(MV &mv)
Replace the vectors in mv with random vectors. 
 
static void MvTimesMatAddMv(const ScalarType alpha, const MV &A, const Teuchos::SerialDenseMatrix< int, ScalarType > &B, const ScalarType beta, MV &mv)
Update mv with . 
 
static Teuchos::RCP< MV > Clone(const MV &X, const int numVecs)
Create a new MultiVector with numVecs columns. 
 
static void MvAddMv(Scalar alpha, const MV &A, Scalar beta, const MV &B, MV &mv)
mv := alpha*A + beta*B 
 
Declaration of basic traits for the multivector type. 
 
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
 
Virtual base class which defines basic traits for the operator type. 
 
static void Apply(const OP &Op, const MV &x, MV &y)
Application method which performs operation y = Op*x. An OperatorError exception is thrown if there i...
 
static void Assign(const MV &A, MV &mv)
mv := A 
 
Output managers remove the need for the eigensolver to know any information about the required output...
 
static Teuchos::RCP< MV > CloneCopy(const MV &mv, const std::vector< int > &index)
Create and return a deep copy of the given columns of mv. 
 
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
 
static void MvNorm(const MV &mv, std::vector< typename Teuchos::ScalarTraits< Scalar >::magnitudeType > &normvec)
For all columns j of mv, set normvec[j] = norm(mv[j]). 
 
static Teuchos::RCP< MV > CloneCopy(const MV &X)
Create and return a deep copy of X. 
 
Traits class which defines basic operations on multivectors. 
 
static void MvTransMv(const ScalarType alpha, const MV &A, const MV &B, Teuchos::SerialDenseMatrix< int, ScalarType > &C)
Compute C := alpha * A^H B. 
 
Virtual base class which defines basic traits for the operator type. 
 
static void MvScale(MV &mv, const ScalarType alpha)
Scale each element of the vectors in mv with alpha. 
 
Anasazi header file which uses auto-configuration information to include necessary C++ headers...
 
basic_FancyOStream & setOutputToRootOnly(const int rootRank)
 
static Teuchos::RCP< MV > CloneViewNonConst(MV &mv, const std::vector< int > &index)
Creates a new MV that shares the selected contents of mv (shallow copy). 
 
static Teuchos::RCP< const MV > CloneView(const MV &mv, const std::vector< int > &index)
Creates a new const MV that shares the selected contents of mv (shallow copy). 
 
static void SetBlock(const MV &A, const std::vector< int > &index, MV &mv)
Copy the vectors in A to a set of vectors in mv indicated by the indices given in index...
 
static int GetNumberVecs(const MV &mv)
Obtain the number of vectors in mv. 
 
OrdinalType numCols() const 
 
Types and exceptions used within Anasazi solvers and interfaces. 
 
Abstract class definition for Anasazi output stream. 
 
static void MvPrint(const MV &mv, std::ostream &os)
Print the mv multi-vector to the os output stream. 
 
Anasazi's templated virtual class for constructing an operator that can interface with the OperatorTr...
 
static Teuchos::RCP< MV > CloneCopy(const MV &mv, const Teuchos::Range1D &index)
Create and return a deep copy of the given columns of mv. 
 
OrdinalType stride() const 
 
OrdinalType numRows() const