PetscErrorCode PEPSolve_Linear(PEP pep) { PetscErrorCode ierr; PEP_LINEAR *ctx = (PEP_LINEAR*)pep->data; PetscScalar sigma; PetscFunctionBegin; ierr = EPSSolve(ctx->eps);CHKERRQ(ierr); ierr = EPSGetConverged(ctx->eps,&pep->nconv);CHKERRQ(ierr); ierr = EPSGetIterationNumber(ctx->eps,&pep->its);CHKERRQ(ierr); ierr = EPSGetConvergedReason(ctx->eps,(EPSConvergedReason*)&pep->reason);CHKERRQ(ierr); /* restore target */ ierr = EPSGetTarget(ctx->eps,&sigma);CHKERRQ(ierr); ierr = EPSSetTarget(ctx->eps,sigma*pep->sfactor);CHKERRQ(ierr); switch (pep->extract) { case PEP_EXTRACT_NORM: ierr = PEPLinearExtract_Norm(pep,ctx->eps);CHKERRQ(ierr); break; case PEP_EXTRACT_RESIDUAL: ierr = PEPLinearExtract_Residual(pep,ctx->eps);CHKERRQ(ierr); break; default: SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"Extraction not implemented in this solver"); } PetscFunctionReturn(0); }
int testSlaterPotWithECS() { PrintTimeStamp(PETSC_COMM_SELF, "ECS", NULL); MPI_Comm comm = PETSC_COMM_SELF; BPS bps; BPSCreate(comm, &bps); BPSSetLine(bps, 100.0, 101); CScaling scaler; CScalingCreate(comm, &scaler); CScalingSetSharpECS(scaler, 60.0, 20.0*M_PI/180.0); int order = 5; BSS bss; BSSCreate(comm, &bss); BSSSetKnots(bss, order, bps); BSSSetCScaling(bss, scaler); BSSSetUp(bss); Pot slater; PotCreate(comm, &slater); PotSetSlater(slater, 7.5, 2, 1.0); if(getenv("SHOW_DEBUG")) BSSView(bss, PETSC_VIEWER_STDOUT_SELF); Mat H; BSSCreateR1Mat(bss, &H); Mat V; BSSCreateR1Mat(bss, &V); BSSPotR1Mat(bss, slater, V); Mat S; BSSCreateR1Mat(bss, &S); BSSSR1Mat(bss, S); BSSD2R1Mat(bss, H); MatScale(H, -0.5); MatAXPY(H, 1.0, V, DIFFERENT_NONZERO_PATTERN); EEPS eps; EEPSCreate(comm, &eps); EEPSSetOperators(eps, H, S); EEPSSetTarget(eps, 3.4); EPSSetDimensions(eps->eps, 10, PETSC_DEFAULT, PETSC_DEFAULT); EPSSetTolerances(eps->eps, PETSC_DEFAULT, 1000); // EPSSetType(eps, EPSARNOLDI); EEPSSolve(eps); PetscInt nconv; PetscScalar kr; EPSGetConverged(eps->eps, &nconv); ASSERT_TRUE(nconv > 0); if(getenv("SHOW_DEBUG")) for(int i = 0; i < nconv; i++) { EPSGetEigenpair(eps->eps, i, &kr, NULL, NULL, NULL); PetscPrintf(comm, "%f, %f\n", PetscRealPart(kr), PetscImaginaryPart(kr)); } EPSGetEigenpair(eps->eps, 0, &kr, NULL, NULL, NULL); PFDestroy(&slater); BSSDestroy(&bss); EEPSDestroy(&eps); MatDestroy(&H); MatDestroy(&V); MatDestroy(&S); // ASSERT_DOUBLE_NEAR(-0.0127745, PetscImaginaryPart(kr), pow(10.0, -4.0)); // ASSERT_DOUBLE_NEAR(3.4263903, PetscRealPart(kr), pow(10.0, -4.0)); return 0; }
PetscErrorCode SolveInit(FEMInf fem, int L, PetscScalar *e0, Vec *x) { PetscErrorCode ierr; Mat H, S; ierr = CalcMat(fem, L, &H, &S); CHKERRQ(ierr); EPS eps; ierr = PrintTimeStamp(fem->comm, "EPS", NULL); CHKERRQ(ierr); ierr = EPSCreate(fem->comm, &eps); CHKERRQ(ierr); ierr = EPSSetTarget(eps, -0.6); CHKERRQ(ierr); ierr = EPSSetWhichEigenpairs(eps, EPS_TARGET_MAGNITUDE); CHKERRQ(ierr); ierr = EPSSetOperators(eps, H, S); CHKERRQ(ierr); if(S == NULL) { ierr = EPSSetProblemType(eps, EPS_NHEP); CHKERRQ(ierr); } else { ierr = EPSSetProblemType(eps, EPS_GNHEP); CHKERRQ(ierr); } Vec x0[1]; MatCreateVecs(H, &x0[0], NULL); int num; FEMInfGetSize(fem, &num); for(int i = 0; i < num; i++) { VecSetValue(x0[0], i, 0.5, INSERT_VALUES); } VecAssemblyBegin(x0[0]); VecAssemblyEnd(x0[0]); EPSSetInitialSpace(eps, 1, x0); ierr = EPSSetFromOptions(eps); CHKERRQ(ierr); ierr = EPSSolve(eps); CHKERRQ(ierr); PetscInt nconv; EPSGetConverged(eps, &nconv); if(nconv == 0) SETERRQ(fem->comm, 1, "Failed to digonalize in init state\n"); Vec x_ans; MatCreateVecs(H, &x_ans, NULL); EPSGetEigenpair(eps, 0, e0, NULL, x_ans, NULL); EPSDestroy(&eps); PetscScalar v[1]; PetscInt idx[1] = {1}; VecGetValues(x_ans, 1, idx, v); PetscScalar scale_factor = v[0] / cabs(v[0]); VecScale( x_ans, 1.0/scale_factor); PetscScalar norm0; Vec Sx; MatCreateVecs(S, &Sx, NULL); MatMult(S, x_ans, Sx); VecDot(x_ans, Sx, &norm0); VecScale(x_ans, 1.0/sqrt(norm0)); *x = x_ans; return 0; }
PETSC_EXTERN void PETSC_STDCALL epsgetconverged_(EPS *eps,PetscInt *nconv, int *__ierr ){ *__ierr = EPSGetConverged(*eps,nconv); }
int SolarEigenvaluesSolver(Mat M, Vec epsCurrent, Vec epspmlQ, Mat D) { PetscErrorCode ierr; EPS eps; PetscInt nconv; Mat B; int nrow, ncol; ierr=MatGetSize(M,&nrow, &ncol); CHKERRQ(ierr); ierr=MatCreateAIJ(PETSC_COMM_WORLD, PETSC_DECIDE, PETSC_DECIDE, nrow, ncol, 2, NULL, 2, NULL, &B); CHKERRQ(ierr); ierr=PetscObjectSetName((PetscObject)B, "epsmatrix"); CHKERRQ(ierr); if (D==PETSC_NULL) { // for purely real epsC, no absorption; ierr=MatDiagonalSet(B,epsCurrent,INSERT_VALUES); CHKERRQ(ierr); MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY); MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY); } else { Vec epsC; VecDuplicate(epsCurrent, &epsC); ierr = VecPointwiseMult(epsC, epsCurrent,epspmlQ); CHKERRQ(ierr); MatSetTwoDiagonals(B, epsC, D, 1.0); VecDestroy(&epsC); } PetscPrintf(PETSC_COMM_WORLD,"!!!---computing eigenvalues---!!! \n"); ierr=EPSCreate(PETSC_COMM_WORLD, &eps); CHKERRQ(ierr); ierr=EPSSetOperators(eps, M, B); CHKERRQ(ierr); //ierr=EPSSetProblemType(eps,EPS_PGNHEP);CHKERRQ(ierr); EPSSetFromOptions(eps); PetscLogDouble t1, t2, tpast; ierr = PetscTime(&t1);CHKERRQ(ierr); ierr=EPSSolve(eps); CHKERRQ(ierr); EPSGetConverged(eps, &nconv); CHKERRQ(ierr); { ierr = PetscTime(&t2);CHKERRQ(ierr); tpast = t2 - t1; int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); if(rank==0) PetscPrintf(PETSC_COMM_SELF,"---The eigensolver time is %f s \n",tpast); } ierr = PetscPrintf(PETSC_COMM_WORLD,"Number of converged eigenpairs: %d\n\n",nconv);CHKERRQ(ierr); double *krarray, *kiarray, *errorarray; krarray = (double *) malloc(sizeof(double)*nconv); kiarray = (double *) malloc(sizeof(double)*nconv); errorarray =(double *) malloc(sizeof(double)*nconv); int ni; for(ni=0; ni<nconv; ni++) { ierr=EPSGetEigenpair(eps,ni, krarray+ni,kiarray+ni,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); ierr = EPSComputeRelativeError(eps,ni,errorarray+ni);CHKERRQ(ierr); ierr=EPSComputeRelativeError(eps, ni, errorarray+ni ); } PetscPrintf(PETSC_COMM_WORLD, "Now print the eigenvalues: \n"); for(ni=0; ni<nconv; ni++) PetscPrintf(PETSC_COMM_WORLD," %g%+gi,", krarray[ni], kiarray[ni]); PetscPrintf(PETSC_COMM_WORLD, "\n\nNow print the normalized eigenvalues: \n"); for(ni=0; ni<nconv; ni++) PetscPrintf(PETSC_COMM_WORLD," %g%+gi,", sqrt(krarray[ni]+pow(omega,2))/(2*PI),kiarray[ni]); PetscPrintf(PETSC_COMM_WORLD, "\n\nstart printing erros"); for(ni=0; ni<nconv; ni++) PetscPrintf(PETSC_COMM_WORLD," %g,", errorarray[ni]); PetscPrintf(PETSC_COMM_WORLD,"\n\n Finish EPS Solving !!! \n\n"); /*-- destroy vectors and free space --*/ EPSDestroy(&eps); MatDestroy(&B); free(krarray); free(kiarray); free(errorarray); PetscFunctionReturn(0); }
PetscErrorCode NEPSolve_SLP(NEP nep) { PetscErrorCode ierr; NEP_SLP *ctx = (NEP_SLP*)nep->data; Mat T=nep->function,Tp=nep->jacobian; Vec u,r=nep->work[0]; PetscScalar lambda,mu,im; PetscReal relerr; PetscInt nconv; PetscFunctionBegin; /* get initial approximation of eigenvalue and eigenvector */ ierr = NEPGetDefaultShift(nep,&lambda);CHKERRQ(ierr); if (!nep->nini) { ierr = BVSetRandomColumn(nep->V,0,nep->rand);CHKERRQ(ierr); } ierr = BVGetColumn(nep->V,0,&u);CHKERRQ(ierr); /* Restart loop */ while (nep->reason == NEP_CONVERGED_ITERATING) { nep->its++; /* evaluate T(lambda) and T'(lambda) */ ierr = NEPComputeFunction(nep,lambda,T,T);CHKERRQ(ierr); ierr = NEPComputeJacobian(nep,lambda,Tp);CHKERRQ(ierr); /* form residual, r = T(lambda)*u (used in convergence test only) */ ierr = MatMult(T,u,r);CHKERRQ(ierr); /* convergence test */ ierr = VecNorm(r,NORM_2,&relerr);CHKERRQ(ierr); nep->errest[nep->nconv] = relerr; nep->eigr[nep->nconv] = lambda; if (relerr<=nep->rtol) { nep->nconv = nep->nconv + 1; nep->reason = NEP_CONVERGED_FNORM_RELATIVE; } ierr = NEPMonitor(nep,nep->its,nep->nconv,nep->eigr,nep->errest,1);CHKERRQ(ierr); if (!nep->nconv) { /* compute eigenvalue correction mu and eigenvector approximation u */ ierr = EPSSetOperators(ctx->eps,T,Tp);CHKERRQ(ierr); ierr = EPSSetInitialSpace(ctx->eps,1,&u);CHKERRQ(ierr); ierr = EPSSolve(ctx->eps);CHKERRQ(ierr); ierr = EPSGetConverged(ctx->eps,&nconv);CHKERRQ(ierr); if (!nconv) { ierr = PetscInfo1(nep,"iter=%D, inner iteration failed, stopping solve\n",nep->its);CHKERRQ(ierr); nep->reason = NEP_DIVERGED_LINEAR_SOLVE; break; } ierr = EPSGetEigenpair(ctx->eps,0,&mu,&im,u,NULL);CHKERRQ(ierr); if (PetscAbsScalar(im)>PETSC_MACHINE_EPSILON) SETERRQ(PetscObjectComm((PetscObject)nep),1,"Complex eigenvalue approximation - not implemented in real scalars"); /* correct eigenvalue */ lambda = lambda - mu; } if (nep->its >= nep->max_it) nep->reason = NEP_DIVERGED_MAX_IT; } ierr = BVRestoreColumn(nep->V,0,&u);CHKERRQ(ierr); PetscFunctionReturn(0); }
void TrustRegionSolver3::calcSmallestEigVal(double &oEigVal, FloatArray &oEigVec, PetscSparseMtrx &K) { PetscErrorCode ierr; ST st; double eig_rtol = 1.0e-3; int max_iter = 10000; int nroot = 1; if ( !epsInit ) { /* * Create eigensolver context */ #ifdef __PARALLEL_MODE MPI_Comm comm = engngModel->giveParallelComm(); #else MPI_Comm comm = PETSC_COMM_SELF; #endif ierr = EPSCreate(comm, & eps); checkPetscError(ierr); epsInit = true; } ierr = EPSSetOperators( eps, * K.giveMtrx(), NULL ); checkPetscError(ierr); ierr = EPSSetProblemType(eps, EPS_NHEP); checkPetscError(ierr); ierr = EPSGetST(eps, & st); checkPetscError(ierr); // ierr = STSetType(st, STCAYLEY); // ierr = STSetType(st, STSINVERT); ierr = STSetType(st, STSHIFT); checkPetscError(ierr); ierr = STSetMatStructure(st, SAME_NONZERO_PATTERN); checkPetscError(ierr); ierr = EPSSetTolerances(eps, ( PetscReal ) eig_rtol, max_iter); checkPetscError(ierr); ierr = EPSSetDimensions(eps, ( PetscInt ) nroot, PETSC_DECIDE, PETSC_DECIDE); checkPetscError(ierr); ierr = EPSSetWhichEigenpairs(eps, EPS_SMALLEST_REAL); checkPetscError(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * Solve the eigensystem * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ EPSConvergedReason eig_reason; int eig_nconv, eig_nite; ierr = EPSSolve(eps); checkPetscError(ierr); ierr = EPSGetConvergedReason(eps, & eig_reason); checkPetscError(ierr); ierr = EPSGetIterationNumber(eps, & eig_nite); checkPetscError(ierr); // printf("SLEPcSolver::solve EPSConvergedReason: %d, number of iterations: %d\n", eig_reason, eig_nite); ierr = EPSGetConverged(eps, & eig_nconv); checkPetscError(ierr); double smallest_eig_val = 1.0e20; if ( eig_nconv > 0 ) { // printf("SLEPcSolver :: solveYourselfAt: Convergence reached for RTOL=%20.15f\n", eig_rtol); FloatArray eig_vals(nroot); PetscScalar kr; Vec Vr; K.createVecGlobal(& Vr); FloatArray Vr_loc; for ( int i = 0; i < eig_nconv && i < nroot; i++ ) { // PetscErrorCode EPSGetEigenpair(EPS eps,PetscInt i,PetscScalar *eigr,PetscScalar *eigi,Vec Vr,Vec Vi) ierr = EPSGetEigenpair(eps, i, & kr, PETSC_NULL, Vr, PETSC_NULL); checkPetscError(ierr); //Store the eigenvalue eig_vals(i) = kr; if(kr < smallest_eig_val) { smallest_eig_val = kr; K.scatterG2L(Vr, Vr_loc); oEigVec = Vr_loc; } } ierr = VecDestroy(& Vr); checkPetscError(ierr); } else { // OOFEM_ERROR("No converged eigenpairs.\n"); printf("Warning: No converged eigenpairs.\n"); smallest_eig_val = 1.0; } oEigVal = smallest_eig_val; }
int main( int argc, char **argv ) { Mat A; /* operator matrix */ Vec x; EPS eps; /* eigenproblem solver context */ const EPSType type; PetscReal error, tol, re, im; PetscScalar kr, ki; PetscErrorCode ierr; PetscInt N, n=10, m, i, j, II, Istart, Iend, nev, maxit, its, nconv; PetscScalar w; PetscBool flag; SlepcInitialize(&argc,&argv,(char*)0,help); ierr = PetscOptionsGetInt(PETSC_NULL,"-n",&n,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-m",&m,&flag);CHKERRQ(ierr); if(!flag) m=n; N = n*m; ierr = PetscPrintf(PETSC_COMM_WORLD,"\nFiedler vector of a 2-D regular mesh, N=%d (%dx%d grid)\n\n",N,n,m);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Compute the operator matrix that defines the eigensystem, Ax=kx In this example, A = L(G), where L is the Laplacian of graph G, i.e. Lii = degree of node i, Lij = -1 if edge (i,j) exists in G - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,N,N);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatGetOwnershipRange(A,&Istart,&Iend);CHKERRQ(ierr); for( II=Istart; II<Iend; II++ ) { i = II/n; j = II-i*n; w = 0.0; if(i>0) { ierr = MatSetValue(A,II,II-n,-1.0,INSERT_VALUES);CHKERRQ(ierr); w=w+1.0; } if(i<m-1) { ierr = MatSetValue(A,II,II+n,-1.0,INSERT_VALUES);CHKERRQ(ierr); w=w+1.0; } if(j>0) { ierr = MatSetValue(A,II,II-1,-1.0,INSERT_VALUES);CHKERRQ(ierr); w=w+1.0; } if(j<n-1) { ierr = MatSetValue(A,II,II+1,-1.0,INSERT_VALUES);CHKERRQ(ierr); w=w+1.0; } ierr = MatSetValue(A,II,II,w,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the eigensolver and set various options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Create eigensolver context */ ierr = EPSCreate(PETSC_COMM_WORLD,&eps);CHKERRQ(ierr); /* Set operators. In this case, it is a standard eigenvalue problem */ ierr = EPSSetOperators(eps,A,PETSC_NULL);CHKERRQ(ierr); ierr = EPSSetProblemType(eps,EPS_HEP);CHKERRQ(ierr); /* Select portion of spectrum */ ierr = EPSSetWhichEigenpairs(eps,EPS_SMALLEST_REAL);CHKERRQ(ierr); /* Set solver parameters at runtime */ ierr = EPSSetFromOptions(eps);CHKERRQ(ierr); /* Attach deflation space: in this case, the matrix has a constant nullspace, [1 1 ... 1]^T is the eigenvector of the zero eigenvalue */ ierr = MatGetVecs(A,&x,PETSC_NULL);CHKERRQ(ierr); ierr = VecSet(x,1.0);CHKERRQ(ierr); ierr = EPSSetDeflationSpace(eps,1,&x);CHKERRQ(ierr); ierr = VecDestroy(x); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the eigensystem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = EPSSolve(eps);CHKERRQ(ierr); ierr = EPSGetIterationNumber(eps, &its);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Number of iterations of the method: %d\n",its);CHKERRQ(ierr); /* Optional: Get some information from the solver and display it */ ierr = EPSGetType(eps,&type);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Solution method: %s\n\n",type);CHKERRQ(ierr); ierr = EPSGetDimensions(eps,&nev,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Number of requested eigenvalues: %d\n",nev);CHKERRQ(ierr); ierr = EPSGetTolerances(eps,&tol,&maxit);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Stopping condition: tol=%.4g, maxit=%d\n",tol,maxit);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Display solution and clean up - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Get number of converged approximate eigenpairs */ ierr = EPSGetConverged(eps,&nconv);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Number of converged approximate eigenpairs: %d\n\n",nconv); CHKERRQ(ierr); if (nconv>0) { /* Display eigenvalues and relative errors */ ierr = PetscPrintf(PETSC_COMM_WORLD, " k ||Ax-kx||/||kx||\n" " ----------------- ------------------\n" );CHKERRQ(ierr); for( i=0; i<nconv; i++ ) { /* Get converged eigenpairs: i-th eigenvalue is stored in kr (real part) and ki (imaginary part) */ ierr = EPSGetEigenpair(eps,i,&kr,&ki,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); /* Compute the relative error associated to each eigenpair */ ierr = EPSComputeRelativeError(eps,i,&error);CHKERRQ(ierr); #ifdef PETSC_USE_COMPLEX re = PetscRealPart(kr); im = PetscImaginaryPart(kr); #else re = kr; im = ki; #endif if (im!=0.0) { ierr = PetscPrintf(PETSC_COMM_WORLD," %9f%+9f j %12g\n",re,im,error);CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_WORLD," %12f %12g\n",re,error);CHKERRQ(ierr); } } ierr = PetscPrintf(PETSC_COMM_WORLD,"\n" );CHKERRQ(ierr); } /* Free work space */ ierr = EPSDestroy(eps);CHKERRQ(ierr); ierr = MatDestroy(A);CHKERRQ(ierr); ierr = SlepcFinalize();CHKERRQ(ierr); return 0; }
NM_Status SLEPcSolver :: solve(SparseMtrx &a, SparseMtrx &b, FloatArray &_eigv, FloatMatrix &_r, double rtol, int nroot) { FILE *outStream; PetscErrorCode ierr; int size; ST st; outStream = domain->giveEngngModel()->giveOutputStream(); // first check whether Lhs is defined if ( a->giveNumberOfRows() != a->giveNumberOfColumns() || b->giveNumberOfRows() != b->giveNumberOfRows() || a->giveNumberOfColumns() != b->giveNumberOfColumns() ) { OOFEM_ERROR("matrices size mismatch"); } A = dynamic_cast< PetscSparseMtrx * >(&a); B = dynamic_cast< PetscSparseMtrx * >(&b); if ( !A || !B ) { OOFEM_ERROR("PetscSparseMtrx Expected"); } size = engngModel->giveParallelContext( A->giveDomainIndex() )->giveNumberOfNaturalEqs(); // A->giveLeqs(); _r.resize(size, nroot); _eigv.resize(nroot); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * Create the eigensolver and set various options * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ int nconv, nite; EPSConvergedReason reason; #ifdef TIME_REPORT Timer timer; timer.startTimer(); #endif if ( !epsInit ) { /* * Create eigensolver context */ #ifdef __PARALLEL_MODE MPI_Comm comm = engngModel->giveParallelComm(); #else MPI_Comm comm = PETSC_COMM_SELF; #endif ierr = EPSCreate(comm, & eps); CHKERRQ(ierr); epsInit = true; } /* * Set operators. In this case, it is a generalized eigenvalue problem */ ierr = EPSSetOperators( eps, * A->giveMtrx(), * B->giveMtrx() ); CHKERRQ(ierr); ierr = EPSSetProblemType(eps, EPS_GHEP); CHKERRQ(ierr); ierr = EPSGetST(eps, & st); CHKERRQ(ierr); ierr = STSetType(st, STSINVERT); CHKERRQ(ierr); ierr = STSetMatStructure(st, SAME_NONZERO_PATTERN); CHKERRQ(ierr); ierr = EPSSetTolerances(eps, ( PetscReal ) rtol, PETSC_DECIDE); CHKERRQ(ierr); ierr = EPSSetDimensions(eps, ( PetscInt ) nroot, PETSC_DECIDE, PETSC_DECIDE); CHKERRQ(ierr); ierr = EPSSetWhichEigenpairs(eps, EPS_SMALLEST_MAGNITUDE); CHKERRQ(ierr); /* * Set solver parameters at runtime */ ierr = EPSSetFromOptions(eps); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * Solve the eigensystem * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = EPSSolve(eps); CHKERRQ(ierr); ierr = EPSGetConvergedReason(eps, & reason); CHKERRQ(ierr); ierr = EPSGetIterationNumber(eps, & nite); CHKERRQ(ierr); OOFEM_LOG_INFO("SLEPcSolver::solve EPSConvergedReason: %d, number of iterations: %d\n", reason, nite); ierr = EPSGetConverged(eps, & nconv); CHKERRQ(ierr); if ( nconv > 0 ) { fprintf(outStream, "SLEPcSolver :: solveYourselfAt: Convergence reached for RTOL=%20.15f", rtol); PetscScalar kr; Vec Vr; ierr = MatGetVecs(* B->giveMtrx(), PETSC_NULL, & Vr); CHKERRQ(ierr); FloatArray Vr_loc; for ( int i = 0; i < nconv && i < nroot; i++ ) { ierr = EPSGetEigenpair(eps, nconv - i - 1, & kr, PETSC_NULL, Vr, PETSC_NULL); CHKERRQ(ierr); //Store the eigenvalue _eigv->at(i + 1) = kr; //Store the eigenvector A->scatterG2L(Vr, Vr_loc); for ( int j = 0; j < size; j++ ) { _r->at(j + 1, i + 1) = Vr_loc.at(j + 1); } } ierr = VecDestroy(Vr); CHKERRQ(ierr); } else { OOFEM_ERROR("No converged eigenpairs"); } #ifdef TIME_REPORT timer.stopTimer(); OOFEM_LOG_INFO( "SLEPcSolver info: user time consumed by solution: %.2fs\n", timer.getUtime() ); #endif return NM_Success; }
int main(int argc,char **argv) { Mat A; /* operator matrix */ EPS eps; /* eigenproblem solver context */ EPSType type; DM da; Vec v0; PetscReal error,tol,re,im,*exact; PetscScalar kr,ki; PetscInt M,N,P,m,n,p,nev,maxit,i,its,nconv,seed; PetscLogDouble t1,t2,t3; PetscBool flg; PetscRandom rctx; PetscErrorCode ierr; SlepcInitialize(&argc,&argv,(char*)0,help); ierr = PetscPrintf(PETSC_COMM_WORLD,"\n3-D Laplacian Eigenproblem\n\n");CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Compute the operator matrix that defines the eigensystem, Ax=kx - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate3d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,-10,-10,-10, PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE, 1,1,NULL,NULL,NULL,&da);CHKERRQ(ierr); /* print DM information */ ierr = DMDAGetInfo(da,NULL,&M,&N,&P,&m,&n,&p,NULL,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Grid partitioning: %D %D %D\n",m,n,p);CHKERRQ(ierr); /* create and fill the matrix */ ierr = DMCreateMatrix(da,&A);CHKERRQ(ierr); ierr = FillMatrix(da,A);CHKERRQ(ierr); /* create random initial vector */ seed = 1; ierr = PetscOptionsGetInt(NULL,"-seed",&seed,NULL);CHKERRQ(ierr); if (seed<0) SETERRQ(PETSC_COMM_WORLD,1,"Seed must be >=0"); ierr = MatGetVecs(A,&v0,NULL);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rctx);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rctx);CHKERRQ(ierr); for (i=0;i<seed;i++) { /* simulate different seeds in the random generator */ ierr = VecSetRandom(v0,rctx);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the eigensolver and set various options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Create eigensolver context */ ierr = EPSCreate(PETSC_COMM_WORLD,&eps);CHKERRQ(ierr); /* Set operators. In this case, it is a standard eigenvalue problem */ ierr = EPSSetOperators(eps,A,NULL);CHKERRQ(ierr); ierr = EPSSetProblemType(eps,EPS_HEP);CHKERRQ(ierr); /* Set specific solver options */ ierr = EPSSetWhichEigenpairs(eps,EPS_SMALLEST_REAL);CHKERRQ(ierr); ierr = EPSSetTolerances(eps,1e-8,PETSC_DEFAULT);CHKERRQ(ierr); ierr = EPSSetInitialSpace(eps,1,&v0);CHKERRQ(ierr); /* Set solver parameters at runtime */ ierr = EPSSetFromOptions(eps);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the eigensystem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscTime(&t1);CHKERRQ(ierr); ierr = EPSSetUp(eps);CHKERRQ(ierr); ierr = PetscTime(&t2);CHKERRQ(ierr); ierr = EPSSolve(eps);CHKERRQ(ierr); ierr = PetscTime(&t3);CHKERRQ(ierr); ierr = EPSGetIterationNumber(eps,&its);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Number of iterations of the method: %D\n",its);CHKERRQ(ierr); /* Optional: Get some information from the solver and display it */ ierr = EPSGetType(eps,&type);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Solution method: %s\n\n",type);CHKERRQ(ierr); ierr = EPSGetDimensions(eps,&nev,NULL,NULL);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Number of requested eigenvalues: %D\n",nev);CHKERRQ(ierr); ierr = EPSGetTolerances(eps,&tol,&maxit);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Stopping condition: tol=%.4g, maxit=%D\n",(double)tol,maxit);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Display solution and clean up - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Get number of converged approximate eigenpairs */ ierr = EPSGetConverged(eps,&nconv);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Number of converged approximate eigenpairs: %D\n\n",nconv);CHKERRQ(ierr); if (nconv>0) { ierr = PetscMalloc1(nconv,&exact);CHKERRQ(ierr); ierr = GetExactEigenvalues(M,N,P,nconv,exact);CHKERRQ(ierr); /* Display eigenvalues and relative errors */ ierr = PetscPrintf(PETSC_COMM_WORLD, " k ||Ax-kx||/||kx|| Eigenvalue Error \n" " ----------------- ------------------ ------------------\n");CHKERRQ(ierr); for (i=0;i<nconv;i++) { /* Get converged eigenpairs: i-th eigenvalue is stored in kr (real part) and ki (imaginary part) */ ierr = EPSGetEigenpair(eps,i,&kr,&ki,NULL,NULL);CHKERRQ(ierr); /* Compute the relative error associated to each eigenpair */ ierr = EPSComputeRelativeError(eps,i,&error);CHKERRQ(ierr); #if defined(PETSC_USE_COMPLEX) re = PetscRealPart(kr); im = PetscImaginaryPart(kr); #else re = kr; im = ki; #endif if (im!=0.0) SETERRQ(PETSC_COMM_WORLD,1,"Eigenvalue should be real"); else { ierr = PetscPrintf(PETSC_COMM_WORLD," %12g %12g %12g\n",(double)re,(double)error,(double)PetscAbsReal(re-exact[i]));CHKERRQ(ierr); } } ierr = PetscFree(exact);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"\n");CHKERRQ(ierr); } /* Show computing times */ ierr = PetscOptionsHasName(NULL,"-showtimes",&flg);CHKERRQ(ierr); if (flg) { ierr = PetscPrintf(PETSC_COMM_WORLD," Elapsed time: %g (setup), %g (solve)\n",(double)(t2-t1),(double)(t3-t2));CHKERRQ(ierr); } /* Free work space */ ierr = EPSDestroy(&eps);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = VecDestroy(&v0);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rctx);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = SlepcFinalize(); return 0; }
/* Compute cyclicly eigenvalue */ PetscErrorCode Arnoldi(com_lsa * com, Mat * A, Vec *v){ EPS eps; /* eigensolver context */ char load_path[PETSC_MAX_PATH_LEN],export_path[PETSC_MAX_PATH_LEN]; PetscInt end,first,validated; PetscErrorCode ierr; /* eigenvalues number is set to 100, can be changed if needed we choosed to fix it because mallocs weren't working properly */ PetscScalar eigenvalues[1000], ei, er; PetscReal re,im,vnorm; PetscInt eigen_nb,j,i,size,one=1, taille; Vec initialv,nullv,*vs; PetscBool flag,data_load,data_export,continuous_export,load_any; int exit_type=0, counter = 0, l; int sos_type = 911; Vec vecteur_initial; PetscViewer viewer; PetscBool need_new_init = PETSC_FALSE, exit = PETSC_FALSE; sprintf(load_path,"./arnoldi.bin"); sprintf(export_path,"./arnoldi.bin"); PetscViewerCreate(PETSC_COMM_WORLD,&viewer); // PetscViewerSetType(viewer,PETSCVIEWERBINARY); // if (skippheader) { PetscViewerBinarySetSkipHeader(viewer,PETSC_TRUE); } // PetscViewerFileSetMode(viewer,FILE_MODE_WRITE); // PetscViewerBinarySetUseMPIIO(viewer,PETSC_TRUE); // PetscViewerFileSetName(viewer,"arnoldidbg.txt"); /* create the eigensolver */ ierr=EPSCreate(PETSC_COMM_WORLD,&eps);CHKERRQ(ierr); /* set the matrix operator */ ierr=EPSSetOperators(eps,*A,PETSC_NULL); /* set options */ ierr=EPSSetType(eps,EPSARNOLDI); ierr=EPSSetFromOptions(eps);CHKERRQ(ierr); /* duplicate vector properties */ ierr=VecDuplicate(*v,&initialv);CHKERRQ(ierr); ierr=VecDuplicate(*v,&nullv);CHKERRQ(ierr); ierr=VecSet(nullv,(PetscScalar)0.0);CHKERRQ(ierr); /* ierr=VecSet(initialv,(PetscScalar)1.0);CHKERRQ(ierr);*/ ierr=VecSetRandom(initialv,PETSC_NULL);//initialize initial vector to random ierr=VecGetSize(initialv,&size);CHKERRQ(ierr); ierr=PetscOptionsGetInt(PETSC_NULL,"-ksp_ls_eigen",&eigen_nb,&flag);CHKERRQ(ierr); if(!flag) eigen_nb=EIGEN_ALL; ierr=PetscOptionsGetString(PETSC_NULL,"-ksp_arnoldi_load",load_path,PETSC_MAX_PATH_LEN,&data_load);CHKERRQ(ierr); ierr=PetscOptionsGetString(PETSC_NULL,"-ksp_arnoldi_export",export_path,PETSC_MAX_PATH_LEN,&data_export);CHKERRQ(ierr); ierr=PetscOptionsHasName(PETSC_NULL,"-ksp_arnoldi_load_any",&load_any);CHKERRQ(ierr); ierr=PetscOptionsHasName(PETSC_NULL,"-ksp_arnoldi_cexport",&continuous_export);CHKERRQ(ierr); if(load_any) PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi loading default data file\n"); PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi path in= %s out= %s\n",load_path,export_path); PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi allocating buffer of %d for invariant subspace\n",eigen_nb*2); vs=malloc(size*sizeof(Vec)); for(i=0;i<size;i++){ ierr=VecDuplicate(*v,&vs[i]);CHKERRQ(ierr); } ierr=VecDuplicate(initialv,&vecteur_initial);CHKERRQ(ierr); /* vecteur_initial = malloc(size * sizeof(PetscScalar));*/ // setting_out_vec_sizes( com, v); end=0; first=1; validated=1; while(!end){ /*check if the program need to exit */ if(exit == PETSC_TRUE) break; /* check if we received an exit message from Father*/ if(!mpi_lsa_com_type_recv(com,&exit_type)){ if(exit_type==666){ end=1; PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi Sending Exit message\n"); mpi_lsa_com_type_send(com,&exit_type); break; } } /* check if we received some data from GMRES */ if(!mpi_lsa_com_vec_recv(com, &initialv)){ VecGetSize(initialv, &taille); /* printf(" ========= %d I RECEIVED %d DATA FROM GMRES ============\n",com->rank_world, taille);*/ /* ierr = VecCopy(vecteur_initial, initialv);*/ } /* */ /* if(!mpi_lsa_com_array_recv(com, &taille, vecteur_initial)){*/ /* // VecGetSize(initialv, &taille);*/ /* printf(" ========= %d I RECEIVED %d DATA FROM GMRES ============\n",com->rank_world, taille);*/ /* for (i = 0; i < taille; i++)*/ /* PetscPrintf(PETSC_COMM_WORLD,"==== > arnoldi %d [%d] = %e\n",com->rank_world, i, vecteur_initial[i]);*/ /* } */ for(j=0;j<eigen_nb;j++){ eigenvalues[j]=(PetscScalar)0.0; } //FIXME: refactoriser les if suivants + flags file read, c'est très très moche if(data_load&&load_any){ load_any=PETSC_FALSE; data_load=PETSC_TRUE; } ierr = VecAssemblyBegin(initialv);CHKERRQ(ierr); ierr = VecAssemblyEnd(initialv);CHKERRQ(ierr); if(!(data_load^=load_any)){ ierr=EPSSetInitialSpace(eps,1,&initialv);CHKERRQ(ierr); } else { /* PetscPrintf(PETSC_COMM_WORLD,"==== > I AM LOADING DATA FROM FILE\n");*/ /* PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi Reading file %s\n",load_path);*/ ierr=readBinaryVecArray(load_path,(int*)one,&initialv);CHKERRQ(ierr); data_load=PETSC_FALSE; load_any=PETSC_FALSE; ierr=EPSSetInitialSpace(eps,1,&initialv);CHKERRQ(ierr); /* PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi Has Read file %s\n",load_path);*/ } ierr=EPSSolve(eps);CHKERRQ(ierr); /*construct new initial vector*/ ierr=EPSGetInvariantSubspace(eps, vs);CHKERRQ(ierr); ++counter; /* get the number of guessed eigenvalues */ ierr=EPSGetConverged(eps,&eigen_nb);CHKERRQ(ierr); /* #ifdef DEBUG*/ /* PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi %d converged eigenvalues\n",eigen_nb);*/ /* #endif*/ /* send them */ for(j=0;j<eigen_nb;j++){ //EPSGetValue(eps,j,&er,&ei); //ierr = EPSGetEigenpair(eps,j,&er,&ei,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); ierr = EPSGetEigenvalue(eps,j,&er,&ei);CHKERRQ(ierr); #ifdef PETSC_USE_COMPLEX re=PetscRealPart(er); im=PetscImaginaryPart(er); #else re=er; im=ei; #endif eigenvalues[j]=(PetscScalar)re+PETSC_i*(PetscScalar)im; // #ifdef DEBUG if(im!=0.0) PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi %d/%d val : %e %e\n",j,eigen_nb,re,im); else PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi %d/%d val : %e\n",j,eigen_nb,er); // #endif } /* ierr=VecGetSize(initialv,&taille);CHKERRQ(ierr);*/ /* PetscPrintf(PETSC_COMM_WORLD,"==== > OUR INITIALV IS OF SIZE %d\n", taille);*/ /* vecteur_initial = realloc(vecteur_initial,taille); */ /* ierr=VecGetArray(initialv, &vecteur_initial);CHKERRQ(ierr);*/ /* for (i = 0; i < taille; i++)*/ /* PetscPrintf(PETSC_COMM_WORLD,"==== > initialv[%d] = %e\n", i, vecteur_initial[i]);*/ /* ierr= VecRestoreArray(initialv, &vecteur_initial);CHKERRQ(ierr);*/ if( eigen_nb != 0){ /* #ifdef DEBUG*/ /* PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi Sending to LS\n");*/ /* #endif*/ /* send the data array */ mpi_lsa_com_array_send(com, &eigen_nb, eigenvalues); /*construct new initial vector*/ /* ierr=EPSGetInvariantSubspace(eps, vs);CHKERRQ(ierr);*/ ierr=VecCopy(vs[0],initialv);CHKERRQ(ierr); for(j=1;j<eigen_nb;j++){ ierr=VecAYPX(initialv,(PetscScalar)1.0,vs[j]); } ierr=VecNorm(initialv,NORM_2,&vnorm);CHKERRQ(ierr); ierr=VecAYPX(initialv,(PetscScalar)(1.0/vnorm),nullv);CHKERRQ(ierr); if(continuous_export){ /* ierr=writeBinaryVecArray(data_export?export_path:"./arnoldi.bin", 1, &initialv);*/ } if(!mpi_lsa_com_type_recv(com,&exit_type)){ if(exit_type==666){ end=1; PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi Sending Exit message\n"); mpi_lsa_com_type_send(com,&exit_type); need_new_init = PETSC_FALSE; exit = PETSC_TRUE; break; } } }else{ need_new_init = PETSC_TRUE; PetscPrintf(PETSC_COMM_WORLD, "!!! Arnoldi has not converged so we change the initial vector !!!\n"); while(need_new_init){ // this was my first try to solve the poblem but it doesn't work better /*ierr=VecSetRandom(initialv,PETSC_NULL);CHKERRQ(ier);*/ // Now the best to do i think is to develop a kind of help from GMRES // Arnoldi when no convergence observed will send a msg to GMRES like an SOS //and GMRES will send a vector wich will be used to generate a new initial vector that make arnoldi converge **I HOPE ** //need_new_init = PETSC_TRUE // mpi_lsa_com_type_send(com,&sos_type); // here we send the message // ierr=VecDuplicate(initialv,&vec_tmp_receive); //PetscPrintf(PETSC_COMM_WORLD, "!!! Arnoldi has not converged so we change the initial vector !!!\n"); /* check if there's an incoming message */ if(!mpi_lsa_com_vec_recv(com, &initialv)){ /* if(!mpi_lsa_com_array_recv(com, &taille, vecteur_initial)){*/ /* printf(" ========= I RECEIVED SOME DATA FROM GMRES ============\n");*/ /* ierr = VecCopy(vecteur_initial, initialv);*/ need_new_init = PETSC_FALSE; }else{ if(!mpi_lsa_com_type_recv(com,&exit_type)){ if(exit_type==666){ end=1; /* PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi Sending Exit message\n");*/ mpi_lsa_com_type_send(com,&exit_type); need_new_init = PETSC_FALSE; exit = PETSC_TRUE; break; } } } //goto checking; //return 1; } if(exit == PETSC_TRUE) break; } // i will check it later } /* if(data_export){*/ /* ierr=writeBinaryVecArray(export_path, 1, &initialv);*/ /* }*/ for(i=0;i<eigen_nb;i++){ ierr=VecDestroy(&(vs[i]));CHKERRQ(ierr); } /* ierr=PetscFree(vs);CHKERRQ(ierr);*/ /* and destroy the eps */ ierr=EPSDestroy(&eps);CHKERRQ(ierr); ierr=VecDestroy(&initialv);CHKERRQ(ierr); ierr=VecDestroy(&nullv);CHKERRQ(ierr); return 0; }
std::pair<unsigned int, unsigned int> SlepcEigenSolver<T>::_solve_generalized_helper (Mat mat_A, Mat mat_B, int nev, // number of requested eigenpairs int ncv, // number of basis vectors const double tol, // solver tolerance const unsigned int m_its) // maximum number of iterations { START_LOG("solve_generalized()", "SlepcEigenSolver"); int ierr=0; // converged eigen pairs and number of iterations int nconv=0; int its=0; #ifdef DEBUG // The relative error. PetscReal error, re, im; // Pointer to vectors of the real parts, imaginary parts. PetscScalar kr, ki; #endif // Set operators. ierr = EPSSetOperators (_eps, mat_A, mat_B); LIBMESH_CHKERRABORT(ierr); //set the problem type and the position of the spectrum set_slepc_problem_type(); set_slepc_position_of_spectrum(); // Set eigenvalues to be computed. #if SLEPC_VERSION_LESS_THAN(3,0,0) ierr = EPSSetDimensions (_eps, nev, ncv); #else ierr = EPSSetDimensions (_eps, nev, ncv, PETSC_DECIDE); #endif LIBMESH_CHKERRABORT(ierr); // Set the tolerance and maximum iterations. ierr = EPSSetTolerances (_eps, tol, m_its); LIBMESH_CHKERRABORT(ierr); // Set runtime options, e.g., // -eps_type <type>, -eps_nev <nev>, -eps_ncv <ncv> // Similar to PETSc, these options will override those specified // above as long as EPSSetFromOptions() is called _after_ any // other customization routines. ierr = EPSSetFromOptions (_eps); LIBMESH_CHKERRABORT(ierr); // Solve the eigenproblem. ierr = EPSSolve (_eps); LIBMESH_CHKERRABORT(ierr); // Get the number of iterations. ierr = EPSGetIterationNumber (_eps, &its); LIBMESH_CHKERRABORT(ierr); // Get number of converged eigenpairs. ierr = EPSGetConverged(_eps,&nconv); LIBMESH_CHKERRABORT(ierr); #ifdef DEBUG // ierr = PetscPrintf(this->comm().get(), // "\n Number of iterations: %d\n" // " Number of converged eigenpairs: %d\n\n", its, nconv); // Display eigenvalues and relative errors. ierr = PetscPrintf(this->comm().get(), " k ||Ax-kx||/|kx|\n" " ----------------- -----------------\n" ); LIBMESH_CHKERRABORT(ierr); for(int i=0; i<nconv; i++ ) { ierr = EPSGetEigenpair(_eps, i, &kr, &ki, PETSC_NULL, PETSC_NULL); LIBMESH_CHKERRABORT(ierr); ierr = EPSComputeRelativeError(_eps, i, &error); LIBMESH_CHKERRABORT(ierr); #ifdef LIBMESH_USE_COMPLEX_NUMBERS re = PetscRealPart(kr); im = PetscImaginaryPart(kr); #else re = kr; im = ki; #endif if (im != .0) { ierr = PetscPrintf(this->comm().get()," %9f%+9f i %12f\n", re, im, error); LIBMESH_CHKERRABORT(ierr); } else { ierr = PetscPrintf(this->comm().get()," %12f %12f\n", re, error); LIBMESH_CHKERRABORT(ierr); } } ierr = PetscPrintf(this->comm().get(),"\n" ); LIBMESH_CHKERRABORT(ierr); #endif // DEBUG STOP_LOG("solve_generalized()", "SlepcEigenSolver"); // return the number of converged eigenpairs // and the number of iterations return std::make_pair(nconv, its); }
int eigen_solver(ndr_data_t *arg) { EPS eps; EPSType type; PetscReal error,tol,re,im; PetscScalar kr,ki; Vec xr,xi; PetscInt i,nev,maxit,its,nconv; PetscErrorCode ierr; ierr = MatGetVecs(arg->A,NULL,&xr);CHKERRQ(ierr); ierr = MatGetVecs(arg->A,NULL,&xi);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the eigensolver and set various options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Create eigensolver context */ ierr = EPSCreate(PETSC_COMM_WORLD,&eps);CHKERRQ(ierr); /* Set operators. In this case, it is a standard eigenvalue problem */ ierr = EPSSetOperators(eps,arg->A,NULL);CHKERRQ(ierr); ierr = EPSSetProblemType(eps,EPS_NHEP);CHKERRQ(ierr); /* Set solver parameters at runtime */ ierr = EPSSetFromOptions(eps);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the eigensystem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = EPSSolve(eps);CHKERRQ(ierr); /* Optional: Get some information from the solver and display it */ ierr = EPSGetIterationNumber(eps,&its);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Number of iterations of the method: %D\n",its);CHKERRQ(ierr); ierr = EPSGetType(eps,&type);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Solution method: %s\n\n",type);CHKERRQ(ierr); ierr = EPSGetDimensions(eps,&nev,NULL,NULL);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Number of requested eigenvalues: %D\n",nev);CHKERRQ(ierr); ierr = EPSGetTolerances(eps,&tol,&maxit);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Stopping condition: tol=%.4g, maxit=%D\n",(double)tol,maxit);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Display solution and clean up - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Get number of converged approximate eigenpairs */ ierr = EPSGetConverged(eps,&nconv);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Number of converged eigenpairs: %D\n\n",nconv);CHKERRQ(ierr); if (nconv>0) { /* Display eigenvalues and relative errors */ ierr = PetscPrintf(PETSC_COMM_WORLD, " k ||Ax-kx||/||kx||\n" " ----------------- ------------------\n");CHKERRQ(ierr); for (i=0;i<nconv;i++) { /* Get converged eigenpairs: i-th eigenvalue is stored in kr (real part) and ki (imaginary part) */ ierr = EPSGetEigenpair(eps,i,&kr,&ki,xr,xi);CHKERRQ(ierr); // VecView(xr,PETSC_VIEWER_STDOUT_WORLD); /* Compute the relative error associated to each eigenpair */ ierr = EPSComputeRelativeError(eps,i,&error);CHKERRQ(ierr); #if defined(PETSC_USE_COMPLEX) re = PetscRealPart(kr); im = PetscImaginaryPart(kr); #else re = kr; im = ki; #endif if (im!=0.0) { ierr = PetscPrintf(PETSC_COMM_WORLD," %9f%+9f j %12g\n",(double)re,(double)im,(double)error);CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_WORLD," %12f %12g\n",(double)re,(double)error);CHKERRQ(ierr); } } ierr = PetscPrintf(PETSC_COMM_WORLD,"\n");CHKERRQ(ierr); } /* Free work space */ ierr = EPSDestroy(&eps);CHKERRQ(ierr); ierr = VecDestroy(&xr);CHKERRQ(ierr); ierr = VecDestroy(&xi);CHKERRQ(ierr); return 0; }
int testBSplineHAtom() { PrintTimeStamp(PETSC_COMM_SELF, "H atom", NULL); MPI_Comm comm = PETSC_COMM_SELF; BPS bps; BPSCreate(comm, &bps); BPSSetExp(bps, 30.0, 61, 3.0); int order = 5; BSS bss; BSSCreate(comm, &bss); BSSSetKnots(bss, order, bps); BSSSetUp(bss); Mat H; BSSCreateR1Mat(bss, &H); Mat S; BSSCreateR1Mat(bss, &S); Mat V; BSSCreateR1Mat(bss, &V); BSSD2R1Mat(bss, H); MatScale(H, -0.5); BSSENR1Mat(bss, 0, 0.0, V); MatAXPY(H, -1.0, V, DIFFERENT_NONZERO_PATTERN); BSSSR1Mat(bss, S); // -- initial space -- Pot psi0; PotCreate(comm, &psi0); PotSetSlater(psi0, 2.0, 1, 1.1); int n_init_space = 1; Vec *xs; PetscMalloc1(n_init_space, &xs); MatCreateVecs(H, &xs[0], NULL); BSSPotR1Vec(bss, psi0, xs[0]); EEPS eps; EEPSCreate(comm, &eps); EEPSSetOperators(eps, H, S); // EPSSetType(eps->eps, EPSJD); EPSSetInitialSpace(eps->eps, 1, xs); EEPSSetTarget(eps, -0.6); // EPSSetInitialSpace(eps->eps, 1, xs); EEPSSolve(eps); int nconv; PetscScalar kr; EPSGetConverged(eps->eps, &nconv); ASSERT_TRUE(nconv > 0); EPSGetEigenpair(eps->eps, 0, &kr, NULL, NULL, NULL); ASSERT_DOUBLE_NEAR(-0.5, kr, pow(10.0, -6.0)); Vec cs; MatCreateVecs(H, &cs, NULL); EEPSGetEigenvector(eps, 0, cs); PetscReal x=1.1; PetscScalar y=0.0; PetscScalar dy=0.0; BSSPsiOne(bss, cs, x, &y); BSSDerivPsiOne(bss, cs, x, &dy); ASSERT_DOUBLE_NEAR(creal(y), 2.0*x*exp(-x), pow(10.0, -6)); ASSERT_DOUBLE_NEAR(creal(dy), 2.0*exp(-x)-2.0*x*exp(-x), pow(10.0, -6)); VecDestroy(&xs[0]); PetscFree(xs); PFDestroy(&psi0); BSSDestroy(&bss); MatDestroy(&H); MatDestroy(&V); MatDestroy(&S); EEPSDestroy(&eps); VecDestroy(&cs); return 0; }
bool eigenSolver::solve(int numEigenValues, std::string which) { if(!_A) return false; Mat A = _A->getMatrix(); Mat B = _B ? _B->getMatrix() : PETSC_NULL; PetscInt N, M; _try(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); _try(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); _try(MatGetSize(A, &N, &M)); PetscInt N2, M2; if (_B) { _try(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); _try(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); _try(MatGetSize(B, &N2, &M2)); } // generalized eigenvalue problem A x - \lambda B x = 0 EPS eps; _try(EPSCreate(PETSC_COMM_WORLD, &eps)); _try(EPSSetOperators(eps, A, B)); if(_hermitian) _try(EPSSetProblemType(eps, _B ? EPS_GHEP : EPS_HEP)); else _try(EPSSetProblemType(eps, _B ? EPS_GNHEP : EPS_NHEP)); // set some default options _try(EPSSetDimensions(eps, numEigenValues, PETSC_DECIDE, PETSC_DECIDE)); _try(EPSSetTolerances(eps, 1.e-7, 20));//1.e-7 20 _try(EPSSetType(eps, EPSKRYLOVSCHUR)); //default //_try(EPSSetType(eps, EPSARNOLDI)); //_try(EPSSetType(eps, EPSARPACK)); //_try(EPSSetType(eps, EPSPOWER)); // override these options at runtime, petsc-style _try(EPSSetFromOptions(eps)); // force options specified directly as arguments if(numEigenValues) _try(EPSSetDimensions(eps, numEigenValues, PETSC_DECIDE, PETSC_DECIDE)); if(which == "smallest") _try(EPSSetWhichEigenpairs(eps, EPS_SMALLEST_MAGNITUDE)); else if(which == "smallestReal") _try(EPSSetWhichEigenpairs(eps, EPS_SMALLEST_REAL)); else if(which == "largest") _try(EPSSetWhichEigenpairs(eps, EPS_LARGEST_MAGNITUDE)); // print info #if (SLEPC_VERSION_RELEASE == 0 || (SLEPC_VERSION_MAJOR > 3 || (SLEPC_VERSION_MAJOR == 3 && SLEPC_VERSION_MINOR >= 4))) EPSType type; #else const EPSType type; #endif _try(EPSGetType(eps, &type)); Msg::Debug("SLEPc solution method: %s", type); PetscInt nev; _try(EPSGetDimensions(eps, &nev, PETSC_NULL, PETSC_NULL)); Msg::Debug("SLEPc number of requested eigenvalues: %d", nev); PetscReal tol; PetscInt maxit; _try(EPSGetTolerances(eps, &tol, &maxit)); Msg::Debug("SLEPc stopping condition: tol=%g, maxit=%d", tol, maxit); // solve Msg::Info("SLEPc solving..."); double t1 = Cpu(); _try(EPSSolve(eps)); // check convergence int its; _try(EPSGetIterationNumber(eps, &its)); EPSConvergedReason reason; _try(EPSGetConvergedReason(eps, &reason)); if(reason == EPS_CONVERGED_TOL){ double t2 = Cpu(); Msg::Debug("SLEPc converged in %d iterations (%g s)", its, t2-t1); } else if(reason == EPS_DIVERGED_ITS) Msg::Error("SLEPc diverged after %d iterations", its); else if(reason == EPS_DIVERGED_BREAKDOWN) Msg::Error("SLEPc generic breakdown in method"); #if (SLEPC_VERSION_MAJOR < 3 || (SLEPC_VERSION_MAJOR == 3 && SLEPC_VERSION_MINOR < 2)) else if(reason == EPS_DIVERGED_NONSYMMETRIC) Msg::Error("The operator is nonsymmetric"); #endif // get number of converged approximate eigenpairs PetscInt nconv; _try(EPSGetConverged(eps, &nconv)); Msg::Debug("SLEPc number of converged eigenpairs: %d", nconv); // ignore additional eigenvalues if we get more than what we asked if(nconv > nev) nconv = nev; if (nconv > 0) { Vec xr, xi; _try(MatGetVecs(A, PETSC_NULL, &xr)); _try(MatGetVecs(A, PETSC_NULL, &xi)); Msg::Debug(" Re[EigenValue] Im[EigenValue]" " Relative error"); for (int i = 0; i < nconv; i++){ PetscScalar kr, ki; _try(EPSGetEigenpair(eps, i, &kr, &ki, xr, xi)); PetscReal error; _try(EPSComputeRelativeError(eps, i, &error)); #if defined(PETSC_USE_COMPLEX) PetscReal re = PetscRealPart(kr); PetscReal im = PetscImaginaryPart(kr); #else PetscReal re = kr; PetscReal im = ki; #endif Msg::Debug("EIG %03d %s%.16e %s%.16e %3.6e", i, (re < 0) ? "" : " ", re, (im < 0) ? "" : " ", im, error); // store eigenvalues and eigenvectors _eigenValues.push_back(std::complex<double>(re, im)); PetscScalar *tmpr, *tmpi; _try(VecGetArray(xr, &tmpr)); _try(VecGetArray(xi, &tmpi)); std::vector<std::complex<double> > ev(N); for(int i = 0; i < N; i++){ #if defined(PETSC_USE_COMPLEX) ev[i] = tmpr[i]; #else ev[i] = std::complex<double>(tmpr[i], tmpi[i]); #endif } _eigenVectors.push_back(ev); } _try(VecDestroy(&xr)); _try(VecDestroy(&xi)); } _try(EPSDestroy(&eps)); if(reason == EPS_CONVERGED_TOL){ Msg::Debug("SLEPc done"); return true; } else{ Msg::Warning("SLEPc failed"); return false; } }
int main(int argc,char **args) { Mat A; PetscInt i; PetscErrorCode ierr; char file[PETSC_MAX_PATH_LEN]; PetscLogDouble numberOfFlops, tsolve1, tsolve2; EPS eps; /* eigenproblem solver context */ const EPSType type; PetscReal error,tol,re,im; PetscScalar kr,ki; Vec xr=0,xi=0; PetscInt nev,maxit,its,nconv; EPSWhich which; EPSProblemType problemType; PetscMPIInt rank; PetscMPIInt numberOfProcessors; PetscBool flg; PetscBool isComplex; PetscViewer fd; SlepcInitialize(&argc,&args,(char*)0,help); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&numberOfProcessors);CHKERRQ(ierr); ierr = PetscOptionsGetString(PETSC_NULL,"-fin",file,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (!flg) { SETERRQ(PETSC_COMM_WORLD,1,"Must indicate matrix file with the -fin option"); } /* Read file */ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file,FILE_MODE_READ,&fd);CHKERRQ(ierr); // Create matrix ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); // Load matrix from file ierr = MatLoad(A,fd);CHKERRQ(ierr); // Destroy viewer ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); // Assemble matrix ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); //ierr = PetscPrintf(PETSC_COMM_SELF,"Reading matrix completes.\n");CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the eigensolver and set various options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Create eigensolver context */ ierr = EPSCreate(PETSC_COMM_WORLD,&eps);CHKERRQ(ierr); /* Set operators. In this case, it is a standard eigenvalue problem */ ierr = EPSSetOperators(eps,A,PETSC_NULL);CHKERRQ(ierr); //ierr = EPSSetProblemType(eps,EPS_HEP);CHKERRQ(ierr); /* Set solver parameters at runtime */ ierr = EPSSetFromOptions(eps);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the eigensystem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PetscTime(tsolve1); ierr = EPSSolve(eps);CHKERRQ(ierr); PetscTime(tsolve2); /* Optional: Get some information from the solver and display it */ ierr = EPSGetProblemType(eps, &problemType);CHKERRQ(ierr); ierr = EPSGetWhichEigenpairs(eps, &which);CHKERRQ(ierr); ierr = EPSGetDimensions(eps,&nev,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); ierr = EPSGetType(eps,&type);CHKERRQ(ierr); ierr = EPSGetTolerances(eps,&tol,&maxit);CHKERRQ(ierr); ierr = EPSGetConverged(eps,&nconv);CHKERRQ(ierr); ierr = EPSGetIterationNumber(eps,&its);CHKERRQ(ierr); ierr = PetscGetFlops(&numberOfFlops);CHKERRQ(ierr); #if defined(PETSC_USE_COMPLEX) isComplex = 1; #else isComplex = 0; #endif //Print output: ierr = PetscPrintf(PETSC_COMM_WORLD,"%D\t %D\t %D\t %D\t %D\t %.4G\t %s\t %D\t %D\t %F\t %2.1e\t",isComplex, numberOfProcessors, problemType, which, nev, tol, type, nconv, its, numberOfFlops, (tsolve2-tsolve1));CHKERRQ(ierr); if (nconv>0) { for (i=0;i<nconv;i++) { /* Get converged eigenpairs: i-th eigenvalue is stored in kr (real part) and ki (imaginary part) */ ierr = EPSGetEigenpair(eps,i,&kr,&ki,xr,xi);CHKERRQ(ierr); /* Compute the relative error associated to each eigenpair */ ierr = EPSComputeRelativeError(eps,i,&error);CHKERRQ(ierr); #if defined(PETSC_USE_COMPLEX) re = PetscRealPart(kr); im = PetscImaginaryPart(kr); #else re = kr; im = ki; #endif if (im!=0.0) { // ierr = PetscPrintf(PETSC_COMM_WORLD," %9F%+9F j %12G\n",re,im,error);CHKERRQ(ierr); } else { // ierr = PetscPrintf(PETSC_COMM_WORLD," %12F %12G\n",re,error);CHKERRQ(ierr); } ierr = PetscPrintf(PETSC_COMM_WORLD,"%12G\t", error);CHKERRQ(ierr); } } ierr = PetscPrintf(PETSC_COMM_WORLD,"\n");CHKERRQ(ierr); //Destructors ierr = MatDestroy(&A);CHKERRQ(ierr); //ierr = PetscFinalize(); ierr = SlepcFinalize();CHKERRQ(ierr); return 0; }
int main(int argc,char **argv) { Mat A; /* problem matrix */ EPS eps; /* eigenproblem solver context */ EPSType type; PetscReal error,tol,re,im; PetscScalar kr,ki,value[3]; Vec xr,xi; PetscInt n=30,i,Istart,Iend,col[3],nev,maxit,its,nconv; PetscBool FirstBlock=PETSC_FALSE,LastBlock=PETSC_FALSE; PetscErrorCode ierr; SlepcInitialize(&argc,&argv,(char*)0,help); ierr = PetscOptionsGetInt(NULL,"-n",&n,NULL);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"\n1-D Laplacian Eigenproblem, n=%D\n\n",n);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Compute the operator matrix that defines the eigensystem, Ax=kx - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = MatGetOwnershipRange(A,&Istart,&Iend);CHKERRQ(ierr); if (Istart==0) FirstBlock=PETSC_TRUE; if (Iend==n) LastBlock=PETSC_TRUE; value[0]=-1.0; value[1]=2.0; value[2]=-1.0; for (i=(FirstBlock? Istart+1: Istart); i<(LastBlock? Iend-1: Iend); i++) { col[0]=i-1; col[1]=i; col[2]=i+1; ierr = MatSetValues(A,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } if (LastBlock) { i=n-1; col[0]=n-2; col[1]=n-1; ierr = MatSetValues(A,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); } if (FirstBlock) { i=0; col[0]=0; col[1]=1; value[0]=2.0; value[1]=-1.0; ierr = MatSetValues(A,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatGetVecs(A,NULL,&xr);CHKERRQ(ierr); ierr = MatGetVecs(A,NULL,&xi);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the eigensolver and set various options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Create eigensolver context */ ierr = EPSCreate(PETSC_COMM_WORLD,&eps);CHKERRQ(ierr); /* Set operators. In this case, it is a standard eigenvalue problem */ ierr = EPSSetOperators(eps,A,NULL);CHKERRQ(ierr); ierr = EPSSetProblemType(eps,EPS_HEP);CHKERRQ(ierr); /* Set solver parameters at runtime */ ierr = EPSSetFromOptions(eps);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the eigensystem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = EPSSolve(eps);CHKERRQ(ierr); /* Optional: Get some information from the solver and display it */ ierr = EPSGetIterationNumber(eps,&its);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Number of iterations of the method: %D\n",its);CHKERRQ(ierr); ierr = EPSGetType(eps,&type);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Solution method: %s\n\n",type);CHKERRQ(ierr); ierr = EPSGetDimensions(eps,&nev,NULL,NULL);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Number of requested eigenvalues: %D\n",nev);CHKERRQ(ierr); ierr = EPSGetTolerances(eps,&tol,&maxit);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Stopping condition: tol=%.4g, maxit=%D\n",(double)tol,maxit);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Display solution and clean up - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Get number of converged approximate eigenpairs */ ierr = EPSGetConverged(eps,&nconv);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Number of converged eigenpairs: %D\n\n",nconv);CHKERRQ(ierr); if (nconv>0) { /* Display eigenvalues and relative errors */ ierr = PetscPrintf(PETSC_COMM_WORLD, " k ||Ax-kx||/||kx||\n" " ----------------- ------------------\n");CHKERRQ(ierr); for (i=0;i<nconv;i++) { /* Get converged eigenpairs: i-th eigenvalue is stored in kr (real part) and ki (imaginary part) */ ierr = EPSGetEigenpair(eps,i,&kr,&ki,xr,xi);CHKERRQ(ierr); /* Compute the relative error associated to each eigenpair */ ierr = EPSComputeRelativeError(eps,i,&error);CHKERRQ(ierr); #if defined(PETSC_USE_COMPLEX) re = PetscRealPart(kr); im = PetscImaginaryPart(kr); #else re = kr; im = ki; #endif if (im!=0.0) { ierr = PetscPrintf(PETSC_COMM_WORLD," %9f%+9f j %12g\n",(double)re,(double)im,(double)error);CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_WORLD," %12f %12g\n",(double)re,(double)error);CHKERRQ(ierr); } } ierr = PetscPrintf(PETSC_COMM_WORLD,"\n");CHKERRQ(ierr); } /* Free work space */ ierr = EPSDestroy(&eps);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = VecDestroy(&xr);CHKERRQ(ierr); ierr = VecDestroy(&xi);CHKERRQ(ierr); ierr = SlepcFinalize(); return 0; }