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