PetscErrorCode EPSSetUp_Arnoldi(EPS eps) { PetscErrorCode ierr; PetscFunctionBegin; ierr = EPSSetDimensions_Default(eps,eps->nev,&eps->ncv,&eps->mpd);CHKERRQ(ierr); if (eps->ncv>eps->nev+eps->mpd) SETERRQ(PetscObjectComm((PetscObject)eps),1,"The value of ncv must not be larger than nev+mpd"); if (!eps->max_it) eps->max_it = PetscMax(100,2*eps->n/eps->ncv); if (!eps->which) { ierr = EPSSetWhichEigenpairs_Default(eps);CHKERRQ(ierr); } if (eps->ishermitian && (eps->which==EPS_LARGEST_IMAGINARY || eps->which==EPS_SMALLEST_IMAGINARY)) SETERRQ(PetscObjectComm((PetscObject)eps),1,"Wrong value of eps->which"); if (!eps->extraction) { ierr = EPSSetExtraction(eps,EPS_RITZ);CHKERRQ(ierr); } if (eps->arbitrary) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Arbitrary selection of eigenpairs not supported in this solver"); ierr = EPSAllocateSolution(eps,1);CHKERRQ(ierr); ierr = EPS_SetInnerProduct(eps);CHKERRQ(ierr); ierr = DSSetType(eps->ds,DSNHEP);CHKERRQ(ierr); if (eps->extraction==EPS_REFINED || eps->extraction==EPS_REFINED_HARMONIC) { ierr = DSSetRefined(eps->ds,PETSC_TRUE);CHKERRQ(ierr); } ierr = DSSetExtraRow(eps->ds,PETSC_TRUE);CHKERRQ(ierr); ierr = DSAllocate(eps->ds,eps->ncv+1);CHKERRQ(ierr); /* dispatch solve method */ if (eps->isgeneralized && eps->ishermitian && !eps->ispositive) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Requested method does not work for indefinite problems"); eps->ops->solve = EPSSolve_Arnoldi; PetscFunctionReturn(0); }
PetscErrorCode EPSSetUp_Lanczos(EPS eps) { EPS_LANCZOS *lanczos = (EPS_LANCZOS*)eps->data; BVOrthogRefineType refine; PetscReal eta; PetscErrorCode ierr; PetscFunctionBegin; ierr = EPSSetDimensions_Default(eps,eps->nev,&eps->ncv,&eps->mpd);CHKERRQ(ierr); if (eps->ncv>eps->nev+eps->mpd) SETERRQ(PetscObjectComm((PetscObject)eps),1,"The value of ncv must not be larger than nev+mpd"); if (!eps->max_it) eps->max_it = PetscMax(100,2*eps->n/eps->ncv); if (!eps->which) { ierr = EPSSetWhichEigenpairs_Default(eps);CHKERRQ(ierr); } switch (eps->which) { case EPS_LARGEST_IMAGINARY: case EPS_SMALLEST_IMAGINARY: case EPS_TARGET_IMAGINARY: SETERRQ(PetscObjectComm((PetscObject)eps),1,"Wrong value of eps->which"); default: ; /* default case to remove warning */ } if (!eps->extraction) { ierr = EPSSetExtraction(eps,EPS_RITZ);CHKERRQ(ierr); } else if (eps->extraction!=EPS_RITZ) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Unsupported extraction type"); if (eps->arbitrary) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Arbitrary selection of eigenpairs not supported in this solver"); ierr = EPSAllocateSolution(eps,1);CHKERRQ(ierr); ierr = EPS_SetInnerProduct(eps);CHKERRQ(ierr); if (lanczos->reorthog != EPS_LANCZOS_REORTHOG_FULL) { ierr = BVGetOrthogonalization(eps->V,NULL,&refine,&eta);CHKERRQ(ierr); ierr = BVSetOrthogonalization(eps->V,BV_ORTHOG_MGS,refine,eta);CHKERRQ(ierr); ierr = PetscInfo(eps,"Switching to MGS orthogonalization\n");CHKERRQ(ierr); } if (lanczos->reorthog == EPS_LANCZOS_REORTHOG_SELECTIVE) { ierr = BVDuplicate(eps->V,&lanczos->AV);CHKERRQ(ierr); } ierr = DSSetType(eps->ds,DSHEP);CHKERRQ(ierr); ierr = DSSetCompact(eps->ds,PETSC_TRUE);CHKERRQ(ierr); ierr = DSAllocate(eps->ds,eps->ncv+1);CHKERRQ(ierr); if (lanczos->reorthog == EPS_LANCZOS_REORTHOG_LOCAL) { ierr = EPSSetWorkVecs(eps,1);CHKERRQ(ierr); } /* dispatch solve method */ if (!eps->ishermitian) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Requested method is only available for Hermitian problems"); if (eps->isgeneralized && eps->ishermitian && !eps->ispositive) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Requested method does not work for indefinite problems"); eps->ops->solve = EPSSolve_Lanczos; PetscFunctionReturn(0); }
PetscErrorCode EPSSetUp_KrylovSchur(EPS eps) { PetscErrorCode ierr; EPS_KRYLOVSCHUR *ctx = (EPS_KRYLOVSCHUR*)eps->data; enum { EPS_KS_DEFAULT,EPS_KS_SYMM,EPS_KS_SLICE,EPS_KS_INDEF } variant; PetscFunctionBegin; /* spectrum slicing requires special treatment of default values */ if (eps->which==EPS_ALL) { ierr = EPSSetUp_KrylovSchur_Slice(eps);CHKERRQ(ierr); } else { ierr = EPSSetDimensions_Default(eps,eps->nev,&eps->ncv,&eps->mpd);CHKERRQ(ierr); if (eps->ncv>eps->nev+eps->mpd) SETERRQ(PetscObjectComm((PetscObject)eps),1,"The value of ncv must not be larger than nev+mpd"); if (!eps->max_it) eps->max_it = PetscMax(100,2*eps->n/eps->ncv); if (!eps->which) { ierr = EPSSetWhichEigenpairs_Default(eps);CHKERRQ(ierr); } } if (eps->isgeneralized && eps->ishermitian && !eps->ispositive && eps->arbitrary) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Arbitrary selection of eigenpairs not implemented for indefinite problems"); if (eps->ishermitian && eps->ispositive && (eps->which==EPS_LARGEST_IMAGINARY || eps->which==EPS_SMALLEST_IMAGINARY)) SETERRQ(PetscObjectComm((PetscObject)eps),1,"Wrong value of eps->which"); if (!eps->extraction) { ierr = EPSSetExtraction(eps,EPS_RITZ);CHKERRQ(ierr); } else if (eps->extraction!=EPS_RITZ && eps->extraction!=EPS_HARMONIC) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Unsupported extraction type"); if (!ctx->keep) ctx->keep = 0.5; ierr = EPSAllocateSolution(eps,1);CHKERRQ(ierr); ierr = EPS_SetInnerProduct(eps);CHKERRQ(ierr); if (eps->arbitrary) { ierr = EPSSetWorkVecs(eps,2);CHKERRQ(ierr); } else if (eps->ishermitian && !eps->ispositive){ ierr = EPSSetWorkVecs(eps,1);CHKERRQ(ierr); } /* dispatch solve method */ if (eps->ishermitian) { if (eps->which==EPS_ALL) { if (eps->isgeneralized && !eps->ispositive) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Spectrum slicing not implemented for indefinite problems"); else variant = EPS_KS_SLICE; } else if (eps->isgeneralized && !eps->ispositive) { variant = EPS_KS_INDEF; } else { switch (eps->extraction) { case EPS_RITZ: variant = EPS_KS_SYMM; break; case EPS_HARMONIC: variant = EPS_KS_DEFAULT; break; default: SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Unsupported extraction type"); } } } else { switch (eps->extraction) { case EPS_RITZ: variant = EPS_KS_DEFAULT; break; case EPS_HARMONIC: variant = EPS_KS_DEFAULT; break; default: SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Unsupported extraction type"); } } switch (variant) { case EPS_KS_DEFAULT: eps->ops->solve = EPSSolve_KrylovSchur_Default; eps->ops->computevectors = EPSComputeVectors_Schur; ierr = DSSetType(eps->ds,DSNHEP);CHKERRQ(ierr); ierr = DSAllocate(eps->ds,eps->ncv+1);CHKERRQ(ierr); break; case EPS_KS_SYMM: eps->ops->solve = EPSSolve_KrylovSchur_Symm; eps->ops->computevectors = EPSComputeVectors_Hermitian; ierr = DSSetType(eps->ds,DSHEP);CHKERRQ(ierr); ierr = DSSetCompact(eps->ds,PETSC_TRUE);CHKERRQ(ierr); ierr = DSSetExtraRow(eps->ds,PETSC_TRUE);CHKERRQ(ierr); ierr = DSAllocate(eps->ds,eps->ncv+1);CHKERRQ(ierr); break; case EPS_KS_SLICE: eps->ops->solve = EPSSolve_KrylovSchur_Slice; eps->ops->computevectors = NULL; ierr = DSSetType(eps->ds,DSHEP);CHKERRQ(ierr); ierr = DSSetCompact(eps->ds,PETSC_TRUE);CHKERRQ(ierr); ierr = DSAllocate(eps->ds,ctx->ncv+1);CHKERRQ(ierr); break; case EPS_KS_INDEF: eps->ops->solve = EPSSolve_KrylovSchur_Indefinite; eps->ops->computevectors = EPSComputeVectors_Indefinite; ierr = DSSetType(eps->ds,DSGHIEP);CHKERRQ(ierr); ierr = DSSetCompact(eps->ds,PETSC_TRUE);CHKERRQ(ierr); ierr = DSAllocate(eps->ds,eps->ncv+1);CHKERRQ(ierr); break; default: SETERRQ(PetscObjectComm((PetscObject)eps),1,"Unexpected error"); } PetscFunctionReturn(0); }
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); }