54 Small(true), Compute_eigenvectors(true)
69 Vector<std::complex<double> > &eigenvalue,
84 int iparam[11]={0,0,0,0,0,0,0,0,0,0,0};
86 int ipntr[14]={0,0,0,0,0,0,0,0,0,0,0,0,0,0};
91 n = problem_pt->
ndof();
101 std::ostringstream warning_stream;
102 warning_stream <<
"Number of requested eigenvalues " << nev <<
"\n" 103 <<
"is greater than the number of Arnoldi vectors:" 107 if(ncv > n) {ncv = n;}
109 warning_stream <<
"Increasing number of Arnoldi vectors to " << ncv
110 <<
"\n but you may want to increase further using\n" 111 <<
"ARPACK::narnoldi()\n" 112 <<
"which will also get rid of this warning.\n";
115 OOMPH_CURRENT_FUNCTION,
116 OOMPH_EXCEPTION_LOCATION);
120 int lworkl = 3*ncv*ncv + 6*ncv;
123 double **v =
new double*;
124 *v =
new double[ncv*n];
129 double *resid =
new double[n];
131 double *workd =
new double[3*n];
133 double *workl =
new double[lworkl];
137 if(
Small) {which[0] =
'S';}
139 else {which[0] =
'L';}
160 std::ostringstream error_stream;
162 <<
"Spectrum is set to an invalid value. It must be 0, 1 or -1\n" 166 OOMPH_CURRENT_FUNCTION,
167 OOMPH_EXCEPTION_LOCATION);
230 DNAUPD(ido, bmat, n, which, nev, tol, resid,
231 ncv, v, ldv, iparam, ipntr, workd, workl, lworkl, info);
248 for(
int i=0;
i<n;
i++) {x[
i] = workd[ipntr[0]-1+
i];}
260 workd[ipntr[1]-1+
i] = rhs[
i];
271 rhs[
i] = workd[ipntr[2]-1+
i];
281 workd[ipntr[1]-1+
i] = rhs[
i];
289 for(
int i=0;
i<n;
i++) {x[
i] = workd[ipntr[0]-1+
i];}
294 workd[ipntr[1]-1+
i] = rhs[
i];
302 oomph_info <<
"Error with _naupd, info = '" << info << std::endl;
303 if(info==-7) {
oomph_info <<
"Not enough memory " << std::endl;}
322 oomph_info <<
"Maximum number of iterations reached." << std::endl;
327 <<
"No shifts could be applied during implicit Arnoldi " 328 <<
"update, try increasing NCV. " 341 int nconv = iparam[4];
356 double *eval_real =
new double[nconv+1];
358 double *eval_imag =
new double[nconv+1];
361 double *workev =
new double[3*ncv];
363 double **z =
new double*;
364 *z =
new double[(nconv+1)*n];
369 DNEUPD ( rvec, howmany, select, eval_real, eval_imag, z, ldv,
370 sigmar, sigmai, workev, bmat, n, which, nev, tol,
371 resid, ncv, v, ldv, iparam, ipntr, workd, workl,
388 oomph_info <<
"Error with _neupd, info = " << ierr << std::endl;
394 eigenvalue.resize(nconv);
395 for(
int j=0;j<nconv;j++)
398 std::complex<double> eigen(eval_real[j],eval_imag[j]);
400 eigenvalue[j] = eigen;
406 eigenvector.resize(nconv);
407 for(
int j=0;j<nconv;j++)
412 eigenvector[j][
i] = z[0][j*n+
i];
418 eigenvector.resize(0);
426 oomph_info <<
" Size of the matrix is " << n << std::endl;
427 oomph_info <<
" The number of Ritz values requested is " << nev
429 oomph_info <<
" The number of Arnoldi vectors generated (NCV) is " << ncv
431 oomph_info <<
" What portion of the spectrum: " << which << std::endl;
432 oomph_info <<
" The number of converged Ritz values is " 433 << nconv << std::endl;
435 <<
" The number of Implicit Arnoldi update iterations taken is " 436 << iparam[2] << std::endl;
437 oomph_info <<
" The number of OP*x is " << iparam[8] << std::endl;
438 oomph_info <<
" The convergence criterion is " << tol << std::endl;
445 delete[] workev; workev=0;
446 delete[] eval_imag; eval_imag=0;
447 delete[] eval_real; eval_real=0;
450 delete[] workl; workl = 0;
451 delete[] workd; workd = 0;
452 delete[] resid; resid = 0;
464 Vector<std::complex<double> > &eigenvalue,
469 char no_eigvecs[2] =
"N";
471 char eigvecs[2] =
"V";
474 int n = problem_pt->
ndof();
481 if(n%2==0) {padding=1;}
487 int padded_n = n + padding;
491 double *M =
new double[padded_n*padded_n];
492 double *A =
new double[padded_n*padded_n];
515 M[index] = temp_M(j,
i);
516 A[index] = temp_AsigmaM(j,
i);
532 double* alpha_r =
new double[n];
533 double* alpha_i =
new double[n];
534 double* beta =
new double[n];
536 double* vec_left =
new double[1];
537 double* vec_right =
new double[n*n];
540 std::vector<double> work(1,0.0);
546 LAPACK_DGGEV( no_eigvecs, eigvecs, n, &A[0], padded_n, &M[0], padded_n,
547 alpha_r, alpha_i, beta, vec_left, 1, vec_right, n,
548 &work[0], -1, info );
551 int required_workspace = ( int ) work[0];
553 work.resize( required_workspace );
556 LAPACK_DGGEV( no_eigvecs, eigvecs, n, &A[0], padded_n, &M[0], padded_n,
557 alpha_r, alpha_i, beta, vec_left, 1, vec_right, n, &work[0],
558 required_workspace, info );
562 eigenvalue.resize(n);
563 eigenvector.resize(n);
566 for (
int i=0;
i<n; ++
i )
572 std::complex<double>(sigmar + alpha_r[
i]/beta[
i],alpha_i[
i]/beta[
i]);
577 for(
int k = 0; k < n; ++k )
579 eigenvector[
i][k] = vec_right[
i*n + k ];
600 Vector<std::complex<double> > &eigenvalue,
606 char no_eigvecs[2] =
"N";
608 char eigvecs[2] =
"V";
615 double *M_linear =
new double[2*n*n];
616 double *A_linear =
new double[2*n*n];
624 M_linear[index] = M(j,
i).real();
625 A_linear[index] = A(j,
i).real();
627 M_linear[index] = M(j,
i).imag();
628 A_linear[index] = A(j,
i).imag();
634 double* alpha =
new double[2*n];
635 double* beta =
new double[2*n];
637 double* vec_left =
new double[2];
638 double* vec_right =
new double[2*n*n];
641 std::vector<double> work(2,0.0);
642 std::vector<double> rwork(8*n,0.0);
649 LAPACK_ZGGEV( no_eigvecs, eigvecs, n, &A_linear[0], n, &M_linear[0], n,
650 alpha, beta, vec_left, 1, vec_right, n,
651 &work[0], -1, &rwork[0], info );
654 int required_workspace = ( int ) work[0];
656 work.resize( 2*required_workspace );
659 LAPACK_ZGGEV( no_eigvecs, eigvecs, n, &A_linear[0], n, &M_linear[0], n,
660 alpha, beta, vec_left, 1, vec_right, n, &work[0],
661 required_workspace, &rwork[0], info );
665 eigenvalue.resize(n);
666 eigenvector.resize(n);
669 for (
int i=0;
i<n; ++
i )
672 std::complex<double> num(alpha[2*
i],alpha[2*i+1]);
673 std::complex<double> den(beta[2*i],beta[2*i+1]);
677 eigenvalue[
i] = num/den;
680 eigenvector[
i].resize(n);
682 for(
int k = 0; k < n; ++k )
684 eigenvector[
i][k] = std::complex<double>(vec_right[2*i*n + 2*k],
685 vec_right[2*i*n + 2*k+1]);
bool Compute_eigenvectors
Boolean to indicate whether or not to compute the eigenvectors.
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...
Abstract base class for matrices of complex doubles – adds abstract interfaces for solving...
void clear()
wipes the DoubleVector
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...
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...
int NArnoldi
Number of Arnoldi vectors to compute.
. SuperLU Project Solver class. This is a combined wrapper for both SuperLU and SuperLU Dist...
virtual unsigned long nrow() const =0
Return the number of rows of the matrix.
OomphCommunicator * communicator_pt()
access function to the oomph-lib communicator
LinearSolver * Linear_solver_pt
Pointer to a linear solver.
bool Small
Boolean to set which part of the spectrum left (default) or right of the shifted value.
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...
void disable_doc_time()
Disable documentation of solve times.
virtual void enable_resolve()
Enable resolve (i.e. store matrix and/or LU decomposition, say) Virtual so it can be overloaded to pe...
virtual ~ARPACK()
Destructor, delete the linear solver.
void solve_eigenproblem(Problem *const &problem_pt, const int &n_eval, Vector< std::complex< double > > &eigenvalue, Vector< DoubleVector > &eigenvector)
Solve the eigen problem.
unsigned long ndof() const
Return the number of dofs.
virtual void disable_resolve()
Disable resolve (i.e. store matrix and/or LU decomposition, say) This function simply resets an inter...
int Spectrum
Integer to set whether the real, imaginary or magnitude is required to be small or large...
void find_eigenvalues(const ComplexMatrixBase &A, const ComplexMatrixBase &M, Vector< std::complex< double > > &eigenvalue, Vector< Vector< std::complex< double > > > &eigenvector)
LinearSolver * Default_linear_solver_pt
Pointer to a default linear solver.
void build_distribution(const LinearAlgebraDistribution *const dist_pt)
setup the distribution of this distributable linear algebra object
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*)
void solve_eigenproblem(Problem *const &problem_pt, const int &n_eval, Vector< std::complex< double > > &eigenvalue, Vector< DoubleVector > &eigenvector)
Solve the eigen problem.
A class for compressed row matrices. This is a distributable object.
LinearAlgebraDistribution * distribution_pt() const
access to the LinearAlgebraDistribution