30 #ifndef OOMPH_TRILINOS_EIGEN_SOLVER_HEADER 31 #define OOMPH_TRILINOS_EIGEN_SOLVER_HEADER 40 #include "AnasaziOutputManager.hpp" 41 #include "AnasaziBasicOutputManager.hpp" 42 #include "AnasaziConfigDefs.hpp" 43 #include "AnasaziOperator.hpp" 44 #include "AnasaziMultiVec.hpp" 45 #include "AnasaziBasicEigenproblem.hpp" 46 #include "AnasaziBlockKrylovSchurSolMgr.hpp" 55 class MultiVecTraits<double,
oomph::DoubleMultiVector>
61 static Teuchos::RCP<oomph::DoubleMultiVector>
Clone(
69 static Teuchos::RCP<oomph::DoubleMultiVector>
79 static Teuchos::RCP<oomph::DoubleMultiVector>
81 const std::vector<int>& index )
88 static Teuchos::RCP<oomph::DoubleMultiVector>
CloneCopy(
98 static Teuchos::RCP<oomph::DoubleMultiVector>
100 const std::vector<int>& index )
109 static Teuchos::RCP<oomph::DoubleMultiVector>
111 const Teuchos::Range1D& index )
121 static Teuchos::RCP<const oomph::DoubleMultiVector>
123 const std::vector<int>& index )
133 static Teuchos::RCP<oomph::DoubleMultiVector>
135 const std::vector<int>& index )
145 static Teuchos::RCP<oomph::DoubleMultiVector>
153 {
return static_cast<int>(mv.
nrow());}
157 {
return static_cast<int>(mv.
nvector()); }
163 const Teuchos::SerialDenseMatrix<int,double>&
B,
173 int mv_n_vector = mv.
nvector();
179 for(
int i=0;
i<n_row_local;++
i)
181 for(
int j=0;j<mv_n_vector;j++)
184 for(
int k=0;k<A_n_vector;k++) {res += C(k,
i)*
B(k,j);}
195 const unsigned n_vector = A.
nvector();
197 for(
unsigned v=0;v<n_vector;v++)
199 for(
unsigned i=0;
i<n_row_local;
i++)
201 mv(v,
i) = alpha*A(v,
i) + beta*
B(v,
i);
214 const std::vector<double>& alpha )
216 const unsigned n_vector = mv.
nvector();
218 for(
unsigned v=0;v<n_vector;v++)
220 for(
unsigned i=0;
i<n_row_local;
i++)
231 Teuchos::SerialDenseMatrix<int,double>&
B)
233 const unsigned A_nvec = A.
nvector();
235 const unsigned mv_nvec = mv.
nvector();
238 for(
unsigned v1=0;v1<A_nvec;v1++)
240 for(
unsigned v2=0;v2<mv_nvec;v2++)
243 for(
unsigned i=0;
i<A_nrow_local;
i++)
245 B(v1,v2) += A(v1,
i)*mv(v2,
i);
256 const int n_total_val = A_nvec*mv_nvec;
258 double b[n_total_val];
double b2[n_total_val];
260 for(
unsigned v1=0;v1<A_nvec;v1++)
262 for(
unsigned v2=0;v2<mv_nvec;v2++)
265 b2[count] = b[count];
271 MPI_Allreduce(&b,&b2,n_total_val,MPI_DOUBLE,MPI_SUM,
275 for(
unsigned v1=0;v1<A_nvec;v1++)
277 for(
unsigned v2=0;v2<mv_nvec;v2++)
279 B(v1,v2) = b2[count];
292 std::vector<double> &b)
300 std::vector<double> &normvec )
301 { mv.
norm(normvec); }
313 const std::vector<int>& index,
317 const unsigned n_index = index.size();
318 if(n_index==0) {
return;}
320 for(
unsigned v=0;v<n_index;v++)
322 for(
unsigned i=0;
i<n_row_local;
i++)
324 mv(index[v],
i) = A(v,
i);
342 const Teuchos::Range1D& index,
346 const unsigned n_index = index.size();
347 if(n_index==0) {
return;}
349 unsigned range_index = index.lbound();
350 for(
unsigned v=0;v<n_index;v++)
352 for(
unsigned i=0;
i<n_row_local;
i++)
354 mv(range_index,
i) = A(v,
i);
371 const unsigned n_vector = mv.
nvector();
373 for(
unsigned v=0;v<n_vector;v++)
375 for(
unsigned i=0;
i<n_row_local;
i++)
377 mv(v,
i) = Teuchos::ScalarTraits<double>::random();
386 Teuchos::ScalarTraits<double>::zero() )
437 class OperatorTraits<double,
oomph::DoubleMultiVector,
480 const double &sigma=0.0) :
481 Problem_pt(problem_pt), Linear_solver_pt(linear_solver_pt), Sigma(sigma)
501 const unsigned n_vec = x.
nvector();
512 Linear_solver_pt->
solve(AsigmaM_pt,X,Y);
517 for(
unsigned i=0;
i<n_row_local;
i++) {y(0,
i) = Y[
i];}
520 for(
unsigned v=1;v<n_vec;++v)
523 Linear_solver_pt->
resolve(X,Y);
527 for(
unsigned i=0;
i<n_row_local;
i++) {y(v,
i) = Y[
i];}
543 typedef Teuchos::ScalarTraits<ST>
SCT;
544 typedef SCT::magnitudeType
MT;
545 typedef Anasazi::MultiVec<ST>
MV;
546 typedef Anasazi::Operator<ST>
OP;
547 typedef Anasazi::MultiVecTraits<ST,MV>
MVT;
548 typedef Anasazi::OperatorTraits<ST,MV,OP>
OPT;
580 ANASAZI() : Linear_solver_pt(0), Default_linear_solver_pt(0), Spectrum(0),
581 NArnoldi(10), Sigma(0.0), Compute_eigenvectors(true)
583 Output_manager_pt =
new Anasazi::BasicOutputManager<ST>();
586 Anasazi::Warnings + Anasazi::FinalSummary + Anasazi::TimingDetails;
587 Output_manager_pt->setVerbosity(verbosity);
590 Output_manager_pt->stream(Anasazi::Warnings)
591 << Anasazi::Anasazi_Version() << std::endl << std::endl;
619 Vector<std::complex<double> > &eigenvalue,
629 Teuchos::RCP<DoubleMultiVector> initial =
631 Anasazi::MultiVecTraits<double,DoubleMultiVector>::MvRandom(*initial);
634 Teuchos::RCP<DoubleMultiVectorOperator> Op_pt =
637 this->linear_solver_pt(),Sigma));
645 new Anasazi::BasicEigenproblem<
double,DoubleMultiVector,
650 anasazi_pt->setHermitian(
false);
653 anasazi_pt->setNEV(n_eval);
656 if (anasazi_pt->setProblem() !=
true) {
658 <<
"Anasazi::BasicEigenproblem::setProblem() had an error." << std::endl
659 <<
"End Result: TEST FAILED" << std::endl;
667 Anasazi::Warnings + Anasazi::FinalSummary + Anasazi::TimingDetails;
669 Teuchos::ParameterList MyPL;
670 MyPL.set(
"Which",
"LM" );
671 MyPL.set(
"Block Size", 1 );
673 MyPL.set(
"Maximum Restarts", 500 );
674 MyPL.set(
"Orthogonalization",
"DGKS" );
675 MyPL.set(
"Verbosity", verbosity );
676 MyPL.set(
"Convergence Tolerance", tol );
677 Anasazi::BlockKrylovSchurSolMgr<
678 double,DoubleMultiVector,
680 BKS(anasazi_pt, MyPL);
683 Anasazi::ReturnType ret = BKS.solve();
684 bool testFailed =
false;
685 if (ret != Anasazi::Converged) {
689 if(testFailed) {
oomph_info <<
"Eigensolver not converged\n";}
692 Anasazi::Eigensolution<double,DoubleMultiVector> sol =
693 anasazi_pt->getSolution();
694 std::vector<Anasazi::Value<double> > evals = sol.Evals;
695 Teuchos::RCP<DoubleMultiVector> evecs = sol.Evecs;
697 eigenvalue.resize(evals.size());
698 eigenvector.resize(evals.size());
700 for(
unsigned i=0;
i<evals.size();
i++)
703 double a = evals[
i].realpart;
double b = evals[
i].imagpart;
704 double det = a*a + b*b;
705 eigenvalue[
i] = std::complex<double>(a/det+Sigma,-b/det);
708 eigenvector[
i].build(evecs->distribution_pt());
709 unsigned nrow_local= evecs->nrow_local();
711 for(
unsigned n=0;n<nrow_local;n++)
713 eigenvector[
i][n] = (*evecs)(
i,n);
static int GetVecLength(const oomph::DoubleMultiVector &mv)
Obtain the global length of the vector.
virtual ~DoubleMultiVectorOperator()
virtual destructor
virtual void solve(Problem *const &problem_pt, DoubleVector &result)=0
Solver: Takes pointer to problem and returns the results vector which contains the solution of the li...
static void MvAddMv(const double alpha, const oomph::DoubleMultiVector &A, const double beta, const oomph::DoubleMultiVector &B, oomph::DoubleMultiVector &mv)
Replace mv with .
static void MvDot(const oomph::DoubleMultiVector &mv, const oomph::DoubleMultiVector &A, std::vector< double > &b)
Compute a vector b where the components are the individual dot-products of the i-th columns of A and ...
LinearSolver *& linear_solver_pt()
Return a pointer to the linear solver object.
static Teuchos::RCP< oomph::DoubleMultiVector > CloneView(oomph::DoubleMultiVector &mv, const std::vector< int > &index)
Creates a new oomph::DoubleMultiVector that contains shallow copies of selected entries of the oomph:...
void get_eigenvalues_left_of_shift()
Set the desired eigenvalues to be left of the shift.
bool Small
Boolean to set which part of the spectrum left (default) or right of the shifted value.
void multiply(const DoubleVector &x, DoubleVector &soln) const
Multiply the matrix by the vector x: soln=Ax.
static void MvScale(oomph::DoubleMultiVector &mv, const double alpha)
Scale each element of the vectors in mv with alpha.
virtual void apply(const DoubleMultiVector &x, DoubleMultiVector &y) const =0
The apply interface.
void apply(const DoubleMultiVector &x, DoubleMultiVector &y) const
The apply interface.
ANASAZI(const ANASAZI &)
Empty copy constructor.
void enable_compute_eigenvectors()
Set to enable the computation of the eigenvectors (default)
virtual void get_eigenproblem_matrices(CRDoubleMatrix &mass_matrix, CRDoubleMatrix &main_matrix, const double &shift=0.0)
Get the matrices required by a eigensolver. If the shift parameter is non-zero the second matrix will...
static void MvPrint(const oomph::DoubleMultiVector &mv, std::ostream &os)
Print the mv multi-vector to the os output stream.
int & narnoldi()
Access function for the number of Arnoldi vectors.
void disable_compute_eigenvectors()
Set to disable the computation of the eigenvectors.
void output(std::ostream &outfile) const
output the contents of the vector
Anasazi::OperatorTraits< ST, MV, OP > OPT
LinearSolver * Linear_solver_pt
bool Compute_eigenvectors
Boolean to indicate whether or not to compute the eigenvectors.
int Spectrum
Integer to set whether the real, imaginary or magnitude is required to be small or large...
OomphCommunicator * communicator_pt() const
const access to the communicator pointer
virtual void resolve(const DoubleVector &rhs, DoubleVector &result)
Resolve the system defined by the last assembled jacobian and the rhs vector. Solution is returned in...
static Teuchos::RCP< oomph::DoubleMultiVector > CloneCopy(const oomph::DoubleMultiVector &mv)
Creates a deep copy of the DoubleMultiVector mv return Reference-counted pointer to the new DoubleMul...
static void SetBlock(const oomph::DoubleMultiVector &A, const Teuchos::Range1D &index, oomph::DoubleMultiVector &mv)
Deep copy of A into specified columns of mv.
static void MvRandom(oomph::DoubleMultiVector &mv)
Replace the vectors in mv with random vectors.
LinearAlgebraDistribution *const & dof_distribution_pt() const
Return the pointer to the dof distribution (read-only)
LinearSolver *const & linear_solver_pt() const
Return a pointer to the linear solver object (const version)
LinearSolver * Default_linear_solver_pt
Pointer to a default linear solver.
static Teuchos::RCP< const oomph::DoubleMultiVector > CloneView(const oomph::DoubleMultiVector &mv, const std::vector< int > &index)
Creates a new oomph::DoubleMultiVector that contains shallow copies of selected entries of the oomph:...
const int & narnoldi() const
Access function for the number of Arnoldi vectors (const version)
Class for the shift invert operation.
static Teuchos::RCP< oomph::DoubleMultiVector > CloneViewNonConst(oomph::DoubleMultiVector &mv, const Teuchos::Range1D &index)
Creates a new oomph::DoubleMultiVector that contains shallow copies of selected entries of the oomph:...
DoubleMultiVectorOperator()
Empty constructor.
static void Apply(const oomph::DoubleMultiVectorOperator &Op, const oomph::DoubleMultiVector &x, oomph::DoubleMultiVector &y)
Matrix operator application method.
void get_eigenvalues_right_of_shift()
Set the desired eigenvalues to be right of the shift.
Class for the Anasazi eigensolver.
static Teuchos::RCP< oomph::DoubleMultiVector > CloneView(oomph::DoubleMultiVector &mv, const Teuchos::Range1D &index)
Creates a new oomph::DoubleMultiVector that contains shallow copies of selected entries of the oomph:...
bool distributed() const
distribution is serial or distributed
double Sigma
Set the shifted value.
Anasazi::MultiVec< ST > MV
static Teuchos::RCP< oomph::DoubleMultiVector > CloneCopy(const oomph::DoubleMultiVector &mv, const std::vector< int > &index)
Creates a new oomph::DoubleMultiVector and (deep) copies the contents of the vectors in index into th...
int NArnoldi
Number of Arnoldi vectors to compute.
DoubleVector & doublevector(const unsigned &i)
access to the DoubleVector representatoin
void initialise(const double &initial_value)
initialise the whole vector with value v
static void MvScale(oomph::DoubleMultiVector &mv, const std::vector< double > &alpha)
Scale each element of the i-th vector in mv with alpha[i].
virtual ~ANASAZI()
Destructor, delete the linear solver.
Anasazi::MultiVecTraits< ST, MV > MVT
static int GetNumberVecs(const oomph::DoubleMultiVector &mv)
Obtain the number of vectors in the multivector.
void norm(std::vector< double > &result) const
compute the 2 norm of this vector
LinearSolver * Linear_solver_pt
Pointer to a linear solver.
Anasazi::Operator< ST > OP
static void Assign(const oomph::DoubleMultiVector &A, oomph::DoubleMultiVector &mv)
mv := A
static Teuchos::RCP< oomph::DoubleMultiVector > CloneViewNonConst(oomph::DoubleMultiVector &mv, const std::vector< int > &index)
Creates a new oomph::DoubleMultiVector that contains shallow copies of selected entries of the oomph:...
ProblemBasedShiftInvertOperator(Problem *const &problem_pt, LinearSolver *const &linear_solver_pt, const double &sigma=0.0)
Teuchos::ScalarTraits< ST > SCT
void track_eigenvalue_real_part()
Set the real part to be the quantity of interest (default)
void disable_doc_time()
Disable documentation of solve times.
static void MvTransMv(const double alpha, const oomph::DoubleMultiVector &A, const oomph::DoubleMultiVector &mv, Teuchos::SerialDenseMatrix< int, double > &B)
Compute a dense matrix B through the matrix-matrix multiply .
virtual void enable_resolve()
Enable resolve (i.e. store matrix and/or LU decomposition, say) Virtual so it can be overloaded to pe...
static void MvTimesMatAddMv(const double alpha, const oomph::DoubleMultiVector &A, const Teuchos::SerialDenseMatrix< int, double > &B, const double beta, oomph::DoubleMultiVector &mv)
Update mv with .
void track_eigenvalue_imaginary_part()
Set the imaginary part fo the quantity of interest.
A multi vector in the mathematical sense, initially developed for linear algebra type applications...
void dot(const DoubleMultiVector &vec, std::vector< double > &result) const
compute the 2 norm of this vector
LinearSolver *& linear_solver_pt()
Return a pointer to the linear solver object.
static void SetBlock(const oomph::DoubleMultiVector &A, const std::vector< int > &index, oomph::DoubleMultiVector &mv)
Copy the vectors in A to a set of vectors in mv indicated by the indices given in index...
void solve_eigenproblem(Problem *const &problem_pt, const int &n_eval, Vector< std::complex< double > > &eigenvalue, Vector< DoubleVector > &eigenvector)
Solve the eigen problem.
unsigned nrow() const
access function to the number of global rows.
static Teuchos::RCP< oomph::DoubleMultiVector > CloneCopy(const oomph::DoubleMultiVector &mv, const Teuchos::Range1D &index)
Deep copy of specified columns of oomph::DoubleMultiVector return Reference-counted pointer to the ne...
unsigned nrow_local() const
access function for the num of local rows on this processor.
A vector in the mathematical sense, initially developed for linear algebra type applications. If MPI then this vector can be distributed - its distribution is described by the LinearAlgebraDistribution object at Distribution_pt. Data is stored in a C-style pointer vector (double*)
static Teuchos::RCP< oomph::DoubleMultiVector > Clone(const oomph::DoubleMultiVector &mv, const int numvecs)
Creates a new empty DoubleMultiVector containing numvecs columns. Return a reference-counted pointer ...
void track_eigenvalue_magnitude()
Set the magnitude to be the quantity of interest.
unsigned nvector() const
Return the number of vectors.
static void MvNorm(const oomph::DoubleMultiVector &mv, std::vector< double > &normvec)
Compute the 2-norm of each individual vector of mv. Upon return, normvec[i] holds the value of ...
static void MvInit(oomph::DoubleMultiVector &mv, const double alpha=Teuchos::ScalarTraits< double >::zero())
Replace each element of the vectors in mv with alpha.
A class for compressed row matrices. This is a distributable object.
LinearAlgebraDistribution * distribution_pt() const
access to the LinearAlgebraDistribution
Anasazi::OutputManager< ST > * Output_manager_pt
Pointer to output manager.