PetscErrorCode EPSSolve_LAPACK(EPS eps) { PetscErrorCode ierr; PetscInt n=eps->n,i,low,high; PetscScalar *array,*pX; Vec v; PetscFunctionBegin; ierr = DSSolve(eps->ds,eps->eigr,eps->eigi);CHKERRQ(ierr); ierr = DSSort(eps->ds,eps->eigr,eps->eigi,NULL,NULL,NULL);CHKERRQ(ierr); /* right eigenvectors */ ierr = DSVectors(eps->ds,DS_MAT_X,NULL,NULL);CHKERRQ(ierr); ierr = DSGetArray(eps->ds,DS_MAT_X,&pX);CHKERRQ(ierr); for (i=0;i<eps->ncv;i++) { ierr = BVGetColumn(eps->V,i,&v);CHKERRQ(ierr); ierr = VecGetOwnershipRange(v,&low,&high);CHKERRQ(ierr); ierr = VecGetArray(v,&array);CHKERRQ(ierr); ierr = PetscMemcpy(array,pX+i*n+low,(high-low)*sizeof(PetscScalar));CHKERRQ(ierr); ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); ierr = BVRestoreColumn(eps->V,i,&v);CHKERRQ(ierr); } ierr = DSRestoreArray(eps->ds,DS_MAT_X,&pX);CHKERRQ(ierr); eps->nconv = eps->ncv; eps->its = 1; eps->reason = EPS_CONVERGED_TOL; PetscFunctionReturn(0); }
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); }
PetscErrorCode PEPComputeVectors_Schur(PEP pep) { PetscErrorCode ierr; PetscInt n,i; Mat Z; Vec v; #if !defined(PETSC_USE_COMPLEX) Vec v1; PetscScalar tmp; PetscReal norm,normi; #endif PetscFunctionBegin; ierr = DSGetDimensions(pep->ds,&n,NULL,NULL,NULL,NULL);CHKERRQ(ierr); ierr = DSVectors(pep->ds,DS_MAT_X,NULL,NULL);CHKERRQ(ierr); ierr = DSGetMat(pep->ds,DS_MAT_X,&Z);CHKERRQ(ierr); ierr = BVSetActiveColumns(pep->V,0,n);CHKERRQ(ierr); ierr = BVMultInPlace(pep->V,Z,0,n);CHKERRQ(ierr); ierr = MatDestroy(&Z);CHKERRQ(ierr); /* Fix eigenvectors if balancing was used */ if ((pep->scale==PEP_SCALE_DIAGONAL || pep->scale==PEP_SCALE_BOTH) && pep->Dr && (pep->refine!=PEP_REFINE_MULTIPLE)) { for (i=0;i<n;i++) { ierr = BVGetColumn(pep->V,i,&v);CHKERRQ(ierr); ierr = VecPointwiseMult(v,v,pep->Dr);CHKERRQ(ierr); ierr = BVRestoreColumn(pep->V,i,&v);CHKERRQ(ierr); } } /* normalization */ for (i=0;i<n;i++) { #if !defined(PETSC_USE_COMPLEX) if (pep->eigi[i] != 0.0) { ierr = BVGetColumn(pep->V,i,&v);CHKERRQ(ierr); ierr = BVGetColumn(pep->V,i+1,&v1);CHKERRQ(ierr); ierr = VecNorm(v,NORM_2,&norm);CHKERRQ(ierr); ierr = VecNorm(v1,NORM_2,&normi);CHKERRQ(ierr); tmp = 1.0 / SlepcAbsEigenvalue(norm,normi); ierr = VecScale(v,tmp);CHKERRQ(ierr); ierr = VecScale(v1,tmp);CHKERRQ(ierr); ierr = BVRestoreColumn(pep->V,i,&v);CHKERRQ(ierr); ierr = BVRestoreColumn(pep->V,i+1,&v1);CHKERRQ(ierr); i++; } else #endif { ierr = BVGetColumn(pep->V,i,&v);CHKERRQ(ierr); ierr = VecNormalize(v,NULL);CHKERRQ(ierr); ierr = BVRestoreColumn(pep->V,i,&v);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); }
PetscErrorCode PEPComputeVectors_Indefinite(PEP pep) { PetscErrorCode ierr; PetscInt n,i; Mat Z; Vec v; #if !defined(PETSC_USE_COMPLEX) Vec v1; PetscScalar tmp; PetscReal norm,normi; #endif PetscFunctionBegin; ierr = DSGetDimensions(pep->ds,&n,NULL,NULL,NULL,NULL);CHKERRQ(ierr); ierr = DSVectors(pep->ds,DS_MAT_X,NULL,NULL);CHKERRQ(ierr); ierr = DSGetMat(pep->ds,DS_MAT_X,&Z);CHKERRQ(ierr); ierr = BVSetActiveColumns(pep->V,0,n);CHKERRQ(ierr); ierr = BVMultInPlace(pep->V,Z,0,n);CHKERRQ(ierr); ierr = MatDestroy(&Z);CHKERRQ(ierr); /* normalization */ for (i=0;i<n;i++) { #if !defined(PETSC_USE_COMPLEX) if (pep->eigi[i] != 0.0) { ierr = BVGetColumn(pep->V,i,&v);CHKERRQ(ierr); ierr = BVGetColumn(pep->V,i+1,&v1);CHKERRQ(ierr); ierr = VecNorm(v,NORM_2,&norm);CHKERRQ(ierr); ierr = VecNorm(v1,NORM_2,&normi);CHKERRQ(ierr); tmp = 1.0 / SlepcAbsEigenvalue(norm,normi); ierr = VecScale(v,tmp);CHKERRQ(ierr); ierr = VecScale(v1,tmp);CHKERRQ(ierr); ierr = BVRestoreColumn(pep->V,i,&v);CHKERRQ(ierr); ierr = BVRestoreColumn(pep->V,i+1,&v1);CHKERRQ(ierr); i++; } else #endif { ierr = BVGetColumn(pep->V,i,&v);CHKERRQ(ierr); ierr = VecNormalize(v,NULL);CHKERRQ(ierr); ierr = BVRestoreColumn(pep->V,i,&v);CHKERRQ(ierr); } } PetscFunctionReturn(0); }
/* EPSComputeVectors_XD - Compute eigenvectors from the vectors provided by the eigensolver. This version is intended for solvers that provide Schur vectors from the QZ decomposition. Given the partial Schur decomposition OP*V=V*T, the following steps are performed: 1) compute eigenvectors of (S,T): S*Z=T*Z*D 2) compute eigenvectors of OP: X=V*Z */ PetscErrorCode EPSComputeVectors_XD(EPS eps) { PetscErrorCode ierr; Mat X; PetscBool symm; PetscFunctionBegin; ierr = PetscObjectTypeCompareAny((PetscObject)eps->ds,&symm,DSHEP,"");CHKERRQ(ierr); if (symm) PetscFunctionReturn(0); ierr = DSVectors(eps->ds,DS_MAT_X,NULL,NULL);CHKERRQ(ierr); ierr = DSNormalize(eps->ds,DS_MAT_X,-1);CHKERRQ(ierr); /* V <- V * X */ ierr = DSGetMat(eps->ds,DS_MAT_X,&X);CHKERRQ(ierr); ierr = BVSetActiveColumns(eps->V,0,eps->nconv);CHKERRQ(ierr); ierr = BVMultInPlace(eps->V,X,0,eps->nconv);CHKERRQ(ierr); ierr = DSRestoreMat(eps->ds,DS_MAT_X,&X);CHKERRQ(ierr); PetscFunctionReturn(0); }