Anasazi Version of the Day
Loading...
Searching...
No Matches
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
16
17namespace Anasazi {
18
20 //
21 //--------Anasazi::EpetraOpMultiVec Implementation-------------------------------
22 //
24
25 // Construction/Destruction
26
27 EpetraOpMultiVec::EpetraOpMultiVec(const Teuchos::RCP<Epetra_Operator> &Op, const Epetra_BlockMap& Map_in, const int numvecs)
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
34 EpetraOpMultiVec::EpetraOpMultiVec(const Teuchos::RCP<Epetra_Operator> &Op,
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
42 EpetraOpMultiVec::EpetraOpMultiVec(const Teuchos::RCP<Epetra_Operator> &Op,
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
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
139 TEUCHOS_TEST_FOR_EXCEPTION(
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
158 TEUCHOS_TEST_FOR_EXCEPTION(
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,
170 Teuchos::SerialDenseMatrix<int,double>& B
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 );
183 TEUCHOS_TEST_FOR_EXCEPTION( info != 0, EpetraSpecializedMultiVecFailure,
184 "Anasazi::EpetraOpMultiVec::MvTransMv(): Error returned from Epetra_Operator::Apply()" );
185
186 TEUCHOS_TEST_FOR_EXCEPTION(
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 );
208 TEUCHOS_TEST_FOR_EXCEPTION( info != 0, EpetraSpecializedMultiVecFailure,
209 "Anasazi::EpetraOpMultiVec::MvDot(): Error returned from Epetra_Operator::Apply()" );
210
211 if (( (int)b.size() >= A_vec->GetNumberVecs() ) ) {
212 TEUCHOS_TEST_FOR_EXCEPTION(
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 );
227 TEUCHOS_TEST_FOR_EXCEPTION( info != 0, EpetraSpecializedMultiVecFailure,
228 "Anasazi::EpetraOpMultiVec::MvNorm(): Error returned from Epetra_Operator::Apply()" );
229
230 if (( (int)normvec.size() >= Epetra_MV->NumVectors() ) ) {
231 TEUCHOS_TEST_FOR_EXCEPTION(
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);
255 TEUCHOS_TEST_FOR_EXCEPTION(
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
Declarations of specialized Anasazi multi-vector and operator classes using Epetra_MultiVector and Ep...
void MvScale(double alpha)
Scale each element of the vectors in *this with alpha.
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...
MultiVec< double > * Clone(const int numvecs) const
Creates a new empty EpetraOpMultiVec containing numvecs columns.
void MvAddMv(double alpha, const MultiVec< double > &A, double beta, const MultiVec< double > &B)
Replace *this with .
MultiVec< double > * CloneCopy() const
Creates a new EpetraOpMultiVec and copies contents of *this into the new vector (deep copy).
const MultiVec< double > * CloneView(const std::vector< int > &index) const
Creates a new EpetraOpMultiVec that shares the selected contents of *this.
EpetraOpMultiVec(const Teuchos::RCP< Epetra_Operator > &Op, const Epetra_BlockMap &Map_in, const int numvecs)
Basic EpetraOpMultiVec constructor.
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 MvTimesMatAddMv(double alpha, const MultiVec< double > &A, const Teuchos::SerialDenseMatrix< int, double > &B, double beta)
Update *this with .
void SetBlock(const MultiVec< double > &A, const std::vector< int > &index)
Copy the vectors in A to a set of vectors in *this.
int GetNumberVecs() const
Obtain the vector length of *this.
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 ...
MultiVec< double > * CloneViewNonConst(const std::vector< int > &index)
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...
virtual int GetNumberVecs() const =0
The number of vectors (i.e., columns) in the multivector.
Namespace Anasazi contains the classes, structs, enums and utilities used by the Anasazi package.
ConjType
Enumerated types used to specify conjugation arguments.