13#ifndef dealii_parpack_solver_h
14#define dealii_parpack_solver_h
31#ifdef DEAL_II_ARPACK_WITH_PARPACK
207template <
typename VectorType>
312 const std::vector<IndexSet> &partitioning);
318 reinit(
const VectorType &distributed_vector);
335 set_shift(
const std::complex<double> sigma);
346 template <
typename MatrixType1,
typename MatrixType2,
typename INVERSE>
348 solve(
const MatrixType1 &A,
349 const MatrixType2 &B,
350 const INVERSE &inverse,
353 const unsigned int n_eigenvalues);
358 template <
typename MatrixType1,
typename MatrixType2,
typename INVERSE>
360 solve(
const MatrixType1 &A,
361 const MatrixType2 &B,
362 const INVERSE &inverse,
365 const unsigned int n_eigenvalues);
434 std::vector<double>
v;
457 std::vector<double>
z;
510 << arg1 <<
" eigenpairs were requested, but only " << arg2
516 <<
"Number of wanted eigenvalues " << arg1
517 <<
" is larger that the size of the matrix " << arg2);
522 <<
"Number of wanted eigenvalues " << arg1
523 <<
" is larger that the size of eigenvectors " << arg2);
529 <<
"To store the real and complex parts of " << arg1
530 <<
" eigenvectors in real-valued vectors, their size (currently set to "
531 << arg2 <<
") should be greater than or equal to " << arg1 + 1);
536 <<
"Number of wanted eigenvalues " << arg1
537 <<
" is larger that the size of eigenvalues " << arg2);
542 <<
"Number of Arnoldi vectors " << arg1
543 <<
" is larger that the size of the matrix " << arg2);
548 <<
"Number of Arnoldi vectors " << arg1
549 <<
" is too small to obtain " << arg2 <<
" eigenvalues");
553 <<
"This ido " << arg1
554 <<
" is not supported. Check documentation of ARPACK");
558 <<
"This mode " << arg1
559 <<
" is not supported. Check documentation of ARPACK");
563 <<
"Error with Pdnaupd, info " << arg1
564 <<
". Check documentation of ARPACK");
568 <<
"Error with Pdneupd, info " << arg1
569 <<
". Check documentation of ARPACK");
573 <<
"Maximum number " << arg1 <<
" of iterations reached.");
577 <<
"No shifts could be applied during implicit"
578 <<
" Arnoldi update, try increasing the number of"
579 <<
" Arnoldi vectors.");
584template <
typename VectorType>
591 src.memory_consumption() +
dst.memory_consumption() +
592 tmp.memory_consumption() +
599template <
typename VectorType>
616 "'largest real part' can only be used for non-symmetric problems!"));
620 "'smallest real part' can only be used for non-symmetric problems!"));
624 "'largest imaginary part' can only be used for non-symmetric problems!"));
628 "'smallest imaginary part' can only be used for non-symmetric problems!"));
631 ExcMessage(
"Currently, only modes 1, 2 and 3 are supported."));
636template <
typename VectorType>
657template <
typename VectorType>
667template <
typename VectorType>
681template <
typename VectorType>
721template <
typename VectorType>
735template <
typename VectorType>
742 src.reinit(distributed_vector);
743 dst.reinit(distributed_vector);
744 tmp.reinit(distributed_vector);
749template <
typename VectorType>
752 const std::vector<IndexSet> &partitioning)
764template <
typename VectorType>
765template <
typename MatrixType1,
typename MatrixType2,
typename INVERSE>
768 const MatrixType2 &B,
769 const INVERSE &inverse,
772 const unsigned int n_eigenvalues)
774 std::vector<VectorType *> eigenvectors_ptr(
eigenvectors.size());
782template <
typename VectorType>
783template <
typename MatrixType1,
typename MatrixType2,
typename INVERSE>
786 const MatrixType2 &mass_matrix,
787 const INVERSE &inverse,
790 const unsigned int n_eigenvalues)
830 bmat[0] = (mode == 1) ?
'I' :
'G';
847 std::strcpy(which,
"LA");
850 std::strcpy(which,
"SA");
853 std::strcpy(which,
"LM");
856 std::strcpy(which,
"SM");
859 std::strcpy(which,
"LR");
862 std::strcpy(which,
"SR");
865 std::strcpy(which,
"LI");
868 std::strcpy(which,
"SI");
871 std::strcpy(which,
"BE");
876 double tol =
control().tolerance();
879 std::vector<int> iparam(11, 0);
886 iparam[2] =
control().max_steps();
899 std::vector<int> ipntr(14, 0);
910 int nev = n_eigenvalues;
911 int n_inside_arpack =
nloc;
962 const int shift_x = ipntr[0] - 1;
963 const int shift_y = ipntr[1] - 1;
974 if ((ido == -1) || (ido == 1 && mode < 3))
983 mass_matrix.vmult(
tmp,
src);
989 system_matrix.vmult(
tmp,
src);
993 workd.data() + shift_x);
998 system_matrix.vmult(
dst,
src);
1003 else if (ido == 1 && mode >= 3)
1007 const int shift_b_x = ipntr[2] - 1;
1034 mass_matrix.vmult(
dst,
src);
1045 workd.data() + shift_y);
1053 char howmany[4] =
"All";
1055 std::vector<double> eigenvalues_real(n_eigenvalues + 1, 0.);
1056 std::vector<double> eigenvalues_im(n_eigenvalues + 1, 0.);
1064 eigenvalues_real.data(),
1088 eigenvalues_real.data(),
1089 eigenvalues_im.data(),
1124 for (
int i = 0; i < nev; ++i)
1133 for (
size_type i = 0; i < n_eigenvalues; ++i)
1135 std::complex<double>(eigenvalues_real[i], eigenvalues_im[i]);
1138 AssertThrow(iparam[4] >=
static_cast<int>(n_eigenvalues),
1155template <
typename VectorType>
size_type n_elements() const
std::vector< size_type > get_index_vector() const
void set_initial_vector(const VectorType &vec)
SolverControl & solver_control
MPI_Comm mpi_communicator
types::global_dof_index size_type
SolverControl & control() const
@ smallest_imaginary_part
void solve(const MatrixType1 &A, const MatrixType2 &B, const INVERSE &inverse, std::vector< std::complex< double > > &eigenvalues, std::vector< VectorType > &eigenvectors, const unsigned int n_eigenvalues)
PArpackSolver(SolverControl &control, const MPI_Comm mpi_communicator, const AdditionalData &data=AdditionalData())
std::vector< types::global_dof_index > local_indices
std::vector< double > workl
std::vector< int > select
std::size_t memory_consumption() const
MPI_Fint mpi_communicator_fortran
void set_shift(const std::complex< double > sigma)
void reinit(const IndexSet &locally_owned_dofs)
std::vector< double > workd
const AdditionalData additional_data
bool initial_vector_provided
void internal_reinit(const IndexSet &locally_owned_dofs)
std::vector< double > resid
std::vector< double > workev
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & PArpackExcInvalidNumberofEigenvalues(int arg1, int arg2)
static ::ExceptionBase & PArpackExcInvalidEigenvalueSize(int arg1, int arg2)
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & PArpackExcNoShifts(int arg1)
static ::ExceptionBase & PArpackExcInvalidEigenvectorSize(int arg1, int arg2)
static ::ExceptionBase & PArpackExcSmallNumberofArnoldiVectors(int arg1, int arg2)
#define Assert(cond, exc)
#define DeclException2(Exception2, type1, type2, outsequence)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & PArpackExcInfoPdneupd(int arg1)
#define AssertIndexRange(index, range)
static ::ExceptionBase & PArpackExcIdo(int arg1)
static ::ExceptionBase & PArpackExcConvergedEigenvectors(int arg1, int arg2)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & PArpackExcInfoMaxIt(int arg1)
static ::ExceptionBase & PArpackExcMode(int arg1)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & PArpackExcInfoPdnaupd(int arg1)
#define DeclException1(Exception1, type1, outsequence)
static ::ExceptionBase & PArpackExcInvalidEigenvectorSizeNonsymmetric(int arg1, int arg2)
static ::ExceptionBase & PArpackExcInvalidNumberofArnoldiVectors(int arg1, int arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
std::enable_if_t< std::is_fundamental_v< T >, std::size_t > memory_consumption(const T &t)
unsigned int global_dof_index
*braid_SplitCommworld & comm
void pdneupd_(MPI_Fint *comm, int *rvec, char *howmany, int *select, double *d, double *di, double *z, int *ldz, double *sigmar, double *sigmai, double *workev, char *bmat, int *n, char *which, int *nev, double *tol, double *resid, int *ncv, double *v, int *nloc, int *iparam, int *ipntr, double *workd, double *workl, int *lworkl, int *info)
void pdsaupd_(MPI_Fint *comm, int *ido, char *bmat, int *n, char *which, int *nev, double *tol, double *resid, int *ncv, double *v, int *nloc, int *iparam, int *ipntr, double *workd, double *workl, int *lworkl, int *info)
void pdnaupd_(MPI_Fint *comm, int *ido, char *bmat, int *n, char *which, int *nev, double *tol, double *resid, int *ncv, double *v, int *nloc, int *iparam, int *ipntr, double *workd, double *workl, int *lworkl, int *info)
void pdseupd_(MPI_Fint *comm, int *rvec, char *howmany, int *select, double *d, double *z, int *ldz, double *sigmar, char *bmat, int *n, char *which, int *nev, double *tol, double *resid, int *ncv, double *v, int *nloc, int *iparam, int *ipntr, double *workd, double *workl, int *lworkl, int *info)
AdditionalData(const unsigned int number_of_arnoldi_vectors=15, const WhichEigenvalues eigenvalue_of_interest=largest_magnitude, const bool symmetric=false, const int mode=3)
const unsigned int number_of_arnoldi_vectors
const WhichEigenvalues eigenvalue_of_interest
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)