#define PETSC_USE_COMPLEX 1 #include #include #include #include struct Matrix { Mat A; }; static PetscErrorCode matMultA(Mat A, Vec x, Vec y) { PetscFunctionBeginUser; void *ctx = NULL; MatShellGetContext(A, &ctx); Matrix &matrix = *static_cast(ctx); MatMult(matrix.A, x, y); PetscFunctionReturn(0); return 0; }; int main(int argc, char **argv) { Mat A; EPS eps; ST st; KSP ksp; PC pc; EPSType type; PetscErrorCode ierr; PetscInt nev = 6; ierr = SlepcInitialize(&argc,&argv,(char*)0,NULL);if (ierr) return ierr; ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); PetscViewer viewer; PetscViewerBinaryOpen(PETSC_COMM_WORLD,"MatA.gz",FILE_MODE_READ,&viewer); MatLoad(A,viewer); PetscViewerDestroy(&viewer); PetscInt N; MatGetSize(A, &N, NULL); ierr = PetscPrintf(PETSC_COMM_WORLD,"\n Acoustic Modes for matrix read from MatA.gz of size, N=%D \n\n", N);CHKERRQ(ierr); std::chrono::high_resolution_clock::time_point ts, te; std::chrono::duration time; ts = std::chrono::high_resolution_clock::now(); Mat Ashell; Matrix ctx; ctx.A = A; PetscInt m,n; MatGetLocalSize(A, &m, &n); MatCreateShell(PETSC_COMM_WORLD, m, n, N, N, &ctx, &Ashell); MatShellSetOperation(Ashell, MATOP_MULT, reinterpret_cast(matMultA)); PetscInt shell = 1; ierr = PetscOptionsGetInt(NULL,NULL,"-shell",&shell,NULL);CHKERRQ(ierr); ierr = EPSCreate(PETSC_COMM_WORLD,&eps);CHKERRQ(ierr); if (shell == 1) { ierr = EPSSetOperators(eps,Ashell,NULL);CHKERRQ(ierr); } else { ierr = EPSSetOperators(eps,A,NULL);CHKERRQ(ierr); } ierr = EPSSetProblemType(eps,EPS_NHEP);CHKERRQ(ierr); PetscInt sinvert = 0; ierr = PetscOptionsGetInt(NULL,NULL,"-sinvert",&sinvert,NULL);CHKERRQ(ierr); PetscInt usejd = 0; ierr = PetscOptionsGetInt(NULL,NULL,"-usejd",&usejd,NULL);CHKERRQ(ierr); if (sinvert == 1) { ierr = EPSGetST(eps,&st);CHKERRQ(ierr); ierr = STSetType(st,STSINVERT); ierr = STSetPreconditionerMat(st,A); CHKERRQ(ierr); ierr = STGetKSP(st,&ksp);CHKERRQ(ierr); ierr = KSPSetType(ksp,KSPBCGSL);CHKERRQ(ierr); ierr = KSPSetTolerances(ksp,1e-4,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); ierr = PCSetType(pc, PCBJACOBI);CHKERRQ(ierr); } else if (usejd == 1) { ierr = EPSSetType(eps,EPSJD);CHKERRQ(ierr); ierr = EPSGetST(eps,&st);CHKERRQ(ierr); ierr = STSetType(st,STPRECOND); ierr = STSetPreconditionerMat(st,A); CHKERRQ(ierr); ierr = STGetKSP(st,&ksp);CHKERRQ(ierr); ierr = KSPSetType(ksp,KSPBCGSL);CHKERRQ(ierr); ierr = KSPSetTolerances(ksp,1e-3,PETSC_DEFAULT,PETSC_DEFAULT,90);CHKERRQ(ierr); ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); ierr = PCSetType(pc, PCBJACOBI);CHKERRQ(ierr); ierr = EPSSetExtraction(eps,EPS_HARMONIC);CHKERRQ(ierr); } ierr = EPSSetWhichEigenpairs(eps,EPS_TARGET_MAGNITUDE);CHKERRQ(ierr); ierr = EPSSetTarget(eps,0.0);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-nev",&nev,NULL);CHKERRQ(ierr); ierr = EPSSetDimensions(eps, nev, PETSC_DEFAULT, PETSC_DEFAULT);CHKERRQ(ierr); ierr = EPSSetFromOptions(eps);CHKERRQ(ierr); PetscInt deflate = 0; ierr = PetscOptionsGetInt(NULL,NULL,"-deflate",&deflate,NULL);CHKERRQ(ierr); if (deflate == 1) { Vec x; ierr = MatCreateVecs(A,&x,NULL);CHKERRQ(ierr); ierr = VecSet(x,std::complex(1.0,1.0));CHKERRQ(ierr); ierr = EPSSetDeflationSpace(eps,1,&x);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); } ierr = EPSSolve(eps);CHKERRQ(ierr); ierr = EPSGetType(eps,&type);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Solution method: %s\n\n",type);CHKERRQ(ierr); ierr = EPSGetConverged(eps,&nev);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Number of converged eigenvalues: %D\n", nev);CHKERRQ(ierr); ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD,PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr); ierr = EPSErrorView(eps,EPS_ERROR_RELATIVE,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); PetscScalar kr, ki; Vec xr, xi; if (shell == 1) { MatCreateVecs(Ashell,NULL,&xr); MatCreateVecs(Ashell,NULL,&xi); } else { MatCreateVecs(A,NULL,&xr); MatCreateVecs(A,NULL,&xi); } PetscPrintf(PETSC_COMM_WORLD," -------------------------------------------------------------------\n"); PetscPrintf(PETSC_COMM_WORLD," %10s %20s %20s\n", "Mode", "Frequency, Real", "Frequency, Imag"); PetscPrintf(PETSC_COMM_WORLD," -------------------------------------------------------------------\n"); for (int i = 0; i < nev; ++i) { EPSGetEigenpair(eps,i, &kr, &ki, xr, xi); PetscScalar omega = sqrt(-kr); PetscScalar f = omega/2.0/3.1415; PetscPrintf(PETSC_COMM_WORLD," %10D %20.3f %20.3f\n", i, std::real(f), std::imag(f)); } PetscPrintf(PETSC_COMM_WORLD," -------------------------------------------------------------------\n"); ierr = EPSDestroy(&eps);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = VecDestroy(&xr);CHKERRQ(ierr); ierr = VecDestroy(&xi);CHKERRQ(ierr); ierr = SlepcFinalize(); te = std::chrono::high_resolution_clock::now(); time = te - ts; std::cout<<"\n Computation finished in " << time.count() << " seconds" << std::endl; return ierr; }