PetscErrorCode NEPSetUp_Interpol(NEP nep) { PetscErrorCode ierr; NEP_INTERPOL *ctx = (NEP_INTERPOL*)nep->data; ST st; RG rg; PetscReal a,b,c,d,s; PetscBool flg,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->max_it) nep->max_it = PetscMax(5000,2*nep->n/nep->ncv); if (!nep->max_funcs) nep->max_funcs = nep->max_it; if (!nep->split) SETERRQ(PetscObjectComm((PetscObject)nep),PETSC_ERR_SUP,"NEPINTERPOL only available for split operator"); /* transfer PEP options */ if (!ctx->pep) { ierr = NEPInterpolGetPEP(nep,&ctx->pep);CHKERRQ(ierr); } ierr = PEPSetBV(ctx->pep,nep->V);CHKERRQ(ierr); ierr = PEPSetBasis(ctx->pep,PEP_BASIS_CHEBYSHEV1);CHKERRQ(ierr); ierr = PEPSetWhichEigenpairs(ctx->pep,PEP_TARGET_MAGNITUDE);CHKERRQ(ierr); ierr = PEPSetTarget(ctx->pep,0.0);CHKERRQ(ierr); ierr = PEPGetST(ctx->pep,&st);CHKERRQ(ierr); ierr = STSetType(st,STSINVERT);CHKERRQ(ierr); ierr = PEPSetDimensions(ctx->pep,nep->nev,nep->ncv?nep->ncv:PETSC_DEFAULT,nep->mpd?nep->mpd:PETSC_DEFAULT);CHKERRQ(ierr); ierr = PEPSetTolerances(ctx->pep,nep->rtol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL/10.0:nep->rtol/10.0,nep->max_it?nep->max_it:PETSC_DEFAULT);CHKERRQ(ierr); /* transfer region options */ ierr = RGIsTrivial(nep->rg,&istrivial);CHKERRQ(ierr); if (istrivial) SETERRQ(PetscObjectComm((PetscObject)nep),PETSC_ERR_SUP,"NEPINTERPOL requires a nontrivial region"); ierr = PetscObjectTypeCompare((PetscObject)nep->rg,RGINTERVAL,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PetscObjectComm((PetscObject)nep),PETSC_ERR_SUP,"Only implemented for interval regions"); ierr = RGIntervalGetEndpoints(nep->rg,&a,&b,&c,&d);CHKERRQ(ierr); if (a<=-PETSC_MAX_REAL || b>=PETSC_MAX_REAL) SETERRQ(PetscObjectComm((PetscObject)nep),PETSC_ERR_SUP,"Only implemented for bounded intervals"); ierr = PEPGetRG(ctx->pep,&rg);CHKERRQ(ierr); ierr = RGIsTrivial(rg,&istrivial);CHKERRQ(ierr); if (istrivial) { /* user did not give region options */ ierr = RGSetType(rg,RGINTERVAL);CHKERRQ(ierr); s = 2.0/(b-a); c = (c==0)? -PETSC_MAX_REAL: c*s; d = (d==0)? PETSC_MAX_REAL: d*s; ierr = RGIntervalSetEndpoints(rg,-1.0,1.0,c,d);CHKERRQ(ierr); } ierr = NEPAllocateSolution(nep,0);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ STSetUp - Prepares for the use of a spectral transformation. Collective on ST Input Parameter: . st - the spectral transformation context Level: advanced .seealso: STCreate(), STApply(), STDestroy() @*/ PetscErrorCode STSetUp(ST st) { PetscInt i,n,k; PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(st,ST_CLASSID,1); STCheckMatrices(st,1); if (st->setupcalled) PetscFunctionReturn(0); ierr = PetscInfo(st,"Setting up new ST\n");CHKERRQ(ierr); ierr = PetscLogEventBegin(ST_SetUp,st,0,0,0);CHKERRQ(ierr); if (!((PetscObject)st)->type_name) { ierr = STSetType(st,STSHIFT);CHKERRQ(ierr); } if (!st->T) { ierr = PetscMalloc(PetscMax(2,st->nmat)*sizeof(Mat),&st->T);CHKERRQ(ierr); ierr = PetscLogObjectMemory((PetscObject)st,PetscMax(2,st->nmat)*sizeof(Mat));CHKERRQ(ierr); for (i=0;i<PetscMax(2,st->nmat);i++) st->T[i] = NULL; } else { for (i=0;i<PetscMax(2,st->nmat);i++) { ierr = MatDestroy(&st->T[i]);CHKERRQ(ierr); } } ierr = MatDestroy(&st->P);CHKERRQ(ierr); if (!st->w) { ierr = MatGetVecs(st->A[0],&st->w,NULL);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)st,(PetscObject)st->w);CHKERRQ(ierr); } if (st->D) { ierr = MatGetLocalSize(st->A[0],NULL,&n);CHKERRQ(ierr); ierr = VecGetLocalSize(st->D,&k);CHKERRQ(ierr); if (n != k) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Balance matrix has wrong dimension %D (should be %D)",k,n); if (!st->wb) { ierr = VecDuplicate(st->D,&st->wb);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)st,(PetscObject)st->wb);CHKERRQ(ierr); } } if (st->ops->setup) { ierr = (*st->ops->setup)(st);CHKERRQ(ierr); } st->setupcalled = 1; ierr = PetscLogEventEnd(ST_SetUp,st,0,0,0);CHKERRQ(ierr); PetscFunctionReturn(0); }
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; }
PetscErrorCode EPSSetFromOptions_JD(EPS eps) { PetscErrorCode ierr; PetscBool flg,op; PetscInt opi,opi0; PetscReal opf; KSP ksp; PetscBool orth; const char *orth_list[2] = {"I","B"}; PetscFunctionBegin; ierr = PetscOptionsHead("EPS Jacobi-Davidson (JD) Options");CHKERRQ(ierr); ierr = EPSJDGetKrylovStart(eps,&op);CHKERRQ(ierr); ierr = PetscOptionsBool("-eps_jd_krylov_start","Start the searching subspace with a krylov basis","EPSJDSetKrylovStart",op,&op,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSJDSetKrylovStart(eps,op);CHKERRQ(ierr); } ierr = EPSJDGetBlockSize(eps,&opi);CHKERRQ(ierr); ierr = PetscOptionsInt("-eps_jd_blocksize","Number vectors add to the searching subspace","EPSJDSetBlockSize",opi,&opi,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSJDSetBlockSize(eps,opi);CHKERRQ(ierr); } ierr = EPSJDGetRestart(eps,&opi,&opi0);CHKERRQ(ierr); ierr = PetscOptionsInt("-eps_jd_minv","Set the size of the searching subspace after restarting","EPSJDSetRestart",opi,&opi,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSJDSetRestart(eps,opi,opi0);CHKERRQ(ierr); } ierr = PetscOptionsInt("-eps_jd_plusk","Set the number of saved eigenvectors from the previous iteration when restarting","EPSJDSetRestart",opi0,&opi0,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSJDSetRestart(eps,opi,opi0);CHKERRQ(ierr); } ierr = EPSJDGetInitialSize(eps,&opi);CHKERRQ(ierr); ierr = PetscOptionsInt("-eps_jd_initial_size","Set the initial size of the searching subspace","EPSJDSetInitialSize",opi,&opi,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSJDSetInitialSize(eps,opi);CHKERRQ(ierr); } ierr = EPSJDGetFix(eps,&opf);CHKERRQ(ierr); ierr = PetscOptionsReal("-eps_jd_fix","Set the tolerance for changing the target in the correction equation","EPSJDSetFix",opf,&opf,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSJDSetFix(eps,opf);CHKERRQ(ierr); } ierr = EPSJDGetBOrth(eps,&orth);CHKERRQ(ierr); ierr = PetscOptionsEList("-eps_jd_borth","orthogonalization used in the search subspace","EPSJDSetBOrth",orth_list,2,orth_list[orth?1:0],&opi,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSJDSetBOrth(eps,opi==1?PETSC_TRUE:PETSC_FALSE);CHKERRQ(ierr); } ierr = EPSJDGetConstCorrectionTol(eps,&op);CHKERRQ(ierr); ierr = PetscOptionsBool("-eps_jd_const_correction_tol","Disable the dynamic stopping criterion when solving the correction equation","EPSJDSetConstCorrectionTol",op,&op,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSJDSetConstCorrectionTol(eps,op);CHKERRQ(ierr); } ierr = EPSJDGetWindowSizes(eps,&opi,&opi0);CHKERRQ(ierr); ierr = PetscOptionsInt("-eps_jd_pwindow","(Experimental!) Set the number of converged vectors in the projector","EPSJDSetWindowSizes",opi,&opi,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSJDSetWindowSizes(eps,opi,opi0);CHKERRQ(ierr); } ierr = PetscOptionsInt("-eps_jd_qwindow","(Experimental!) Set the number of converged vectors in the projected problem","EPSJDSetWindowSizes",opi0,&opi0,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSJDSetWindowSizes(eps,opi,opi0);CHKERRQ(ierr); } /* Set STPrecond as the default ST */ if (!((PetscObject)eps->st)->type_name) { ierr = STSetType(eps->st,STPRECOND);CHKERRQ(ierr); } ierr = STPrecondSetKSPHasMat(eps->st,PETSC_FALSE);CHKERRQ(ierr); /* Set the default options of the KSP */ ierr = STGetKSP(eps->st,&ksp);CHKERRQ(ierr); if (!((PetscObject)ksp)->type_name) { ierr = KSPSetType(ksp,KSPBCGSL);CHKERRQ(ierr); ierr = KSPSetTolerances(ksp,1e-4,PETSC_DEFAULT,PETSC_DEFAULT,90);CHKERRQ(ierr); } ierr = PetscOptionsTail();CHKERRQ(ierr); PetscFunctionReturn(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,B,C,D,mat[4]; ST st; Vec v,w; STType type; PetscScalar value[3],sigma; PetscInt n=10,i,Istart,Iend,col[3]; 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 plus diagonal, n=%D\n\n",n);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Compute the operator matrix for the 1-D Laplacian - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 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 = MatCreate(PETSC_COMM_WORLD,&B);CHKERRQ(ierr); ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr); ierr = MatSetFromOptions(B);CHKERRQ(ierr); ierr = MatSetUp(B);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&C);CHKERRQ(ierr); ierr = MatSetSizes(C,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr); ierr = MatSetFromOptions(C);CHKERRQ(ierr); ierr = MatSetUp(C);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&D);CHKERRQ(ierr); ierr = MatSetSizes(D,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr); ierr = MatSetFromOptions(D);CHKERRQ(ierr); ierr = MatSetUp(D);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); ierr = MatSetValue(B,i,i,(PetscScalar)i,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); ierr = MatSetValue(B,i,i,(PetscScalar)i,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 = MatSetValue(B,i,i,-1.0,INSERT_VALUES);CHKERRQ(ierr); } for (i=Istart;i<Iend;i++) { ierr = MatSetValue(C,i,n-i-1,1.0,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValue(D,i,i,i*.1,INSERT_VALUES);CHKERRQ(ierr); if (i==0) { ierr = MatSetValue(D,0,n-1,1.0,INSERT_VALUES);CHKERRQ(ierr); } if (i==n-1) { ierr = MatSetValue(D,n-1,0,1.0,INSERT_VALUES);CHKERRQ(ierr); } } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyBegin(D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatGetVecs(A,&v,&w);CHKERRQ(ierr); ierr = VecSet(v,1.0);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the spectral transformation object - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = STCreate(PETSC_COMM_WORLD,&st);CHKERRQ(ierr); mat[0] = A; mat[1] = B; mat[2] = C; mat[3] = D; ierr = STSetOperators(st,4,mat);CHKERRQ(ierr); ierr = STSetFromOptions(st);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apply the transformed operator for several ST's - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* shift, sigma=0.0 */ ierr = STSetUp(st);CHKERRQ(ierr); ierr = STGetType(st,&type);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"ST type %s\n",type);CHKERRQ(ierr); for (i=0;i<4;i++) { ierr = STMatMult(st,i,v,w); ierr = PetscPrintf(PETSC_COMM_WORLD,"k= %D\n",i);CHKERRQ(ierr); ierr = VecView(w,NULL);CHKERRQ(ierr); } ierr = STMatSolve(st,v,w); ierr = PetscPrintf(PETSC_COMM_WORLD,"solve\n");CHKERRQ(ierr); ierr = VecView(w,NULL);CHKERRQ(ierr); /* shift, sigma=0.1 */ sigma = 0.1; ierr = STSetShift(st,sigma);CHKERRQ(ierr); ierr = STGetShift(st,&sigma);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"With shift=%g\n",(double)PetscRealPart(sigma));CHKERRQ(ierr); for (i=0;i<4;i++) { ierr = STMatMult(st,i,v,w); ierr = PetscPrintf(PETSC_COMM_WORLD,"k= %D\n",i);CHKERRQ(ierr); ierr = VecView(w,NULL);CHKERRQ(ierr); } ierr = STMatSolve(st,v,w); ierr = PetscPrintf(PETSC_COMM_WORLD,"solve\n");CHKERRQ(ierr); ierr = VecView(w,NULL);CHKERRQ(ierr); /* sinvert, sigma=0.1 */ ierr = STPostSolve(st);CHKERRQ(ierr); ierr = STSetType(st,STSINVERT);CHKERRQ(ierr); ierr = STGetType(st,&type);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"ST type %s\n",type);CHKERRQ(ierr); ierr = STGetShift(st,&sigma);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"With shift=%g\n",(double)PetscRealPart(sigma));CHKERRQ(ierr); for (i=0;i<4;i++) { ierr = STMatMult(st,i,v,w); ierr = PetscPrintf(PETSC_COMM_WORLD,"k= %D\n",i);CHKERRQ(ierr); ierr = VecView(w,NULL);CHKERRQ(ierr); } ierr = STMatSolve(st,v,w); ierr = PetscPrintf(PETSC_COMM_WORLD,"solve\n");CHKERRQ(ierr); ierr = VecView(w,NULL);CHKERRQ(ierr); /* sinvert, sigma=-0.5 */ sigma = -0.5; ierr = STSetShift(st,sigma);CHKERRQ(ierr); ierr = STGetShift(st,&sigma);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"With shift=%g\n",(double)PetscRealPart(sigma));CHKERRQ(ierr); for (i=0;i<4;i++) { ierr = STMatMult(st,i,v,w); ierr = PetscPrintf(PETSC_COMM_WORLD,"k= %D\n",i);CHKERRQ(ierr); ierr = VecView(w,NULL);CHKERRQ(ierr); } ierr = STMatSolve(st,v,w); ierr = PetscPrintf(PETSC_COMM_WORLD,"solve\n");CHKERRQ(ierr); ierr = VecView(w,NULL);CHKERRQ(ierr); ierr = STDestroy(&st);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = MatDestroy(&D);CHKERRQ(ierr); ierr = VecDestroy(&v);CHKERRQ(ierr); ierr = VecDestroy(&w);CHKERRQ(ierr); ierr = SlepcFinalize(); return 0; }
#define stgettype_ stgettype #define stcreate_ stcreate #define stdestroy_ stdestroy #define stsetoptionsprefix_ stsetoptionsprefix #define stappendoptionsprefix_ stappendoptionsprefix #define stgetoptionsprefix_ stgetoptionsprefix #define stview_ stview #define stgetmatmode_ stgetmatmode #endif PETSC_EXTERN void PETSC_STDCALL stsettype_(ST *st,CHAR type PETSC_MIXED_LEN(len),PetscErrorCode *ierr PETSC_END_LEN(len)) { char *t; FIXCHAR(type,len,t); *ierr = STSetType(*st,t); FREECHAR(type,t); } PETSC_EXTERN void PETSC_STDCALL stgettype_(ST *st,CHAR name PETSC_MIXED_LEN(len),PetscErrorCode *ierr PETSC_END_LEN(len)) { STType tname; *ierr = STGetType(*st,&tname); if (*ierr) return; *ierr = PetscStrncpy(name,tname,len); FIXRETURNCHAR(PETSC_TRUE,name,len); } PETSC_EXTERN void PETSC_STDCALL stcreate_(MPI_Fint *comm,ST *newst,PetscErrorCode *ierr) { *ierr = STCreate(MPI_Comm_f2c(*(comm)),newst);
PetscErrorCode EPSSetUp_XD(EPS eps) { PetscErrorCode ierr; EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data; dvdDashboard *dvd = &data->ddb; dvdBlackboard b; PetscInt min_size_V,plusk,bs,initv,i,cX_in_proj,cX_in_impr,nmat; Mat A,B; KSP ksp; PetscBool t,ipB,ispositive,dynamic; HarmType_t harm; InitType_t init; PetscReal fix; PetscScalar target; PetscFunctionBegin; /* Setup EPS options and get the problem specification */ ierr = EPSXDGetBlockSize_XD(eps,&bs);CHKERRQ(ierr); if (bs <= 0) bs = 1; if (eps->ncv) { if (eps->ncv<eps->nev) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"The value of ncv must be at least nev"); } else if (eps->mpd) eps->ncv = eps->mpd + eps->nev + bs; else if (eps->nev<500) eps->ncv = PetscMin(eps->n-bs,PetscMax(2*eps->nev,eps->nev+15))+bs; else eps->ncv = PetscMin(eps->n-bs,eps->nev+500)+bs; if (!eps->mpd) eps->mpd = eps->ncv; if (eps->mpd > eps->ncv) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"The mpd has to be less or equal than ncv"); if (eps->mpd < 2) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"The mpd has to be greater than 2"); if (!eps->max_it) eps->max_it = PetscMax(100*eps->ncv,2*eps->n); if (!eps->which) eps->which = EPS_LARGEST_MAGNITUDE; if (eps->ishermitian && (eps->which==EPS_LARGEST_IMAGINARY || eps->which==EPS_SMALLEST_IMAGINARY)) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Wrong value of eps->which"); if (!(eps->nev + bs <= eps->ncv)) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"The ncv has to be greater than nev plus blocksize"); if (eps->trueres) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"-eps_true_residual is temporally disable in this solver."); ierr = EPSXDGetRestart_XD(eps,&min_size_V,&plusk);CHKERRQ(ierr); if (!min_size_V) min_size_V = PetscMin(PetscMax(bs,5),eps->mpd/2); if (!(min_size_V+bs <= eps->mpd)) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"The value of minv must be less than mpd minus blocksize"); ierr = EPSXDGetInitialSize_XD(eps,&initv);CHKERRQ(ierr); if (eps->mpd < initv) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"The initv has to be less or equal than mpd"); /* Set STPrecond as the default ST */ if (!((PetscObject)eps->st)->type_name) { ierr = STSetType(eps->st,STPRECOND);CHKERRQ(ierr); } ierr = STPrecondSetKSPHasMat(eps->st,PETSC_FALSE);CHKERRQ(ierr); /* Change the default sigma to inf if necessary */ if (eps->which == EPS_LARGEST_MAGNITUDE || eps->which == EPS_LARGEST_REAL || eps->which == EPS_LARGEST_IMAGINARY) { ierr = STSetDefaultShift(eps->st,PETSC_MAX_REAL);CHKERRQ(ierr); } /* Davidson solvers only support STPRECOND */ ierr = STSetUp(eps->st);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)eps->st,STPRECOND,&t);CHKERRQ(ierr); if (!t) SETERRQ1(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"%s only works with precond spectral transformation", ((PetscObject)eps)->type_name); /* Setup problem specification in dvd */ ierr = STGetNumMatrices(eps->st,&nmat);CHKERRQ(ierr); ierr = STGetOperators(eps->st,0,&A);CHKERRQ(ierr); if (nmat>1) { ierr = STGetOperators(eps->st,1,&B);CHKERRQ(ierr); } ierr = EPSReset_XD(eps);CHKERRQ(ierr); ierr = PetscMemzero(dvd,sizeof(dvdDashboard));CHKERRQ(ierr); dvd->A = A; dvd->B = eps->isgeneralized? B : NULL; ispositive = eps->ispositive; dvd->sA = DVD_MAT_IMPLICIT | (eps->ishermitian? DVD_MAT_HERMITIAN : 0) | ((ispositive && !eps->isgeneralized) ? DVD_MAT_POS_DEF : 0); /* Asume -eps_hermitian means hermitian-definite in generalized problems */ if (!ispositive && !eps->isgeneralized && eps->ishermitian) ispositive = PETSC_TRUE; if (!eps->isgeneralized) dvd->sB = DVD_MAT_IMPLICIT | DVD_MAT_HERMITIAN | DVD_MAT_IDENTITY | DVD_MAT_UNITARY | DVD_MAT_POS_DEF; else dvd->sB = DVD_MAT_IMPLICIT | (eps->ishermitian? DVD_MAT_HERMITIAN : 0) | (ispositive? DVD_MAT_POS_DEF : 0); ipB = (dvd->B && data->ipB && DVD_IS(dvd->sB,DVD_MAT_HERMITIAN))?PETSC_TRUE:PETSC_FALSE; if (data->ipB && !ipB) data->ipB = PETSC_FALSE; dvd->correctXnorm = ipB; dvd->sEP = ((!eps->isgeneralized || (eps->isgeneralized && ipB))? DVD_EP_STD : 0) | (ispositive? DVD_EP_HERMITIAN : 0) | ((eps->problem_type == EPS_GHIEP && ipB) ? DVD_EP_INDEFINITE : 0); dvd->nev = eps->nev; dvd->which = eps->which; dvd->withTarget = PETSC_TRUE; switch (eps->which) { case EPS_TARGET_MAGNITUDE: case EPS_TARGET_IMAGINARY: dvd->target[0] = target = eps->target; dvd->target[1] = 1.0; break; case EPS_TARGET_REAL: dvd->target[0] = PetscRealPart(target = eps->target); dvd->target[1] = 1.0; break; case EPS_LARGEST_REAL: case EPS_LARGEST_MAGNITUDE: case EPS_LARGEST_IMAGINARY: /* TODO: think about this case */ dvd->target[0] = 1.0; dvd->target[1] = target = 0.0; break; case EPS_SMALLEST_MAGNITUDE: case EPS_SMALLEST_REAL: case EPS_SMALLEST_IMAGINARY: /* TODO: think about this case */ dvd->target[0] = target = 0.0; dvd->target[1] = 1.0; break; case EPS_WHICH_USER: ierr = STGetShift(eps->st,&target);CHKERRQ(ierr); dvd->target[0] = target; dvd->target[1] = 1.0; break; case EPS_ALL: SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Unsupported option: which == EPS_ALL"); break; default: SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Unsupported value of option 'which'"); } dvd->tol = eps->tol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL:eps->tol; dvd->eps = eps; /* Setup the extraction technique */ if (!eps->extraction) { if (ipB || ispositive) eps->extraction = EPS_RITZ; else { switch (eps->which) { case EPS_TARGET_REAL: case EPS_TARGET_MAGNITUDE: case EPS_TARGET_IMAGINARY: case EPS_SMALLEST_MAGNITUDE: case EPS_SMALLEST_REAL: case EPS_SMALLEST_IMAGINARY: eps->extraction = EPS_HARMONIC; break; case EPS_LARGEST_REAL: case EPS_LARGEST_MAGNITUDE: case EPS_LARGEST_IMAGINARY: eps->extraction = EPS_HARMONIC_LARGEST; break; default: eps->extraction = EPS_RITZ; } } } switch (eps->extraction) { case EPS_RITZ: harm = DVD_HARM_NONE; break; case EPS_HARMONIC: harm = DVD_HARM_RR; break; case EPS_HARMONIC_RELATIVE: harm = DVD_HARM_RRR; break; case EPS_HARMONIC_RIGHT: harm = DVD_HARM_REIGS; break; case EPS_HARMONIC_LARGEST: harm = DVD_HARM_LEIGS; break; default: SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Unsupported extraction type"); } /* Setup the type of starting subspace */ ierr = EPSXDGetKrylovStart_XD(eps,&t);CHKERRQ(ierr); init = (!t)? DVD_INITV_CLASSIC : DVD_INITV_KRYLOV; /* Setup the presence of converged vectors in the projected problem and in the projector */ ierr = EPSXDGetWindowSizes_XD(eps,&cX_in_impr,&cX_in_proj);CHKERRQ(ierr); if (cX_in_impr>0) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"The option pwindow is temporally disable in this solver."); if (cX_in_proj>0) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"The option qwindow is temporally disable in this solver."); if (min_size_V <= cX_in_proj) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"minv has to be greater than qwindow"); if (bs > 1 && cX_in_impr > 0) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Unsupported option: pwindow > 0 and bs > 1"); /* Get the fix parameter */ ierr = EPSXDGetFix_XD(eps,&fix);CHKERRQ(ierr); /* Get whether the stopping criterion is used */ ierr = EPSJDGetConstCorrectionTol_JD(eps,&dynamic);CHKERRQ(ierr); /* Preconfigure dvd */ ierr = STGetKSP(eps->st,&ksp);CHKERRQ(ierr); ierr = dvd_schm_basic_preconf(dvd,&b,eps->mpd,min_size_V,bs, initv, PetscAbs(eps->nini), plusk,harm, ksp,init,eps->trackall, data->ipB,cX_in_proj,cX_in_impr, data->scheme);CHKERRQ(ierr); /* Allocate memory */ ierr = EPSAllocateSolution(eps,0);CHKERRQ(ierr); /* Setup orthogonalization */ ierr = EPS_SetInnerProduct(eps);CHKERRQ(ierr); if (!(ipB && dvd->B)) { ierr = BVSetMatrix(eps->V,NULL,PETSC_FALSE);CHKERRQ(ierr); } for (i=0;i<eps->ncv;i++) eps->perm[i] = i; /* Configure dvd for a basic GD */ ierr = dvd_schm_basic_conf(dvd,&b,eps->mpd,min_size_V,bs, initv, PetscAbs(eps->nini),plusk, harm,dvd->withTarget, target,ksp, fix,init,eps->trackall, data->ipB,cX_in_proj,cX_in_impr,dynamic, data->scheme);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { Mat A,B,M,mat[2]; ST st; Vec v,w; STType type; PetscScalar value[3],sigma,tau; PetscInt n=10,i,Istart,Iend,col[3]; 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 plus diagonal, n=%D\n\n",n);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Compute the operator matrix for the 1-D Laplacian - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 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 = MatCreate(PETSC_COMM_WORLD,&B);CHKERRQ(ierr); ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr); ierr = MatSetFromOptions(B);CHKERRQ(ierr); ierr = MatSetUp(B);CHKERRQ(ierr); ierr = MatGetOwnershipRange(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); ierr = MatSetValue(B,i,i,(PetscScalar)i,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); ierr = MatSetValue(B,i,i,(PetscScalar)i,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 = MatSetValue(B,i,i,-1.0,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatGetVecs(A,&v,&w);CHKERRQ(ierr); ierr = VecSet(v,1.0);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the spectral transformation object - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = STCreate(PETSC_COMM_WORLD,&st);CHKERRQ(ierr); mat[0] = A; mat[1] = B; ierr = STSetOperators(st,2,mat);CHKERRQ(ierr); ierr = STSetFromOptions(st);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Apply the transformed operator for several ST's - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* shift, sigma=0.0 */ ierr = STSetUp(st);CHKERRQ(ierr); ierr = STGetType(st,&type);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"ST type %s\n",type);CHKERRQ(ierr); ierr = STApply(st,v,w);CHKERRQ(ierr); ierr = VecView(w,NULL);CHKERRQ(ierr); /* shift, sigma=0.1 */ sigma = 0.1; ierr = STSetShift(st,sigma);CHKERRQ(ierr); ierr = STGetShift(st,&sigma);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"With shift=%g\n",(double)PetscRealPart(sigma));CHKERRQ(ierr); ierr = STApply(st,v,w);CHKERRQ(ierr); ierr = VecView(w,NULL);CHKERRQ(ierr); /* sinvert, sigma=0.1 */ ierr = STPostSolve(st);CHKERRQ(ierr); /* undo changes if inplace */ ierr = STSetType(st,STSINVERT);CHKERRQ(ierr); ierr = STGetType(st,&type);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"ST type %s\n",type);CHKERRQ(ierr); ierr = STGetShift(st,&sigma);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"With shift=%g\n",(double)PetscRealPart(sigma));CHKERRQ(ierr); ierr = STApply(st,v,w);CHKERRQ(ierr); ierr = VecView(w,NULL);CHKERRQ(ierr); /* sinvert, sigma=-0.5 */ sigma = -0.5; ierr = STSetShift(st,sigma);CHKERRQ(ierr); ierr = STGetShift(st,&sigma);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"With shift=%g\n",(double)PetscRealPart(sigma));CHKERRQ(ierr); ierr = STApply(st,v,w);CHKERRQ(ierr); ierr = VecView(w,NULL);CHKERRQ(ierr); /* cayley, sigma=-0.5, tau=-0.5 (equal to sigma by default) */ ierr = STPostSolve(st);CHKERRQ(ierr); /* undo changes if inplace */ ierr = STSetType(st,STCAYLEY);CHKERRQ(ierr); ierr = STSetUp(st);CHKERRQ(ierr); ierr = STGetType(st,&type);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"ST type %s\n",type);CHKERRQ(ierr); ierr = STGetShift(st,&sigma);CHKERRQ(ierr); ierr = STCayleyGetAntishift(st,&tau);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"With shift=%g, antishift=%g\n",(double)PetscRealPart(sigma),(double)PetscRealPart(tau));CHKERRQ(ierr); ierr = STApply(st,v,w);CHKERRQ(ierr); ierr = VecView(w,NULL);CHKERRQ(ierr); /* cayley, sigma=1.1, tau=1.1 (still equal to sigma) */ sigma = 1.1; ierr = STSetShift(st,sigma);CHKERRQ(ierr); ierr = STGetShift(st,&sigma);CHKERRQ(ierr); ierr = STCayleyGetAntishift(st,&tau);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"With shift=%g, antishift=%g\n",(double)PetscRealPart(sigma),(double)PetscRealPart(tau));CHKERRQ(ierr); ierr = STApply(st,v,w);CHKERRQ(ierr); ierr = VecView(w,NULL);CHKERRQ(ierr); /* cayley, sigma=1.1, tau=-1.0 */ tau = -1.0; ierr = STCayleySetAntishift(st,tau);CHKERRQ(ierr); ierr = STGetShift(st,&sigma);CHKERRQ(ierr); ierr = STCayleyGetAntishift(st,&tau);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"With shift=%g, antishift=%g\n",(double)PetscRealPart(sigma),(double)PetscRealPart(tau));CHKERRQ(ierr); ierr = STApply(st,v,w);CHKERRQ(ierr); ierr = VecView(w,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Check inner product matrix in Cayley - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = STGetBilinearForm(st,&M);CHKERRQ(ierr); ierr = MatMult(M,v,w);CHKERRQ(ierr); ierr = VecView(w,NULL);CHKERRQ(ierr); ierr = STDestroy(&st);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = MatDestroy(&M);CHKERRQ(ierr); ierr = VecDestroy(&v);CHKERRQ(ierr); ierr = VecDestroy(&w);CHKERRQ(ierr); ierr = SlepcFinalize(); return 0; }