LCOV - code coverage report
Current view: top level - eps/tests - test9.c (source / functions) Hit Total Coverage
Test: SLEPc Lines: 91 91 100.0 %
Date: 2024-11-23 00:39:48 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

          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[] = "Eigenvalue problem associated with a Markov model of a random walk on a triangular grid. "
      12             :   "It is a standard nonsymmetric eigenproblem with real eigenvalues and the rightmost eigenvalue is known to be 1.\n"
      13             :   "This example illustrates how the user can set the initial vector.\n\n"
      14             :   "The command line options are:\n"
      15             :   "  -m <m>, where <m> = number of grid subdivisions in each dimension.\n\n";
      16             : 
      17             : #include <slepceps.h>
      18             : 
      19             : /*
      20             :    User-defined routines
      21             : */
      22             : PetscErrorCode MatMarkovModel(PetscInt m,Mat A);
      23             : PetscErrorCode MyEigenSort(PetscScalar ar,PetscScalar ai,PetscScalar br,PetscScalar bi,PetscInt *r,void *ctx);
      24             : 
      25             : /*
      26             :    Check if computed eigenvectors have unit norm
      27             : */
      28          24 : PetscErrorCode CheckNormalizedVectors(EPS eps)
      29             : {
      30          24 :   PetscInt       i,nconv;
      31          24 :   Mat            A;
      32          24 :   Vec            xr,xi;
      33          24 :   PetscReal      error=0.0,normr;
      34             : #if !defined(PETSC_USE_COMPLEX)
      35             :   PetscReal      normi;
      36             : #endif
      37             : 
      38          24 :   PetscFunctionBeginUser;
      39          24 :   PetscCall(EPSGetConverged(eps,&nconv));
      40          24 :   if (nconv>0) {
      41          24 :     PetscCall(EPSGetOperators(eps,&A,NULL));
      42          24 :     PetscCall(MatCreateVecs(A,&xr,&xi));
      43         239 :     for (i=0;i<nconv;i++) {
      44         215 :       PetscCall(EPSGetEigenvector(eps,i,xr,xi));
      45             : #if defined(PETSC_USE_COMPLEX)
      46         215 :       PetscCall(VecNorm(xr,NORM_2,&normr));
      47         259 :       error = PetscMax(error,PetscAbsReal(normr-PetscRealConstant(1.0)));
      48             : #else
      49             :       PetscCall(VecNormBegin(xr,NORM_2,&normr));
      50             :       PetscCall(VecNormBegin(xi,NORM_2,&normi));
      51             :       PetscCall(VecNormEnd(xr,NORM_2,&normr));
      52             :       PetscCall(VecNormEnd(xi,NORM_2,&normi));
      53             :       error = PetscMax(error,PetscAbsReal(SlepcAbsEigenvalue(normr,normi)-PetscRealConstant(1.0)));
      54             : #endif
      55             :     }
      56          24 :     PetscCall(VecDestroy(&xr));
      57          24 :     PetscCall(VecDestroy(&xi));
      58          24 :     if (error>100*PETSC_MACHINE_EPSILON) PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Vectors are not normalized. Error=%g\n",(double)error));
      59             :   }
      60          24 :   PetscFunctionReturn(PETSC_SUCCESS);
      61             : }
      62             : 
      63          28 : int main(int argc,char **argv)
      64             : {
      65          28 :   Vec            v0;              /* initial vector */
      66          28 :   Mat            A;               /* operator matrix */
      67          28 :   EPS            eps;             /* eigenproblem solver context */
      68          28 :   PetscReal      tol=0.5*PETSC_SMALL;
      69          28 :   PetscInt       N,m=15,nev;
      70          28 :   PetscScalar    origin=0.0;
      71          28 :   PetscBool      flg,delay,skipnorm=PETSC_FALSE;
      72             : 
      73          28 :   PetscFunctionBeginUser;
      74          28 :   PetscCall(SlepcInitialize(&argc,&argv,NULL,help));
      75             : 
      76          28 :   PetscCall(PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL));
      77          28 :   N = m*(m+1)/2;
      78          28 :   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"\nMarkov Model, N=%" PetscInt_FMT " (m=%" PetscInt_FMT ")\n\n",N,m));
      79          28 :   PetscCall(PetscOptionsGetBool(NULL,NULL,"-skipnorm",&skipnorm,NULL));
      80             : 
      81             :   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      82             :      Compute the operator matrix that defines the eigensystem, Ax=kx
      83             :      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
      84             : 
      85          28 :   PetscCall(MatCreate(PETSC_COMM_WORLD,&A));
      86          28 :   PetscCall(MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,N,N));
      87          28 :   PetscCall(MatSetFromOptions(A));
      88          28 :   PetscCall(MatMarkovModel(m,A));
      89             : 
      90             :   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      91             :                 Create the eigensolver and set various options
      92             :      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
      93             : 
      94             :   /*
      95             :      Create eigensolver context
      96             :   */
      97          28 :   PetscCall(EPSCreate(PETSC_COMM_WORLD,&eps));
      98             : 
      99             :   /*
     100             :      Set operators. In this case, it is a standard eigenvalue problem
     101             :   */
     102          28 :   PetscCall(EPSSetOperators(eps,A,NULL));
     103          28 :   PetscCall(EPSSetProblemType(eps,EPS_NHEP));
     104          28 :   PetscCall(EPSSetTolerances(eps,tol,PETSC_CURRENT));
     105             : 
     106             :   /*
     107             :      Set the custom comparing routine in order to obtain the eigenvalues
     108             :      closest to the target on the right only
     109             :   */
     110          28 :   PetscCall(EPSSetEigenvalueComparison(eps,MyEigenSort,&origin));
     111             : 
     112             :   /*
     113             :      Set solver parameters at runtime
     114             :   */
     115          28 :   PetscCall(EPSSetFromOptions(eps));
     116          28 :   PetscCall(PetscObjectTypeCompare((PetscObject)eps,EPSARNOLDI,&flg));
     117          28 :   if (flg) {
     118           5 :     PetscCall(EPSArnoldiGetDelayed(eps,&delay));
     119           5 :     if (delay) PetscCall(PetscPrintf(PETSC_COMM_WORLD," Warning: delayed reorthogonalization may be unstable\n"));
     120             :   }
     121             : 
     122             :   /*
     123             :      Set the initial vector. This is optional, if not done the initial
     124             :      vector is set to random values
     125             :   */
     126          28 :   PetscCall(MatCreateVecs(A,&v0,NULL));
     127          28 :   PetscCall(VecSetValue(v0,0,-1.5,INSERT_VALUES));
     128          28 :   PetscCall(VecSetValue(v0,1,2.1,INSERT_VALUES));
     129          28 :   PetscCall(VecAssemblyBegin(v0));
     130          28 :   PetscCall(VecAssemblyEnd(v0));
     131          28 :   PetscCall(EPSSetInitialSpace(eps,1,&v0));
     132             : 
     133             :   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     134             :                       Solve the eigensystem
     135             :      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     136             : 
     137          28 :   PetscCall(EPSSolve(eps));
     138          28 :   PetscCall(EPSGetDimensions(eps,&nev,NULL,NULL));
     139          28 :   PetscCall(PetscPrintf(PETSC_COMM_WORLD," Number of requested eigenvalues: %" PetscInt_FMT "\n",nev));
     140             : 
     141             :   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     142             :                     Display solution and clean up
     143             :      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     144             : 
     145          28 :   PetscCall(EPSErrorView(eps,EPS_ERROR_RELATIVE,NULL));
     146          28 :   if (!skipnorm) PetscCall(CheckNormalizedVectors(eps));
     147          28 :   PetscCall(EPSDestroy(&eps));
     148          28 :   PetscCall(MatDestroy(&A));
     149          28 :   PetscCall(VecDestroy(&v0));
     150          28 :   PetscCall(SlepcFinalize());
     151             :   return 0;
     152             : }
     153             : 
     154          28 : PetscErrorCode MatMarkovModel(PetscInt m,Mat A)
     155             : {
     156          28 :   const PetscReal cst = 0.5/(PetscReal)(m-1);
     157          28 :   PetscReal       pd,pu;
     158          28 :   PetscInt        Istart,Iend,i,j,jmax,ix=0;
     159             : 
     160          28 :   PetscFunctionBeginUser;
     161          28 :   PetscCall(MatGetOwnershipRange(A,&Istart,&Iend));
     162         448 :   for (i=1;i<=m;i++) {
     163         420 :     jmax = m-i+1;
     164        3780 :     for (j=1;j<=jmax;j++) {
     165        3360 :       ix = ix + 1;
     166        3360 :       if (ix-1<Istart || ix>Iend) continue;  /* compute only owned rows */
     167        3120 :       if (j!=jmax) {
     168        2730 :         pd = cst*(PetscReal)(i+j-1);
     169             :         /* north */
     170        2730 :         if (i==1) PetscCall(MatSetValue(A,ix-1,ix,2*pd,INSERT_VALUES));
     171        2366 :         else PetscCall(MatSetValue(A,ix-1,ix,pd,INSERT_VALUES));
     172             :         /* east */
     173        2730 :         if (j==1) PetscCall(MatSetValue(A,ix-1,ix+jmax-1,2*pd,INSERT_VALUES));
     174        2366 :         else PetscCall(MatSetValue(A,ix-1,ix+jmax-1,pd,INSERT_VALUES));
     175             :       }
     176             :       /* south */
     177        3120 :       pu = 0.5 - cst*(PetscReal)(i+j-3);
     178        3120 :       if (j>1) PetscCall(MatSetValue(A,ix-1,ix-2,pu,INSERT_VALUES));
     179             :       /* west */
     180        3360 :       if (i>1) PetscCall(MatSetValue(A,ix-1,ix-jmax-2,pu,INSERT_VALUES));
     181             :     }
     182             :   }
     183          28 :   PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY));
     184          28 :   PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY));
     185          28 :   PetscFunctionReturn(PETSC_SUCCESS);
     186             : }
     187             : 
     188             : /*
     189             :     Function for user-defined eigenvalue ordering criterion.
     190             : 
     191             :     Given two eigenvalues ar+i*ai and br+i*bi, the subroutine must choose
     192             :     one of them as the preferred one according to the criterion.
     193             :     In this example, the preferred value is the one furthest away from the origin.
     194             : */
     195       86706 : PetscErrorCode MyEigenSort(PetscScalar ar,PetscScalar ai,PetscScalar br,PetscScalar bi,PetscInt *r,void *ctx)
     196             : {
     197       86706 :   PetscScalar origin = *(PetscScalar*)ctx;
     198       86706 :   PetscReal   d;
     199             : 
     200       86706 :   PetscFunctionBeginUser;
     201       86706 :   d = (SlepcAbsEigenvalue(br-origin,bi) - SlepcAbsEigenvalue(ar-origin,ai))/PetscMax(SlepcAbsEigenvalue(ar-origin,ai),SlepcAbsEigenvalue(br-origin,bi));
     202       86706 :   *r = d > PETSC_SQRT_MACHINE_EPSILON ? 1 : (d < -PETSC_SQRT_MACHINE_EPSILON ? -1 : PetscSign(PetscRealPart(br)));
     203       86706 :   PetscFunctionReturn(PETSC_SUCCESS);
     204             : }
     205             : 
     206             : /*TEST
     207             : 
     208             :    testset:
     209             :       args: -eps_nev 4
     210             :       output_file: output/test9_1.out
     211             :       filter: sed -e "s/97136/97137/g"
     212             :       test:
     213             :          suffix: 1
     214             :          args: -eps_type {{krylovschur arnoldi lapack}} -eps_ncv 8 -eps_max_it 300
     215             :       test:
     216             :          suffix: 1_gd
     217             :          args: -eps_type gd -st_pc_type none
     218             :       test:
     219             :          suffix: 1_gd2
     220             :          args: -eps_type gd -eps_gd_double_expansion -st_pc_type none
     221             : 
     222             :    test:
     223             :       suffix: 2
     224             :       args: -eps_balance {{none oneside twoside}} -eps_krylovschur_locking {{0 1}} -eps_nev 4 -eps_max_it 1500
     225             :       requires: double
     226             :       output_file: output/test9_1.out
     227             : 
     228             :    test:
     229             :       suffix: 3
     230             :       nsize: 2
     231             :       args: -eps_type arnoldi -eps_arnoldi_delayed -eps_largest_real -eps_nev 3 -eps_tol 1e-7 -bv_orthog_refine {{never ifneeded}} -skipnorm
     232             :       requires: !single
     233             :       output_file: output/test9_3.out
     234             : 
     235             :    test:
     236             :       suffix: 4
     237             :       args: -eps_nev 4 -eps_true_residual
     238             :       requires: !single
     239             :       output_file: output/test9_1.out
     240             : 
     241             :    test:
     242             :       suffix: 5
     243             :       args: -eps_type jd -eps_nev 3 -eps_target .5 -eps_harmonic -st_ksp_type bicg -st_pc_type lu -eps_jd_minv 2
     244             :       filter: sed -e "s/[+-]0\.0*i//g"
     245             :       requires: !single
     246             : 
     247             :    test:
     248             :       suffix: 5_arpack
     249             :       args: -eps_nev 3 -st_type sinvert -eps_target .5 -eps_type arpack -eps_ncv 10
     250             :       requires: arpack !single
     251             :       output_file: output/test9_5.out
     252             : 
     253             :    testset:
     254             :       args: -eps_type ciss -eps_tol 1e-9 -rg_type ellipse -rg_ellipse_center 0.55 -rg_ellipse_radius 0.05 -rg_ellipse_vscale 0.1 -eps_ciss_usest 0 -eps_all
     255             :       requires: !single
     256             :       output_file: output/test9_6.out
     257             :       test:
     258             :          suffix: 6
     259             :       test:
     260             :          suffix: 6_hankel
     261             :          args: -eps_ciss_extraction hankel -eps_ciss_spurious_threshold 1e-6 -eps_ncv 64
     262             :       test:
     263             :          suffix: 6_cheby
     264             :          args: -eps_ciss_quadrule chebyshev
     265             :       test:
     266             :          suffix: 6_hankel_cheby
     267             :          args: -eps_ciss_extraction hankel -eps_ciss_quadrule chebyshev -eps_ncv 64
     268             :       test:
     269             :          suffix: 6_refine
     270             :          args: -eps_ciss_moments 4 -eps_ciss_blocksize 5 -eps_ciss_refine_inner 1 -eps_ciss_refine_blocksize 2
     271             :       test:
     272             :          suffix: 6_bcgs
     273             :          args: -eps_ciss_realmats -eps_ciss_ksp_type bcgs -eps_ciss_pc_type ilu -eps_ciss_integration_points 8
     274             : 
     275             :    test:
     276             :       suffix: 6_cheby_interval
     277             :       args: -eps_type ciss -eps_tol 1e-9 -rg_type interval -rg_interval_endpoints 0.5,0.6 -eps_ciss_quadrule chebyshev -eps_ciss_usest 0 -eps_all
     278             :       requires: !single
     279             :       output_file: output/test9_6.out
     280             : 
     281             :    testset:
     282             :       args: -eps_nev 4 -eps_two_sided -eps_view_vectors ::ascii_info -eps_view_values
     283             :       filter: sed -e "s/\(0x[0-9a-fA-F]*\)/objectid/"
     284             :       test:
     285             :          suffix: 7_real
     286             :          requires: !single !complex
     287             :       test:
     288             :          suffix: 7
     289             :          requires: !single complex
     290             : 
     291             :    test:
     292             :       suffix: 8
     293             :       args: -eps_nev 4 -eps_ncv 7 -eps_view_values draw -eps_monitor draw::draw_lg
     294             :       requires: x
     295             :       output_file: output/test9_1.out
     296             : 
     297             :    test:
     298             :       suffix: 5_ksphpddm
     299             :       args: -eps_nev 3 -st_type sinvert -eps_target .5 -st_ksp_type hpddm -st_ksp_hpddm_type gcrodr -eps_ncv 10
     300             :       requires: hpddm
     301             :       output_file: output/test9_5.out
     302             : 
     303             :    test:
     304             :       suffix: 5_pchpddm
     305             :       args: -eps_nev 3 -st_type sinvert -eps_target .5 -st_pc_type hpddm -st_pc_hpddm_coarse_pc_type lu -eps_ncv 10
     306             :       requires: hpddm
     307             :       output_file: output/test9_5.out
     308             : 
     309             : TEST*/

Generated by: LCOV version 1.14