Anasazi  Version of the Day
AnasaziEpetraAdapter.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Anasazi: Block Eigensolvers Package
5 // Copyright 2004 Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
46 #ifndef ANASAZI_EPETRA_ADAPTER_HPP
47 #define ANASAZI_EPETRA_ADAPTER_HPP
48 
49 #include "AnasaziConfigDefs.hpp"
50 #include "Anasaziepetra_DLLExportMacro.h"
51 #include "AnasaziTypes.hpp"
52 #include "AnasaziMultiVec.hpp"
53 #include "AnasaziOperator.hpp"
54 
55 #include "Teuchos_Assert.hpp"
56 #include "Teuchos_SerialDenseMatrix.hpp"
57 #include "Epetra_MultiVector.h"
58 #include "Epetra_Vector.h"
59 #include "Epetra_Operator.h"
60 #include "Epetra_Map.h"
61 #include "Epetra_LocalMap.h"
62 
63 #if defined(HAVE_ANASAZI_TPETRA) && defined(HAVE_ANASAZI_TSQR)
64 # include <Tpetra_ConfigDefs.hpp> // HAVE_TPETRA_EPETRA
65 # if defined(HAVE_TPETRA_EPETRA)
66 # include <Epetra_TsqrAdaptor.hpp>
67 # endif // defined(HAVE_TPETRA_EPETRA)
68 #endif // defined(HAVE_ANASAZI_TPETRA) && defined(HAVE_ANASAZI_TSQR)
69 
70 namespace Anasazi {
71 
73 
74 
78  class EpetraMultiVecFailure : public AnasaziError {public:
79  EpetraMultiVecFailure(const std::string& what_arg) : AnasaziError(what_arg)
80  {}};
81 
85  class EpetraOpFailure : public AnasaziError {public:
86  EpetraOpFailure(const std::string& what_arg) : AnasaziError(what_arg)
87  {}};
88 
90 
92 
93 
98 
99  public:
102 
104  virtual Epetra_MultiVector* GetEpetraMultiVec() { return 0; }
105 
107  virtual const Epetra_MultiVector* GetEpetraMultiVec() const { return 0; }
108  };
109 
111 
113  //
114  //--------template class AnasaziEpetraMultiVec-----------------
115  //
117 
124  class ANASAZIEPETRA_LIB_DLL_EXPORT EpetraMultiVec : public MultiVec<double>, public Epetra_MultiVector, public EpetraMultiVecAccessor {
125  public:
127 
128 
130 
135  EpetraMultiVec(const Epetra_BlockMap& Map_in, const int numvecs);
136 
138  EpetraMultiVec(const Epetra_MultiVector & P_vec);
139 
141 
149  EpetraMultiVec(const Epetra_BlockMap& Map_in, double * array, const int numvecs, const int stride=0);
150 
152 
158  EpetraMultiVec(Epetra_DataAccess CV, const Epetra_MultiVector& P_vec, const std::vector<int>& index);
159 
161  virtual ~EpetraMultiVec() {};
162 
164 
166 
167 
172  MultiVec<double> * Clone ( const int numvecs ) const;
173 
179  MultiVec<double> * CloneCopy () const;
180 
188  MultiVec<double> * CloneCopy ( const std::vector<int>& index ) const;
189 
197  MultiVec<double> * CloneViewNonConst ( const std::vector<int>& index );
198 
206  const MultiVec<double> * CloneView ( const std::vector<int>& index ) const;
207 
209 
211  ptrdiff_t GetGlobalLength () const
212  {
213  if ( Map().GlobalIndicesLongLong() )
214  return static_cast<ptrdiff_t>( GlobalLength64() );
215  else
216  return static_cast<ptrdiff_t>( GlobalLength() );
217  }
218 
221  int GetNumberVecs () const { return NumVectors(); }
222 
224 
226 
227 
229  void MvTimesMatAddMv ( double alpha, const MultiVec<double>& A,
230  const Teuchos::SerialDenseMatrix<int,double>& B,
231  double beta );
232 
235  void MvAddMv ( double alpha, const MultiVec<double>& A,
236  double beta, const MultiVec<double>& B);
237 
240  void MvTransMv ( double alpha, const MultiVec<double>& A, Teuchos::SerialDenseMatrix<int,double>& B
241 #ifdef HAVE_ANASAZI_EXPERIMENTAL
242  , ConjType conj = Anasazi::CONJ
243 #endif
244  ) const;
245 
248  void MvDot ( const MultiVec<double>& A, std::vector<double> &b
249 #ifdef HAVE_ANASAZI_EXPERIMENTAL
250  , ConjType conj = Anasazi::CONJ
251 #endif
252  ) const;
253 
256  void MvScale ( double alpha ) {
257  TEUCHOS_TEST_FOR_EXCEPTION( this->Scale( alpha )!=0, EpetraMultiVecFailure,
258  "Anasazi::EpetraMultiVec::MvScale call to Epetra_MultiVector::Scale() returned a nonzero value.");
259  }
260 
263  void MvScale ( const std::vector<double>& alpha );
264 
266 
268 
272  void MvNorm ( std::vector<double> & normvec ) const {
273  if (((int)normvec.size() >= GetNumberVecs()) ) {
274  TEUCHOS_TEST_FOR_EXCEPTION( this->Norm2(&normvec[0])!=0, EpetraMultiVecFailure,
275  "Anasazi::EpetraMultiVec::MvNorm call to Epetra_MultiVector::Norm2() returned a nonzero value.");
276  }
277  };
279 
281 
282 
287  void SetBlock ( const MultiVec<double>& A, const std::vector<int>& index );
288 
291  void MvRandom() {
292  TEUCHOS_TEST_FOR_EXCEPTION( this->Random()!=0, EpetraMultiVecFailure,
293  "Anasazi::EpetraMultiVec::MvRandom call to Epetra_MultiVector::Random() returned a nonzero value.");
294  };
295 
298  void MvInit ( double alpha ) {
299  TEUCHOS_TEST_FOR_EXCEPTION( this->PutScalar( alpha )!=0, EpetraMultiVecFailure,
300  "Anasazi::EpetraMultiVec::MvInit call to Epetra_MultiVector::PutScalar() returned a nonzero value.");
301  };
302 
304 
305 
307  Epetra_MultiVector* GetEpetraMultiVec() { return this; };
308 
310  const Epetra_MultiVector* GetEpetraMultiVec() const { return this; };
311 
313 
315 
317 
319  void MvPrint( std::ostream& os ) const { os << *this << std::endl; };
321 
322  private:
323  };
324  //-------------------------------------------------------------
325 
327  //
328  //--------template class AnasaziEpetraOp---------------------
329  //
331 
338  class ANASAZIEPETRA_LIB_DLL_EXPORT EpetraOp : public virtual Operator<double> {
339  public:
341 
342 
344  EpetraOp(const Teuchos::RCP<Epetra_Operator> &Op );
345 
347  ~EpetraOp();
349 
351 
352 
356  void Apply ( const MultiVec<double>& X, MultiVec<double>& Y ) const;
358 
359  private:
360 //use pragmas to disable some false-positive warnings for windows
361 // sharedlibs export
362 #ifdef _MSC_VER
363 #pragma warning(push)
364 #pragma warning(disable:4251)
365 #endif
366  Teuchos::RCP<Epetra_Operator> Epetra_Op;
367 #ifdef _MSC_VER
368 #pragma warning(pop)
369 #endif
370  };
371  //-------------------------------------------------------------
372 
374  //
375  //--------template class AnasaziEpetraGenOp--------------------
376  //
378 
392  class ANASAZIEPETRA_LIB_DLL_EXPORT EpetraGenOp : public virtual Operator<double>, public virtual Epetra_Operator {
393  public:
395 
398  EpetraGenOp(const Teuchos::RCP<Epetra_Operator> &AOp,
399  const Teuchos::RCP<Epetra_Operator> &MOp,
400  bool isAInverse = true );
401 
403  ~EpetraGenOp();
404 
406 
408  void Apply ( const MultiVec<double>& X, MultiVec<double>& Y ) const;
409 
411 
413  int Apply(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const;
414 
416 
418  int ApplyInverse(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const;
419 
421  const char* Label() const { return "Epetra_Operator applying A^{-1}M"; };
422 
424  bool UseTranspose() const { return (false); };
425 
427  int SetUseTranspose(bool /*UseTranspose_in*/) { return 0; };
428 
430  bool HasNormInf() const { return (false); };
431 
433  double NormInf() const { return (-1.0); };
434 
436  const Epetra_Comm& Comm() const { return Epetra_AOp->Comm(); };
437 
439  const Epetra_Map& OperatorDomainMap() const { return Epetra_AOp->OperatorDomainMap(); };
440 
442  const Epetra_Map& OperatorRangeMap() const { return Epetra_AOp->OperatorRangeMap(); };
443 
444  private:
445  bool isAInverse;
446 
447 //use pragmas to disable some false-positive warnings for windows
448 // sharedlibs export
449 #ifdef _MSC_VER
450 #pragma warning(push)
451 #pragma warning(disable:4251)
452 #endif
453  Teuchos::RCP<Epetra_Operator> Epetra_AOp;
454  Teuchos::RCP<Epetra_Operator> Epetra_MOp;
455 #ifdef _MSC_VER
456 #pragma warning(pop)
457 #endif
458  };
459 
461  //
462  //--------template class AnasaziEpetraSymOp--------------------
463  //
465 
478  class ANASAZIEPETRA_LIB_DLL_EXPORT EpetraSymOp : public virtual Operator<double>, public virtual Epetra_Operator {
479  public:
481 
483  EpetraSymOp(const Teuchos::RCP<Epetra_Operator> &Op, bool isTrans = false );
484 
486  ~EpetraSymOp();
487 
489 
491  void Apply ( const MultiVec<double>& X, MultiVec<double>& Y ) const;
492 
494 
496  int Apply(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const;
497 
499 
502  int ApplyInverse(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const;
503 
505  const char* Label() const { return "Epetra_Operator applying A^TA or AA^T"; };
506 
508  bool UseTranspose() const { return (false); };
509 
511  int SetUseTranspose(bool /*UseTranspose_in*/) { return 0; };
512 
514  bool HasNormInf() const { return (false); };
515 
517  double NormInf() const { return (-1.0); };
518 
520  const Epetra_Comm& Comm() const { return Epetra_Op->Comm(); };
521 
523  const Epetra_Map& OperatorDomainMap() const { return Epetra_Op->OperatorDomainMap(); };
524 
526  const Epetra_Map& OperatorRangeMap() const { return Epetra_Op->OperatorRangeMap(); };
527 
528  private:
529 
530 //use pragmas to disable false-positive warnings in generating windows sharedlib exports
531 #ifdef _MSC_VER
532 #pragma warning(push)
533 #pragma warning(disable:4251)
534 #endif
535  Teuchos::RCP<Epetra_Operator> Epetra_Op;
536 #ifdef _MSC_VER
537 #pragma warning(pop)
538 #endif
539 
540  bool isTrans_;
541  };
542 
543 
545  //
546  //--------template class AnasaziEpetraSymMVOp---------------------
547  //
549 
562  class ANASAZIEPETRA_LIB_DLL_EXPORT EpetraSymMVOp : public virtual Operator<double> {
563  public:
565 
567  EpetraSymMVOp(const Teuchos::RCP<const Epetra_MultiVector> &MV,
568  bool isTrans = false );
569 
572 
574 
576  void Apply ( const MultiVec<double>& X, MultiVec<double>& Y ) const;
577 
578  private:
579 
580 //use pragmas to disable some false-positive warnings for windows
581 // sharedlibs export
582 #ifdef _MSC_VER
583 #pragma warning(push)
584 #pragma warning(disable:4251)
585 #endif
586  Teuchos::RCP<const Epetra_MultiVector> Epetra_MV;
587  Teuchos::RCP<const Epetra_Map> MV_localmap;
588  Teuchos::RCP<const Epetra_BlockMap> MV_blockmap;
589 #ifdef _MSC_VER
590 #pragma warning(pop)
591 #endif
592 
593  bool isTrans_;
594  };
595 
597  //
598  //--------template class AnasaziEpetraWSymMVOp---------------------
599  //
601 
614  class ANASAZIEPETRA_LIB_DLL_EXPORT EpetraWSymMVOp : public virtual Operator<double> {
615  public:
617  EpetraWSymMVOp(const Teuchos::RCP<const Epetra_MultiVector> &MV,
618  const Teuchos::RCP<Epetra_Operator> &OP );
619 
622 
624 
626  void Apply ( const MultiVec<double>& X, MultiVec<double>& Y ) const;
627 
628  private:
629 //use pragmas to disable some false-positive warnings for windows
630 // sharedlibs export
631 #ifdef _MSC_VER
632 #pragma warning(push)
633 #pragma warning(disable:4251)
634 #endif
635  Teuchos::RCP<const Epetra_MultiVector> Epetra_MV;
636  Teuchos::RCP<Epetra_Operator> Epetra_OP;
637  Teuchos::RCP<Epetra_MultiVector> Epetra_WMV;
638  Teuchos::RCP<const Epetra_Map> MV_localmap;
639  Teuchos::RCP<const Epetra_BlockMap> MV_blockmap;
640 #ifdef _MSC_VER
641 #pragma warning(pop)
642 #endif
643  };
644 
646  //
647  //--------template class AnasaziEpetraW2SymMVOp---------------------
648  //
650 
663  class ANASAZIEPETRA_LIB_DLL_EXPORT EpetraW2SymMVOp : public virtual Operator<double> {
664  public:
666  EpetraW2SymMVOp(const Teuchos::RCP<const Epetra_MultiVector> &MV,
667  const Teuchos::RCP<Epetra_Operator> &OP );
668 
671 
673 
675  void Apply ( const MultiVec<double>& X, MultiVec<double>& Y ) const;
676 
677  private:
678 //use pragmas to disable some false-positive warnings for windows
679 // sharedlibs export
680 #ifdef _MSC_VER
681 #pragma warning(push)
682 #pragma warning(disable:4251)
683 #endif
684  Teuchos::RCP<const Epetra_MultiVector> Epetra_MV;
685  Teuchos::RCP<Epetra_Operator> Epetra_OP;
686  Teuchos::RCP<Epetra_MultiVector> Epetra_WMV;
687  Teuchos::RCP<const Epetra_Map> MV_localmap;
688  Teuchos::RCP<const Epetra_BlockMap> MV_blockmap;
689 #ifdef _MSC_VER
690 #pragma warning(pop)
691 #endif
692  };
693 
694 
696  //
697  // Implementation of the Anasazi::MultiVecTraits for Epetra::MultiVector.
698  //
700 
711  template<>
712  class MultiVecTraits<double, Epetra_MultiVector>
713  {
714  public:
715 
717 
718 
723  static Teuchos::RCP<Epetra_MultiVector>
724  Clone (const Epetra_MultiVector& mv, const int outNumVecs)
725  {
726  TEUCHOS_TEST_FOR_EXCEPTION(outNumVecs <= 0, std::invalid_argument,
727  "Belos::MultiVecTraits<double, Epetra_MultiVector>::"
728  "Clone(mv, outNumVecs = " << outNumVecs << "): "
729  "outNumVecs must be positive.");
730  // FIXME (mfh 13 Jan 2011) Anasazi currently lets Epetra fill in
731  // the entries of the returned multivector with zeros, but Belos
732  // does not. We retain this different behavior for now, but the
733  // two versions will need to be reconciled.
734  return Teuchos::rcp (new Epetra_MultiVector (mv.Map(), outNumVecs));
735  }
736 
741  static Teuchos::RCP<Epetra_MultiVector>
742  CloneCopy (const Epetra_MultiVector& mv)
743  {
744  return Teuchos::rcp (new Epetra_MultiVector (mv));
745  }
746 
752  static Teuchos::RCP<Epetra_MultiVector>
753  CloneCopy (const Epetra_MultiVector& mv, const std::vector<int>& index)
754  {
755  const int inNumVecs = GetNumberVecs (mv);
756  const int outNumVecs = index.size();
757 
758  // Simple, inexpensive tests of the index vector.
759  TEUCHOS_TEST_FOR_EXCEPTION(outNumVecs == 0, std::invalid_argument,
760  "Anasazi::MultiVecTraits<double,Epetra_MultiVector>::"
761  "CloneCopy(mv, index = {}): At least one vector must be"
762  " cloned from mv.");
763  if (outNumVecs > inNumVecs)
764  {
765  std::ostringstream os;
766  os << "Anasazi::MultiVecTraits<double,Epetra_MultiVector>::"
767  "CloneCopy(mv, index = {";
768  for (int k = 0; k < outNumVecs - 1; ++k)
769  os << index[k] << ", ";
770  os << index[outNumVecs-1] << "}): There are " << outNumVecs
771  << " indices to copy, but only " << inNumVecs << " columns of mv.";
772  TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, os.str());
773  }
774 #ifdef TEUCHOS_DEBUG
775  // In debug mode, we perform more expensive tests of the index
776  // vector, to ensure all the elements are in range.
777  // Dereferencing the iterator is valid because index has length
778  // > 0.
779  const int minIndex = *std::min_element (index.begin(), index.end());
780  const int maxIndex = *std::max_element (index.begin(), index.end());
781 
782  if (minIndex < 0)
783  {
784  std::ostringstream os;
785  os << "Anasazi::MultiVecTraits<double,Epetra_MultiVector>::"
786  "CloneCopy(mv, index = {";
787  for (int k = 0; k < outNumVecs - 1; ++k)
788  os << index[k] << ", ";
789  os << index[outNumVecs-1] << "}): Indices must be nonnegative, but "
790  "the smallest index " << minIndex << " is negative.";
791  TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, os.str());
792  }
793  if (maxIndex >= inNumVecs)
794  {
795  std::ostringstream os;
796  os << "Anasazi::MultiVecTraits<double,Epetra_MultiVector>::"
797  "CloneCopy(mv, index = {";
798  for (int k = 0; k < outNumVecs - 1; ++k)
799  os << index[k] << ", ";
800  os << index[outNumVecs-1] << "}): Indices must be strictly less than "
801  "the number of vectors " << inNumVecs << " in mv; the largest index "
802  << maxIndex << " is out of bounds.";
803  TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, os.str());
804  }
805 #endif // TEUCHOS_DEBUG
806  // Cast to nonconst, because Epetra_MultiVector's constructor
807  // wants a nonconst int array argument. It doesn't actually
808  // change the entries of the array.
809  std::vector<int>& tmpind = const_cast< std::vector<int>& > (index);
810  return Teuchos::rcp (new Epetra_MultiVector (Epetra_DataAccess::Copy, mv, &tmpind[0], index.size()));
811  }
812 
813  static Teuchos::RCP<Epetra_MultiVector>
814  CloneCopy (const Epetra_MultiVector& mv, const Teuchos::Range1D& index)
815  {
816  const int inNumVecs = GetNumberVecs (mv);
817  const int outNumVecs = index.size();
818  const bool validRange = outNumVecs > 0 && index.lbound() >= 0 &&
819  index.ubound() < inNumVecs;
820  if (! validRange)
821  {
822  std::ostringstream os;
823  os << "Anasazi::MultiVecTraits<double,Epetra_MultiVector>::Clone(mv,"
824  "index=[" << index.lbound() << ", " << index.ubound() << "]): ";
825  TEUCHOS_TEST_FOR_EXCEPTION(outNumVecs == 0, std::invalid_argument,
826  os.str() << "Column index range must be nonempty.");
827  TEUCHOS_TEST_FOR_EXCEPTION(index.lbound() < 0, std::invalid_argument,
828  os.str() << "Column index range must be nonnegative.");
829  TEUCHOS_TEST_FOR_EXCEPTION(index.ubound() >= inNumVecs, std::invalid_argument,
830  os.str() << "Column index range must not exceed "
831  "number of vectors " << inNumVecs << " in the "
832  "input multivector.");
833  }
834  return Teuchos::rcp (new Epetra_MultiVector (Epetra_DataAccess::Copy, mv, index.lbound(), index.size()));
835  }
836 
842  static Teuchos::RCP<Epetra_MultiVector>
843  CloneViewNonConst (Epetra_MultiVector& mv, const std::vector<int>& index)
844  {
845  const int inNumVecs = GetNumberVecs (mv);
846  const int outNumVecs = index.size();
847 
848  // Simple, inexpensive tests of the index vector.
849  TEUCHOS_TEST_FOR_EXCEPTION(outNumVecs == 0, std::invalid_argument,
850  "Anasazi::MultiVecTraits<double,Epetra_MultiVector>::"
851  "CloneViewNonConst(mv, index = {}): The output view "
852  "must have at least one column.");
853  if (outNumVecs > inNumVecs)
854  {
855  std::ostringstream os;
856  os << "Anasazi::MultiVecTraits<double,Epetra_MultiVector>::"
857  "CloneViewNonConst(mv, index = {";
858  for (int k = 0; k < outNumVecs - 1; ++k)
859  os << index[k] << ", ";
860  os << index[outNumVecs-1] << "}): There are " << outNumVecs
861  << " indices to view, but only " << inNumVecs << " columns of mv.";
862  TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, os.str());
863  }
864 #ifdef TEUCHOS_DEBUG
865  // In debug mode, we perform more expensive tests of the index
866  // vector, to ensure all the elements are in range.
867  // Dereferencing the iterator is valid because index has length
868  // > 0.
869  const int minIndex = *std::min_element (index.begin(), index.end());
870  const int maxIndex = *std::max_element (index.begin(), index.end());
871 
872  if (minIndex < 0)
873  {
874  std::ostringstream os;
875  os << "Anasazi::MultiVecTraits<double,Epetra_MultiVector>::"
876  "CloneViewNonConst(mv, index = {";
877  for (int k = 0; k < outNumVecs - 1; ++k)
878  os << index[k] << ", ";
879  os << index[outNumVecs-1] << "}): Indices must be nonnegative, but "
880  "the smallest index " << minIndex << " is negative.";
881  TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, os.str());
882  }
883  if (maxIndex >= inNumVecs)
884  {
885  std::ostringstream os;
886  os << "Anasazi::MultiVecTraits<double,Epetra_MultiVector>::"
887  "CloneViewNonConst(mv, index = {";
888  for (int k = 0; k < outNumVecs - 1; ++k)
889  os << index[k] << ", ";
890  os << index[outNumVecs-1] << "}): Indices must be strictly less than "
891  "the number of vectors " << inNumVecs << " in mv; the largest index "
892  << maxIndex << " is out of bounds.";
893  TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, os.str());
894  }
895 #endif // TEUCHOS_DEBUG
896  // Cast to nonconst, because Epetra_MultiVector's constructor
897  // wants a nonconst int array argument. It doesn't actually
898  // change the entries of the array.
899  std::vector<int>& tmpind = const_cast< std::vector<int>& > (index);
900  return Teuchos::rcp (new Epetra_MultiVector (Epetra_DataAccess::View, mv, &tmpind[0], index.size()));
901  }
902 
903  static Teuchos::RCP<Epetra_MultiVector>
904  CloneViewNonConst (Epetra_MultiVector& mv, const Teuchos::Range1D& index)
905  {
906  const bool validRange = index.size() > 0 &&
907  index.lbound() >= 0 &&
908  index.ubound() < mv.NumVectors();
909  if (! validRange)
910  {
911  std::ostringstream os;
912  os << "Anasazi::MultiVecTraits<double,Epetra_MultiVector>::CloneView"
913  "NonConst(mv,index=[" << index.lbound() << ", " << index.ubound()
914  << "]): ";
915  TEUCHOS_TEST_FOR_EXCEPTION(index.size() == 0, std::invalid_argument,
916  os.str() << "Column index range must be nonempty.");
917  TEUCHOS_TEST_FOR_EXCEPTION(index.lbound() < 0, std::invalid_argument,
918  os.str() << "Column index range must be nonnegative.");
919  TEUCHOS_TEST_FOR_EXCEPTION(index.ubound() >= mv.NumVectors(),
920  std::invalid_argument,
921  os.str() << "Column index range must not exceed "
922  "number of vectors " << mv.NumVectors() << " in "
923  "the input multivector.");
924  }
925  return Teuchos::rcp (new Epetra_MultiVector (Epetra_DataAccess::View, mv, index.lbound(), index.size()));
926  }
927 
933  static Teuchos::RCP<const Epetra_MultiVector>
934  CloneView (const Epetra_MultiVector& mv, const std::vector<int>& index)
935  {
936  const int inNumVecs = GetNumberVecs (mv);
937  const int outNumVecs = index.size();
938 
939  // Simple, inexpensive tests of the index vector.
940  TEUCHOS_TEST_FOR_EXCEPTION(outNumVecs == 0, std::invalid_argument,
941  "Belos::MultiVecTraits<double,Epetra_MultiVector>::"
942  "CloneView(mv, index = {}): The output view "
943  "must have at least one column.");
944  if (outNumVecs > inNumVecs)
945  {
946  std::ostringstream os;
947  os << "Belos::MultiVecTraits<double,Epetra_MultiVector>::"
948  "CloneView(mv, index = {";
949  for (int k = 0; k < outNumVecs - 1; ++k)
950  os << index[k] << ", ";
951  os << index[outNumVecs-1] << "}): There are " << outNumVecs
952  << " indices to view, but only " << inNumVecs << " columns of mv.";
953  TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, os.str());
954  }
955 #ifdef TEUCHOS_DEBUG
956  // In debug mode, we perform more expensive tests of the index
957  // vector, to ensure all the elements are in range.
958  // Dereferencing the iterator is valid because index has length
959  // > 0.
960  const int minIndex = *std::min_element (index.begin(), index.end());
961  const int maxIndex = *std::max_element (index.begin(), index.end());
962 
963  if (minIndex < 0)
964  {
965  std::ostringstream os;
966  os << "Belos::MultiVecTraits<double,Epetra_MultiVector>::"
967  "CloneView(mv, index = {";
968  for (int k = 0; k < outNumVecs - 1; ++k)
969  os << index[k] << ", ";
970  os << index[outNumVecs-1] << "}): Indices must be nonnegative, but "
971  "the smallest index " << minIndex << " is negative.";
972  TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, os.str());
973  }
974  if (maxIndex >= inNumVecs)
975  {
976  std::ostringstream os;
977  os << "Belos::MultiVecTraits<double,Epetra_MultiVector>::"
978  "CloneView(mv, index = {";
979  for (int k = 0; k < outNumVecs - 1; ++k)
980  os << index[k] << ", ";
981  os << index[outNumVecs-1] << "}): Indices must be strictly less than "
982  "the number of vectors " << inNumVecs << " in mv; the largest index "
983  << maxIndex << " is out of bounds.";
984  TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, os.str());
985  }
986 #endif // TEUCHOS_DEBUG
987  // Cast to nonconst, because Epetra_MultiVector's constructor
988  // wants a nonconst int array argument. It doesn't actually
989  // change the entries of the array.
990  std::vector<int>& tmpind = const_cast< std::vector<int>& > (index);
991  return Teuchos::rcp (new Epetra_MultiVector (Epetra_DataAccess::View, mv, &tmpind[0], index.size()));
992  }
993 
994  static Teuchos::RCP<Epetra_MultiVector>
995  CloneView (const Epetra_MultiVector& mv, const Teuchos::Range1D& index)
996  {
997  const bool validRange = index.size() > 0 &&
998  index.lbound() >= 0 &&
999  index.ubound() < mv.NumVectors();
1000  if (! validRange)
1001  {
1002  std::ostringstream os;
1003  os << "Anasazi::MultiVecTraits<double,Epetra_MultiVector>::CloneView"
1004  "(mv,index=[" << index.lbound() << ", " << index.ubound()
1005  << "]): ";
1006  TEUCHOS_TEST_FOR_EXCEPTION(index.size() == 0, std::invalid_argument,
1007  os.str() << "Column index range must be nonempty.");
1008  TEUCHOS_TEST_FOR_EXCEPTION(index.lbound() < 0, std::invalid_argument,
1009  os.str() << "Column index range must be nonnegative.");
1010  TEUCHOS_TEST_FOR_EXCEPTION(index.ubound() >= mv.NumVectors(),
1011  std::invalid_argument,
1012  os.str() << "Column index range must not exceed "
1013  "number of vectors " << mv.NumVectors() << " in "
1014  "the input multivector.");
1015  }
1016  return Teuchos::rcp (new Epetra_MultiVector(Epetra_DataAccess::View, mv, index.lbound(), index.size()));
1017  }
1018 
1020 
1022 
1023 
1025  static ptrdiff_t GetGlobalLength( const Epetra_MultiVector& mv )
1026  {
1027  if (mv.Map().GlobalIndicesLongLong())
1028  return static_cast<ptrdiff_t>( mv.GlobalLength64() );
1029  else
1030  return static_cast<ptrdiff_t>( mv.GlobalLength() );
1031  }
1032 
1034  static int GetNumberVecs( const Epetra_MultiVector& mv )
1035  { return mv.NumVectors(); }
1036 
1037  static bool HasConstantStride( const Epetra_MultiVector& mv )
1038  { return mv.ConstantStride(); }
1040 
1042 
1043 
1046  static void MvTimesMatAddMv( double alpha, const Epetra_MultiVector& A,
1047  const Teuchos::SerialDenseMatrix<int,double>& B,
1048  double beta, Epetra_MultiVector& mv )
1049  {
1050  Epetra_LocalMap LocalMap(B.numRows(), 0, mv.Map().Comm());
1051  Epetra_MultiVector B_Pvec(Epetra_DataAccess::View, LocalMap, B.values(), B.stride(), B.numCols());
1052 
1053  TEUCHOS_TEST_FOR_EXCEPTION( mv.Multiply( 'N', 'N', alpha, A, B_Pvec, beta )!=0, EpetraMultiVecFailure,
1054  "Anasazi::MultiVecTraits<double, Epetra_MultiVector>::MvTimesMatAddMv call to Epetra_MultiVector::Multiply() returned a nonzero value.");
1055  }
1056 
1059  static void MvAddMv( double alpha, const Epetra_MultiVector& A, double beta, const Epetra_MultiVector& B, Epetra_MultiVector& mv )
1060  {
1061  // epetra mv.Update(alpha,A,beta,B,gamma) will check
1062  // alpha == 0.0
1063  // and
1064  // beta == 0.0
1065  // and based on this will call
1066  // mv.Update(beta,B,gamma)
1067  // or
1068  // mv.Update(alpha,A,gamma)
1069  //
1070  // mv.Update(alpha,A,gamma)
1071  // will then check for one of
1072  // gamma == 0
1073  // or
1074  // gamma == 1
1075  // or
1076  // alpha == 1
1077  // in that order. however, it will not look for the combination
1078  // alpha == 1 and gamma = 0
1079  // which is a common use case when we wish to assign
1080  // mv = A (in which case alpha == 1, beta == gamma == 0)
1081  // or
1082  // mv = B (in which case beta == 1, alpha == gamma == 0)
1083  //
1084  // therefore, we will check for these use cases ourselves
1085  if (beta == 0.0) {
1086  if (alpha == 1.0) {
1087  // assign
1088  mv = A;
1089  }
1090  else {
1091  // single update
1092  TEUCHOS_TEST_FOR_EXCEPTION( mv.Update( alpha, A, 0.0 )!=0, EpetraMultiVecFailure,
1093  "Anasazi::MultiVecTraits<double, Epetra_MultiVector>::MvAddMv call to Epetra_MultiVector::Update(alpha,A,0.0) returned a nonzero value.");
1094  }
1095  }
1096  else if (alpha == 0.0) {
1097  if (beta == 1.0) {
1098  // assign
1099  mv = B;
1100  }
1101  else {
1102  // single update
1103  TEUCHOS_TEST_FOR_EXCEPTION( mv.Update( beta, B, 0.0 )!=0, EpetraMultiVecFailure,
1104  "Anasazi::MultiVecTraits<double, Epetra_MultiVector>::MvAddMv call to Epetra_MultiVector::Update(beta,B,0.0) returned a nonzero value.");
1105  }
1106  }
1107  else {
1108  // double update
1109  TEUCHOS_TEST_FOR_EXCEPTION( mv.Update( alpha, A, beta, B, 0.0 )!=0, EpetraMultiVecFailure,
1110  "Anasazi::MultiVecTraits<double, Epetra_MultiVector>::MvAddMv call to Epetra_MultiVector::Update(alpha,A,beta,B,0.0) returned a nonzero value.");
1111  }
1112  }
1113 
1116  static void MvTransMv( double alpha, const Epetra_MultiVector& A, const Epetra_MultiVector& mv, Teuchos::SerialDenseMatrix<int,double>& B
1117 #ifdef HAVE_ANASAZI_EXPERIMENTAL
1118  , ConjType conj = Anasazi::CONJ
1119 #endif
1120  )
1121  {
1122  Epetra_LocalMap LocalMap(B.numRows(), 0, mv.Map().Comm());
1123  Epetra_MultiVector B_Pvec(Epetra_DataAccess::View, LocalMap, B.values(), B.stride(), B.numCols());
1124 
1125  TEUCHOS_TEST_FOR_EXCEPTION( B_Pvec.Multiply( 'T', 'N', alpha, A, mv, 0.0 )!=0, EpetraMultiVecFailure,
1126  "Anasazi::MultiVecTraits<double, Epetra_MultiVector>::MvTransMv call to Epetra_MultiVector::Multiply() returned a nonzero value.");
1127  }
1128 
1131  static void MvDot( const Epetra_MultiVector& A, const Epetra_MultiVector& B, std::vector<double> &b
1132 #ifdef HAVE_ANASAZI_EXPERIMENTAL
1133  , ConjType conj = Anasazi::CONJ
1134 #endif
1135  )
1136  {
1137 #ifdef TEUCHOS_DEBUG
1138  TEUCHOS_TEST_FOR_EXCEPTION(A.NumVectors() != B.NumVectors(),std::invalid_argument,
1139  "Anasazi::MultiVecTraits<double,Epetra_MultiVector>::MvDot(A,B,b): A and B must have the same number of vectors.");
1140  TEUCHOS_TEST_FOR_EXCEPTION(b.size() != (unsigned int)A.NumVectors(),std::invalid_argument,
1141  "Anasazi::MultiVecTraits<double,Epetra_MultiVector>::MvDot(A,B,b): b must have room for all dot products.");
1142 #endif
1143  TEUCHOS_TEST_FOR_EXCEPTION( A.Dot( B, &b[0] )!=0, EpetraMultiVecFailure,
1144  "Anasazi::MultiVecTraits<double, Epetra_MultiVector>::MvDot(A,B,b) call to Epetra_MultiVector::Dot() returned a nonzero value.");
1145  }
1146 
1148 
1150 
1154  static void MvNorm( const Epetra_MultiVector& mv, std::vector<double> &normvec )
1155  {
1156 #ifdef TEUCHOS_DEBUG
1157  TEUCHOS_TEST_FOR_EXCEPTION((unsigned int)mv.NumVectors() != normvec.size(),std::invalid_argument,
1158  "Anasazi::MultiVecTraits<double,Epetra_MultiVector>::MvNorm(mv,normvec): normvec must be the same size of mv.");
1159 #endif
1160  TEUCHOS_TEST_FOR_EXCEPTION( mv.Norm2(&normvec[0])!=0, EpetraMultiVecFailure,
1161  "Anasazi::MultiVecTraits<double, Epetra_MultiVector>::MvNorm call to Epetra_MultiVector::Norm2() returned a nonzero value.");
1162  }
1163 
1165 
1167 
1168 
1170  static void
1171  SetBlock (const Epetra_MultiVector& A,
1172  const std::vector<int>& index,
1173  Epetra_MultiVector& mv)
1174  {
1175  const int inNumVecs = GetNumberVecs (A);
1176  const int outNumVecs = index.size();
1177 
1178  // FIXME (mfh 13 Jan 2011) Belos allows A to have more columns
1179  // than index.size(), in which case we just take the first
1180  // index.size() columns of A. Anasazi requires that A have the
1181  // same number of columns as index.size(). Changing Anasazi's
1182  // behavior should not break existing Anasazi solvers, but the
1183  // tests need to be done.
1184  if (inNumVecs != outNumVecs)
1185  {
1186  std::ostringstream os;
1187  os << "Belos::MultiVecTraits<double,Epetra_MultiVector>::"
1188  "SetBlock(A, mv, index = {";
1189  if (outNumVecs > 0)
1190  {
1191  for (int k = 0; k < outNumVecs - 1; ++k)
1192  os << index[k] << ", ";
1193  os << index[outNumVecs-1];
1194  }
1195  os << "}): A has only " << inNumVecs << " columns, but there are "
1196  << outNumVecs << " indices in the index vector.";
1197  TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, os.str());
1198  }
1199  // Make a view of the columns of mv indicated by the index std::vector.
1200  Teuchos::RCP<Epetra_MultiVector> mv_view = CloneViewNonConst (mv, index);
1201 
1202  // View of columns [0, outNumVecs-1] of the source multivector A.
1203  // If A has fewer columns than mv_view, then create a view of
1204  // the first outNumVecs columns of A.
1205  Teuchos::RCP<const Epetra_MultiVector> A_view;
1206  if (outNumVecs == inNumVecs)
1207  A_view = Teuchos::rcpFromRef (A); // Const, non-owning RCP
1208  else
1209  A_view = CloneView (A, Teuchos::Range1D(0, outNumVecs - 1));
1210 
1211  // Assignment calls Epetra_MultiVector::Assign(), which deeply
1212  // copies the data directly, ignoring the underlying
1213  // Epetra_Map(s). If A and mv don't have the same data
1214  // distribution (Epetra_Map), this may result in incorrect or
1215  // undefined behavior. Epetra_MultiVector::Update() also
1216  // ignores the Epetra_Maps, so we might as well just use the
1217  // (perhaps slightly cheaper) Assign() method via operator=().
1218  *mv_view = *A_view;
1219  }
1220 
1221  static void
1222  SetBlock (const Epetra_MultiVector& A,
1223  const Teuchos::Range1D& index,
1224  Epetra_MultiVector& mv)
1225  {
1226  const int numColsA = A.NumVectors();
1227  const int numColsMv = mv.NumVectors();
1228  // 'index' indexes into mv; it's the index set of the target.
1229  const bool validIndex = index.lbound() >= 0 && index.ubound() < numColsMv;
1230  // We can't take more columns out of A than A has.
1231  const bool validSource = index.size() <= numColsA;
1232 
1233  if (! validIndex || ! validSource)
1234  {
1235  std::ostringstream os;
1236  os << "Anasazi::MultiVecTraits<double, Epetra_MultiVector>::SetBlock"
1237  "(A, index=[" << index.lbound() << ", " << index.ubound() << "], "
1238  "mv): ";
1239  TEUCHOS_TEST_FOR_EXCEPTION(index.lbound() < 0, std::invalid_argument,
1240  os.str() << "Range lower bound must be nonnegative.");
1241  TEUCHOS_TEST_FOR_EXCEPTION(index.ubound() >= numColsMv, std::invalid_argument,
1242  os.str() << "Range upper bound must be less than "
1243  "the number of columns " << numColsA << " in the "
1244  "'mv' output argument.");
1245  TEUCHOS_TEST_FOR_EXCEPTION(index.size() > numColsA, std::invalid_argument,
1246  os.str() << "Range must have no more elements than"
1247  " the number of columns " << numColsA << " in the "
1248  "'A' input argument.");
1249  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Should never get here!");
1250  }
1251 
1252  // View of columns [index.lbound(), index.ubound()] of the
1253  // target multivector mv. We avoid view creation overhead by
1254  // only creating a view if the index range is different than [0,
1255  // (# columns in mv) - 1].
1256  Teuchos::RCP<Epetra_MultiVector> mv_view;
1257  if (index.lbound() == 0 && index.ubound()+1 == numColsMv)
1258  mv_view = Teuchos::rcpFromRef (mv); // Non-const, non-owning RCP
1259  else
1260  mv_view = CloneViewNonConst (mv, index);
1261 
1262  // View of columns [0, index.size()-1] of the source multivector
1263  // A. If A has fewer columns than mv_view, then create a view
1264  // of the first index.size() columns of A.
1265  Teuchos::RCP<const Epetra_MultiVector> A_view;
1266  if (index.size() == numColsA)
1267  A_view = Teuchos::rcpFromRef (A); // Const, non-owning RCP
1268  else
1269  A_view = CloneView (A, Teuchos::Range1D(0, index.size()-1));
1270 
1271  // Assignment calls Epetra_MultiVector::Assign(), which deeply
1272  // copies the data directly, ignoring the underlying
1273  // Epetra_Map(s). If A and mv don't have the same data
1274  // distribution (Epetra_Map), this may result in incorrect or
1275  // undefined behavior. Epetra_MultiVector::Update() also
1276  // ignores the Epetra_Maps, so we might as well just use the
1277  // (perhaps slightly cheaper) Assign() method via operator=().
1278  *mv_view = *A_view;
1279  }
1280 
1281  static void
1282  Assign (const Epetra_MultiVector& A,
1283  Epetra_MultiVector& mv)
1284  {
1285  const int numColsA = GetNumberVecs (A);
1286  const int numColsMv = GetNumberVecs (mv);
1287  if (numColsA > numColsMv)
1288  {
1289  std::ostringstream os;
1290  os << "Anasazi::MultiVecTraits<double, Epetra_MultiVector>::Assign"
1291  "(A, mv): ";
1292  TEUCHOS_TEST_FOR_EXCEPTION(numColsA > numColsMv, std::invalid_argument,
1293  os.str() << "Input multivector 'A' has "
1294  << numColsA << " columns, but output multivector "
1295  "'mv' has only " << numColsMv << " columns.");
1296  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Should never get here!");
1297  }
1298  // View of the first [0, numColsA-1] columns of mv.
1299  Teuchos::RCP<Epetra_MultiVector> mv_view;
1300  if (numColsMv == numColsA)
1301  mv_view = Teuchos::rcpFromRef (mv); // Non-const, non-owning RCP
1302  else // numColsMv > numColsA
1303  mv_view = CloneView (mv, Teuchos::Range1D(0, numColsA - 1));
1304 
1305  // Assignment calls Epetra_MultiVector::Assign(), which deeply
1306  // copies the data directly, ignoring the underlying
1307  // Epetra_Map(s). If A and mv don't have the same data
1308  // distribution (Epetra_Map), this may result in incorrect or
1309  // undefined behavior. Epetra_MultiVector::Update() also
1310  // ignores the Epetra_Maps, so we might as well just use the
1311  // (perhaps slightly cheaper) Assign() method via operator=().
1312  *mv_view = A;
1313  }
1314 
1317  static void MvScale ( Epetra_MultiVector& mv, double alpha )
1318  {
1319  TEUCHOS_TEST_FOR_EXCEPTION( mv.Scale( alpha )!=0, EpetraMultiVecFailure,
1320  "Anasazi::MultiVecTraits<double, Epetra_MultiVector>::MvScale call to Epetra_MultiVector::Scale(mv,double alpha) returned a nonzero value.");
1321  }
1322 
1325  static void MvScale ( Epetra_MultiVector& mv, const std::vector<double>& alpha )
1326  {
1327  // Check to make sure the vector is as long as the multivector has columns.
1328  int numvecs = mv.NumVectors();
1329 #ifdef TEUCHOS_DEBUG
1330  TEUCHOS_TEST_FOR_EXCEPTION( alpha.size() != (unsigned int)numvecs, std::invalid_argument,
1331  "Anasazi::MultiVecTraits<double, Epetra_MultiVector>::MvScale(mv,vector alpha): size of alpha inconsistent with number of vectors in mv.")
1332 #endif
1333  for (int i=0; i<numvecs; i++) {
1334  TEUCHOS_TEST_FOR_EXCEPTION( mv(i)->Scale(alpha[i])!=0, EpetraMultiVecFailure,
1335  "Anasazi::MultiVecTraits<double, Epetra_MultiVector>::MvScale call to Epetra_MultiVector::Scale() returned a nonzero value.");
1336  }
1337  }
1338 
1341  static void MvRandom( Epetra_MultiVector& mv )
1342  {
1343  TEUCHOS_TEST_FOR_EXCEPTION( mv.Random()!=0, EpetraMultiVecFailure,
1344  "Anasazi::MultiVecTraits<double, Epetra_MultiVector>::MvRandom call to Epetra_MultiVector::Random() returned a nonzero value.");
1345  }
1346 
1349  static void MvInit( Epetra_MultiVector& mv, double alpha = Teuchos::ScalarTraits<double>::zero() )
1350  {
1351  TEUCHOS_TEST_FOR_EXCEPTION( mv.PutScalar(alpha)!=0, EpetraMultiVecFailure,
1352  "Anasazi::MultiVecTraits<double, Epetra_MultiVector>::MvInit call to Epetra_MultiVector::PutScalar() returned a nonzero value.");
1353  }
1354 
1356 
1358 
1359 
1362  static void MvPrint( const Epetra_MultiVector& mv, std::ostream& os )
1363  { os << mv << std::endl; }
1364 
1366 
1367 #if defined(HAVE_ANASAZI_TPETRA) && defined(HAVE_ANASAZI_TSQR)
1368 # if defined(HAVE_TPETRA_EPETRA)
1369  typedef Epetra::TsqrAdaptor tsqr_adaptor_type;
1375 # endif // defined(HAVE_TPETRA_EPETRA)
1376 #endif // defined(HAVE_ANASAZI_TPETRA) && defined(HAVE_ANASAZI_TSQR)
1377  };
1378 
1380  //
1381  // Implementation of the Anasazi::OperatorTraits for Epetra::Operator.
1382  //
1384 
1396  template <>
1397  class OperatorTraits < double, Epetra_MultiVector, Epetra_Operator >
1398  {
1399  public:
1400 
1404  static void Apply ( const Epetra_Operator& Op,
1405  const Epetra_MultiVector& x,
1406  Epetra_MultiVector& y )
1407  {
1408 #ifdef TEUCHOS_DEBUG
1409  TEUCHOS_TEST_FOR_EXCEPTION(x.NumVectors() != y.NumVectors(),std::invalid_argument,
1410  "Anasazi::OperatorTraits<double,Epetra_MultiVector,Epetra_Operator>::Apply(Op,x,y): x and y must have the same number of columns.");
1411 #endif
1412  int ret = Op.Apply(x,y);
1413  TEUCHOS_TEST_FOR_EXCEPTION(ret != 0, OperatorError,
1414  "Anasazi::OperatorTraits<double,Epetra_Multivector,Epetra_Operator>::Apply(): Error in Epetra_Operator::Apply(). Code " << ret);
1415  }
1416 
1417  };
1418 
1419 } // end of Anasazi namespace
1420 
1421 #endif
1422 // end of file ANASAZI_EPETRA_ADAPTER_HPP
void MvRandom()
Fill the vectors in *this with random numbers.
Adapter class for creating an operators often used in solving generalized eigenproblems.
EpetraMultiVecAccessor is an interfaceto allow any Anasazi::MultiVec implementation that is based on ...
const Epetra_Comm & Comm() const
Returns the Epetra_Comm communicator associated with this operator.
static void MvAddMv(double alpha, const Epetra_MultiVector &A, double beta, const Epetra_MultiVector &B, Epetra_MultiVector &mv)
Replace mv with .
void MvInit(double alpha)
Replace each element of the vectors in *this with alpha.
static void SetBlock(const Epetra_MultiVector &A, const std::vector< int > &index, Epetra_MultiVector &mv)
Copy the vectors in A to a set of vectors in mv indicated by the indices given in index...
virtual ~EpetraMultiVecAccessor()
Destructor.
Adapter class for creating a weighted symmetric operator from an Epetra_MultiVector and Epetra_Operat...
ptrdiff_t GetGlobalLength() const
The number of rows in the multivector.
static void MvInit(Epetra_MultiVector &mv, double alpha=Teuchos::ScalarTraits< double >::zero())
Replace each element of the vectors in mv with alpha.
Virtual base class which defines basic traits for the operator type.
const char * Label() const
Returns a character string describing the operator.
virtual Epetra_MultiVector * GetEpetraMultiVec()
Return the pointer to the Epetra_MultiVector object.
static void MvPrint(const Epetra_MultiVector &mv, std::ostream &os)
Print the mv multi-vector to the os output stream.
static void MvRandom(Epetra_MultiVector &mv)
Replace the vectors in mv with random vectors.
static void MvTransMv(double alpha, const Epetra_MultiVector &A, const Epetra_MultiVector &mv, Teuchos::SerialDenseMatrix< int, double > &B)
Compute a dense matrix B through the matrix-matrix multiply .
bool UseTranspose() const
Returns the current UseTranspose setting [always false for this operator].
An exception class parent to all Anasazi exceptions.
double NormInf() const
Returns the infinity norm of the global matrix [not functional for this operator].
Interface for multivectors used by Anasazi&#39; linear solvers.
Namespace Anasazi contains the classes, structs, enums and utilities used by the Anasazi package...
Basic adapter class for Anasazi::Operator that uses Epetra_Operator.
static void MvDot(const Epetra_MultiVector &A, const Epetra_MultiVector &B, std::vector< double > &b)
Compute a vector b where the components are the individual dot-products of the i-th columns of A and ...
bool HasNormInf() const
Returns true if this object can provide an approximate inf-norm [always false for this operator]...
const Epetra_Map & OperatorRangeMap() const
Returns the Epetra_Map object associated with the range of this operator.
double NormInf() const
Returns the infinity norm of the global matrix [not functional for this operator].
const Epetra_Comm & Comm() const
Returns the Epetra_Comm communicator associated with this operator.
ConjType
Enumerated types used to specify conjugation arguments.
bool UseTranspose() const
Returns the current UseTranspose setting [always false for this operator].
static Teuchos::RCP< Epetra_MultiVector > CloneCopy(const Epetra_MultiVector &mv, const std::vector< int > &index)
Creates a new Epetra_MultiVector and copies the selected contents of mv into the new vector (deep cop...
Epetra_MultiVector * GetEpetraMultiVec()
Return the pointer to the Epetra_MultiVector object.
int GetNumberVecs() const
The number of vectors (i.e., columns) in the multivector.
const char * Label() const
Returns a character string describing the operator.
const Epetra_Map & OperatorRangeMap() const
Returns the Epetra_Map object associated with the range of this operator.
static void MvScale(Epetra_MultiVector &mv, const std::vector< double > &alpha)
Scale each element of the i-th vector in mv with alpha[i].
static void MvTimesMatAddMv(double alpha, const Epetra_MultiVector &A, const Teuchos::SerialDenseMatrix< int, double > &B, double beta, Epetra_MultiVector &mv)
Update mv with .
Traits class which defines basic operations on multivectors.
static Teuchos::RCP< const Epetra_MultiVector > CloneView(const Epetra_MultiVector &mv, const std::vector< int > &index)
Creates a new const Epetra_MultiVector that shares the selected contents of mv (shallow copy)...
Adapter class for creating a weighted operator from an Epetra_MultiVector and Epetra_Operator.
virtual const Epetra_MultiVector * GetEpetraMultiVec() const
Return the pointer to the Epetra_MultiVector object.
const Epetra_Map & OperatorDomainMap() const
Returns the Epetra_Map object associated with the domain of this operator.
static Teuchos::RCP< Epetra_MultiVector > Clone(const Epetra_MultiVector &mv, const int outNumVecs)
Creates a new empty Epetra_MultiVector containing numVecs columns.
Anasazi header file which uses auto-configuration information to include necessary C++ headers...
void MvPrint(std::ostream &os) const
Print *this EpetraMultiVec.
static ptrdiff_t GetGlobalLength(const Epetra_MultiVector &mv)
Obtain the vector length of mv.
int SetUseTranspose(bool)
If set true, the transpose of this operator will be applied [not functional for this operator]...
Adapter class for creating a symmetric operator from an Epetra_Operator.
const Epetra_MultiVector * GetEpetraMultiVec() const
Return the pointer to the Epetra_MultiVector object.
void MvScale(double alpha)
Scale each element of the vectors in *this with alpha.
static void MvScale(Epetra_MultiVector &mv, double alpha)
Scale each element of the vectors in mv with alpha.
static void Apply(const Epetra_Operator &Op, const Epetra_MultiVector &x, Epetra_MultiVector &y)
This method takes the Epetra_MultiVector x and applies the Epetra_Operator Op to it resulting in the ...
Templated virtual class for creating operators that can interface with the Anasazi::OperatorTraits cl...
static Teuchos::RCP< Epetra_MultiVector > CloneViewNonConst(Epetra_MultiVector &mv, const std::vector< int > &index)
Creates a new Epetra_MultiVector that shares the selected contents of mv (shallow copy)...
void MvNorm(std::vector< double > &normvec) const
Compute the 2-norm of each individual vector of *this. Upon return, normvec[i] holds the 2-norm of th...
EpetraMultiVecFailure is thrown when a return value from an Epetra call on an Epetra_MultiVector is n...
Types and exceptions used within Anasazi solvers and interfaces.
Interface for multivectors used by Anasazi&#39;s linear solvers.
Adapter class for creating a symmetric operator from an Epetra_MultiVector.
static void MvNorm(const Epetra_MultiVector &mv, std::vector< double > &normvec)
Compute the 2-norm of each individual vector of mv. Upon return, normvec[i] holds the value of ...
static int GetNumberVecs(const Epetra_MultiVector &mv)
Obtain the number of vectors in mv.
static Teuchos::RCP< Epetra_MultiVector > CloneCopy(const Epetra_MultiVector &mv)
Creates a new Epetra_MultiVector and copies contents of mv into the new vector (deep copy)...
Anasazi&#39;s templated virtual class for constructing an operator that can interface with the OperatorTr...
virtual ~EpetraMultiVec()
Destructor.
int SetUseTranspose(bool)
If set true, the transpose of this operator will be applied [not functional for this operator]...
EpetraOpFailure is thrown when a return value from an Epetra call on an Epetra_Operator is non-zero...
Exceptions thrown to signal error in operator application.
const Epetra_Map & OperatorDomainMap() const
Returns the Epetra_Map object associated with the domain of this operator.
Basic adapter class for Anasazi::MultiVec that uses Epetra_MultiVector.
bool HasNormInf() const
Returns true if this object can provide an approximate inf-norm [always false for this operator]...