/* PEPComputeScaleFactor - compute sfactor as described in [Betcke 2008]. */ PetscErrorCode PEPComputeScaleFactor(PEP pep) { PetscErrorCode ierr; PetscBool has0,has1,flg; PetscReal norm0,norm1; Mat T[2]; PEPBasis basis; PetscFunctionBegin; if (pep->scale==PEP_SCALE_NONE || pep->scale==PEP_SCALE_DIAGONAL) { /* no scalar scaling */ pep->sfactor = 1.0; PetscFunctionReturn(0); } if (pep->sfactor_set) PetscFunctionReturn(0); /* user provided value */ ierr = PEPGetBasis(pep,&basis);CHKERRQ(ierr); if (basis==PEP_BASIS_MONOMIAL) { ierr = STGetTransform(pep->st,&flg);CHKERRQ(ierr); if (flg) { ierr = STGetTOperators(pep->st,0,&T[0]);CHKERRQ(ierr); ierr = STGetTOperators(pep->st,pep->nmat-1,&T[1]);CHKERRQ(ierr); } else { T[0] = pep->A[0]; T[1] = pep->A[pep->nmat-1]; } if (pep->nmat>2) { ierr = MatHasOperation(T[0],MATOP_NORM,&has0);CHKERRQ(ierr); ierr = MatHasOperation(T[1],MATOP_NORM,&has1);CHKERRQ(ierr); if (has0 && has1) { ierr = MatNorm(T[0],NORM_INFINITY,&norm0);CHKERRQ(ierr); ierr = MatNorm(T[1],NORM_INFINITY,&norm1);CHKERRQ(ierr); pep->sfactor = PetscPowReal(norm0/norm1,1.0/(pep->nmat-1)); } else { pep->sfactor = 1.0; } } } else pep->sfactor = 1.0; 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); }
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); }