LCOV - code coverage report
Current view: top level - pep/tutorials/nlevp - planar_waveguide.c (source / functions) Hit Total Coverage
Test: SLEPc Lines: 89 93 95.7 %
Date: 2024-12-18 00:51:33 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             :    This example implements one of the problems found at
      12             :        NLEVP: A Collection of Nonlinear Eigenvalue Problems,
      13             :        The University of Manchester.
      14             :    The details of the collection can be found at:
      15             :        [1] T. Betcke et al., "NLEVP: A Collection of Nonlinear Eigenvalue
      16             :            Problems", ACM Trans. Math. Software 39(2), Article 7, 2013.
      17             : 
      18             :    The planar_waveguide problem is a quartic PEP with symmetric matrices,
      19             :    arising from a finite element solution of the propagation constants in a
      20             :    six-layer planar waveguide.
      21             : */
      22             : 
      23             : static char help[] = "FEM solution of the propagation constants in a six-layer planar waveguide.\n\n"
      24             :   "The command line options are:\n"
      25             :   "  -n <n>, the dimension of the matrices.\n\n";
      26             : 
      27             : #include <slepcpep.h>
      28             : 
      29             : #define NMAT 5
      30             : #define NL   6
      31             : 
      32           2 : int main(int argc,char **argv)
      33             : {
      34           2 :   Mat            A[NMAT];         /* problem matrices */
      35           2 :   PEP            pep;             /* polynomial eigenproblem solver context */
      36           2 :   PetscInt       n=128,nlocal,k,Istart,Iend,i,j,start_ct,end_ct;
      37           2 :   PetscReal      w=9.92918,a=0.0,b=2.0,h,deltasq;
      38           2 :   PetscReal      nref[NL],K2[NL],q[NL],*md,*supd,*subd;
      39           2 :   PetscScalar    v,alpha;
      40           2 :   PetscBool      terse;
      41             : 
      42           2 :   PetscFunctionBeginUser;
      43           2 :   PetscCall(SlepcInitialize(&argc,&argv,NULL,help));
      44             : 
      45           2 :   PetscCall(PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL));
      46           2 :   n = (n/4)*4;
      47           2 :   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"\nPlanar waveguide, n=%" PetscInt_FMT "\n\n",n+1));
      48           2 :   h = (b-a)/n;
      49           2 :   nlocal = (n/4)-1;
      50             : 
      51             :   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      52             :           Set waveguide parameters used in construction of matrices
      53             :      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
      54             : 
      55             :   /* refractive indices in each layer */
      56           2 :   nref[0] = 1.5;
      57           2 :   nref[1] = 1.66;
      58           2 :   nref[2] = 1.6;
      59           2 :   nref[3] = 1.53;
      60           2 :   nref[4] = 1.66;
      61           2 :   nref[5] = 1.0;
      62             : 
      63          14 :   for (i=0;i<NL;i++) K2[i] = w*w*nref[i]*nref[i];
      64           2 :   deltasq = K2[0] - K2[NL-1];
      65          14 :   for (i=0;i<NL;i++) q[i] = K2[i] - (K2[0] + K2[NL-1])/2;
      66             : 
      67             :   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      68             :                      Compute the polynomial matrices
      69             :      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
      70             : 
      71             :   /* initialize matrices */
      72          12 :   for (i=0;i<NMAT;i++) {
      73          10 :     PetscCall(MatCreate(PETSC_COMM_WORLD,&A[i]));
      74          10 :     PetscCall(MatSetSizes(A[i],PETSC_DECIDE,PETSC_DECIDE,n+1,n+1));
      75          10 :     PetscCall(MatSetFromOptions(A[i]));
      76             :   }
      77           2 :   PetscCall(MatGetOwnershipRange(A[0],&Istart,&Iend));
      78             : 
      79             :   /* A0 */
      80           2 :   alpha = (h/6)*(deltasq*deltasq/16);
      81         260 :   for (i=Istart;i<Iend;i++) {
      82         258 :     v = 4.0;
      83         258 :     if (i==0 || i==n) v = 2.0;
      84         258 :     PetscCall(MatSetValue(A[0],i,i,v*alpha,INSERT_VALUES));
      85         258 :     if (i>0) PetscCall(MatSetValue(A[0],i,i-1,alpha,INSERT_VALUES));
      86         258 :     if (i<n) PetscCall(MatSetValue(A[0],i,i+1,alpha,INSERT_VALUES));
      87             :   }
      88             : 
      89             :   /* A1 */
      90           2 :   if (Istart==0) PetscCall(MatSetValue(A[1],0,0,-deltasq/4,INSERT_VALUES));
      91           2 :   if (Iend==n+1) PetscCall(MatSetValue(A[1],n,n,deltasq/4,INSERT_VALUES));
      92             : 
      93             :   /* A2 */
      94           2 :   alpha = 1.0/h;
      95         260 :   for (i=Istart;i<Iend;i++) {
      96         258 :     v = 2.0;
      97         258 :     if (i==0 || i==n) v = 1.0;
      98         258 :     PetscCall(MatSetValue(A[2],i,i,v*alpha,ADD_VALUES));
      99         258 :     if (i>0) PetscCall(MatSetValue(A[2],i,i-1,-alpha,ADD_VALUES));
     100         258 :     if (i<n) PetscCall(MatSetValue(A[2],i,i+1,-alpha,ADD_VALUES));
     101             :   }
     102           2 :   PetscCall(PetscMalloc3(n+1,&md,n+1,&supd,n+1,&subd));
     103             : 
     104           2 :   md[0]   = 2.0*q[1];
     105           2 :   supd[1] = q[1];
     106           2 :   subd[0] = q[1];
     107             : 
     108          10 :   for (k=1;k<=NL-2;k++) {
     109             : 
     110           8 :     end_ct = k*(nlocal+1);
     111           8 :     start_ct = end_ct-nlocal;
     112             : 
     113         256 :     for (j=start_ct;j<end_ct;j++) {
     114         248 :       md[j] = 4*q[k];
     115         248 :       supd[j+1] = q[k];
     116         248 :       subd[j] = q[k];
     117             :     }
     118             : 
     119           8 :     if (k < 4) {  /* interface points */
     120           6 :       md[end_ct] = 4*(q[k] + q[k+1])/2.0;
     121           6 :       supd[end_ct+1] = q[k+1];
     122           6 :       subd[end_ct] = q[k+1];
     123             :     }
     124             : 
     125             :   }
     126             : 
     127           2 :   md[n] = 2*q[NL-2];
     128           2 :   supd[n] = q[NL-2];
     129           2 :   subd[n] = q[NL-2];
     130             : 
     131           2 :   alpha = -h/6.0;
     132         260 :   for (i=Istart;i<Iend;i++) {
     133         258 :     PetscCall(MatSetValue(A[2],i,i,md[i]*alpha,ADD_VALUES));
     134         258 :     if (i>0) PetscCall(MatSetValue(A[2],i,i-1,subd[i-1]*alpha,ADD_VALUES));
     135         258 :     if (i<n) PetscCall(MatSetValue(A[2],i,i+1,supd[i+1]*alpha,ADD_VALUES));
     136             :   }
     137           2 :   PetscCall(PetscFree3(md,supd,subd));
     138             : 
     139             :   /* A3 */
     140           2 :   if (Istart==0) PetscCall(MatSetValue(A[3],0,0,1.0,INSERT_VALUES));
     141           2 :   if (Iend==n+1) PetscCall(MatSetValue(A[3],n,n,1.0,INSERT_VALUES));
     142             : 
     143             :   /* A4 */
     144           2 :   alpha = (h/6);
     145         260 :   for (i=Istart;i<Iend;i++) {
     146         258 :     v = 4.0;
     147         258 :     if (i==0 || i==n) v = 2.0;
     148         258 :     PetscCall(MatSetValue(A[4],i,i,v*alpha,INSERT_VALUES));
     149         258 :     if (i>0) PetscCall(MatSetValue(A[4],i,i-1,alpha,INSERT_VALUES));
     150         258 :     if (i<n) PetscCall(MatSetValue(A[4],i,i+1,alpha,INSERT_VALUES));
     151             :   }
     152             : 
     153             :   /* assemble matrices */
     154          12 :   for (i=0;i<NMAT;i++) PetscCall(MatAssemblyBegin(A[i],MAT_FINAL_ASSEMBLY));
     155          12 :   for (i=0;i<NMAT;i++) PetscCall(MatAssemblyEnd(A[i],MAT_FINAL_ASSEMBLY));
     156             : 
     157             :   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     158             :                 Create the eigensolver and solve the problem
     159             :      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     160             : 
     161           2 :   PetscCall(PEPCreate(PETSC_COMM_WORLD,&pep));
     162           2 :   PetscCall(PEPSetOperators(pep,NMAT,A));
     163           2 :   PetscCall(PEPSetFromOptions(pep));
     164           2 :   PetscCall(PEPSolve(pep));
     165             : 
     166             :   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     167             :                     Display solution and clean up
     168             :      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     169             : 
     170             :   /* show detailed info unless -terse option is given by user */
     171           2 :   PetscCall(PetscOptionsHasName(NULL,NULL,"-terse",&terse));
     172           2 :   if (terse) PetscCall(PEPErrorView(pep,PEP_ERROR_BACKWARD,NULL));
     173             :   else {
     174           0 :     PetscCall(PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD,PETSC_VIEWER_ASCII_INFO_DETAIL));
     175           0 :     PetscCall(PEPConvergedReasonView(pep,PETSC_VIEWER_STDOUT_WORLD));
     176           0 :     PetscCall(PEPErrorView(pep,PEP_ERROR_BACKWARD,PETSC_VIEWER_STDOUT_WORLD));
     177           0 :     PetscCall(PetscViewerPopFormat(PETSC_VIEWER_STDOUT_WORLD));
     178             :   }
     179           2 :   PetscCall(PEPDestroy(&pep));
     180          12 :   for (i=0;i<NMAT;i++) PetscCall(MatDestroy(&A[i]));
     181           2 :   PetscCall(SlepcFinalize());
     182             :   return 0;
     183             : }
     184             : 
     185             : /*TEST
     186             : 
     187             :    test:
     188             :       suffix: 1
     189             :       args: -pep_type {{toar linear}} -pep_nev 4 -st_type sinvert -terse
     190             :       requires: !single
     191             : 
     192             : TEST*/

Generated by: LCOV version 1.14