16 #ifndef dealii_arpack_solver_h 17 #define dealii_arpack_solver_h 19 #include <deal.II/base/config.h> 21 #include <deal.II/base/smartpointer.h> 23 #include <deal.II/lac/solver_control.h> 28 #ifdef DEAL_II_WITH_ARPACK 30 DEAL_II_NAMESPACE_OPEN
273 template <
typename VectorType>
283 set_shift(
const std::complex<double> sigma);
334 template <
typename VectorType,
335 typename MatrixType1,
336 typename MatrixType2,
339 solve(
const MatrixType1 & A,
340 const MatrixType2 & B,
341 const INVERSE & inverse,
344 const unsigned int n_eigenvalues = 0);
362 std::vector<double> resid;
382 <<
"Number of wanted eigenvalues " << arg1
383 <<
" is larger that the size of the matrix " << arg2);
388 <<
"Number of wanted eigenvalues " << arg1
389 <<
" is larger that the size of eigenvectors " << arg2);
395 <<
"To store the real and complex parts of " << arg1
396 <<
" eigenvectors in real-valued vectors, their size (currently set to " 397 << arg2 <<
") should be greater than or equal to " << arg1 + 1);
402 <<
"Number of wanted eigenvalues " << arg1
403 <<
" is larger that the size of eigenvalues " << arg2);
408 <<
"Number of Arnoldi vectors " << arg1
409 <<
" is larger that the size of the matrix " << arg2);
414 <<
"Number of Arnoldi vectors " << arg1
415 <<
" is too small to obtain " << arg2 <<
" eigenvalues");
419 <<
"This ido " << arg1
420 <<
" is not supported. Check documentation of ARPACK");
424 <<
"This mode " << arg1
425 <<
" is not supported. Check documentation of ARPACK");
429 <<
"Error with dsaupd, info " << arg1
430 <<
". Check documentation of ARPACK");
434 <<
"Error with dnaupd, info " << arg1
435 <<
". Check documentation of ARPACK");
439 <<
"Error with dseupd, info " << arg1
440 <<
". Check documentation of ARPACK");
444 <<
"Error with dneupd, info " << arg1
445 <<
". Check documentation of ARPACK");
449 <<
"Maximum number " << arg1 <<
" of iterations reached.");
452 "No shifts could be applied during implicit" 453 " Arnoldi update, try increasing the number of" 454 " Arnoldi vectors.");
459 const unsigned int number_of_arnoldi_vectors,
461 const bool symmetric)
462 : number_of_arnoldi_vectors(number_of_arnoldi_vectors)
463 , eigenvalue_of_interest(eigenvalue_of_interest)
464 , symmetric(symmetric)
472 "'largest real part' can only be used for non-symmetric problems!"));
476 "'smallest real part' can only be used for non-symmetric problems!"));
480 "'largest imaginary part' can only be used for non-symmetric problems!"));
484 "'smallest imaginary part' can only be used for non-symmetric problems!"));
509 template <
typename VectorType>
514 resid.resize(vec.size());
515 for (
size_type i = 0; i < vec.size(); ++i)
520 template <
typename VectorType,
521 typename MatrixType1,
522 typename MatrixType2,
526 const MatrixType2 & mass_matrix,
527 const INVERSE & inverse,
530 const unsigned int n_eigenvalues)
536 const unsigned int nev_const =
537 (n_eigenvalues == 0) ?
eigenvalues.size() : n_eigenvalues;
539 unsigned int nev = nev_const;
585 std::strcpy(which,
"LA");
588 std::strcpy(which,
"SA");
591 std::strcpy(which,
"LM");
594 std::strcpy(which,
"SM");
597 std::strcpy(which,
"LR");
600 std::strcpy(which,
"SR");
603 std::strcpy(which,
"LI");
606 std::strcpy(which,
"SI");
609 std::strcpy(which,
"BE");
625 std::vector<double> v(ldv * ncv, 0.0);
628 std::vector<int> iparam(11, 0);
639 std::vector<int> ipntr(14, 0);
642 std::vector<double> workd(3 * n, 0.);
645 std::vector<double> workl(lworkl, 0.);
699 VectorType src, dst, tmp;
705 for (
size_type i = 0; i < src.size(); ++i)
706 src(i) = workd[ipntr[0] - 1 + i];
709 mass_matrix.vmult(tmp, src);
711 inverse.vmult(dst, tmp);
713 for (
size_type i = 0; i < dst.size(); ++i)
714 workd[ipntr[1] - 1 + i] = dst(i);
720 VectorType src, dst, tmp, tmp2;
726 for (
size_type i = 0; i < src.size(); ++i)
728 src(i) = workd[ipntr[2] - 1 + i];
729 tmp(i) = workd[ipntr[0] - 1 + i];
732 inverse.vmult(dst, src);
734 for (
size_type i = 0; i < dst.size(); ++i)
735 workd[ipntr[1] - 1 + i] = dst(i);
745 for (
size_type i = 0; i < src.size(); ++i)
746 src(i) = workd[ipntr[0] - 1 + i];
749 mass_matrix.vmult(dst, src);
751 for (
size_type i = 0; i < dst.size(); ++i)
752 workd[ipntr[1] - 1 + i] = dst(i);
785 std::vector<int> select(ncv, 1);
789 std::vector<double> eigenvalues_real(nev + 1, 0.);
790 std::vector<double> eigenvalues_im(nev + 1, 0.);
795 std::vector<double> z(ldz * nev, 0.);
799 eigenvalues_real.data(),
821 std::vector<double> workev(3 * ncv, 0.);
825 eigenvalues_real.data(),
826 eigenvalues_im.data(),
867 for (
unsigned int i = 0; i < nev; ++i)
868 for (
unsigned int j = 0; j < n; ++j)
871 for (
unsigned int i = 0; i < nev_const; ++i)
873 std::complex<double>(eigenvalues_real[i], eigenvalues_im[i]);
884 DEAL_II_NAMESPACE_CLOSE
AdditionalData(const unsigned int number_of_arnoldi_vectors=15, const WhichEigenvalues eigenvalue_of_interest=largest_magnitude, const bool symmetric=false)
SolverControl & solver_control
#define DeclException2(Exception2, type1, type2, outsequence)
std::array< std::pair< Number, Tensor< 1, dim, Number > >, std::integral_constant< int, dim >::value > eigenvectors(const SymmetricTensor< 2, dim, Number > &T, const SymmetricTensorEigenvectorMethod method=SymmetricTensorEigenvectorMethod::ql_implicit_shifts)
std::array< Number, 1 > eigenvalues(const SymmetricTensor< 2, 1, Number > &T)
void set_shift(const std::complex< double > sigma)
std::array< std::pair< Number, Tensor< 1, dim, Number > >, std::integral_constant< int, dim >::value > eigenvectors(const SymmetricTensor< 2, dim, Number > &T, const SymmetricTensorEigenvectorMethod method=SymmetricTensorEigenvectorMethod::ql_implicit_shifts)
static ::ExceptionBase & ArpackExcInvalidEigenvalueSize(int arg1, int arg2)
static ::ExceptionBase & ArpackExcInvalidEigenvectorSizeNonsymmetric(int arg1, int arg2)
static ::ExceptionBase & ArpackExcArpackMode(int arg1)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define DeclException1(Exception1, type1, outsequence)
#define Assert(cond, exc)
static ::ExceptionBase & ArpackExcInvalidNumberofArnoldiVectors(int arg1, int arg2)
#define DeclExceptionMsg(Exception, defaulttext)
types::global_dof_index size_type
ArpackSolver(SolverControl &control, const AdditionalData &data=AdditionalData())
static ::ExceptionBase & ArpackExcSmallNumberofArnoldiVectors(int arg1, int arg2)
static ::ExceptionBase & ArpackExcInvalidEigenvectorSize(int arg1, int arg2)
const AdditionalData additional_data
static ::ExceptionBase & ArpackExcArpackInfodneupd(int arg1)
static ::ExceptionBase & ArpackExcArpackInfoMaxIt(int arg1)
unsigned int global_dof_index
static ::ExceptionBase & ArpackExcInvalidNumberofEigenvalues(int arg1, int arg2)
void set_initial_vector(const VectorType &vec)
unsigned int max_steps() const
static ::ExceptionBase & ArpackExcArpackInfodseupd(int arg1)
bool initial_vector_provided
static ::ExceptionBase & ArpackExcArpackInfodsaupd(int arg1)
const unsigned int number_of_arnoldi_vectors
std::array< Number, 1 > eigenvalues(const SymmetricTensor< 2, 1, Number > &T)
static ::ExceptionBase & ArpackExcArpackIdo(int arg1)
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=0)
SolverControl & control() const
const WhichEigenvalues eigenvalue_of_interest
static ::ExceptionBase & ArpackExcArpackInfodnaupd(int arg1)
static ::ExceptionBase & ArpackExcArpackNoShifts()