19 template <
typename _Type>
20 SparseLinearEigenSystem<_Type>::SparseLinearEigenSystem(SparseMatrix<_Type >* Aptr, SparseMatrix<_Type >* Bptr) :
21 LinearEigenSystem_base() {
22 m_region_defined =
false;
23 m_guess_defined =
false;
29 m_order = (EPSWhich)7;
31 m_calc_eigenvectors =
true;
34 template <
typename _Type>
35 SparseLinearEigenSystem<_Type>::~SparseLinearEigenSystem() {
38 template <
typename _Type>
39 unsigned SparseLinearEigenSystem<_Type>::get_nconv()
const {
43 template <
typename _Type>
44 void SparseLinearEigenSystem<_Type>::set_nev(
unsigned n) {
48 template <
typename _Type>
49 void SparseLinearEigenSystem<_Type>::set_target(std::complex<double> target) {
54 template <
typename _Type>
55 void SparseLinearEigenSystem<_Type>::set_order(std::string order_string) {
57 if(order_string ==
"EPS_TARGET_MAGNITUDE") {
61 if(order_string ==
"EPS_TARGET_REAL") {
65 if(order_string ==
"EPS_TARGET_IMAGINARY") {
82 problem =
"The SparseLinearEigenSystem::set_order method has been called\n";
83 problem +=
"with an ordering_string that is not recognised.\n";
84 throw ExceptionExternal(problem);
88 template <
typename _Type>
89 bool& SparseLinearEigenSystem<_Type>::region_defined() {
90 return m_region_defined;
93 template <
typename _Type>
94 void SparseLinearEigenSystem<_Type>::set_region(
const double& a,
const double& b,
const double& c,
const double& d) {
95 m_region_defined =
true;
102 template <
typename _Type>
103 bool& SparseLinearEigenSystem<_Type>::guess_defined() {
104 return m_guess_defined;
107 template <
typename _Type>
108 void SparseLinearEigenSystem<_Type>::set_initial_guess(
const DenseVector<_Type>& guess) {
109 m_guess_defined =
true;
110 m_initial_guess = guess;
113 template <
typename _Type>
114 void SparseLinearEigenSystem<_Type >::eigensolve() {
120 template <
typename _Type>
121 void SparseLinearEigenSystem<_Type>::eigensolve_slepc() {
124 problem =
"The SparseLinearEigenSystem::eigensolve method has been called\n";
125 problem +=
"but the compiler option -DSLEPC was not provided when\n";
126 problem +=
"the library was built.";
127 throw ExceptionExternal(problem);
138 Vec petsc_xr,petsc_xi;
153 MatCreate(PETSC_COMM_WORLD,&petsc_A);
154 MatSetSizes(petsc_A,PETSC_DECIDE,PETSC_DECIDE,n,n);
155 MatSetFromOptions(petsc_A);
159 PetscInt* all_rows_nnz =
new PetscInt[ n ];
160 m_pA -> nelts_all_rows(all_rows_nnz);
164 MatSeqAIJSetPreallocation(petsc_A, 0, all_rows_nnz);
169 for(PetscInt i = 0; i<n; ++i) {
171 std::size_t nelts_in_row = all_rows_nnz[i];
173 PetscInt* cols =
new PetscInt[all_rows_nnz[i]];
175 PetscScalar* storage =
new PetscScalar[all_rows_nnz[i]];
177 m_pA -> get_row_petsc(i, storage, cols);
178 MatSetValues(petsc_A,1,&i,nelts_in_row,cols,storage,INSERT_VALUES);
184 delete[] all_rows_nnz;
188 MatAssemblyBegin(petsc_A,MAT_FINAL_ASSEMBLY);
189 MatAssemblyEnd(petsc_A,MAT_FINAL_ASSEMBLY);
193 MatCreate(PETSC_COMM_WORLD,&petsc_B);
195 MatSetSizes(petsc_B,PETSC_DECIDE,PETSC_DECIDE,n,n);
197 MatSetFromOptions(petsc_B);
201 all_rows_nnz =
new PetscInt[ n ];
202 m_pB -> nelts_all_rows(all_rows_nnz);
205 MatSeqAIJSetPreallocation(petsc_B, 0, all_rows_nnz);
210 for(PetscInt i = 0; i<n; ++i) {
212 std::size_t nelts_in_row = all_rows_nnz[i];
214 PetscInt* cols =
new PetscInt[all_rows_nnz[i]];
216 PetscScalar* storage =
new PetscScalar[all_rows_nnz[i]];
218 m_pB -> get_row_petsc(i, storage, cols);
219 MatSetValues(petsc_B,1,&i,nelts_in_row,cols,storage,INSERT_VALUES);
225 delete[] all_rows_nnz;
229 MatAssemblyBegin(petsc_B,MAT_FINAL_ASSEMBLY);
230 MatAssemblyEnd(petsc_B,MAT_FINAL_ASSEMBLY);
234 MatCreateVecs(petsc_A,NULL,&petsc_xr);
235 MatCreateVecs(petsc_A,NULL,&petsc_xi);
238 MatCreateVecs(petsc_A,NULL,&petsc_x);
245 EPSCreate(PETSC_COMM_WORLD,&petsc_eps);
247 EPSSetOperators(petsc_eps,petsc_A,petsc_B);
249 EPSSetProblemType(petsc_eps,EPS_GNHEP);
251 EPSSetType(petsc_eps, EPSKRYLOVSCHUR);
253 EPSSetFromOptions(petsc_eps);
257 EPSSetTarget(petsc_eps, m_shift.real());
260 EPSSetTarget(petsc_eps, m_shift);
263 EPSSetWhichEigenpairs(petsc_eps, m_order);
268 EPSSetDimensions(petsc_eps,m_nev,5,PETSC_DEFAULT);
272 EPSSetDimensions(petsc_eps,m_nev,2*m_nev,PETSC_DEFAULT);
306 if(m_region_defined) {
308 EPSGetRG(petsc_eps, &petsc_rg);
309 RGSetType(petsc_rg, RGINTERVAL);
310 RGIntervalSetEndpoints(petsc_rg,m_real_left,m_real_right,
311 m_imag_bottom,m_imag_top);
315 EPSGetST(petsc_eps, &petsc_st);
318 STSetType(petsc_st, STSINVERT);
322 STGetKSP(petsc_st, &petsc_ksp);
324 KSPSetOperators(petsc_ksp,petsc_A,petsc_A);
326 KSPSetType(petsc_ksp, KSPPREONLY);
329 KSPGetPC(petsc_ksp,&petsc_pc);
331 PCSetType(petsc_pc,PCLU);
332 PCFactorSetMatSolverType(petsc_pc,MATSOLVERMUMPS);
333 PCFactorSetUpMatSolverType(petsc_pc);
337 PCFactorGetMatrix(petsc_pc,&petsc_F);
352 PetscInt its, lits, maxit;
353 EPSType petsc_eps_type;
356 std::cout <<
"[DEBUG] Target location for eigenvalue = " << m_shift <<
"\n";
357 std::cout <<
"[DEBUG] Target ordering of returned eigenvalues (see EPSWhich enum) = " << m_order <<
"\n";
361 EPSGetIterationNumber(petsc_eps,&its);
362 PetscPrintf(PETSC_COMM_WORLD,
"[DEBUG] Number of iterations of the method: %D\n",its);
363 EPSGetST(petsc_eps,&petsc_st);
364 STGetKSP(petsc_st,&petsc_ksp);
365 KSPGetTotalIterations(petsc_ksp,&lits);
366 PetscPrintf(PETSC_COMM_WORLD,
"[DEBUG] Number of linear iterations of the method: %D\n",lits);
367 EPSGetType(petsc_eps,&petsc_eps_type);
368 PetscPrintf(PETSC_COMM_WORLD,
"[DEBUG] Solution method: %s\n\n",petsc_eps_type);
369 PetscPrintf(PETSC_COMM_WORLD,
"[DEBUG] Number of requested eigenvalues: %D\n",m_nev);
370 EPSGetTolerances(petsc_eps,&tol,&maxit);
371 PetscPrintf(PETSC_COMM_WORLD,
"[DEBUG] Stopping condition: tol=%.4g, maxit=%D\n",(
double)tol,maxit);
377 PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD,PETSC_VIEWER_ASCII_INFO_DETAIL);
379 EPSConvergedReasonView(petsc_eps,PETSC_VIEWER_STDOUT_WORLD);
380 EPSErrorView(petsc_eps,EPS_ERROR_ABSOLUTE,PETSC_VIEWER_STDOUT_WORLD);
381 PetscViewerPopFormat(PETSC_VIEWER_STDOUT_WORLD);
388 EPSGetConverged(petsc_eps,&nconv);
390 m_nconv = (unsigned)nconv;
392 m_all_eigenvalues = DenseVector<D_complex>(m_nconv, 0.0);
394 m_all_eigenvectors = DenseMatrix<D_complex>(m_nconv, n, 0.0);
396 for(
unsigned i=0; i<m_nconv; i++) {
398 EPSGetEigenvalue(petsc_eps,i,&m_all_eigenvalues[i],NULL);
399 std::cout << m_all_eigenvalues[i] <<
"\n";
402 double lambda_r,lambda_i;
403 EPSGetEigenvalue(petsc_eps,i,&lambda_r,&lambda_i);
404 m_all_eigenvalues[i] =
D_complex(lambda_r, lambda_i);
407 if(m_calc_eigenvectors) {
410 EPSGetEigenvector(petsc_eps,i,petsc_xr,petsc_xi);
413 VecGetArray1d(petsc_xr, n, 0, &arrayr);
415 VecGetArray1d(petsc_xi, n, 0, &arrayi);
416 for(
int j=0; j<n; ++j) {
417 m_all_eigenvectors[i][j]=
D_complex(arrayr[j], arrayi[j]);
420 VecRestoreArray1d(petsc_xr, n, 0, &arrayr);
421 VecRestoreArray1d(petsc_xi, n, 0, &arrayi);
425 EPSGetEigenvector(petsc_eps,i,petsc_x,NULL);
428 VecGetArray1d(petsc_x, n, 0, &array);
429 for(
int j=0; j<n; ++j) {
430 m_all_eigenvectors[i][j]=array[j];
433 VecRestoreArray1d(petsc_x, n, 0, &array);
442 EPSDestroy(&petsc_eps);
443 MatDestroy(&petsc_A);
444 MatDestroy(&petsc_B);
446 VecDestroy(&petsc_xr);
447 VecDestroy(&petsc_xi);
450 VecDestroy(&petsc_x);
458 template class SparseLinearEigenSystem<D_complex>
462 template class SparseLinearEigenSystem<double>
The collection of CppNoddy exceptions.
Specification of the sparse linear eigensystem class.
A spec for the CppNoddy Timer object.
A collection of OO numerical routines aimed at simple (typical) applied problems in continuum mechani...
std::complex< double > D_complex
A complex double precision number using std::complex.