26 #ifndef OOMPH_TRILINOS_EIGEN_SOLVER_HEADER
27 #define OOMPH_TRILINOS_EIGEN_SOLVER_HEADER
36 #include "AnasaziOutputManager.hpp"
37 #include "AnasaziBasicOutputManager.hpp"
38 #include "AnasaziConfigDefs.hpp"
39 #include "AnasaziOperator.hpp"
40 #include "AnasaziMultiVec.hpp"
41 #include "AnasaziBasicEigenproblem.hpp"
42 #include "AnasaziBlockKrylovSchurSolMgr.hpp"
51 class MultiVecTraits<double,
oomph::DoubleMultiVector>
56 static Teuchos::RCP<oomph::DoubleMultiVector>
Clone(
64 static Teuchos::RCP<oomph::DoubleMultiVector>
CloneCopy(
74 static Teuchos::RCP<oomph::DoubleMultiVector>
CloneCopy(
82 static Teuchos::RCP<oomph::DoubleMultiVector>
CloneCopy(
113 static Teuchos::RCP<const oomph::DoubleMultiVector>
CloneView(
124 static Teuchos::RCP<oomph::DoubleMultiVector>
CloneView(
135 static Teuchos::RCP<oomph::DoubleMultiVector>
CloneView(
144 return static_cast<int>(mv.
nrow());
150 return static_cast<int>(mv.
nvector());
157 const Teuchos::SerialDenseMatrix<int, double>&
B,
168 int mv_n_vector = mv.
nvector();
174 for (
int i = 0;
i < n_row_local; ++
i)
176 for (
int j = 0; j < mv_n_vector; j++)
179 for (
int k = 0; k < A_n_vector; k++)
181 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);
217 const std::vector<double>& alpha)
219 const unsigned n_vector = mv.
nvector();
221 for (
unsigned v = 0; v < n_vector; v++)
223 for (
unsigned i = 0;
i < n_row_local;
i++)
225 mv(v,
i) *= alpha[v];
236 Teuchos::SerialDenseMatrix<int, double>&
B)
238 const unsigned A_nvec = A.
nvector();
240 const unsigned mv_nvec = mv.
nvector();
243 for (
unsigned v1 = 0; v1 < A_nvec; v1++)
245 for (
unsigned v2 = 0; v2 < mv_nvec; v2++)
248 for (
unsigned i = 0;
i < A_nrow_local;
i++)
250 B(v1, v2) += A(v1,
i) * mv(v2,
i);
261 const int n_total_val = A_nvec * mv_nvec;
263 double b[n_total_val];
264 double b2[n_total_val];
266 for (
unsigned v1 = 0; v1 < A_nvec; v1++)
268 for (
unsigned v2 = 0; v2 < mv_nvec; v2++)
270 b[count] =
B(v1, v2);
271 b2[count] = b[count];
285 for (
unsigned v1 = 0; v1 < A_nvec; v1++)
287 for (
unsigned v2 = 0; v2 < mv_nvec; v2++)
289 B(v1, v2) = b2[count];
304 std::vector<double>& b)
315 std::vector<double>& normvec)
332 const std::vector<int>& index,
336 const unsigned n_index = index.size();
342 for (
unsigned v = 0; v < n_index; v++)
344 for (
unsigned i = 0;
i < n_row_local;
i++)
346 mv(index[v],
i) = A(v,
i);
364 const Teuchos::Range1D& index,
368 const unsigned n_index = index.size();
374 unsigned range_index = index.lbound();
375 for (
unsigned v = 0; v < n_index; v++)
377 for (
unsigned i = 0;
i < n_row_local;
i++)
379 mv(range_index,
i) = A(v,
i);
398 const unsigned n_vector = mv.
nvector();
400 for (
unsigned v = 0; v < n_vector; v++)
402 for (
unsigned i = 0;
i < n_row_local;
i++)
404 mv(v,
i) = Teuchos::ScalarTraits<double>::random();
413 const double alpha = Teuchos::ScalarTraits<double>::zero())
465 class OperatorTraits<double,
466 oomph::DoubleMultiVector,
506 const double& sigma = 0.0)
528 const unsigned n_vec = x.
nvector();
550 for (
unsigned i = 0;
i < n_row_local;
i++)
556 for (
unsigned v = 1; v < n_vec; ++v)
565 for (
unsigned i = 0;
i < n_row_local;
i++)
597 const double& sigma = 0.0)
622 const unsigned n_vec = x.
nvector();
639 for (
unsigned i = 0;
i < n_row_local;
i++)
645 for (
unsigned v = 1; v < n_vec; ++v)
650 for (
unsigned i = 0;
i < n_row_local;
i++)
666 typedef Teuchos::ScalarTraits<ST>
SCT;
667 typedef SCT::magnitudeType
MT;
668 typedef Anasazi::MultiVec<ST>
MV;
669 typedef Anasazi::Operator<ST>
OP;
670 typedef Anasazi::MultiVecTraits<ST, MV>
MVT;
671 typedef Anasazi::OperatorTraits<ST, MV, OP>
OPT;
708 verbosity += Anasazi::Warnings;
709 verbosity += Anasazi::FinalSummary;
710 verbosity += Anasazi::TimingDetails;
715 << Anasazi::Anasazi_Version() << std::endl
766 Vector<std::complex<double>>& alpha,
770 const bool& do_adjoint_problem)
780 unsigned n = eigenvalue.size();
783 for (
unsigned i = 0;
i < n;
i++)
785 alpha[
i] = eigenvalue[
i];
793 Vector<std::complex<double>>& eigenvalue,
796 const bool& do_adjoint_problem)
806 Teuchos::RCP<DoubleMultiVector> initial =
808 Anasazi::MultiVecTraits<double, DoubleMultiVector>::MvRandom(*initial);
811 Teuchos::RCP<DoubleMultiVectorOperator> Op_pt;
812 if (do_adjoint_problem)
824 Teuchos::RCP<Anasazi::BasicEigenproblem<double,
827 anasazi_pt = Teuchos::rcp(
828 new Anasazi::BasicEigenproblem<
double,
834 anasazi_pt->setHermitian(
false);
837 anasazi_pt->setNEV(n_eval);
840 if (anasazi_pt->setProblem() !=
true)
842 oomph_info <<
"Anasazi::BasicEigenproblem::setProblem() had an error."
844 <<
"End Result: TEST FAILED" << std::endl;
852 verbosity += Anasazi::Warnings;
859 Teuchos::ParameterList MyPL;
860 MyPL.set(
"Which",
"LM");
861 MyPL.set(
"Block Size", 1);
863 MyPL.set(
"Maximum Restarts", 500);
864 MyPL.set(
"Orthogonalization",
"DGKS");
865 MyPL.set(
"Verbosity", verbosity);
866 MyPL.set(
"Convergence Tolerance", tol);
867 Anasazi::BlockKrylovSchurSolMgr<double,
870 BKS(anasazi_pt, MyPL);
873 Anasazi::ReturnType ret = BKS.solve();
874 if (ret != Anasazi::Converged)
876 std::string error_message =
"Eigensolver did not converge!\n";
879 error_message, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
884 Anasazi::Eigensolution<double, DoubleMultiVector> sol =
885 anasazi_pt->getSolution();
886 std::vector<Anasazi::Value<double>> evals = sol.Evals;
887 Teuchos::RCP<DoubleMultiVector> evecs = sol.Evecs;
894 std::vector<int> index_vector = sol.index;
897 unsigned n_eval_avail = evals.size();
898 eigenvalue.resize(n_eval_avail);
899 eigenvector_real.resize(n_eval_avail);
900 eigenvector_imag.resize(n_eval_avail);
903 for (
unsigned i = 0;
i < n_eval_avail;
i++)
906 double a = evals[
i].realpart;
907 double b = evals[
i].imagpart;
908 double det = a * a + b * b;
909 eigenvalue[
i] = std::complex<double>(a / det +
Sigma_real, -b / det);
913 eigenvector_real[
i].build(evecs->distribution_pt(), 0.0);
914 eigenvector_imag[
i].build(evecs->distribution_pt(), 0.0);
938 if (index_vector[
i] == 0)
942 eigenvector_real[
i][j] = (*evecs)(
i, j);
943 eigenvector_imag[
i][j] = 0.0;
946 else if (index_vector[
i] == 1)
950 eigenvector_real[
i][j] = (*evecs)(
i, j);
951 eigenvector_imag[
i][j] = (*evecs)(
i + 1, j);
954 else if (index_vector[
i] == -1)
958 eigenvector_real[
i][j] = (*evecs)(
i - 1, j);
959 eigenvector_imag[
i][j] = -(*evecs)(
i, j);
964 oomph_info <<
"Never get here: index_vector[ " <<
i
965 <<
" ] = " << index_vector[
i] << std::endl;
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 int GetVecLength(const oomph::DoubleMultiVector &mv)
Obtain the global length of the vector.
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...
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 .
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 .
static void MvPrint(const oomph::DoubleMultiVector &mv, std::ostream &os)
Print the mv multi-vector to the os output stream.
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:...
static void SetBlock(const oomph::DoubleMultiVector &A, const Teuchos::Range1D &index, oomph::DoubleMultiVector &mv)
Deep copy of A into specified columns of mv.
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:...
static void MvScale(oomph::DoubleMultiVector &mv, const std::vector< double > &alpha)
Scale each element of the i-th vector in mv with alpha[i].
static void MvScale(oomph::DoubleMultiVector &mv, const double alpha)
Scale each element of the vectors in mv with alpha.
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:...
static void MvAddMv(const double alpha, const oomph::DoubleMultiVector &A, const double beta, const oomph::DoubleMultiVector &B, oomph::DoubleMultiVector &mv)
Replace mv with .
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 ...
static int GetNumberVecs(const oomph::DoubleMultiVector &mv)
Obtain the number of vectors in the multivector.
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.
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:...
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 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:...
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 ...
static void MvRandom(oomph::DoubleMultiVector &mv)
Replace the vectors in mv with random vectors.
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...
static void MvInit(oomph::DoubleMultiVector &mv, const double alpha=Teuchos::ScalarTraits< double >::zero())
Replace each element of the vectors in mv with alpha.
static void Assign(const oomph::DoubleMultiVector &A, oomph::DoubleMultiVector &mv)
mv := A
static void Apply(const oomph::DoubleMultiVectorOperator &Op, const oomph::DoubleMultiVector &x, oomph::DoubleMultiVector &y)
Matrix operator application method.
Class for the Anasazi eigensolver.
void solve_eigenproblem(Problem *const &problem_pt, const int &n_eval, Vector< std::complex< double >> &alpha, Vector< double > &beta, Vector< DoubleVector > &eigenvector_real, Vector< DoubleVector > &eigenvector_imag, const bool &do_adjoint_problem)
Solve the real eigenproblem that is assembled by elements in a mesh in a Problem object....
LinearSolver * Default_linear_solver_pt
Pointer to a default linear solver.
Anasazi::OutputManager< ST > * Output_manager_pt
Pointer to output manager.
Teuchos::ScalarTraits< ST > SCT
Anasazi::OperatorTraits< ST, MV, OP > OPT
virtual ~ANASAZI()
Destructor, delete the linear solver.
LinearSolver * Linear_solver_pt
Pointer to a linear solver.
void solve_eigenproblem(Problem *const &problem_pt, const int &n_eval, Vector< std::complex< double >> &eigenvalue, Vector< DoubleVector > &eigenvector_real, Vector< DoubleVector > &eigenvector_imag, const bool &do_adjoint_problem)
Solve the eigen problem.
LinearSolver *const & linear_solver_pt() const
Return a pointer to the linear solver object (const version)
Anasazi::MultiVec< ST > MV
Anasazi::MultiVecTraits< ST, MV > MVT
ANASAZI(const ANASAZI &)
Empty copy constructor.
Anasazi::Operator< ST > OP
LinearSolver *& linear_solver_pt()
Return a pointer to the linear solver object.
Class for the adjoing problem shift invert operation.
CRDoubleMatrix * AsigmaM_pt
Problem * Problem_pt
Pointer to the problem.
AdjointProblemBasedShiftInvertOperator(Problem *const &problem_pt, LinearSolver *const &linear_solver_pt, const double &sigma=0.0)
void apply(const DoubleMultiVector &x, DoubleMultiVector &y) const
Now specify how to apply the operator.
double Sigma
Storage for the shift.
LinearSolver * Linear_solver_pt
Pointer to the linear solver used.
CRDoubleMatrix * M_pt
Storage for the matrices.
A class for compressed row matrices. This is a distributable object.
void multiply(const DoubleVector &x, DoubleVector &soln) const
Multiply the matrix by the vector x: soln=Ax.
void get_matrix_transpose(CRDoubleMatrix *result) const
Returns the transpose of this matrix.
bool distributed() const
distribution is serial or distributed
LinearAlgebraDistribution * distribution_pt() const
access to the LinearAlgebraDistribution
unsigned nrow() const
access function to the number of global rows.
unsigned nrow_local() const
access function for the num of local rows on this processor.
Base class for Oomph-lib's Vector Operator classes that will be used with the DoubleMultiVector.
DoubleMultiVectorOperator()
Empty constructor.
virtual ~DoubleMultiVectorOperator()
virtual destructor
virtual void apply(const DoubleMultiVector &x, DoubleMultiVector &y) const =0
The apply interface.
A multi vector in the mathematical sense, initially developed for linear algebra type applications....
void output(std::ostream &outfile) const
output the contents of the vector
void initialise(const double &initial_value)
initialise the whole vector with value v
void dot(const DoubleMultiVector &vec, std::vector< double > &result) const
compute the 2 norm of this vector
void norm(std::vector< double > &result) const
compute the 2 norm of this vector
DoubleVector & doublevector(const unsigned &i)
access to the DoubleVector representatoin
unsigned nvector() const
Return the number of vectors.
A vector in the mathematical sense, initially developed for linear algebra type applications....
Base class for all EigenProblem solves. This simply defines standard interfaces so that different sol...
double Sigma_real
Double value that represents the real part of the shift in shifted eigensolvers.
Describes the distribution of a distributable linear algebra type object. Typically this is a contain...
OomphCommunicator * communicator_pt() const
const access to the communicator pointer
Base class for all linear solvers. This merely defines standard interfaces for linear solvers,...
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...
virtual void enable_resolve()
Enable resolve (i.e. store matrix and/or LU decomposition, say) Virtual so it can be overloaded to pe...
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...
void disable_doc_time()
Disable documentation of solve times.
An OomphLibError object which should be thrown when an run-time error is encountered....
Class for the shift invert operation.
void apply(const DoubleMultiVector &x, DoubleMultiVector &y) const
The apply interface.
ProblemBasedShiftInvertOperator(Problem *const &problem_pt, LinearSolver *const &linear_solver_pt, const double &sigma=0.0)
CRDoubleMatrix * AsigmaM_pt
LinearSolver * Linear_solver_pt
////////////////////////////////////////////////////////////////// //////////////////////////////////...
LinearAlgebraDistribution *const & dof_distribution_pt() const
Return the pointer to the dof distribution (read-only)
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...
LinearSolver *& linear_solver_pt()
Return a pointer to the linear solver object.
void create_new_linear_algebra_distribution(LinearAlgebraDistribution *&dist_pt)
Get new linear algebra distribution (you're in charge of deleting it!)
A slight extension to the standard template vector class so that we can include "graceful" array rang...
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...