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; }
void SlepcEigenSolver<T>:: set_slepc_position_of_spectrum() { int ierr = 0; switch (this->_position_of_spectrum) { case LARGEST_MAGNITUDE: ierr = EPSSetWhichEigenpairs (_eps, EPS_LARGEST_MAGNITUDE); LIBMESH_CHKERRABORT(ierr); return; case SMALLEST_MAGNITUDE: ierr = EPSSetWhichEigenpairs (_eps, EPS_SMALLEST_MAGNITUDE); LIBMESH_CHKERRABORT(ierr); return; case LARGEST_REAL: ierr = EPSSetWhichEigenpairs (_eps, EPS_LARGEST_REAL); LIBMESH_CHKERRABORT(ierr); return; case SMALLEST_REAL: ierr = EPSSetWhichEigenpairs (_eps, EPS_SMALLEST_REAL); LIBMESH_CHKERRABORT(ierr); return; case LARGEST_IMAGINARY: ierr = EPSSetWhichEigenpairs (_eps, EPS_LARGEST_IMAGINARY); LIBMESH_CHKERRABORT(ierr); return; case SMALLEST_IMAGINARY: ierr = EPSSetWhichEigenpairs (_eps, EPS_SMALLEST_IMAGINARY); LIBMESH_CHKERRABORT(ierr); return; default: libMesh::err << "ERROR: Unsupported SLEPc position of spectrum: " << this->_position_of_spectrum << std::endl; libmesh_error(); } }
PetscErrorCode NEPSetUp_SLP(NEP nep) { PetscErrorCode ierr; NEP_SLP *ctx = (NEP_SLP*)nep->data; ST st; PetscBool istrivial; PetscFunctionBegin; if (nep->ncv) { /* ncv set */ if (nep->ncv<nep->nev) SETERRQ(PetscObjectComm((PetscObject)nep),1,"The value of ncv must be at least nev"); } else if (nep->mpd) { /* mpd set */ nep->ncv = PetscMin(nep->n,nep->nev+nep->mpd); } else { /* neither set: defaults depend on nev being small or large */ if (nep->nev<500) nep->ncv = PetscMin(nep->n,PetscMax(2*nep->nev,nep->nev+15)); else { nep->mpd = 500; nep->ncv = PetscMin(nep->n,nep->nev+nep->mpd); } } if (!nep->mpd) nep->mpd = nep->ncv; if (nep->ncv>nep->nev+nep->mpd) SETERRQ(PetscObjectComm((PetscObject)nep),1,"The value of ncv must not be larger than nev+mpd"); if (nep->nev>1) { ierr = PetscInfo(nep,"Warning: requested more than one eigenpair but SLP can only compute one\n");CHKERRQ(ierr); } if (!nep->max_it) nep->max_it = PetscMax(5000,2*nep->n/nep->ncv); if (!nep->max_funcs) nep->max_funcs = nep->max_it; ierr = RGIsTrivial(nep->rg,&istrivial);CHKERRQ(ierr); if (!istrivial) SETERRQ(PetscObjectComm((PetscObject)nep),PETSC_ERR_SUP,"This solver does not support region filtering"); if (!ctx->eps) { ierr = NEPSLPGetEPS(nep,&ctx->eps);CHKERRQ(ierr); } ierr = EPSSetWhichEigenpairs(ctx->eps,EPS_TARGET_MAGNITUDE);CHKERRQ(ierr); ierr = EPSSetTarget(ctx->eps,0.0);CHKERRQ(ierr); ierr = EPSGetST(ctx->eps,&st);CHKERRQ(ierr); ierr = STSetType(st,STSINVERT);CHKERRQ(ierr); ierr = EPSSetDimensions(ctx->eps,1,nep->ncv?nep->ncv:PETSC_DEFAULT,nep->mpd?nep->mpd:PETSC_DEFAULT);CHKERRQ(ierr); ierr = EPSSetTolerances(ctx->eps,nep->rtol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL/10.0:nep->rtol/10.0,nep->max_it?nep->max_it:PETSC_DEFAULT);CHKERRQ(ierr); ierr = NEPAllocateSolution(nep,0);CHKERRQ(ierr); ierr = NEPSetWorkVecs(nep,1);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { Mat A; /* problem matrix */ EPS eps; /* eigenproblem solver context */ ST st; PetscReal tol=PetscMax(1000*PETSC_MACHINE_EPSILON,1e-9); PetscScalar value[3]; PetscInt n=30,i,Istart,Iend,col[3]; PetscBool FirstBlock=PETSC_FALSE,LastBlock=PETSC_FALSE,flg; 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); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the eigensolver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = EPSCreate(PETSC_COMM_WORLD,&eps);CHKERRQ(ierr); ierr = EPSSetOperators(eps,A,NULL);CHKERRQ(ierr); ierr = EPSSetProblemType(eps,EPS_HEP);CHKERRQ(ierr); ierr = EPSSetTolerances(eps,tol,PETSC_DEFAULT);CHKERRQ(ierr); ierr = EPSSetFromOptions(eps);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve for largest eigenvalues - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = EPSSetWhichEigenpairs(eps,EPS_LARGEST_REAL);CHKERRQ(ierr); ierr = EPSSolve(eps);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," - - - Largest eigenvalues - - -\n");CHKERRQ(ierr); ierr = EPSPrintSolution(eps,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve for smallest eigenvalues - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = EPSSetWhichEigenpairs(eps,EPS_SMALLEST_REAL);CHKERRQ(ierr); ierr = EPSSolve(eps);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," - - - Smallest eigenvalues - - -\n");CHKERRQ(ierr); ierr = EPSPrintSolution(eps,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve for interior eigenvalues (target=2.1) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = EPSSetWhichEigenpairs(eps,EPS_TARGET_MAGNITUDE);CHKERRQ(ierr); ierr = EPSSetTarget(eps,2.1);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)eps,EPSLANCZOS,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSGetST(eps,&st);CHKERRQ(ierr); ierr = STSetType(st,STSINVERT);CHKERRQ(ierr); } else { ierr = PetscObjectTypeCompare((PetscObject)eps,EPSKRYLOVSCHUR,&flg);CHKERRQ(ierr); if (!flg) { ierr = PetscObjectTypeCompare((PetscObject)eps,EPSARNOLDI,&flg);CHKERRQ(ierr); } if (flg) { ierr = EPSSetExtraction(eps,EPS_HARMONIC);CHKERRQ(ierr); } } ierr = EPSSolve(eps);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," - - - Interior eigenvalues - - -\n");CHKERRQ(ierr); ierr = EPSPrintSolution(eps,NULL);CHKERRQ(ierr); ierr = EPSDestroy(&eps);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = SlepcFinalize(); return 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; }
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; } }
PetscErrorCode PEPSetUp_Linear(PEP pep) { PetscErrorCode ierr; PEP_LINEAR *ctx = (PEP_LINEAR*)pep->data; PetscInt i=0; EPSWhich which; PetscBool trackall,istrivial,flg; PetscScalar sigma; /* function tables */ PetscErrorCode (*fcreate[][2])(MPI_Comm,PEP_LINEAR*,Mat*) = { { MatCreateExplicit_Linear_N1A, MatCreateExplicit_Linear_N1B }, /* N1 */ { MatCreateExplicit_Linear_N2A, MatCreateExplicit_Linear_N2B }, /* N2 */ { MatCreateExplicit_Linear_S1A, MatCreateExplicit_Linear_S1B }, /* S1 */ { MatCreateExplicit_Linear_S2A, MatCreateExplicit_Linear_S2B }, /* S2 */ { MatCreateExplicit_Linear_H1A, MatCreateExplicit_Linear_H1B }, /* H1 */ { MatCreateExplicit_Linear_H2A, MatCreateExplicit_Linear_H2B } /* H2 */ }; PetscErrorCode (*fmult[][2])(Mat,Vec,Vec) = { { MatMult_Linear_N1A, MatMult_Linear_N1B }, { MatMult_Linear_N2A, MatMult_Linear_N2B }, { MatMult_Linear_S1A, MatMult_Linear_S1B }, { MatMult_Linear_S2A, MatMult_Linear_S2B }, { MatMult_Linear_H1A, MatMult_Linear_H1B }, { MatMult_Linear_H2A, MatMult_Linear_H2B } }; PetscErrorCode (*fgetdiagonal[][2])(Mat,Vec) = { { MatGetDiagonal_Linear_N1A, MatGetDiagonal_Linear_N1B }, { MatGetDiagonal_Linear_N2A, MatGetDiagonal_Linear_N2B }, { MatGetDiagonal_Linear_S1A, MatGetDiagonal_Linear_S1B }, { MatGetDiagonal_Linear_S2A, MatGetDiagonal_Linear_S2B }, { MatGetDiagonal_Linear_H1A, MatGetDiagonal_Linear_H1B }, { MatGetDiagonal_Linear_H2A, MatGetDiagonal_Linear_H2B } }; PetscFunctionBegin; if (!ctx->cform) ctx->cform = 1; if (!pep->which) pep->which = PEP_LARGEST_MAGNITUDE; if (pep->basis!=PEP_BASIS_MONOMIAL) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"Solver not implemented for non-monomial bases"); if (pep->nmat!=3) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"Solver only available for quadratic problems"); if (pep->scale==PEP_SCALE_DIAGONAL || pep->scale==PEP_SCALE_BOTH) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"Diagonal scaling not allowed in PEP linear solver"); ierr = STGetTransform(pep->st,&flg);CHKERRQ(ierr); if (flg) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"ST transformation flag not allowed for PEP linear solver"); /* compute scale factor if no set by user */ ierr = PEPComputeScaleFactor(pep);CHKERRQ(ierr); ierr = STGetOperators(pep->st,0,&ctx->K);CHKERRQ(ierr); ierr = STGetOperators(pep->st,1,&ctx->C);CHKERRQ(ierr); ierr = STGetOperators(pep->st,2,&ctx->M);CHKERRQ(ierr); ctx->sfactor = pep->sfactor; ierr = MatDestroy(&ctx->A);CHKERRQ(ierr); ierr = MatDestroy(&ctx->B);CHKERRQ(ierr); ierr = VecDestroy(&ctx->x1);CHKERRQ(ierr); ierr = VecDestroy(&ctx->x2);CHKERRQ(ierr); ierr = VecDestroy(&ctx->y1);CHKERRQ(ierr); ierr = VecDestroy(&ctx->y2);CHKERRQ(ierr); switch (pep->problem_type) { case PEP_GENERAL: i = 0; break; case PEP_HERMITIAN: i = 2; break; case PEP_GYROSCOPIC: i = 4; break; default: SETERRQ(PetscObjectComm((PetscObject)pep),1,"Wrong value of pep->problem_type"); } i += ctx->cform-1; if (ctx->explicitmatrix) { ctx->x1 = ctx->x2 = ctx->y1 = ctx->y2 = NULL; ierr = (*fcreate[i][0])(PetscObjectComm((PetscObject)pep),ctx,&ctx->A);CHKERRQ(ierr); ierr = (*fcreate[i][1])(PetscObjectComm((PetscObject)pep),ctx,&ctx->B);CHKERRQ(ierr); } else { ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)pep),1,pep->nloc,pep->n,NULL,&ctx->x1);CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)pep),1,pep->nloc,pep->n,NULL,&ctx->x2);CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)pep),1,pep->nloc,pep->n,NULL,&ctx->y1);CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)pep),1,pep->nloc,pep->n,NULL,&ctx->y2);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)pep,(PetscObject)ctx->x1);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)pep,(PetscObject)ctx->x2);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)pep,(PetscObject)ctx->y1);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)pep,(PetscObject)ctx->y2);CHKERRQ(ierr); ierr = MatCreateShell(PetscObjectComm((PetscObject)pep),2*pep->nloc,2*pep->nloc,2*pep->n,2*pep->n,ctx,&ctx->A);CHKERRQ(ierr); ierr = MatShellSetOperation(ctx->A,MATOP_MULT,(void(*)(void))fmult[i][0]);CHKERRQ(ierr); ierr = MatShellSetOperation(ctx->A,MATOP_GET_DIAGONAL,(void(*)(void))fgetdiagonal[i][0]);CHKERRQ(ierr); ierr = MatCreateShell(PetscObjectComm((PetscObject)pep),2*pep->nloc,2*pep->nloc,2*pep->n,2*pep->n,ctx,&ctx->B);CHKERRQ(ierr); ierr = MatShellSetOperation(ctx->B,MATOP_MULT,(void(*)(void))fmult[i][1]);CHKERRQ(ierr); ierr = MatShellSetOperation(ctx->B,MATOP_GET_DIAGONAL,(void(*)(void))fgetdiagonal[i][1]);CHKERRQ(ierr); } ierr = PetscLogObjectParent((PetscObject)pep,(PetscObject)ctx->A);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)pep,(PetscObject)ctx->B);CHKERRQ(ierr); if (!ctx->eps) { ierr = PEPLinearGetEPS(pep,&ctx->eps);CHKERRQ(ierr); } ierr = EPSSetOperators(ctx->eps,ctx->A,ctx->B);CHKERRQ(ierr); if (pep->problem_type==PEP_HERMITIAN) { ierr = EPSSetProblemType(ctx->eps,EPS_GHIEP);CHKERRQ(ierr); } else { ierr = EPSSetProblemType(ctx->eps,EPS_GNHEP);CHKERRQ(ierr); } switch (pep->which) { case PEP_LARGEST_MAGNITUDE: which = EPS_LARGEST_MAGNITUDE; break; case PEP_SMALLEST_MAGNITUDE: which = EPS_SMALLEST_MAGNITUDE; break; case PEP_LARGEST_REAL: which = EPS_LARGEST_REAL; break; case PEP_SMALLEST_REAL: which = EPS_SMALLEST_REAL; break; case PEP_LARGEST_IMAGINARY: which = EPS_LARGEST_IMAGINARY; break; case PEP_SMALLEST_IMAGINARY: which = EPS_SMALLEST_IMAGINARY; break; case PEP_TARGET_MAGNITUDE: which = EPS_TARGET_MAGNITUDE; break; case PEP_TARGET_REAL: which = EPS_TARGET_REAL; break; case PEP_TARGET_IMAGINARY: which = EPS_TARGET_IMAGINARY; break; default: SETERRQ(PetscObjectComm((PetscObject)pep),1,"Wrong value of which"); } ierr = EPSSetWhichEigenpairs(ctx->eps,which);CHKERRQ(ierr); ierr = EPSSetDimensions(ctx->eps,pep->nev,pep->ncv?pep->ncv:PETSC_DEFAULT,pep->mpd?pep->mpd:PETSC_DEFAULT);CHKERRQ(ierr); ierr = EPSSetTolerances(ctx->eps,pep->tol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL/10.0:pep->tol/10.0,pep->max_it?pep->max_it:PETSC_DEFAULT);CHKERRQ(ierr); ierr = RGIsTrivial(pep->rg,&istrivial);CHKERRQ(ierr); if (!istrivial) { ierr = EPSSetRG(ctx->eps,pep->rg);CHKERRQ(ierr); } /* Transfer the trackall option from pep to eps */ ierr = PEPGetTrackAll(pep,&trackall);CHKERRQ(ierr); ierr = EPSSetTrackAll(ctx->eps,trackall);CHKERRQ(ierr); /* temporary change of target */ if (pep->sfactor!=1.0) { ierr = EPSGetTarget(ctx->eps,&sigma);CHKERRQ(ierr); ierr = EPSSetTarget(ctx->eps,sigma/pep->sfactor);CHKERRQ(ierr); } ierr = EPSSetUp(ctx->eps);CHKERRQ(ierr); ierr = EPSGetDimensions(ctx->eps,NULL,&pep->ncv,&pep->mpd);CHKERRQ(ierr); ierr = EPSGetTolerances(ctx->eps,NULL,&pep->max_it);CHKERRQ(ierr); if (pep->nini>0) { ierr = PetscInfo(pep,"Ignoring initial vectors\n");CHKERRQ(ierr); } ierr = PEPAllocateSolution(pep,0);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode cHamiltonianMatrix::hamiltonianRescaling(){ // ierr = MatCreateVecs(Hpolaron,NULL,&xr);CHKERRQ(ierr); // ierr = MatCreateVecs(Hpolaron,NULL,&xi);CHKERRQ(ierr); ierr = EPSCreate(PETSC_COMM_WORLD,&eps);CHKERRQ(ierr); ierr = EPSSetOperators(eps,Hpolaron,NULL);CHKERRQ(ierr); ierr = EPSSetProblemType(eps,EPS_HEP);CHKERRQ(ierr); // PetscBool her; // ierr = EPSIsHermitian(eps, &her); CHKERRQ(ierr); if (rank==0) {cout << endl;cout << "is hermitian? (has to be) " << her << endl;} // PetscBool pos; // ierr = EPSIsPositive(eps, &pos); CHKERRQ(ierr); if (rank==0) {cout << "is positive? (not really)" << pos << endl;cout << endl;} // ierr = EPSSetType(eps,EPSPOWER);CHKERRQ(ierr); ierr = EPSSetWhichEigenpairs(eps,EPS_LARGEST_REAL);CHKERRQ(ierr); // ierr = EPSSetFromOptions(eps);CHKERRQ(ierr); 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); // 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); // ------- maximum and minimum of energy spectrum ---------- ierr = EPSGetEigenpair(eps,0,&HpolaronMax,NULL,NULL,NULL);CHKERRQ(ierr); ierr = EPSSetWhichEigenpairs(eps,EPS_SMALLEST_REAL);CHKERRQ(ierr); ierr = EPSSolve(eps);CHKERRQ(ierr); ierr = EPSGetEigenpair(eps,0,&HpolaronMin,NULL,NULL,NULL);CHKERRQ(ierr); double epsilon_cut_off = 0.01; a_scaling = PetscRealPart(HpolaronMax-HpolaronMin)/(2.0-epsilon_cut_off); b_scaling = PetscRealPart(HpolaronMax+HpolaronMin)/2.0; if (rank==0) { cout << "HpolaronMax is " << HpolaronMax << endl; cout << "HpolaronMin is " << HpolaronMin << endl; cout << "a_scaling is " << a_scaling << endl; cout << "b_scaling is " << b_scaling << endl; } /* % --------- rescaled Hamiltonian ------------- */ ierr = MatShift(Hpolaron,-b_scaling);CHKERRQ(ierr); ierr = MatScale(Hpolaron,1.0/a_scaling); // ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_ASCII_DENSE );CHKERRQ(ierr); // // ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_ASCII_MATLAB );CHKERRQ(ierr); // ierr = MatView(Hpolaron, PETSC_VIEWER_STDOUT_WORLD );CHKERRQ(ierr); // ierr = EPSSetOperators(eps,Hpolaron,NULL);CHKERRQ(ierr); // ierr = EPSSetProblemType(eps,EPS_HEP);CHKERRQ(ierr); // ierr = EPSSolve(eps);CHKERRQ(ierr); // ierr = EPSGetConverged(eps,&nconv);CHKERRQ(ierr); // ierr = PetscPrintf(PETSC_COMM_WORLD," Number of converged eigenpairs: %D\n\n",nconv);CHKERRQ(ierr); // ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD,PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr); // ierr = EPSReasonView(eps,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); // ierr = EPSErrorView(eps,EPS_ERROR_RELATIVE,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); // ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); if (rank==0) cout << "Characteristic Coherance Time: t_c=" << 1.0/(2.0*a_scaling/dim/L) << endl; /* %--------------------------------------------------- % -------- End of Cosntruction of Hamiltonian ------ %============================================================= */ return ierr; }
/*@ EPSSetFromOptions - Sets EPS options from the options database. This routine must be called before EPSSetUp() if the user is to be allowed to set the solver type. Collective on EPS Input Parameters: . eps - the eigensolver context Notes: To see all options, run your program with the -help option. Level: beginner @*/ PetscErrorCode EPSSetFromOptions(EPS eps) { PetscErrorCode ierr; char type[256],monfilename[PETSC_MAX_PATH_LEN]; PetscBool flg,flg1,flg2,flg3; PetscReal r,array[2]={0,0}; PetscScalar s; PetscInt i,j,k; PetscViewer monviewer; SlepcConvMonitor ctx; PetscFunctionBegin; PetscValidHeaderSpecific(eps,EPS_CLASSID,1); if (!EPSRegisterAllCalled) { ierr = EPSRegisterAll();CHKERRQ(ierr); } ierr = PetscObjectOptionsBegin((PetscObject)eps);CHKERRQ(ierr); ierr = PetscOptionsFList("-eps_type","Eigenvalue Problem Solver method","EPSSetType",EPSList,(char*)(((PetscObject)eps)->type_name?((PetscObject)eps)->type_name:EPSKRYLOVSCHUR),type,256,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetType(eps,type);CHKERRQ(ierr); } /* Set the type if it was never set. */ if (!((PetscObject)eps)->type_name) { ierr = EPSSetType(eps,EPSKRYLOVSCHUR);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroupBegin("-eps_hermitian","hermitian eigenvalue problem","EPSSetProblemType",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetProblemType(eps,EPS_HEP);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-eps_gen_hermitian","generalized hermitian eigenvalue problem","EPSSetProblemType",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetProblemType(eps,EPS_GHEP);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-eps_non_hermitian","non-hermitian eigenvalue problem","EPSSetProblemType",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetProblemType(eps,EPS_NHEP);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-eps_gen_non_hermitian","generalized non-hermitian eigenvalue problem","EPSSetProblemType",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetProblemType(eps,EPS_GNHEP);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-eps_pos_gen_non_hermitian","generalized non-hermitian eigenvalue problem with positive semi-definite B","EPSSetProblemType",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetProblemType(eps,EPS_PGNHEP);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroupEnd("-eps_gen_indefinite","generalized hermitian-indefinite eigenvalue problem","EPSSetProblemType",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetProblemType(eps,EPS_GHIEP);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroupBegin("-eps_ritz","Rayleigh-Ritz extraction","EPSSetExtraction",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetExtraction(eps,EPS_RITZ);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-eps_harmonic","harmonic Ritz extraction","EPSSetExtraction",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetExtraction(eps,EPS_HARMONIC);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-eps_harmonic_relative","relative harmonic Ritz extraction","EPSSetExtraction",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetExtraction(eps,EPS_HARMONIC_RELATIVE);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-eps_harmonic_right","right harmonic Ritz extraction","EPSSetExtraction",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetExtraction(eps,EPS_HARMONIC_RIGHT);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-eps_harmonic_largest","largest harmonic Ritz extraction","EPSSetExtraction",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetExtraction(eps,EPS_HARMONIC_LARGEST);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-eps_refined","refined Ritz extraction","EPSSetExtraction",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetExtraction(eps,EPS_REFINED);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroupEnd("-eps_refined_harmonic","refined harmonic Ritz extraction","EPSSetExtraction",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetExtraction(eps,EPS_REFINED_HARMONIC);CHKERRQ(ierr); } ierr = PetscOptionsEnum("-eps_balance","Balancing method","EPSSetBalance",EPSBalanceTypes,(PetscEnum)eps->balance,(PetscEnum*)&eps->balance,NULL);CHKERRQ(ierr); j = eps->balance_its; ierr = PetscOptionsInt("-eps_balance_its","Number of iterations in balancing","EPSSetBalance",eps->balance_its,&j,&flg1);CHKERRQ(ierr); r = eps->balance_cutoff; ierr = PetscOptionsReal("-eps_balance_cutoff","Cutoff value in balancing","EPSSetBalance",eps->balance_cutoff,&r,&flg2);CHKERRQ(ierr); if (flg1 || flg2) { ierr = EPSSetBalance(eps,eps->balance,j,r);CHKERRQ(ierr); } i = eps->max_it? eps->max_it: PETSC_DEFAULT; ierr = PetscOptionsInt("-eps_max_it","Maximum number of iterations","EPSSetTolerances",eps->max_it,&i,&flg1);CHKERRQ(ierr); r = eps->tol; ierr = PetscOptionsReal("-eps_tol","Tolerance","EPSSetTolerances",eps->tol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL:eps->tol,&r,&flg2);CHKERRQ(ierr); if (flg1 || flg2) { ierr = EPSSetTolerances(eps,r,i);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroupBegin("-eps_conv_eig","Relative error convergence test","EPSSetConvergenceTest",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetConvergenceTest(eps,EPS_CONV_EIG);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-eps_conv_norm","Convergence test relative to the eigenvalue and the matrix norms","EPSSetConvergenceTest",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetConvergenceTest(eps,EPS_CONV_NORM);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-eps_conv_abs","Absolute error convergence test","EPSSetConvergenceTest",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetConvergenceTest(eps,EPS_CONV_ABS);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroupEnd("-eps_conv_user","User-defined convergence test","EPSSetConvergenceTest",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetConvergenceTest(eps,EPS_CONV_USER);CHKERRQ(ierr); } i = eps->nev; ierr = PetscOptionsInt("-eps_nev","Number of eigenvalues to compute","EPSSetDimensions",eps->nev,&i,&flg1);CHKERRQ(ierr); j = eps->ncv? eps->ncv: PETSC_DEFAULT; ierr = PetscOptionsInt("-eps_ncv","Number of basis vectors","EPSSetDimensions",eps->ncv,&j,&flg2);CHKERRQ(ierr); k = eps->mpd? eps->mpd: PETSC_DEFAULT; ierr = PetscOptionsInt("-eps_mpd","Maximum dimension of projected problem","EPSSetDimensions",eps->mpd,&k,&flg3);CHKERRQ(ierr); if (flg1 || flg2 || flg3) { ierr = EPSSetDimensions(eps,i,j,k);CHKERRQ(ierr); } /* -----------------------------------------------------------------------*/ /* Cancels all monitors hardwired into code before call to EPSSetFromOptions() */ flg = PETSC_FALSE; ierr = PetscOptionsBool("-eps_monitor_cancel","Remove any hardwired monitor routines","EPSMonitorCancel",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = EPSMonitorCancel(eps);CHKERRQ(ierr); } /* Prints approximate eigenvalues and error estimates at each iteration */ ierr = PetscOptionsString("-eps_monitor","Monitor first unconverged approximate eigenvalue and error estimate","EPSMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)eps),monfilename,&monviewer);CHKERRQ(ierr); ierr = EPSMonitorSet(eps,EPSMonitorFirst,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } ierr = PetscOptionsString("-eps_monitor_conv","Monitor approximate eigenvalues and error estimates as they converge","EPSMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscNew(&ctx);CHKERRQ(ierr); ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)eps),monfilename,&ctx->viewer);CHKERRQ(ierr); ierr = EPSMonitorSet(eps,EPSMonitorConverged,ctx,(PetscErrorCode (*)(void**))SlepcConvMonitorDestroy);CHKERRQ(ierr); } ierr = PetscOptionsString("-eps_monitor_all","Monitor approximate eigenvalues and error estimates","EPSMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)eps),monfilename,&monviewer);CHKERRQ(ierr); ierr = EPSMonitorSet(eps,EPSMonitorAll,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); ierr = EPSSetTrackAll(eps,PETSC_TRUE);CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsBool("-eps_monitor_lg","Monitor first unconverged approximate eigenvalue and error estimate graphically","EPSMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = EPSMonitorSet(eps,EPSMonitorLG,NULL,NULL);CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsBool("-eps_monitor_lg_all","Monitor error estimates graphically","EPSMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = EPSMonitorSet(eps,EPSMonitorLGAll,NULL,NULL);CHKERRQ(ierr); ierr = EPSSetTrackAll(eps,PETSC_TRUE);CHKERRQ(ierr); } /* -----------------------------------------------------------------------*/ ierr = PetscOptionsBoolGroupBegin("-eps_largest_magnitude","compute largest eigenvalues in magnitude","EPSSetWhichEigenpairs",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetWhichEigenpairs(eps,EPS_LARGEST_MAGNITUDE);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-eps_smallest_magnitude","compute smallest eigenvalues in magnitude","EPSSetWhichEigenpairs",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetWhichEigenpairs(eps,EPS_SMALLEST_MAGNITUDE);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-eps_largest_real","compute largest real parts","EPSSetWhichEigenpairs",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetWhichEigenpairs(eps,EPS_LARGEST_REAL);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-eps_smallest_real","compute smallest real parts","EPSSetWhichEigenpairs",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetWhichEigenpairs(eps,EPS_SMALLEST_REAL);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-eps_largest_imaginary","compute largest imaginary parts","EPSSetWhichEigenpairs",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetWhichEigenpairs(eps,EPS_LARGEST_IMAGINARY);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-eps_smallest_imaginary","compute smallest imaginary parts","EPSSetWhichEigenpairs",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetWhichEigenpairs(eps,EPS_SMALLEST_IMAGINARY);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-eps_target_magnitude","compute nearest eigenvalues to target","EPSSetWhichEigenpairs",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetWhichEigenpairs(eps,EPS_TARGET_MAGNITUDE);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-eps_target_real","compute eigenvalues with real parts close to target","EPSSetWhichEigenpairs",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetWhichEigenpairs(eps,EPS_TARGET_REAL);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-eps_target_imaginary","compute eigenvalues with imaginary parts close to target","EPSSetWhichEigenpairs",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetWhichEigenpairs(eps,EPS_TARGET_IMAGINARY);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroupEnd("-eps_all","compute all eigenvalues in an interval","EPSSetWhichEigenpairs",&flg);CHKERRQ(ierr); if (flg) { ierr = EPSSetWhichEigenpairs(eps,EPS_ALL);CHKERRQ(ierr); } ierr = PetscOptionsScalar("-eps_target","Value of the target","EPSSetTarget",eps->target,&s,&flg);CHKERRQ(ierr); if (flg) { if (eps->which!=EPS_TARGET_REAL && eps->which!=EPS_TARGET_IMAGINARY) { ierr = EPSSetWhichEigenpairs(eps,EPS_TARGET_MAGNITUDE);CHKERRQ(ierr); } ierr = EPSSetTarget(eps,s);CHKERRQ(ierr); } k = 2; ierr = PetscOptionsRealArray("-eps_interval","Computational interval (two real values separated with a comma without spaces)","EPSSetInterval",array,&k,&flg);CHKERRQ(ierr); if (flg) { if (k<2) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_SIZ,"Must pass two values in -eps_interval (comma-separated without spaces)"); ierr = EPSSetWhichEigenpairs(eps,EPS_ALL);CHKERRQ(ierr); ierr = EPSSetInterval(eps,array[0],array[1]);CHKERRQ(ierr); } ierr = PetscOptionsBool("-eps_true_residual","Compute true residuals explicitly","EPSSetTrueResidual",eps->trueres,&eps->trueres,NULL);CHKERRQ(ierr); ierr = PetscOptionsName("-eps_view","Print detailed information on solver used","EPSView",0);CHKERRQ(ierr); ierr = PetscOptionsName("-eps_plot_eigs","Make a plot of the computed eigenvalues","EPSSolve",0);CHKERRQ(ierr); if (eps->ops->setfromoptions) { ierr = (*eps->ops->setfromoptions)(eps);CHKERRQ(ierr); } ierr = PetscObjectProcessOptionsHandlers((PetscObject)eps);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); if (!eps->V) { ierr = EPSGetBV(eps,&eps->V);CHKERRQ(ierr); } ierr = BVSetFromOptions(eps->V);CHKERRQ(ierr); if (!eps->rg) { ierr = EPSGetRG(eps,&eps->rg);CHKERRQ(ierr); } ierr = RGSetFromOptions(eps->rg);CHKERRQ(ierr); if (!eps->ds) { ierr = EPSGetDS(eps,&eps->ds);CHKERRQ(ierr); } ierr = DSSetFromOptions(eps->ds);CHKERRQ(ierr); ierr = STSetFromOptions(eps->st);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(eps->rand);CHKERRQ(ierr); PetscFunctionReturn(0); }
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; }
int main(int argc,char **argv) { Mat A; /* eigenvalue problem matrix */ EPS eps; /* eigenproblem solver context */ EPSType type; PetscScalar delta1,delta2,L,h,value[3]; PetscInt N=30,n,i,col[3],Istart,Iend,nev; PetscBool FirstBlock=PETSC_FALSE,LastBlock=PETSC_FALSE; CTX_BRUSSEL *ctx; PetscErrorCode ierr; SlepcInitialize(&argc,&argv,(char*)0,help); ierr = PetscOptionsGetInt(NULL,"-n",&N,NULL);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"\nBrusselator wave model, n=%D\n\n",N);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Generate the matrix - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Create shell matrix context and set default parameters */ ierr = PetscNew(&ctx);CHKERRQ(ierr); ctx->alpha = 2.0; ctx->beta = 5.45; delta1 = 0.008; delta2 = 0.004; L = 0.51302; /* Look the command line for user-provided parameters */ ierr = PetscOptionsGetScalar(NULL,"-L",&L,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetScalar(NULL,"-alpha",&ctx->alpha,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetScalar(NULL,"-beta",&ctx->beta,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetScalar(NULL,"-delta1",&delta1,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetScalar(NULL,"-delta2",&delta2,NULL);CHKERRQ(ierr); /* Create matrix T */ ierr = MatCreate(PETSC_COMM_WORLD,&ctx->T);CHKERRQ(ierr); ierr = MatSetSizes(ctx->T,PETSC_DECIDE,PETSC_DECIDE,N,N);CHKERRQ(ierr); ierr = MatSetFromOptions(ctx->T);CHKERRQ(ierr); ierr = MatSetUp(ctx->T);CHKERRQ(ierr); ierr = MatGetOwnershipRange(ctx->T,&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(ctx->T,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } if (LastBlock) { i=N-1; col[0]=N-2; col[1]=N-1; ierr = MatSetValues(ctx->T,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(ctx->T,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(ctx->T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(ctx->T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatGetLocalSize(ctx->T,&n,NULL);CHKERRQ(ierr); /* Fill the remaining information in the shell matrix context and create auxiliary vectors */ h = 1.0 / (PetscReal)(N+1); ctx->tau1 = delta1 / ((h*L)*(h*L)); ctx->tau2 = delta2 / ((h*L)*(h*L)); ctx->sigma = 0.0; ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,n,PETSC_DECIDE,NULL,&ctx->x1);CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,n,PETSC_DECIDE,NULL,&ctx->x2);CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,n,PETSC_DECIDE,NULL,&ctx->y1);CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,n,PETSC_DECIDE,NULL,&ctx->y2);CHKERRQ(ierr); /* Create the shell matrix */ ierr = MatCreateShell(PETSC_COMM_WORLD,2*n,2*n,2*N,2*N,(void*)ctx,&A);CHKERRQ(ierr); ierr = MatShellSetOperation(A,MATOP_MULT,(void(*)())MatMult_Brussel);CHKERRQ(ierr); ierr = MatShellSetOperation(A,MATOP_SHIFT,(void(*)())MatShift_Brussel);CHKERRQ(ierr); ierr = MatShellSetOperation(A,MATOP_GET_DIAGONAL,(void(*)())MatGetDiagonal_Brussel);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_NHEP);CHKERRQ(ierr); /* Ask for the rightmost eigenvalues */ ierr = EPSSetWhichEigenpairs(eps,EPS_LARGEST_REAL);CHKERRQ(ierr); /* Set other solver options 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 = 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); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Display solution and clean up - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = EPSPrintSolution(eps,NULL);CHKERRQ(ierr); ierr = EPSDestroy(&eps);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&ctx->T);CHKERRQ(ierr); ierr = VecDestroy(&ctx->x1);CHKERRQ(ierr); ierr = VecDestroy(&ctx->x2);CHKERRQ(ierr); ierr = VecDestroy(&ctx->y1);CHKERRQ(ierr); ierr = VecDestroy(&ctx->y2);CHKERRQ(ierr); ierr = PetscFree(ctx);CHKERRQ(ierr); ierr = SlepcFinalize(); return 0; }
void SlepcEigenSolver<T>:: set_slepc_position_of_spectrum() { PetscErrorCode ierr = 0; switch (this->_position_of_spectrum) { case LARGEST_MAGNITUDE: { ierr = EPSSetWhichEigenpairs (_eps, EPS_LARGEST_MAGNITUDE); LIBMESH_CHKERR(ierr); return; } case SMALLEST_MAGNITUDE: { ierr = EPSSetWhichEigenpairs (_eps, EPS_SMALLEST_MAGNITUDE); LIBMESH_CHKERR(ierr); return; } case LARGEST_REAL: { ierr = EPSSetWhichEigenpairs (_eps, EPS_LARGEST_REAL); LIBMESH_CHKERR(ierr); return; } case SMALLEST_REAL: { ierr = EPSSetWhichEigenpairs (_eps, EPS_SMALLEST_REAL); LIBMESH_CHKERR(ierr); return; } case LARGEST_IMAGINARY: { ierr = EPSSetWhichEigenpairs (_eps, EPS_LARGEST_IMAGINARY); LIBMESH_CHKERR(ierr); return; } case SMALLEST_IMAGINARY: { ierr = EPSSetWhichEigenpairs (_eps, EPS_SMALLEST_IMAGINARY); LIBMESH_CHKERR(ierr); return; } // The EPS_TARGET_XXX enums were added in SLEPc 3.1 #if !SLEPC_VERSION_LESS_THAN(3,1,0) case TARGET_MAGNITUDE: { ierr = EPSSetTarget(_eps, this->_target_val); LIBMESH_CHKERR(ierr); ierr = EPSSetWhichEigenpairs (_eps, EPS_TARGET_MAGNITUDE); LIBMESH_CHKERR(ierr); return; } case TARGET_REAL: { ierr = EPSSetTarget(_eps, this->_target_val); LIBMESH_CHKERR(ierr); ierr = EPSSetWhichEigenpairs (_eps, EPS_TARGET_REAL); LIBMESH_CHKERR(ierr); return; } case TARGET_IMAGINARY: { ierr = EPSSetTarget(_eps, this->_target_val); LIBMESH_CHKERR(ierr); ierr = EPSSetWhichEigenpairs (_eps, EPS_TARGET_IMAGINARY); LIBMESH_CHKERR(ierr); return; } #endif default: libmesh_error_msg("ERROR: Unsupported SLEPc position of spectrum: " << this->_position_of_spectrum); } }