LCOV - code coverage report
Current view: top level - sys/classes/ds/tests - test23.c (source / functions) Hit Total Coverage
Test: SLEPc Lines: 114 120 95.0 %
Date: 2024-12-18 00:42:09 Functions: 1 1 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[] = "Test interface functions of DSNEP.\n\n";
      12             : 
      13             : #include <slepcds.h>
      14             : 
      15           1 : int main(int argc,char **argv)
      16             : {
      17           1 :   DS             ds;
      18           1 :   FN             f1,f2,f3,funs[3];
      19           1 :   SlepcSC        sc;
      20           1 :   PetscScalar    *Id,*A,*B,*wr,*wi,*X,*W,coeffs[2],auxr,alpha;
      21           1 :   PetscReal      tau=0.001,h,a=20,xi,re,im,nrm,aux;
      22           1 :   PetscInt       i,j,ii,jj,k,n=10,ld,nev,nfun,midx,ip,rits,meth,spls;
      23           1 :   PetscViewer    viewer;
      24           1 :   PetscBool      verbose;
      25           1 :   RG             rg;
      26           1 :   DSMatType      mat[3]={DS_MAT_E0,DS_MAT_E1,DS_MAT_E2};
      27             : #if defined(PETSC_USE_COMPLEX)
      28             :   PetscBool      flg;
      29             : #else
      30           1 :   PetscScalar    auxi;
      31             : #endif
      32             : 
      33           1 :   PetscFunctionBeginUser;
      34           1 :   PetscCall(SlepcInitialize(&argc,&argv,NULL,help));
      35           1 :   PetscCall(PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL));
      36           1 :   PetscCall(PetscOptionsGetReal(NULL,NULL,"-tau",&tau,NULL));
      37           1 :   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Solve a Dense System of type NEP - dimension %" PetscInt_FMT ", tau=%g.\n",n,(double)tau));
      38           1 :   PetscCall(PetscOptionsHasName(NULL,NULL,"-verbose",&verbose));
      39             : 
      40             :   /* Create DS object and set options */
      41           1 :   PetscCall(DSCreate(PETSC_COMM_WORLD,&ds));
      42           1 :   PetscCall(DSSetType(ds,DSNEP));
      43             : #if defined(PETSC_USE_COMPLEX)
      44             :   PetscCall(DSSetMethod(ds,1));  /* contour integral */
      45             : #endif
      46           1 :   PetscCall(DSNEPGetRG(ds,&rg));
      47           1 :   PetscCall(RGSetType(rg,RGELLIPSE));
      48           1 :   PetscCall(DSNEPSetMinimality(ds,1));
      49           1 :   PetscCall(DSNEPSetIntegrationPoints(ds,16));
      50           1 :   PetscCall(DSNEPSetRefine(ds,PETSC_CURRENT,2));
      51           1 :   PetscCall(DSNEPSetSamplingSize(ds,25));
      52           1 :   PetscCall(DSSetFromOptions(ds));
      53             : 
      54             :   /* Print current options */
      55           1 :   PetscCall(DSGetMethod(ds,&meth));
      56             : #if defined(PETSC_USE_COMPLEX)
      57             :   PetscCheck(meth==1,PETSC_COMM_WORLD,PETSC_ERR_USER_INPUT,"This example requires ds_method=1");
      58             :   PetscCall(RGIsTrivial(rg,&flg));
      59             :   PetscCheck(!flg,PETSC_COMM_WORLD,PETSC_ERR_USER_INPUT,"Must at least set the radius of the ellipse");
      60             : #endif
      61             : 
      62           1 :   PetscCall(DSNEPGetMinimality(ds,&midx));
      63           1 :   PetscCall(DSNEPGetIntegrationPoints(ds,&ip));
      64           1 :   PetscCall(DSNEPGetRefine(ds,NULL,&rits));
      65           1 :   PetscCall(DSNEPGetSamplingSize(ds,&spls));
      66           1 :   if (meth==1) {
      67           0 :     PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Contour integral method with %" PetscInt_FMT " integration points, minimality index %" PetscInt_FMT ", and sampling size %" PetscInt_FMT "\n",ip,midx,spls));
      68           0 :     if (rits) PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Doing %" PetscInt_FMT " iterations of Newton refinement\n",rits));
      69             :   }
      70             : 
      71             :   /* Set functions (prior to DSAllocate) */
      72           1 :   PetscCall(FNCreate(PETSC_COMM_WORLD,&f1));
      73           1 :   PetscCall(FNSetType(f1,FNRATIONAL));
      74           1 :   coeffs[0] = -1.0; coeffs[1] = 0.0;
      75           1 :   PetscCall(FNRationalSetNumerator(f1,2,coeffs));
      76             : 
      77           1 :   PetscCall(FNCreate(PETSC_COMM_WORLD,&f2));
      78           1 :   PetscCall(FNSetType(f2,FNRATIONAL));
      79           1 :   coeffs[0] = 1.0;
      80           1 :   PetscCall(FNRationalSetNumerator(f2,1,coeffs));
      81             : 
      82           1 :   PetscCall(FNCreate(PETSC_COMM_WORLD,&f3));
      83           1 :   PetscCall(FNSetType(f3,FNEXP));
      84           1 :   PetscCall(FNSetScale(f3,-tau,1.0));
      85             : 
      86           1 :   funs[0] = f1;
      87           1 :   funs[1] = f2;
      88           1 :   funs[2] = f3;
      89           1 :   PetscCall(DSNEPSetFN(ds,3,funs));
      90             : 
      91             :   /* Set dimensions */
      92           1 :   ld = n;
      93           1 :   PetscCall(DSAllocate(ds,ld));
      94           1 :   PetscCall(DSSetDimensions(ds,n,0,0));
      95             : 
      96             :   /* Set up viewer */
      97           1 :   PetscCall(PetscViewerASCIIGetStdout(PETSC_COMM_WORLD,&viewer));
      98           1 :   PetscCall(PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL));
      99           1 :   PetscCall(PetscViewerPopFormat(viewer));
     100           1 :   if (verbose) PetscCall(PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB));
     101             : 
     102             :   /* Fill matrices */
     103           1 :   PetscCall(DSGetArray(ds,DS_MAT_E0,&Id));
     104          11 :   for (i=0;i<n;i++) Id[i+i*ld]=1.0;
     105           1 :   PetscCall(DSRestoreArray(ds,DS_MAT_E0,&Id));
     106           1 :   h = PETSC_PI/(PetscReal)(n+1);
     107           1 :   PetscCall(DSGetArray(ds,DS_MAT_E1,&A));
     108          11 :   for (i=0;i<n;i++) A[i+i*ld]=-2.0/(h*h)+a;
     109          10 :   for (i=1;i<n;i++) {
     110           9 :     A[i+(i-1)*ld]=1.0/(h*h);
     111           9 :     A[(i-1)+i*ld]=1.0/(h*h);
     112             :   }
     113           1 :   PetscCall(DSRestoreArray(ds,DS_MAT_E1,&A));
     114           1 :   PetscCall(DSGetArray(ds,DS_MAT_E2,&B));
     115          11 :   for (i=0;i<n;i++) {
     116          10 :     xi = (i+1)*h;
     117          10 :     B[i+i*ld] = -4.1+xi*(1.0-PetscExpReal(xi-PETSC_PI));
     118             :   }
     119           1 :   PetscCall(DSRestoreArray(ds,DS_MAT_E2,&B));
     120             : 
     121           1 :   if (verbose) {
     122           0 :     PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Initial - - - - - - - - -\n"));
     123           0 :     PetscCall(DSView(ds,viewer));
     124             :   }
     125             : 
     126             :   /* Solve */
     127           1 :   PetscCall(PetscCalloc2(n,&wr,n,&wi));
     128           1 :   PetscCall(DSGetSlepcSC(ds,&sc));
     129           1 :   sc->comparison    = SlepcCompareLargestMagnitude;
     130           1 :   sc->comparisonctx = NULL;
     131           1 :   sc->map           = NULL;
     132           1 :   sc->mapobj        = NULL;
     133           1 :   PetscCall(DSSolve(ds,wr,wi));
     134           1 :   PetscCall(DSSort(ds,wr,wi,NULL,NULL,NULL));
     135             : 
     136           1 :   if (verbose) {
     137           0 :     PetscCall(PetscPrintf(PETSC_COMM_WORLD,"After solve - - - - - - - - -\n"));
     138           0 :     PetscCall(DSView(ds,viewer));
     139             :   }
     140           1 :   PetscCall(DSGetDimensions(ds,NULL,NULL,NULL,&nev));
     141             : 
     142             :   /* Print computed eigenvalues */
     143           1 :   PetscCall(DSNEPGetNumFN(ds,&nfun));
     144           1 :   PetscCall(PetscMalloc1(ld*ld,&W));
     145           1 :   PetscCall(DSVectors(ds,DS_MAT_X,NULL,NULL));
     146           1 :   PetscCall(DSGetArray(ds,DS_MAT_X,&X));
     147           1 :   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Computed eigenvalues =\n"));
     148           2 :   for (i=0;i<nev;i++) {
     149             : #if defined(PETSC_USE_COMPLEX)
     150             :     re = PetscRealPart(wr[i]);
     151             :     im = PetscImaginaryPart(wr[i]);
     152             : #else
     153           1 :     re = wr[i];
     154           1 :     im = wi[i];
     155             : #endif
     156             :     /* Residual */
     157           1 :     PetscCall(PetscArrayzero(W,ld*ld));
     158           4 :     for (k=0;k<nfun;k++) {
     159           3 :       PetscCall(FNEvaluateFunction(funs[k],wr[i],&alpha));
     160           3 :       PetscCall(DSGetArray(ds,mat[k],&A));
     161         333 :       for (jj=0;jj<n;jj++) for (ii=0;ii<n;ii++) W[jj*ld+ii] += alpha*A[jj*ld+ii];
     162           3 :       PetscCall(DSRestoreArray(ds,mat[k],&A));
     163             :     }
     164             :     nrm = 0.0;
     165          11 :     for (k=0;k<n;k++) {
     166             :       auxr = 0.0;
     167             : #if !defined(PETSC_USE_COMPLEX)
     168             :       auxi = 0.0;
     169             : #endif
     170         110 :       for (j=0;j<n;j++) {
     171         100 :         auxr += W[k+j*ld]*X[i*ld+j];
     172             : #if !defined(PETSC_USE_COMPLEX)
     173         100 :         if (PetscAbs(wi[j])!=0.0) auxi += W[k+j*ld]*X[(i+1)*ld+j];
     174             : #endif
     175             :       }
     176          10 :       aux = SlepcAbsEigenvalue(auxr,auxi);
     177          10 :       nrm += aux*aux;
     178             :     }
     179           1 :     nrm = PetscSqrtReal(nrm);
     180           1 :     if (nrm>1000*n*PETSC_MACHINE_EPSILON) PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Warning: the residual norm of the %" PetscInt_FMT "-th computed eigenpair %g\n",i,(double)nrm));
     181           1 :     if (PetscAbs(im)<1e-10) PetscCall(PetscViewerASCIIPrintf(viewer,"  %.5f\n",(double)re));
     182           1 :     else PetscCall(PetscViewerASCIIPrintf(viewer,"  %.5f%+.5fi\n",(double)re,(double)im));
     183             :   }
     184           1 :   PetscCall(PetscFree(W));
     185           1 :   PetscCall(DSRestoreArray(ds,DS_MAT_X,&X));
     186           1 :   PetscCall(DSRestoreArray(ds,DS_MAT_W,&W));
     187           1 :   PetscCall(PetscFree2(wr,wi));
     188           1 :   PetscCall(FNDestroy(&f1));
     189           1 :   PetscCall(FNDestroy(&f2));
     190           1 :   PetscCall(FNDestroy(&f3));
     191           1 :   PetscCall(DSDestroy(&ds));
     192           1 :   PetscCall(SlepcFinalize());
     193             :   return 0;
     194             : }
     195             : 
     196             : /*TEST
     197             : 
     198             :    testset:
     199             :       test:
     200             :          suffix: 1
     201             :          requires: !complex
     202             :       test:
     203             :          suffix: 2
     204             :          args: -ds_nep_rg_ellipse_radius 10
     205             :          filter: sed -e "s/[+-]0\.0*i//g" | sed -e "s/37411/37410/"
     206             :          requires: complex
     207             : 
     208             : TEST*/

Generated by: LCOV version 1.14