Anasazi  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
AnasaziSpecializedEpetraAdapter.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Anasazi: Block Eigensolvers Package
4 //
5 // Copyright 2004 NTESS and the Anasazi contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
11 #include "Teuchos_ScalarTraits.hpp"
12 
17 namespace Anasazi {
18 
20  //
21  //--------Anasazi::EpetraOpMultiVec Implementation-------------------------------
22  //
24 
25  // Construction/Destruction
26 
28  : Epetra_OP( Op )
29  {
30  Epetra_MV = Teuchos::rcp( new Epetra_MultiVector(Map_in, numvecs) );
31  Epetra_MV_Temp = Teuchos::rcp( new Epetra_MultiVector(Map_in, numvecs) );
32  }
33 
35  const Epetra_BlockMap& Map_in, double * array, const int numvecs, const int stride)
36  : Epetra_OP( Op )
37  {
38  Epetra_MV = Teuchos::rcp( new Epetra_MultiVector(Epetra_DataAccess::Copy, Map_in, array, stride, numvecs) );
39  Epetra_MV_Temp = Teuchos::rcp( new Epetra_MultiVector(Map_in, numvecs) );
40  }
41 
43  Epetra_DataAccess CV, const Epetra_MultiVector& P_vec, const std::vector<int>& index)
44  : Epetra_OP( Op )
45  {
46  Epetra_MV = Teuchos::rcp( new Epetra_MultiVector(CV, P_vec, &(const_cast<std::vector<int> &>(index))[0], index.size()) );
47  Epetra_MV_Temp = Teuchos::rcp( new Epetra_MultiVector( P_vec.Map(), index.size()) );
48  }
49 
51  : Epetra_OP( P_vec.Epetra_OP )
52  {
53  Epetra_MV = Teuchos::rcp( new Epetra_MultiVector( *(P_vec.Epetra_MV) ) );
54  Epetra_MV_Temp = Teuchos::rcp( new Epetra_MultiVector( *(P_vec.Epetra_MV_Temp) ) );
55  }
56 
57  //
58  // member functions inherited from Anasazi::MultiVec
59  //
60  //
61  // Simulating a virtual copy constructor. If we could rely on the co-variance
62  // of virtual functions, we could return a pointer to EpetraOpMultiVec
63  // (the derived type) instead of a pointer to the pure virtual base class.
64  //
65 
66  MultiVec<double>* EpetraOpMultiVec::Clone ( const int numvecs ) const
67  {
68  EpetraOpMultiVec *ptr_apv = new EpetraOpMultiVec( Epetra_OP, Epetra_MV->Map(), numvecs );
69  return ptr_apv; // safe upcast.
70  }
71  //
72  // the following is a virtual copy constructor returning
73  // a pointer to the pure virtual class. vector values are
74  // copied.
75  //
76 
78  {
79  EpetraOpMultiVec *ptr_apv = new EpetraOpMultiVec(*this);
80  return ptr_apv; // safe upcast
81  }
82 
83 
84  MultiVec<double>* EpetraOpMultiVec::CloneCopy ( const std::vector<int>& index ) const
85  {
86  EpetraOpMultiVec * ptr_apv = new EpetraOpMultiVec( Epetra_OP, Copy, *Epetra_MV, index);
87  return ptr_apv; // safe upcast.
88  }
89 
90 
91  MultiVec<double>* EpetraOpMultiVec::CloneViewNonConst ( const std::vector<int>& index )
92  {
93  EpetraOpMultiVec * ptr_apv = new EpetraOpMultiVec( Epetra_OP, Epetra_DataAccess::View, *Epetra_MV, index);
94  return ptr_apv; // safe upcast.
95  }
96 
97  const MultiVec<double>* EpetraOpMultiVec::CloneView ( const std::vector<int>& index ) const
98  {
99  EpetraOpMultiVec * ptr_apv = new EpetraOpMultiVec( Epetra_OP, Epetra_DataAccess::View, *Epetra_MV, index);
100  return ptr_apv; // safe upcast.
101  }
102 
103 
104  void EpetraOpMultiVec::SetBlock( const MultiVec<double>& A, const std::vector<int>& index )
105  {
106  // this should be revisited to e
107  EpetraOpMultiVec temp_vec(Epetra_OP, Epetra_DataAccess::View, *Epetra_MV, index);
108 
109  int numvecs = index.size();
110  if ( A.GetNumberVecs() != numvecs ) {
111  std::vector<int> index2( numvecs );
112  for(int i=0; i<numvecs; i++)
113  index2[i] = i;
114  EpetraOpMultiVec *tmp_vec = dynamic_cast<EpetraOpMultiVec *>(&const_cast<MultiVec<double> &>(A));
115  TEUCHOS_TEST_FOR_EXCEPTION( tmp_vec==NULL, std::invalid_argument, "Anasazi::EpetraOpMultiVec::SetBlocks() cast of MultiVec<double> to EpetraOpMultiVec failed.");
116  EpetraOpMultiVec A_vec(Epetra_OP, Epetra_DataAccess::View, *(tmp_vec->GetEpetraMultiVector()), index2);
117  temp_vec.MvAddMv( 1.0, A_vec, 0.0, A_vec );
118  }
119  else {
120  temp_vec.MvAddMv( 1.0, A, 0.0, A );
121  }
122  }
123 
124  //-------------------------------------------------------------
125  //
126  // *this <- alpha * A * B + beta * (*this)
127  //
128  //-------------------------------------------------------------
129 
130  void EpetraOpMultiVec::MvTimesMatAddMv ( double alpha, const MultiVec<double>& A,
131  const Teuchos::SerialDenseMatrix<int,double>& B, double beta )
132  {
133  Epetra_LocalMap LocalMap(B.numRows(), 0, Epetra_MV->Map().Comm());
134  Epetra_MultiVector B_Pvec(Epetra_DataAccess::View, LocalMap, B.values(), B.stride(), B.numCols());
135 
136  EpetraOpMultiVec *A_vec = dynamic_cast<EpetraOpMultiVec *>(&const_cast<MultiVec<double> &>(A));
137  TEUCHOS_TEST_FOR_EXCEPTION( A_vec==NULL, std::invalid_argument, "Anasazi::EpetraOpMultiVec::SetBlocks() cast of MultiVec<double> to EpetraOpMultiVec failed.");
138 
140  Epetra_MV->Multiply( 'N', 'N', alpha, *(A_vec->GetEpetraMultiVector()), B_Pvec, beta ) != 0,
141  EpetraSpecializedMultiVecFailure, "Anasazi::EpetraOpMultiVec::MvTimesMatAddMv() call to Epetra_MultiVec::Multiply() returned a nonzero value.");
142  }
143 
144  //-------------------------------------------------------------
145  //
146  // *this <- alpha * A + beta * B
147  //
148  //-------------------------------------------------------------
149 
150  void EpetraOpMultiVec::MvAddMv ( double alpha , const MultiVec<double>& A,
151  double beta, const MultiVec<double>& B)
152  {
153  EpetraOpMultiVec *A_vec = dynamic_cast<EpetraOpMultiVec *>(&const_cast<MultiVec<double> &>(A));
154  TEUCHOS_TEST_FOR_EXCEPTION( A_vec==NULL, std::invalid_argument, "Anasazi::EpetraOpMultiVec::MvAddMv() cast of MultiVec<double> to EpetraOpMultiVec failed.");
155  EpetraOpMultiVec *B_vec = dynamic_cast<EpetraOpMultiVec *>(&const_cast<MultiVec<double> &>(B));
156  TEUCHOS_TEST_FOR_EXCEPTION( B_vec==NULL, std::invalid_argument, "Anasazi::EpetraOpMultiVec::MvAddMv() cast of MultiVec<double> to EpetraOpMultiVec failed.");
157 
159  Epetra_MV->Update( alpha, *(A_vec->GetEpetraMultiVector()), beta, *(B_vec->GetEpetraMultiVector()), 0.0 ) != 0,
160  EpetraSpecializedMultiVecFailure, "Anasazi::EpetraOpMultiVec::MvAddMv() call to Epetra_MultiVec::Update() returned a nonzero value.");
161  }
162 
163  //-------------------------------------------------------------
164  //
165  // dense B <- alpha * A^T * OP * (*this)
166  //
167  //-------------------------------------------------------------
168 
169  void EpetraOpMultiVec::MvTransMv ( double alpha, const MultiVec<double>& A,
171 #ifdef HAVE_ANASAZI_EXPERIMENTAL
172  , ConjType conj
173 #endif
174  ) const
175  {
176  EpetraOpMultiVec *A_vec = dynamic_cast<EpetraOpMultiVec *>(&const_cast<MultiVec<double> &>(A));
177 
178  if (A_vec) {
179  Epetra_LocalMap LocalMap(B.numRows(), 0, Epetra_MV->Map().Comm());
180  Epetra_MultiVector B_Pvec(Epetra_DataAccess::View, LocalMap, B.values(), B.stride(), B.numCols());
181 
182  int info = Epetra_OP->Apply( *Epetra_MV, *Epetra_MV_Temp );
184  "Anasazi::EpetraOpMultiVec::MvTransMv(): Error returned from Epetra_Operator::Apply()" );
185 
187  B_Pvec.Multiply( 'T', 'N', alpha, *(A_vec->GetEpetraMultiVector()), *Epetra_MV_Temp, 0.0 ) != 0,
188  EpetraSpecializedMultiVecFailure, "Anasazi::EpetraOpMultiVec::MvTransMv() call to Epetra_MultiVector::Multiply() returned a nonzero value.");
189  }
190  }
191 
192  //-------------------------------------------------------------
193  //
194  // b[i] = A[i]^T * OP * this[i]
195  //
196  //-------------------------------------------------------------
197 
198  void EpetraOpMultiVec::MvDot ( const MultiVec<double>& A, std::vector<double> & b
199 #ifdef HAVE_ANASAZI_EXPERIMENTAL
200  , ConjType conj
201 #endif
202  ) const
203  {
204  EpetraOpMultiVec *A_vec = dynamic_cast<EpetraOpMultiVec *>(&const_cast<MultiVec<double> &>(A));
205  TEUCHOS_TEST_FOR_EXCEPTION( A_vec==NULL, std::invalid_argument, "Anasazi::EpetraOpMultiVec::MvDot() cast of MultiVec<double> to EpetraOpMultiVec failed.");
206 
207  int info = Epetra_OP->Apply( *Epetra_MV, *Epetra_MV_Temp );
209  "Anasazi::EpetraOpMultiVec::MvDot(): Error returned from Epetra_Operator::Apply()" );
210 
211  if (( (int)b.size() >= A_vec->GetNumberVecs() ) ) {
213  Epetra_MV_Temp->Dot( *(A_vec->GetEpetraMultiVector()), &b[0] ) != 0,
214  EpetraSpecializedMultiVecFailure, "Anasazi::EpetraOpMultiVec::MvDot() call to Epetra_MultiVector::Dot() returned an error.");
215  }
216  }
217 
218  //-------------------------------------------------------------
219  //
220  // normvec[i] = || this[i] ||_OP
221  //
222  //-------------------------------------------------------------
223 
224  void EpetraOpMultiVec::MvNorm ( std::vector<double> & normvec ) const
225  {
226  int info = Epetra_OP->Apply( *Epetra_MV, *Epetra_MV_Temp );
228  "Anasazi::EpetraOpMultiVec::MvNorm(): Error returned from Epetra_Operator::Apply()" );
229 
230  if (( (int)normvec.size() >= Epetra_MV->NumVectors() ) ) {
232  Epetra_MV_Temp->Dot( *Epetra_MV, &normvec[0] ) != 0,
233  EpetraSpecializedMultiVecFailure, "Anasazi::EpetraOpMultiVec::MvNorm() call to Epetra_MultiVector::Dot() returned an error.");
234  }
235 
236  for (int i=0; i<Epetra_MV->NumVectors(); ++i)
237  normvec[i] = Teuchos::ScalarTraits<double>::squareroot( normvec[i] );
238  }
239 
240  //-------------------------------------------------------------
241  //
242  // this[i] = alpha[i] * this[i]
243  //
244  //-------------------------------------------------------------
245  void EpetraOpMultiVec::MvScale ( const std::vector<double>& alpha )
246  {
247  // Check to make sure the vector is as long as the multivector has columns.
248  int numvecs = this->GetNumberVecs();
249  TEUCHOS_TEST_FOR_EXCEPTION( (int)alpha.size() != numvecs, std::invalid_argument,
250  "Anasazi::EpetraOpMultiVec::MvScale() alpha argument size was inconsistent with number of vectors in mv.");
251 
252  std::vector<int> tmp_index( 1, 0 );
253  for (int i=0; i<numvecs; i++) {
254  Epetra_MultiVector temp_vec(Epetra_DataAccess::View, *Epetra_MV, &tmp_index[0], 1);
256  temp_vec.Scale( alpha[i] ) != 0,
257  EpetraSpecializedMultiVecFailure, "Anasazi::EpetraOpMultiVec::MvScale() call to Epetra_MultiVector::Scale() returned a nonzero value.");
258  tmp_index[0]++;
259  }
260  }
261 
262 } // namespace Anasazi
ScalarType * values() const
Declarations of specialized Anasazi multi-vector and operator classes using Epetra_MultiVector and Ep...
void MvTransMv(double alpha, const MultiVec< double > &A, Teuchos::SerialDenseMatrix< int, double > &B) const
Compute a dense matrix B through the matrix-matrix multiply .
void MvDot(const MultiVec< double > &A, std::vector< double > &b) const
Compute a vector b where the components are the individual dot-products, i.e. where A[i] is the i-th...
const MultiVec< double > * CloneView(const std::vector< int > &index) const
Creates a new EpetraOpMultiVec that shares the selected contents of *this.
EpetraSpecializedMultiVecFailure is thrown when a return value from an Epetra call on an Epetra_Multi...
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
int GetNumberVecs() const
Obtain the vector length of *this.
EpetraOpMultiVec(const Teuchos::RCP< Epetra_Operator > &Op, const Epetra_BlockMap &Map_in, const int numvecs)
Basic EpetraOpMultiVec constructor.
virtual int Apply(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const =0
ConjType
Enumerated types used to specify conjugation arguments.
virtual int GetNumberVecs() const =0
The number of vectors (i.e., columns) in the multivector.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
void MvScale(double alpha)
Scale each element of the vectors in *this with alpha.
Specialized adapter class for Anasazi::MultiVec that uses Epetra_MultiVector and Epetra_Operator to d...
MultiVec< double > * CloneViewNonConst(const std::vector< int > &index)
Creates a new EpetraOpMultiVec that shares the selected contents of *this.
MultiVec< double > * CloneCopy() const
Creates a new EpetraOpMultiVec and copies contents of *this into the new vector (deep copy)...
MultiVec< double > * Clone(const int numvecs) const
Creates a new empty EpetraOpMultiVec containing numvecs columns.
OrdinalType numCols() const
void SetBlock(const MultiVec< double > &A, const std::vector< int > &index)
Copy the vectors in A to a set of vectors in *this.
void MvTimesMatAddMv(double alpha, const MultiVec< double > &A, const Teuchos::SerialDenseMatrix< int, double > &B, double beta)
Update *this with .
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...
Epetra_DataAccess
void MvAddMv(double alpha, const MultiVec< double > &A, double beta, const MultiVec< double > &B)
Replace *this with .
OrdinalType stride() const
OrdinalType numRows() const