PetscErrorCode EPSGetArbitraryValues(EPS eps,PetscScalar *rr,PetscScalar *ri) { PetscErrorCode ierr; PetscInt i,newi,ld,n,l; Vec xr=eps->work[0],xi=eps->work[1]; PetscScalar re,im,*Zr,*Zi,*X; PetscFunctionBegin; ierr = DSGetLeadingDimension(eps->ds,&ld);CHKERRQ(ierr); ierr = DSGetDimensions(eps->ds,&n,NULL,&l,NULL,NULL);CHKERRQ(ierr); for (i=l;i<n;i++) { re = eps->eigr[i]; im = eps->eigi[i]; ierr = STBackTransform(eps->st,1,&re,&im);CHKERRQ(ierr); newi = i; ierr = DSVectors(eps->ds,DS_MAT_X,&newi,NULL);CHKERRQ(ierr); ierr = DSGetArray(eps->ds,DS_MAT_X,&X);CHKERRQ(ierr); Zr = X+i*ld; if (newi==i+1) Zi = X+newi*ld; else Zi = NULL; ierr = EPSComputeRitzVector(eps,Zr,Zi,eps->V,xr,xi);CHKERRQ(ierr); ierr = DSRestoreArray(eps->ds,DS_MAT_X,&X);CHKERRQ(ierr); ierr = (*eps->arbitrary)(re,im,xr,xi,rr+i,ri+i,eps->arbitraryctx);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscErrorCode EPSMonitor_Linear(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *ctx) { PetscInt i; PEP pep = (PEP)ctx; ST st; PetscErrorCode ierr; PetscFunctionBegin; for (i=0;i<PetscMin(nest,pep->ncv);i++) { pep->eigr[i] = eigr[i]; pep->eigi[i] = eigi[i]; pep->errest[i] = errest[i]; } ierr = EPSGetST(eps,&st);CHKERRQ(ierr); ierr = STBackTransform(st,nest,pep->eigr,pep->eigi);CHKERRQ(ierr); ierr = PEPMonitor(pep,its,nconv,pep->eigr,pep->eigi,pep->errest,nest);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* PEPKrylovConvergence - This is the analogue to EPSKrylovConvergence, but for polynomial Krylov methods. Differences: - Always non-symmetric - Does not check for STSHIFT - No correction factor - No support for true residual */ PetscErrorCode PEPKrylovConvergence(PEP pep,PetscBool getall,PetscInt kini,PetscInt nits,PetscReal beta,PetscInt *kout) { PetscErrorCode ierr; PetscInt k,newk,marker,ld,inside; PetscScalar re,im; PetscReal resnorm; PetscBool istrivial; PetscFunctionBegin; ierr = RGIsTrivial(pep->rg,&istrivial);CHKERRQ(ierr); ierr = DSGetLeadingDimension(pep->ds,&ld);CHKERRQ(ierr); marker = -1; if (pep->trackall) getall = PETSC_TRUE; for (k=kini;k<kini+nits;k++) { /* eigenvalue */ re = pep->eigr[k]; im = pep->eigi[k]; if (!istrivial || pep->conv==PEP_CONV_NORM) { ierr = STBackTransform(pep->st,1,&re,&im);CHKERRQ(ierr); } if (!istrivial) { ierr = RGCheckInside(pep->rg,1,&re,&im,&inside);CHKERRQ(ierr); if (marker==-1 && inside<=0) marker = k; if (!pep->conv==PEP_CONV_NORM) { /* make sure pep->converged below uses the right value */ re = pep->eigr[k]; im = pep->eigi[k]; } } newk = k; ierr = DSVectors(pep->ds,DS_MAT_X,&newk,&resnorm);CHKERRQ(ierr); resnorm *= beta; /* error estimate */ ierr = (*pep->converged)(pep,re,im,resnorm,&pep->errest[k],pep->convergedctx);CHKERRQ(ierr); if (marker==-1 && pep->errest[k] >= pep->tol) marker = k; if (newk==k+1) { pep->errest[k+1] = pep->errest[k]; k++; } if (marker!=-1 && !getall) break; } if (marker!=-1) k = marker; *kout = k; PetscFunctionReturn(0); }
/*@ PEPSolve - Solves the polynomial eigensystem. Collective on PEP Input Parameter: . pep - eigensolver context obtained from PEPCreate() Options Database Keys: + -pep_view - print information about the solver used - -pep_plot_eigs - plot computed eigenvalues Level: beginner .seealso: PEPCreate(), PEPSetUp(), PEPDestroy(), PEPSetTolerances() @*/ PetscErrorCode PEPSolve(PEP pep) { PetscErrorCode ierr; PetscInt i; PetscReal re,im; PetscBool flg,islinear; PetscViewer viewer; PetscViewerFormat format; PetscDraw draw; PetscDrawSP drawsp; PetscFunctionBegin; PetscValidHeaderSpecific(pep,PEP_CLASSID,1); ierr = PetscLogEventBegin(PEP_Solve,pep,0,0,0);CHKERRQ(ierr); /* call setup */ ierr = PEPSetUp(pep);CHKERRQ(ierr); pep->nconv = 0; pep->its = 0; for (i=0;i<pep->ncv;i++) { pep->eigr[i] = 0.0; pep->eigi[i] = 0.0; pep->errest[i] = 0.0; } ierr = PEPMonitor(pep,pep->its,pep->nconv,pep->eigr,pep->eigi,pep->errest,pep->ncv);CHKERRQ(ierr); ierr = (*pep->ops->solve)(pep);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)pep,PEPLINEAR,&islinear);CHKERRQ(ierr); if (!islinear) { ierr = STPostSolve(pep->st);CHKERRQ(ierr); } if (!pep->reason) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); if (!islinear) { /* Map eigenvalues back to the original problem */ ierr = STGetTransform(pep->st,&flg);CHKERRQ(ierr); if (flg) { ierr = STBackTransform(pep->st,pep->nconv,pep->eigr,pep->eigi);CHKERRQ(ierr); } } pep->state = PEP_STATE_SOLVED; if (pep->refine==PEP_REFINE_SIMPLE && pep->rits>0) { ierr = PEPComputeVectors(pep);CHKERRQ(ierr); ierr = PEPNewtonRefinementSimple(pep,&pep->rits,&pep->rtol,pep->nconv);CHKERRQ(ierr); pep->state = PEP_STATE_EIGENVECTORS; } #if !defined(PETSC_USE_COMPLEX) /* reorder conjugate eigenvalues (positive imaginary first) */ for (i=0;i<pep->nconv-1;i++) { if (pep->eigi[i] != 0) { if (pep->eigi[i] < 0) { pep->eigi[i] = -pep->eigi[i]; pep->eigi[i+1] = -pep->eigi[i+1]; /* the next correction only works with eigenvectors */ ierr = PEPComputeVectors(pep);CHKERRQ(ierr); ierr = BVScaleColumn(pep->V,i+1,-1.0);CHKERRQ(ierr); } i++; } } #endif /* sort eigenvalues according to pep->which parameter */ ierr = SlepcSortEigenvalues(pep->sc,pep->nconv,pep->eigr,pep->eigi,pep->perm);CHKERRQ(ierr); ierr = PetscLogEventEnd(PEP_Solve,pep,0,0,0);CHKERRQ(ierr); /* various viewers */ ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)pep),((PetscObject)pep)->prefix,"-pep_view",&viewer,&format,&flg);CHKERRQ(ierr); if (flg && !PetscPreLoadingOn) { ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); ierr = PEPView(pep,viewer);CHKERRQ(ierr); ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsGetBool(((PetscObject)pep)->prefix,"-pep_plot_eigs",&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = PetscViewerDrawOpen(PETSC_COMM_SELF,0,"Computed Eigenvalues",PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);CHKERRQ(ierr); ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); ierr = PetscDrawSPCreate(draw,1,&drawsp);CHKERRQ(ierr); for (i=0;i<pep->nconv;i++) { #if defined(PETSC_USE_COMPLEX) re = PetscRealPart(pep->eigr[i]); im = PetscImaginaryPart(pep->eigi[i]); #else re = pep->eigr[i]; im = pep->eigi[i]; #endif ierr = PetscDrawSPAddPoint(drawsp,&re,&im);CHKERRQ(ierr); } ierr = PetscDrawSPDraw(drawsp,PETSC_TRUE);CHKERRQ(ierr); ierr = PetscDrawSPDestroy(&drawsp);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } /* Remove the initial subspace */ pep->nini = 0; PetscFunctionReturn(0); }