/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SLEPc - Scalable Library for Eigenvalue Problem Computations Copyright (c) 2002-2019, Universitat Politecnica de Valencia, Spain This file is part of SLEPc. SLEPc is distributed under a 2-clause BSD license (see LICENSE). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ static char help[] = "Solves the same eigenproblem as in example ex2, but using a shell matrix. " "The problem is a standard symmetric eigenproblem corresponding to the 2-D Laplacian operator.\n\n" "The command line options are:\n" " -n , where = number of grid subdivisions in both x and y dimensions.\n\n"; #include /* User-defined routines */ PetscErrorCode MatMult_Laplacian2D(Mat A,Vec x,Vec y); PetscErrorCode MatGetDiagonal_Laplacian2D(Mat A,Vec diag); int main(int argc,char **argv) { Mat A,B; /* operator matrix */ EPS eps; /* eigenproblem solver context */ ST st; EPSType type; PetscMPIInt size; PetscInt N,n=10,nev,Istart,Iend,II,i,j; PetscBool terse; PetscErrorCode ierr; ierr = SlepcInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_WORLD,1,"This is a uniprocessor example only"); ierr = PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);CHKERRQ(ierr); N = n*n; ierr = PetscPrintf(PETSC_COMM_WORLD,"\n2-D Laplacian Eigenproblem (matrix-free version), N=%D (%Dx%D grid)\n\n",N,n,n);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the operator matrix that defines the eigensystem, Ax=kx - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreateShell(PETSC_COMM_WORLD,N,N,N,N,&n,&A);CHKERRQ(ierr); ierr = MatShellSetOperation(A,MATOP_MULT,(void(*)(void))MatMult_Laplacian2D);CHKERRQ(ierr); /*ierr = MatShellSetOperation(A,MATOP_MULT_TRANSPOSE,(void(*)(void))MatMult_Laplacian2D);CHKERRQ(ierr); ierr = MatShellSetOperation(A,MATOP_GET_DIAGONAL,(void(*)(void))MatGetDiagonal_Laplacian2D);CHKERRQ(ierr);*/ ierr = MatCreate(PETSC_COMM_WORLD,&B);CHKERRQ(ierr); ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,N,N);CHKERRQ(ierr); ierr = MatSetFromOptions(B);CHKERRQ(ierr); ierr = MatSetUp(B);CHKERRQ(ierr); ierr = MatGetOwnershipRange(B,&Istart,&Iend);CHKERRQ(ierr); for (II=Istart;II0) { ierr = MatSetValue(B,II,II-n,-1.0,INSERT_VALUES);CHKERRQ(ierr); } if (i0) { ierr = MatSetValue(B,II,II-1,-1.0,INSERT_VALUES);CHKERRQ(ierr); } if (j