13#ifndef dealii_arpack_solver_h
14#define dealii_arpack_solver_h
31#ifdef DEAL_II_WITH_ARPACK
270 template <
typename VectorType>
280 set_shift(
const std::complex<double> sigma);
329 template <
typename VectorType,
typename MatrixType,
typename INVERSE>
331 solve(
const MatrixType &B,
332 const INVERSE &inverse,
335 const unsigned int n_eigenvalues = 0);
343 template <
typename VectorType,
344 typename MatrixType1,
345 typename MatrixType2,
348 "Use solve() without the system matrix argument.")
349 void
solve(const MatrixType1 &A,
350 const MatrixType2 &B,
351 const INVERSE &inverse,
354 const
unsigned int n_eigenvalues = 0);
393 << " is larger that the
size of the matrix " << arg2);
405 << "To store the real and complex parts of " << arg1
407 << arg2 << ") should be greater than or
equal to " << arg1 + 1);
418 << "Number of Arnoldi vectors " << arg1
419 << " is larger that the
size of the matrix " << arg2);
424 << "Number of Arnoldi vectors " << arg1
429 << "This ido " << arg1
430 << " is not supported. Check documentation of ARPACK");
434 << "This mode " << arg1
435 << " is not supported. Check documentation of ARPACK");
439 << "Error with dsaupd, info " << arg1
440 << ". Check documentation of ARPACK");
444 << "Error with dnaupd, info " << arg1
445 << ". Check documentation of ARPACK");
449 << "Error with dseupd, info " << arg1
450 << ". Check documentation of ARPACK");
454 << "Error with dneupd, info " << arg1
455 << ". Check documentation of ARPACK");
459 << "Maximum number " << arg1 << " of iterations reached.");
462 "No shifts could be applied during implicit"
463 " Arnoldi update, try increasing the number of"
464 " Arnoldi vectors.");
469 const
unsigned int number_of_arnoldi_vectors,
471 const
bool symmetric)
472 : number_of_arnoldi_vectors(number_of_arnoldi_vectors)
473 , eigenvalue_of_interest(eigenvalue_of_interest)
474 , symmetric(symmetric)
482 "'largest real part' can only be used for non-symmetric problems!"));
486 "'smallest real part' can only be used for non-symmetric problems!"));
490 "'largest imaginary part' can only be used for non-symmetric problems!"));
494 "'smallest imaginary part' can only be used for non-symmetric problems!"));
502 "'largest algebraic part' can only be used for symmetric problems!"));
506 "'smallest algebraic part' can only be used for symmetric problems!"));
509 "'both ends' can only be used for symmetric problems!"));
534template <
typename VectorType>
539 resid.resize(vec.size());
540 for (
size_type i = 0; i < vec.size(); ++i)
545template <
typename VectorType,
546 typename MatrixType1,
547 typename MatrixType2,
551 const MatrixType2 &mass_matrix,
552 const INVERSE &inverse,
555 const unsigned int n_eigenvalues)
562template <
typename VectorType,
typename MatrixType,
typename INVERSE>
565 const INVERSE &inverse,
568 const unsigned int n_eigenvalues)
574 const unsigned int nev_const =
575 (n_eigenvalues == 0) ?
eigenvalues.size() : n_eigenvalues;
577 unsigned int nev = nev_const;
623 std::strcpy(which,
"LA");
626 std::strcpy(which,
"SA");
629 std::strcpy(which,
"LM");
632 std::strcpy(which,
"SM");
635 std::strcpy(which,
"LR");
638 std::strcpy(which,
"SR");
641 std::strcpy(which,
"LI");
644 std::strcpy(which,
"SI");
647 std::strcpy(which,
"BE");
663 std::vector<double> v(ldv * ncv, 0.0);
666 std::vector<int> iparam(11, 0);
677 std::vector<int> ipntr(14, 0);
680 std::vector<double> workd(3 * n, 0.);
683 std::vector<double> workl(lworkl, 0.);
737 VectorType src, dst, tmp;
743 for (
size_type i = 0; i < src.size(); ++i)
744 src(i) = workd[ipntr[0] - 1 + i];
747 mass_matrix.vmult(tmp, src);
749 inverse.vmult(dst, tmp);
751 for (
size_type i = 0; i < dst.size(); ++i)
752 workd[ipntr[1] - 1 + i] = dst(i);
758 VectorType src, dst, tmp, tmp2;
764 for (
size_type i = 0; i < src.size(); ++i)
766 src(i) = workd[ipntr[2] - 1 + i];
767 tmp(i) = workd[ipntr[0] - 1 + i];
770 inverse.vmult(dst, src);
772 for (
size_type i = 0; i < dst.size(); ++i)
773 workd[ipntr[1] - 1 + i] = dst(i);
783 for (
size_type i = 0; i < src.size(); ++i)
784 src(i) = workd[ipntr[0] - 1 + i];
787 mass_matrix.vmult(dst, src);
789 for (
size_type i = 0; i < dst.size(); ++i)
790 workd[ipntr[1] - 1 + i] = dst(i);
826 std::vector<int> select(ncv, 1);
830 std::vector<double> eigenvalues_real(nev + 1, 0.);
831 std::vector<double> eigenvalues_im(nev + 1, 0.);
836 std::vector<double> z(ldz * nev, 0.);
840 eigenvalues_real.data(),
862 std::vector<double> workev(3 * ncv, 0.);
866 eigenvalues_real.data(),
867 eigenvalues_im.data(),
908 for (
unsigned int i = 0; i < nev; ++i)
909 for (
unsigned int j = 0; j < n; ++j)
912 for (
unsigned int i = 0; i < nev_const; ++i)
914 std::complex<double>(eigenvalues_real[i], eigenvalues_im[i]);
* x_component_mask set(0, true)
void dseupd_(int *rvec, char *howmany, int *select, double *d, double *z, int *ldz, double *sigmar, char *bmat, unsigned int *n, char *which, unsigned int *nev, double *tol, double *resid, int *ncv, double *v, int *ldv, int *iparam, int *ipntr, double *workd, double *workl, int *lworkl, int *info)
void dsaupd_(int *ido, char *bmat, unsigned int *n, char *which, unsigned int *nev, double *tol, double *resid, int *ncv, double *v, int *ldv, int *iparam, int *ipntr, double *workd, double *workl, int *lworkl, int *info)
void dnaupd_(int *ido, char *bmat, unsigned int *n, char *which, unsigned int *nev, const double *tol, double *resid, int *ncv, double *v, int *ldv, int *iparam, int *ipntr, double *workd, double *workl, int *lworkl, int *info)
void dneupd_(int *rvec, char *howmany, int *select, double *d, double *di, double *z, int *ldz, double *sigmar, double *sigmai, double *workev, char *bmat, unsigned int *n, char *which, unsigned int *nev, double *tol, double *resid, int *ncv, double *v, int *ldv, int *iparam, int *ipntr, double *workd, double *workl, int *lworkl, int *info)
SolverControl & control() const
void set_initial_vector(const VectorType &vec)
bool initial_vector_provided
ArpackSolver(SolverControl &control, const AdditionalData &data=AdditionalData())
std::vector< double > resid
void solve(const MatrixType &B, const INVERSE &inverse, std::vector< std::complex< double > > &eigenvalues, std::vector< VectorType > &eigenvectors, const unsigned int n_eigenvalues=0)
SolverControl & solver_control
@ smallest_imaginary_part
void set_shift(const std::complex< double > sigma)
const AdditionalData additional_data
virtual State check(const unsigned int step, const double check_value)
unsigned int max_steps() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_DEPRECATED_WITH_COMMENT(comment)
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ArpackExcInvalidEigenvalueSize(int arg1, int arg2)
static ::ExceptionBase & ArpackExcArpackInfoMaxIt(int arg1)
static ::ExceptionBase & ArpackExcInvalidNumberofArnoldiVectors(int arg1, int arg2)
static ::ExceptionBase & ArpackExcInvalidEigenvectorSizeNonsymmetric(int arg1, int arg2)
static ::ExceptionBase & ArpackExcSmallNumberofArnoldiVectors(int arg1, int arg2)
static ::ExceptionBase & ArpackExcArpackNoShifts()
static ::ExceptionBase & ArpackExcInvalidEigenvectorSize(int arg1, int arg2)
static ::ExceptionBase & ArpackExcArpackMode(int arg1)
static ::ExceptionBase & ArpackExcInvalidNumberofEigenvalues(int arg1, int arg2)
#define Assert(cond, exc)
static ::ExceptionBase & ArpackExcArpackInfodneupd(int arg1)
#define DeclException2(Exception2, type1, type2, outsequence)
static ::ExceptionBase & ArpackExcArpackInfodsaupd(int arg1)
static ::ExceptionBase & ArpackExcArpackInfodnaupd(int arg1)
#define DeclExceptionMsg(Exception, defaulttext)
static ::ExceptionBase & ArpackExcArpackInfodseupd(int arg1)
static ::ExceptionBase & ArpackExcArpackIdo(int arg1)
#define DeclException1(Exception1, type1, outsequence)
static ::ExceptionBase & ExcMessage(std::string arg1)
std::vector< index_type > data
unsigned int global_dof_index
const WhichEigenvalues eigenvalue_of_interest
const unsigned int number_of_arnoldi_vectors
std::array< Number, 1 > eigenvalues(const SymmetricTensor< 2, 1, Number > &T)
std::array< std::pair< Number, Tensor< 1, dim, Number > >, dim > eigenvectors(const SymmetricTensor< 2, dim, Number > &T, const SymmetricTensorEigenvectorMethod method=SymmetricTensorEigenvectorMethod::ql_implicit_shifts)