Line data Source code
1 : /*
2 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3 : SLEPc - Scalable Library for Eigenvalue Problem Computations
4 : Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain
5 :
6 : This file is part of SLEPc.
7 : SLEPc is distributed under a 2-clause BSD license (see LICENSE).
8 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9 : */
10 :
11 : static char help[] = "Tests a user-defined convergence test.\n\n";
12 :
13 : #include <slepceps.h>
14 :
15 : /*
16 : MyConvergedAbsolute - Bizarre convergence test that requires more accuracy
17 : to positive eigenvalues compared to negative ones.
18 : */
19 65 : PetscErrorCode MyConvergedAbsolute(EPS eps,PetscScalar eigr,PetscScalar eigi,PetscReal res,PetscReal *errest,void *ctx)
20 : {
21 65 : PetscFunctionBegin;
22 65 : *errest = (PetscRealPart(eigr)<0.0)?res:100*res;
23 65 : PetscFunctionReturn(PETSC_SUCCESS);
24 : }
25 :
26 1 : int main(int argc,char **argv)
27 : {
28 1 : Mat A; /* problem matrix */
29 1 : EPS eps; /* eigenproblem solver context */
30 1 : PetscInt n=30,i,Istart,Iend;
31 :
32 1 : PetscFunctionBeginUser;
33 1 : PetscCall(SlepcInitialize(&argc,&argv,NULL,help));
34 1 : PetscCall(PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL));
35 1 : PetscCall(PetscPrintf(PETSC_COMM_WORLD,"\nTridiagonal Eigenproblem, n=%" PetscInt_FMT "\n\n",n));
36 :
37 : /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
38 : Compute the operator matrix that defines the eigensystem, Ax=kx
39 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
40 :
41 1 : PetscCall(MatCreate(PETSC_COMM_WORLD,&A));
42 1 : PetscCall(MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,n,n));
43 1 : PetscCall(MatSetFromOptions(A));
44 :
45 1 : PetscCall(MatGetOwnershipRange(A,&Istart,&Iend));
46 201 : for (i=Istart;i<Iend;i++) {
47 200 : if (i>0) PetscCall(MatSetValue(A,i,i-1,-1.0,INSERT_VALUES));
48 200 : if (i<n-1) PetscCall(MatSetValue(A,i,i+1,-1.0,INSERT_VALUES));
49 : }
50 1 : PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY));
51 1 : PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY));
52 1 : PetscCall(MatShift(A,-1e-3));
53 :
54 : /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
55 : Create the eigensolver
56 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
57 1 : PetscCall(EPSCreate(PETSC_COMM_WORLD,&eps));
58 1 : PetscCall(EPSSetOperators(eps,A,NULL));
59 1 : PetscCall(EPSSetProblemType(eps,EPS_HEP));
60 : /* set user-defined convergence test */
61 1 : PetscCall(EPSSetConvergenceTestFunction(eps,MyConvergedAbsolute,NULL,NULL));
62 1 : PetscCall(EPSSetFromOptions(eps));
63 :
64 : /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
65 : Solve the problem
66 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
67 1 : PetscCall(EPSSolve(eps));
68 1 : PetscCall(EPSErrorView(eps,EPS_ERROR_RELATIVE,NULL));
69 :
70 1 : PetscCall(EPSDestroy(&eps));
71 1 : PetscCall(MatDestroy(&A));
72 1 : PetscCall(SlepcFinalize());
73 : return 0;
74 : }
75 :
76 : /*TEST
77 :
78 : test:
79 : suffix: 1
80 : args: -n 200 -eps_nev 6 -eps_ncv 24 -eps_smallest_magnitude
81 : requires: !single
82 :
83 : TEST*/
|