Actual source code: epsopts.c

  1: /*
  2:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3:    SLEPc - Scalable Library for Eigenvalue Problem Computations
  4:    Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain

  6:    This file is part of SLEPc.
  7:    SLEPc is distributed under a 2-clause BSD license (see LICENSE).
  8:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  9: */
 10: /*
 11:    EPS routines related to options that can be set via the command-line
 12:    or procedurally.
 13: */

 15: #include <slepc/private/epsimpl.h>
 16: #include <petscdraw.h>

 18: /*@
 19:    EPSMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type
 20:    indicated by the user.

 22:    Collective

 24:    Input Parameters:
 25: +  eps      - the linear eigensolver context
 26: .  opt      - the command line option for this monitor
 27: .  name     - the monitor type one is seeking
 28: .  ctx      - an optional user context for the monitor, or `NULL`
 29: -  trackall - whether this monitor tracks all eigenvalues or not

 31:    Level: developer

 33: .seealso: [](ch:eps), `EPSMonitorSet()`, `EPSSetTrackAll()`
 34: @*/
 35: PetscErrorCode EPSMonitorSetFromOptions(EPS eps,const char opt[],const char name[],PetscCtx ctx,PetscBool trackall)
 36: {
 37:   PetscErrorCode       (*mfunc)(EPS,PetscInt,PetscInt,PetscScalar*,PetscScalar*,PetscReal*,PetscInt,void*);
 38:   PetscErrorCode       (*cfunc)(PetscViewer,PetscViewerFormat,void*,PetscViewerAndFormat**);
 39:   PetscErrorCode       (*dfunc)(PetscViewerAndFormat**);
 40:   PetscViewerAndFormat *vf;
 41:   PetscViewer          viewer;
 42:   PetscViewerFormat    format;
 43:   PetscViewerType      vtype;
 44:   char                 key[PETSC_MAX_PATH_LEN];
 45:   PetscBool            flg;

 47:   PetscFunctionBegin;
 48:   PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)eps),((PetscObject)eps)->options,((PetscObject)eps)->prefix,opt,&viewer,&format,&flg));
 49:   if (!flg) PetscFunctionReturn(PETSC_SUCCESS);

 51:   PetscCall(PetscViewerGetType(viewer,&vtype));
 52:   PetscCall(SlepcMonitorMakeKey_Internal(name,vtype,format,key));
 53:   PetscCall(PetscFunctionListFind(EPSMonitorList,key,&mfunc));
 54:   PetscCheck(mfunc,PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Specified viewer and format not supported");
 55:   PetscCall(PetscFunctionListFind(EPSMonitorCreateList,key,&cfunc));
 56:   PetscCall(PetscFunctionListFind(EPSMonitorDestroyList,key,&dfunc));
 57:   if (!cfunc) cfunc = PetscViewerAndFormatCreate_Internal;
 58:   if (!dfunc) dfunc = PetscViewerAndFormatDestroy;

 60:   PetscCall((*cfunc)(viewer,format,ctx,&vf));
 61:   PetscCall(PetscViewerDestroy(&viewer));
 62:   PetscCall(EPSMonitorSet(eps,mfunc,vf,(PetscCtxDestroyFn*)dfunc));
 63:   if (trackall) PetscCall(EPSSetTrackAll(eps,PETSC_TRUE));
 64:   PetscFunctionReturn(PETSC_SUCCESS);
 65: }

 67: /*@
 68:    EPSSetFromOptions - Sets `EPS` options from the options database.
 69:    This routine must be called before `EPSSetUp()` if the user is to be
 70:    allowed to configure the solver.

 72:    Collective

 74:    Input Parameter:
 75: .  eps - the linear eigensolver context

 77:    Note:
 78:    To see all options, run your program with the `-help` option.

 80:    Level: beginner

 82: .seealso: [](ch:eps), `EPSSetOptionsPrefix()`
 83: @*/
 84: PetscErrorCode EPSSetFromOptions(EPS eps)
 85: {
 86:   char           type[256];
 87:   PetscBool      set,flg,flg1,flg2,flg3,bval;
 88:   PetscReal      r,array[2]={0,0};
 89:   PetscScalar    s;
 90:   PetscInt       i,j,k;
 91:   EPSBalance     bal;

 93:   PetscFunctionBegin;
 95:   PetscCall(EPSRegisterAll());
 96:   PetscObjectOptionsBegin((PetscObject)eps);
 97:     PetscCall(PetscOptionsFList("-eps_type","Eigensolver method","EPSSetType",EPSList,(char*)(((PetscObject)eps)->type_name?((PetscObject)eps)->type_name:EPSKRYLOVSCHUR),type,sizeof(type),&flg));
 98:     if (flg) PetscCall(EPSSetType(eps,type));
 99:     else if (!((PetscObject)eps)->type_name) PetscCall(EPSSetType(eps,EPSKRYLOVSCHUR));

101:     PetscCall(PetscOptionsBoolGroupBegin("-eps_hermitian","Hermitian eigenvalue problem","EPSSetProblemType",&flg));
102:     if (flg) PetscCall(EPSSetProblemType(eps,EPS_HEP));
103:     PetscCall(PetscOptionsBoolGroup("-eps_gen_hermitian","Generalized Hermitian eigenvalue problem","EPSSetProblemType",&flg));
104:     if (flg) PetscCall(EPSSetProblemType(eps,EPS_GHEP));
105:     PetscCall(PetscOptionsBoolGroup("-eps_non_hermitian","Non-Hermitian eigenvalue problem","EPSSetProblemType",&flg));
106:     if (flg) PetscCall(EPSSetProblemType(eps,EPS_NHEP));
107:     PetscCall(PetscOptionsBoolGroup("-eps_gen_non_hermitian","Generalized non-Hermitian eigenvalue problem","EPSSetProblemType",&flg));
108:     if (flg) PetscCall(EPSSetProblemType(eps,EPS_GNHEP));
109:     PetscCall(PetscOptionsBoolGroup("-eps_pos_gen_non_hermitian","Generalized non-Hermitian eigenvalue problem with positive semi-definite B","EPSSetProblemType",&flg));
110:     if (flg) PetscCall(EPSSetProblemType(eps,EPS_PGNHEP));
111:     PetscCall(PetscOptionsBoolGroup("-eps_gen_indefinite","Generalized Hermitian-indefinite eigenvalue problem","EPSSetProblemType",&flg));
112:     if (flg) PetscCall(EPSSetProblemType(eps,EPS_GHIEP));
113:     PetscCall(PetscOptionsBoolGroup("-eps_bse","Structured Bethe-Salpeter eigenvalue problem","EPSSetProblemType",&flg));
114:     if (flg) PetscCall(EPSSetProblemType(eps,EPS_BSE));
115:     PetscCall(PetscOptionsBoolGroup("-eps_hamiltonian","Structured Hamiltonian eigenvalue problem","EPSSetProblemType",&flg));
116:     if (flg) PetscCall(EPSSetProblemType(eps,EPS_HAMILT));
117:     PetscCall(PetscOptionsBoolGroupEnd("-eps_lrep","Structured Linear Response eigenvalue problem","EPSSetProblemType",&flg));
118:     if (flg) PetscCall(EPSSetProblemType(eps,EPS_LREP));

120:     PetscCall(PetscOptionsBoolGroupBegin("-eps_ritz","Rayleigh-Ritz extraction","EPSSetExtraction",&flg));
121:     if (flg) PetscCall(EPSSetExtraction(eps,EPS_RITZ));
122:     PetscCall(PetscOptionsBoolGroup("-eps_harmonic","Harmonic Ritz extraction","EPSSetExtraction",&flg));
123:     if (flg) PetscCall(EPSSetExtraction(eps,EPS_HARMONIC));
124:     PetscCall(PetscOptionsBoolGroup("-eps_harmonic_relative","Relative harmonic Ritz extraction","EPSSetExtraction",&flg));
125:     if (flg) PetscCall(EPSSetExtraction(eps,EPS_HARMONIC_RELATIVE));
126:     PetscCall(PetscOptionsBoolGroup("-eps_harmonic_right","Right harmonic Ritz extraction","EPSSetExtraction",&flg));
127:     if (flg) PetscCall(EPSSetExtraction(eps,EPS_HARMONIC_RIGHT));
128:     PetscCall(PetscOptionsBoolGroup("-eps_harmonic_largest","Largest harmonic Ritz extraction","EPSSetExtraction",&flg));
129:     if (flg) PetscCall(EPSSetExtraction(eps,EPS_HARMONIC_LARGEST));
130:     PetscCall(PetscOptionsBoolGroup("-eps_refined","Refined Ritz extraction","EPSSetExtraction",&flg));
131:     if (flg) PetscCall(EPSSetExtraction(eps,EPS_REFINED));
132:     PetscCall(PetscOptionsBoolGroupEnd("-eps_refined_harmonic","Refined harmonic Ritz extraction","EPSSetExtraction",&flg));
133:     if (flg) PetscCall(EPSSetExtraction(eps,EPS_REFINED_HARMONIC));

135:     bal = eps->balance;
136:     PetscCall(PetscOptionsEnum("-eps_balance","Balancing method","EPSSetBalance",EPSBalanceTypes,(PetscEnum)bal,(PetscEnum*)&bal,&flg1));
137:     j = eps->balance_its;
138:     PetscCall(PetscOptionsInt("-eps_balance_its","Number of iterations in balancing","EPSSetBalance",eps->balance_its,&j,&flg2));
139:     r = eps->balance_cutoff;
140:     PetscCall(PetscOptionsReal("-eps_balance_cutoff","Cutoff value in balancing","EPSSetBalance",eps->balance_cutoff,&r,&flg3));
141:     if (flg1 || flg2 || flg3) PetscCall(EPSSetBalance(eps,bal,j,r));

143:     i = eps->max_it;
144:     PetscCall(PetscOptionsInt("-eps_max_it","Maximum number of iterations","EPSSetTolerances",eps->max_it,&i,&flg1));
145:     r = eps->tol;
146:     PetscCall(PetscOptionsReal("-eps_tol","Tolerance","EPSSetTolerances",SlepcDefaultTol(eps->tol),&r,&flg2));
147:     if (flg1 || flg2) PetscCall(EPSSetTolerances(eps,r,i));

149:     r = eps->thres;
150:     PetscCall(PetscOptionsReal("-eps_threshold_absolute","Absolute threshold","EPSSetThreshold",r,&r,&flg));
151:     if (flg) PetscCall(EPSSetThreshold(eps,r,PETSC_FALSE));
152:     PetscCall(PetscOptionsReal("-eps_threshold_relative","Relative threshold","EPSSetThreshold",r,&r,&flg));
153:     if (flg) PetscCall(EPSSetThreshold(eps,r,PETSC_TRUE));

155:     PetscCall(PetscOptionsBoolGroupBegin("-eps_conv_rel","Relative error convergence test","EPSSetConvergenceTest",&flg));
156:     if (flg) PetscCall(EPSSetConvergenceTest(eps,EPS_CONV_REL));
157:     PetscCall(PetscOptionsBoolGroup("-eps_conv_norm","Convergence test relative to the eigenvalue and the matrix norms","EPSSetConvergenceTest",&flg));
158:     if (flg) PetscCall(EPSSetConvergenceTest(eps,EPS_CONV_NORM));
159:     PetscCall(PetscOptionsBoolGroup("-eps_conv_abs","Absolute error convergence test","EPSSetConvergenceTest",&flg));
160:     if (flg) PetscCall(EPSSetConvergenceTest(eps,EPS_CONV_ABS));
161:     PetscCall(PetscOptionsBoolGroupEnd("-eps_conv_user","User-defined convergence test","EPSSetConvergenceTest",&flg));
162:     if (flg) PetscCall(EPSSetConvergenceTest(eps,EPS_CONV_USER));

164:     PetscCall(PetscOptionsBoolGroupBegin("-eps_stop_basic","Stop iteration if all eigenvalues converged or max_it reached","EPSSetStoppingTest",&flg));
165:     if (flg) PetscCall(EPSSetStoppingTest(eps,EPS_STOP_BASIC));
166:     PetscCall(PetscOptionsBoolGroup("-eps_stop_threshold","Stop iteration if a converged eigenvalue is below/above the threshold","EPSSetStoppingTest",&flg));
167:     if (flg) PetscCall(EPSSetStoppingTest(eps,EPS_STOP_THRESHOLD));
168:     PetscCall(PetscOptionsBoolGroupEnd("-eps_stop_user","User-defined stopping test","EPSSetStoppingTest",&flg));
169:     if (flg) PetscCall(EPSSetStoppingTest(eps,EPS_STOP_USER));

171:     i = eps->nev;
172:     PetscCall(PetscOptionsInt("-eps_nev","Number of eigenvalues to compute","EPSSetDimensions",eps->nev,&i,&flg1));
173:     if (!flg1) i = PETSC_CURRENT;
174:     j = eps->ncv;
175:     PetscCall(PetscOptionsInt("-eps_ncv","Number of basis vectors","EPSSetDimensions",eps->ncv,&j,&flg2));
176:     k = eps->mpd;
177:     PetscCall(PetscOptionsInt("-eps_mpd","Maximum dimension of projected problem","EPSSetDimensions",eps->mpd,&k,&flg3));
178:     if (flg1 || flg2 || flg3) PetscCall(EPSSetDimensions(eps,i,j,k));

180:     PetscCall(PetscOptionsBoolGroupBegin("-eps_largest_magnitude","Compute largest eigenvalues in magnitude","EPSSetWhichEigenpairs",&flg));
181:     if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_LARGEST_MAGNITUDE));
182:     PetscCall(PetscOptionsBoolGroup("-eps_smallest_magnitude","Compute smallest eigenvalues in magnitude","EPSSetWhichEigenpairs",&flg));
183:     if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_SMALLEST_MAGNITUDE));
184:     PetscCall(PetscOptionsBoolGroup("-eps_largest_real","Compute eigenvalues with largest real parts","EPSSetWhichEigenpairs",&flg));
185:     if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_LARGEST_REAL));
186:     PetscCall(PetscOptionsBoolGroup("-eps_smallest_real","Compute eigenvalues with smallest real parts","EPSSetWhichEigenpairs",&flg));
187:     if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_SMALLEST_REAL));
188:     PetscCall(PetscOptionsBoolGroup("-eps_largest_imaginary","Compute eigenvalues with largest imaginary parts","EPSSetWhichEigenpairs",&flg));
189:     if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_LARGEST_IMAGINARY));
190:     PetscCall(PetscOptionsBoolGroup("-eps_smallest_imaginary","Compute eigenvalues with smallest imaginary parts","EPSSetWhichEigenpairs",&flg));
191:     if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_SMALLEST_IMAGINARY));
192:     PetscCall(PetscOptionsBoolGroup("-eps_target_magnitude","Compute eigenvalues closest to target","EPSSetWhichEigenpairs",&flg));
193:     if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_TARGET_MAGNITUDE));
194:     PetscCall(PetscOptionsBoolGroup("-eps_target_real","Compute eigenvalues with real parts closest to target","EPSSetWhichEigenpairs",&flg));
195:     if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_TARGET_REAL));
196:     PetscCall(PetscOptionsBoolGroup("-eps_target_imaginary","Compute eigenvalues with imaginary parts closest to target","EPSSetWhichEigenpairs",&flg));
197:     if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_TARGET_IMAGINARY));
198:     PetscCall(PetscOptionsBoolGroup("-eps_all","Compute all eigenvalues in an interval or a region","EPSSetWhichEigenpairs",&flg));
199:     if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_ALL));
200:     PetscCall(PetscOptionsBoolGroupEnd("-eps_which_user","Select the user-defined selection criterion","EPSSetWhichEigenpairs",&flg));
201:     if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_WHICH_USER));

203:     PetscCall(PetscOptionsScalar("-eps_target","Value of the target","EPSSetTarget",eps->target,&s,&flg));
204:     if (flg) {
205:       if (eps->which!=EPS_TARGET_REAL && eps->which!=EPS_TARGET_IMAGINARY) PetscCall(EPSSetWhichEigenpairs(eps,EPS_TARGET_MAGNITUDE));
206:       PetscCall(EPSSetTarget(eps,s));
207:     }

209:     k = 2;
210:     PetscCall(PetscOptionsRealArray("-eps_interval","Computational interval (two real values separated with a comma without spaces)","EPSSetInterval",array,&k,&flg));
211:     if (flg) {
212:       PetscCheck(k>1,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_SIZ,"Must pass two values in -eps_interval (comma-separated without spaces)");
213:       PetscCall(EPSSetWhichEigenpairs(eps,EPS_ALL));
214:       PetscCall(EPSSetInterval(eps,array[0],array[1]));
215:     }

217:     PetscCall(PetscOptionsBool("-eps_true_residual","Compute true residuals explicitly","EPSSetTrueResidual",eps->trueres,&eps->trueres,NULL));
218:     PetscCall(PetscOptionsBool("-eps_purify","Postprocess eigenvectors for purification","EPSSetPurify",eps->purify,&bval,&flg));
219:     if (flg) PetscCall(EPSSetPurify(eps,bval));
220:     PetscCall(PetscOptionsBool("-eps_two_sided","Use two-sided variant (to compute left eigenvectors)","EPSSetTwoSided",eps->twosided,&bval,&flg));
221:     if (flg) PetscCall(EPSSetTwoSided(eps,bval));

223:     /* -----------------------------------------------------------------------*/
224:     /*
225:       Cancels all monitors hardwired into code before call to EPSSetFromOptions()
226:     */
227:     PetscCall(PetscOptionsBool("-eps_monitor_cancel","Remove any hardwired monitor routines","EPSMonitorCancel",PETSC_FALSE,&flg,&set));
228:     if (set && flg) PetscCall(EPSMonitorCancel(eps));
229:     PetscCall(EPSMonitorSetFromOptions(eps,"-eps_monitor","first_approximation",NULL,PETSC_FALSE));
230:     PetscCall(EPSMonitorSetFromOptions(eps,"-eps_monitor_all","all_approximations",NULL,PETSC_TRUE));
231:     PetscCall(EPSMonitorSetFromOptions(eps,"-eps_monitor_conv","convergence_history",NULL,PETSC_FALSE));

233:     /* -----------------------------------------------------------------------*/
234:     PetscCall(PetscOptionsName("-eps_view","Print detailed information on solver used","EPSView",&set));
235:     PetscCall(PetscOptionsName("-eps_view_vectors","View computed eigenvectors","EPSVectorsView",&set));
236:     PetscCall(PetscOptionsName("-eps_view_values","View computed eigenvalues","EPSValuesView",&set));
237:     PetscCall(PetscOptionsName("-eps_converged_reason","Print reason for convergence, and number of iterations","EPSConvergedReasonView",&set));
238:     PetscCall(PetscOptionsName("-eps_error_absolute","Print absolute errors of each eigenpair","EPSErrorView",&set));
239:     PetscCall(PetscOptionsName("-eps_error_relative","Print relative errors of each eigenpair","EPSErrorView",&set));
240:     PetscCall(PetscOptionsName("-eps_error_backward","Print backward errors of each eigenpair","EPSErrorView",&set));

242:     PetscTryTypeMethod(eps,setfromoptions,PetscOptionsObject);
243:     PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)eps,PetscOptionsObject));
244:   PetscOptionsEnd();

246:   if (!eps->V) PetscCall(EPSGetBV(eps,&eps->V));
247:   PetscCall(BVSetFromOptions(eps->V));
248:   if (!eps->rg) PetscCall(EPSGetRG(eps,&eps->rg));
249:   PetscCall(RGSetFromOptions(eps->rg));
250:   if (eps->useds) {
251:     if (!eps->ds) PetscCall(EPSGetDS(eps,&eps->ds));
252:     PetscCall(EPSSetDSType(eps));
253:     PetscCall(DSSetFromOptions(eps->ds));
254:   }
255:   if (!eps->st) PetscCall(EPSGetST(eps,&eps->st));
256:   PetscCall(EPSSetDefaultST(eps));
257:   PetscCall(STSetFromOptions(eps->st));
258:   eps->setfromoptionscalled++;
259:   PetscFunctionReturn(PETSC_SUCCESS);
260: }

262: /*@
263:    EPSGetTolerances - Gets the tolerance and maximum iteration count used
264:    by the `EPS` convergence tests.

266:    Not Collective

268:    Input Parameter:
269: .  eps - the linear eigensolver context

271:    Output Parameters:
272: +  tol - the convergence tolerance
273: -  maxits - maximum number of iterations

275:    Notes:
276:    The user can specify `NULL` for any parameter that is not needed.

278:    Level: intermediate

280: .seealso: [](ch:eps), `EPSSetTolerances()`
281: @*/
282: PetscErrorCode EPSGetTolerances(EPS eps,PetscReal *tol,PetscInt *maxits)
283: {
284:   PetscFunctionBegin;
286:   if (tol)    *tol    = eps->tol;
287:   if (maxits) *maxits = eps->max_it;
288:   PetscFunctionReturn(PETSC_SUCCESS);
289: }

291: /*@
292:    EPSSetTolerances - Sets the tolerance and maximum iteration count used
293:    by the `EPS` convergence tests.

295:    Logically Collective

297:    Input Parameters:
298: +  eps    - the linear eigensolver context
299: .  tol    - the convergence tolerance
300: -  maxits - maximum number of iterations to use

302:    Options Database Keys:
303: +  -eps_tol tol       - sets the convergence tolerance
304: -  -eps_max_it maxits - sets the maximum number of iterations allowed

306:    Note:
307:    Use `PETSC_CURRENT` to retain the current value of any of the parameters.
308:    Use `PETSC_DETERMINE` for either argument to assign a default value computed
309:    internally (may be different in each solver).
310:    For `maxits` use `PETSC_UNLIMITED` to indicate there is no upper bound on this value.

312:    Level: intermediate

314: .seealso: [](ch:eps), `EPSGetTolerances()`
315: @*/
316: PetscErrorCode EPSSetTolerances(EPS eps,PetscReal tol,PetscInt maxits)
317: {
318:   PetscFunctionBegin;
322:   if (tol == (PetscReal)PETSC_DETERMINE) {
323:     eps->tol   = PETSC_DETERMINE;
324:     eps->state = EPS_STATE_INITIAL;
325:   } else if (tol != (PetscReal)PETSC_CURRENT) {
326:     PetscCheck(tol>0.0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of tol. Must be > 0");
327:     eps->tol = tol;
328:   }
329:   if (maxits == PETSC_DETERMINE) {
330:     eps->max_it = PETSC_DETERMINE;
331:     eps->state  = EPS_STATE_INITIAL;
332:   } else if (maxits == PETSC_UNLIMITED) {
333:     eps->max_it = PETSC_INT_MAX;
334:   } else if (maxits != PETSC_CURRENT) {
335:     PetscCheck(maxits>0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of maxits. Must be > 0");
336:     eps->max_it = maxits;
337:   }
338:   PetscFunctionReturn(PETSC_SUCCESS);
339: }

341: /*@
342:    EPSGetDimensions - Gets the number of eigenvalues to compute
343:    and the dimension of the subspace.

345:    Not Collective

347:    Input Parameter:
348: .  eps - the linear eigensolver context

350:    Output Parameters:
351: +  nev - number of eigenvalues to compute
352: .  ncv - the maximum dimension of the subspace to be used by the solver
353: -  mpd - the maximum dimension allowed for the projected problem

355:    Level: intermediate

357: .seealso: [](ch:eps), `EPSSetDimensions()`
358: @*/
359: PetscErrorCode EPSGetDimensions(EPS eps,PetscInt *nev,PetscInt *ncv,PetscInt *mpd)
360: {
361:   PetscFunctionBegin;
363:   if (nev) *nev = eps->nev? eps->nev: 1;
364:   if (ncv) *ncv = eps->ncv;
365:   if (mpd) *mpd = eps->mpd;
366:   PetscFunctionReturn(PETSC_SUCCESS);
367: }

369: /*@
370:    EPSSetDimensions - Sets the number of eigenvalues to compute
371:    and the dimension of the subspace.

373:    Logically Collective

375:    Input Parameters:
376: +  eps - the linear eigensolver context
377: .  nev - number of eigenvalues to compute
378: .  ncv - the maximum dimension of the subspace to be used by the solver
379: -  mpd - the maximum dimension allowed for the projected problem

381:    Options Database Keys:
382: +  -eps_nev nev - sets the number of eigenvalues
383: .  -eps_ncv ncv - sets the dimension of the subspace
384: -  -eps_mpd mpd - sets the maximum projected dimension

386:    Notes:
387:    Use `PETSC_DETERMINE` for `ncv` and `mpd` to assign a reasonably good value, which is
388:    dependent on the solution method. For any of the arguments, use `PETSC_CURRENT`
389:    to preserve the current value.

391:    The parameters `ncv` and `mpd` are intimately related, so that the user is advised
392:    to set one of them at most. Normal usage is\:

394:     1. In cases where `nev` is small, the user sets `ncv` (a reasonable default is `2*nev`).
395:     2. In cases where `nev` is large, the user sets `mpd`.

397:    The value of `ncv` should always be between `nev` and `(nev+mpd)`, typically
398:    `ncv=nev+mpd`. If `nev` is not too large, `mpd=nev` is a reasonable choice, otherwise
399:    a smaller value should be used.

401:    When computing all eigenvalues in an interval, see `EPSSetInterval()`, these
402:    parameters lose relevance, and tuning must be done with
403:    `EPSKrylovSchurSetDimensions()`.

405:    Level: intermediate

407: .seealso: [](ch:eps), `EPSGetDimensions()`, `EPSSetInterval()`, `EPSKrylovSchurSetDimensions()`
408: @*/
409: PetscErrorCode EPSSetDimensions(EPS eps,PetscInt nev,PetscInt ncv,PetscInt mpd)
410: {
411:   PetscFunctionBegin;
416:   if (nev != PETSC_CURRENT) {
417:     PetscCheck(nev>0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of nev. Must be > 0");
418:     eps->nev = nev;
419:   }
420:   if (ncv == PETSC_DETERMINE) {
421:     eps->ncv = PETSC_DETERMINE;
422:   } else if (ncv != PETSC_CURRENT) {
423:     PetscCheck(ncv>0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of ncv. Must be > 0");
424:     eps->ncv = ncv;
425:   }
426:   if (mpd == PETSC_DETERMINE) {
427:     eps->mpd = PETSC_DETERMINE;
428:   } else if (mpd != PETSC_CURRENT) {
429:     PetscCheck(mpd>0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of mpd. Must be > 0");
430:     eps->mpd = mpd;
431:   }
432:   eps->state = EPS_STATE_INITIAL;
433:   PetscFunctionReturn(PETSC_SUCCESS);
434: }

436: /*@
437:    EPSSetWhichEigenpairs - Specifies which portion of the spectrum is
438:    to be sought.

440:    Logically Collective

442:    Input Parameters:
443: +  eps   - the linear eigensolver context
444: -  which - the portion of the spectrum to be sought, see `EPSWhich` for possible values

446:    Options Database Keys:
447: +  -eps_largest_magnitude  - sets largest eigenvalues in magnitude
448: .  -eps_smallest_magnitude - sets smallest eigenvalues in magnitude
449: .  -eps_largest_real       - sets largest real parts
450: .  -eps_smallest_real      - sets smallest real parts
451: .  -eps_largest_imaginary  - sets largest imaginary parts
452: .  -eps_smallest_imaginary - sets smallest imaginary parts
453: .  -eps_target_magnitude   - sets eigenvalues closest to target
454: .  -eps_target_real        - sets real parts closest to target
455: .  -eps_target_imaginary   - sets imaginary parts closest to target
456: .  -eps_all                - sets all eigenvalues in an interval or region
457: -  -eps_which_user         - select the user-defined selection criterion

459:    Notes:
460:    Not all eigensolvers implemented in `EPS` account for all the possible values
461:    of `which`. Also, some values make sense only for certain types of
462:    problems. If SLEPc is compiled for real numbers `EPS_LARGEST_IMAGINARY`
463:    and `EPS_SMALLEST_IMAGINARY` use the absolute value of the imaginary part
464:    for eigenvalue selection.

466:    The target is a scalar value provided with `EPSSetTarget()`.

468:    The criterion `EPS_TARGET_IMAGINARY` is available only in case PETSc and
469:    SLEPc have been built with complex scalars.

471:    `EPS_ALL` is intended for use in combination with an interval (see
472:    `EPSSetInterval()`), when all eigenvalues within the interval are requested,
473:    or in the context of the `EPSCISS` solver for computing all eigenvalues in a region.

475:    Level: intermediate

477: .seealso: [](ch:eps), `EPSGetWhichEigenpairs()`, `EPSSetTarget()`, `EPSSetInterval()`, `EPSSetDimensions()`, `EPSSetEigenvalueComparison()`, `EPSWhich`
478: @*/
479: PetscErrorCode EPSSetWhichEigenpairs(EPS eps,EPSWhich which)
480: {
481:   PetscFunctionBegin;
484:   switch (which) {
485:     case EPS_LARGEST_MAGNITUDE:
486:     case EPS_SMALLEST_MAGNITUDE:
487:     case EPS_LARGEST_REAL:
488:     case EPS_SMALLEST_REAL:
489:     case EPS_LARGEST_IMAGINARY:
490:     case EPS_SMALLEST_IMAGINARY:
491:     case EPS_TARGET_MAGNITUDE:
492:     case EPS_TARGET_REAL:
493: #if PetscDefined(USE_COMPLEX)
494:     case EPS_TARGET_IMAGINARY:
495: #endif
496:     case EPS_ALL:
497:     case EPS_WHICH_USER:
498:       if (eps->which != which) {
499:         eps->state = EPS_STATE_INITIAL;
500:         eps->which = which;
501:       }
502:       break;
503: #if !PetscDefined(USE_COMPLEX)
504:     case EPS_TARGET_IMAGINARY:
505:       SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"EPS_TARGET_IMAGINARY can be used only with complex scalars");
506: #endif
507:     default:
508:       SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid 'which' value");
509:   }
510:   PetscFunctionReturn(PETSC_SUCCESS);
511: }

513: /*@
514:    EPSGetWhichEigenpairs - Returns which portion of the spectrum is to be
515:    sought.

517:    Not Collective

519:    Input Parameter:
520: .  eps - the linear eigensolver context

522:    Output Parameter:
523: .  which - the portion of the spectrum to be sought, see `EPSWhich` for possible values

525:    Level: intermediate

527: .seealso: [](ch:eps), `EPSSetWhichEigenpairs()`, `EPSWhich`
528: @*/
529: PetscErrorCode EPSGetWhichEigenpairs(EPS eps,EPSWhich *which)
530: {
531:   PetscFunctionBegin;
533:   PetscAssertPointer(which,2);
534:   *which = eps->which;
535:   PetscFunctionReturn(PETSC_SUCCESS);
536: }

538: /*@
539:    EPSSetThreshold - Sets the threshold used in the threshold stopping test.

541:    Logically Collective

543:    Input Parameters:
544: +  eps   - the linear eigensolver context
545: .  thres - the threshold value
546: -  rel   - whether the threshold is relative or not

548:    Options Database Keys:
549: +  -eps_threshold_absolute thres - sets an absolute threshold
550: -  -eps_threshold_relative thres - sets a relative threshold

552:    Notes:
553:    This function internally calls `EPSSetStoppingTest()` to set a special stopping
554:    test based on the threshold, where eigenvalues are computed in sequence until
555:    the next eigenvalue approximation is below the threshold `thres` (in magnitude).
556:    This is the interpretation in case of searching for largest eigenvalues in magnitude,
557:    see `EPSSetWhichEigenpairs()`.

559:    If the solver is configured to compute smallest magnitude eigenvalues, then the
560:    threshold must be interpreted in the opposite direction, i.e., the computation
561:    will stop when the next eigenvalue approximation is above the threshold (in magnitude).

563:    The threshold can also be used when computing largest/smallest real eigenvalues
564:    (i.e, rightmost or leftmost), in which case the threshold is allowed to be
565:    negative. The solver will stop when the next eigenvalue approximation is above
566:    or below the threshold (considering the real part of the eigenvalue). This mode
567:    is allowed only in problem types whose eigenvalues are always real (e.g., `EPS_HEP`).

569:    In the case of largest magnitude eigenvalues, the threshold can be made relative
570:    with respect to the dominant eigenvalue. Otherwise, the argument `rel` should be
571:    `PETSC_FALSE`.

573:    An additional use case is with target magnitude selection of eigenvalues (e.g.,
574:    with shift-and-invert), but this must be used with caution to avoid unexpected
575:    behavior. With an absolute threshold, the solver will assume that leftmost
576:    eigenvalues are being computed (e.g., with `target`=0 for a problem with real
577:    positive eigenvalues). In case of a relative threshold, a value of `thres`<1
578:    implies that the wanted eigenvalues are the largest ones, and otherwise the
579:    solver assumes that smallest eigenvalues are being computed.

581:    When the next eigenvalue approximation does not satisfy the threshold criterion,
582:    the solver will carry out an additional iteration/restart. This provides more
583:    guarantees that eigenvalue multiplicity is resolved correctly. As a result,
584:    sometimes the solver will return more converged eigenvalues than strictly
585:    satisfying the criterion.

587:    Since the number of computed eigenvalues is not known a priori, the solver
588:    will need to reallocate the basis of vectors internally, to have enough room
589:    to accommodate all the eigenvectors. Hence, this option must be used with
590:    caution to avoid out-of-memory problems. The recommendation is to set the value
591:    of `ncv` to be larger than the estimated number of eigenvalues, to minimize the
592:    number of reallocations.

594:    If a number of wanted eigenvalues has been set with `EPSSetDimensions()`
595:    it is also taken into account and the solver will stop when one of the two
596:    conditions (threshold or number of converged values) is met.

598:    Use `EPSSetStoppingTest()` to return to the usual computation of a fixed number
599:    of eigenvalues.

601:    Level: advanced

603: .seealso: [](ch:eps), `EPSGetThreshold()`, `EPSSetStoppingTest()`, `EPSSetDimensions()`, `EPSSetWhichEigenpairs()`, `EPSSetProblemType()`
604: @*/
605: PetscErrorCode EPSSetThreshold(EPS eps,PetscReal thres,PetscBool rel)
606: {
607:   PetscFunctionBegin;
611:   if (eps->thres != thres || eps->threlative != rel) {
612:     eps->thres = thres;
613:     eps->threlative = rel;
614:     eps->state = EPS_STATE_INITIAL;
615:     PetscCall(EPSSetStoppingTest(eps,EPS_STOP_THRESHOLD));
616:   }
617:   PetscFunctionReturn(PETSC_SUCCESS);
618: }

620: /*@
621:    EPSGetThreshold - Gets the threshold used by the threshold stopping test.

623:    Not Collective

625:    Input Parameter:
626: .  eps - the linear eigensolver context

628:    Output Parameters:
629: +  thres - the threshold
630: -  rel   - whether the threshold is relative or not

632:    Level: advanced

634: .seealso: [](ch:eps), `EPSSetThreshold()`
635: @*/
636: PetscErrorCode EPSGetThreshold(EPS eps,PetscReal *thres,PetscBool *rel)
637: {
638:   PetscFunctionBegin;
640:   if (thres) *thres = eps->thres;
641:   if (rel)   *rel   = eps->threlative;
642:   PetscFunctionReturn(PETSC_SUCCESS);
643: }

645: /*@
646:    EPSSetEigenvalueComparison - Specifies the eigenvalue comparison function
647:    when `EPSSetWhichEigenpairs()` is set to `EPS_WHICH_USER`.

649:    Logically Collective

651:    Input Parameters:
652: +  eps  - the linear eigensolver context
653: .  func - the comparison function, see `SlepcEigenvalueComparisonFn` for the calling sequence
654: -  ctx  - a context pointer (the last parameter to the comparison function)

656:    Level: advanced

658: .seealso: [](ch:eps), `EPSSetWhichEigenpairs()`, `EPSWhich`
659: @*/
660: PetscErrorCode EPSSetEigenvalueComparison(EPS eps,SlepcEigenvalueComparisonFn *func,PetscCtx ctx)
661: {
662:   PetscFunctionBegin;
664:   eps->sc->comparison    = func;
665:   eps->sc->comparisonctx = ctx;
666:   eps->which             = EPS_WHICH_USER;
667:   PetscFunctionReturn(PETSC_SUCCESS);
668: }

670: /*@
671:    EPSSetArbitrarySelection - Specifies a function intended to look for
672:    eigenvalues according to an arbitrary selection criterion. This criterion
673:    can be based on a computation involving the current eigenvector approximation.

675:    Logically Collective

677:    Input Parameters:
678: +  eps  - the linear eigensolver context
679: .  func - the arbitrary selection function, see `SlepcArbitrarySelectionFn` for a calling sequence
680: -  ctx  - a context pointer (the last parameter to the arbitrary selection function)

682:    Notes:
683:    This provides a mechanism to select eigenpairs by evaluating a user-defined
684:    function. When a function has been provided, the default selection based on
685:    sorting the eigenvalues is replaced by the sorting of the results of this
686:    function (with the same sorting criterion given in `EPSSetWhichEigenpairs()`).

688:    For instance, suppose you want to compute those eigenvectors that maximize
689:    a certain computable expression. Then implement the computation using
690:    the arguments `xr` and `xi`, and return the result in `rr`. Then set the standard
691:    sorting by magnitude so that the eigenpair with largest value of `rr` is
692:    selected.

694:    This evaluation function is collective, that is, all processes call it and
695:    it can use collective operations; furthermore, the computed result must
696:    be the same in all processes.

698:    The result of `func` is expressed as a complex number so that it is possible to
699:    use the standard eigenvalue sorting functions, but normally only `rr` is used.
700:    Set `ri` to zero unless it is meaningful in your application.

702:    Level: advanced

704: .seealso: [](ch:eps), `EPSSetWhichEigenpairs()`, `EPSSetArbitrarySelectionContextDestroy()`
705: @*/
706: PetscErrorCode EPSSetArbitrarySelection(EPS eps,SlepcArbitrarySelectionFn *func,PetscCtx ctx)
707: {
708:   PetscFunctionBegin;
710:   if (eps->arbitrarydestroy) PetscCall((*eps->arbitrarydestroy)(&eps->arbitraryctx));
711:   eps->arbitrary    = func;
712:   eps->arbitraryctx = ctx;
713:   eps->state        = EPS_STATE_INITIAL;
714:   PetscFunctionReturn(PETSC_SUCCESS);
715: }

717: /*@
718:    EPSSetArbitrarySelectionContextDestroy - Set a context destroy function for the
719:    context used in the arbitrary selection.

721:    Logically Collective

723:    Input Parameters:
724: +  eps     - the linear eigensolver context
725: -  destroy - context destroy function, see `PetscCtxDestroyFn` for its calling sequence

727:    Level: advanced

729: .seealso: [](ch:eps), `EPSSetArbitrarySelection()`
730: @*/
731: PetscErrorCode EPSSetArbitrarySelectionContextDestroy(EPS eps,PetscCtxDestroyFn *destroy)
732: {
733:   PetscFunctionBegin;
735:   eps->arbitrarydestroy = destroy;
736:   PetscFunctionReturn(PETSC_SUCCESS);
737: }

739: /*@
740:    EPSSetConvergenceTestFunction - Sets a function to compute the error estimate
741:    used in the convergence test.

743:    Logically Collective

745:    Input Parameters:
746: +  eps     - the linear eigensolver context
747: .  func    - convergence test function, see `EPSConvergenceTestFn` for the calling sequence
748: .  ctx     - context for private data for the convergence routine (may be `NULL`)
749: -  destroy - a routine for destroying the context (may be `NULL`), see `PetscCtxDestroyFn`
750:              for the calling sequence

752:    Notes:
753:    When this is called with a user-defined function, then the convergence
754:    criterion is set to `EPS_CONV_USER`, see `EPSSetConvergenceTest()`.

756:    If the error estimate returned by the convergence test function is less than
757:    the tolerance, then the eigenvalue is accepted as converged.

759:    Level: advanced

761: .seealso: [](ch:eps), `EPSSetConvergenceTest()`, `EPSSetTolerances()`
762: @*/
763: PetscErrorCode EPSSetConvergenceTestFunction(EPS eps,EPSConvergenceTestFn *func,PetscCtx ctx,PetscCtxDestroyFn *destroy)
764: {
765:   PetscFunctionBegin;
767:   if (eps->convergeddestroy) PetscCall((*eps->convergeddestroy)(&eps->convergedctx));
768:   eps->convergeduser    = func;
769:   eps->convergeddestroy = destroy;
770:   eps->convergedctx     = ctx;
771:   if (func == EPSConvergedRelative) eps->conv = EPS_CONV_REL;
772:   else if (func == EPSConvergedNorm) eps->conv = EPS_CONV_NORM;
773:   else if (func == EPSConvergedAbsolute) eps->conv = EPS_CONV_ABS;
774:   else {
775:     eps->conv      = EPS_CONV_USER;
776:     eps->converged = eps->convergeduser;
777:   }
778:   PetscFunctionReturn(PETSC_SUCCESS);
779: }

781: /*@
782:    EPSSetConvergenceTest - Specifies how to compute the error estimate
783:    used in the convergence test.

785:    Logically Collective

787:    Input Parameters:
788: +  eps  - the linear eigensolver context
789: -  conv - the type of convergence test, see `EPSConv` for possible values

791:    Options Database Keys:
792: +  -eps_conv_abs  - sets the absolute convergence test
793: .  -eps_conv_rel  - sets the convergence test relative to the eigenvalue
794: .  -eps_conv_norm - sets the convergence test relative to the matrix norms
795: -  -eps_conv_user - selects the user-defined convergence test

797:    Level: intermediate

799: .seealso: [](ch:eps), `EPSGetConvergenceTest()`, `EPSSetConvergenceTestFunction()`, `EPSSetStoppingTest()`, `EPSConv`
800: @*/
801: PetscErrorCode EPSSetConvergenceTest(EPS eps,EPSConv conv)
802: {
803:   PetscFunctionBegin;
806:   switch (conv) {
807:     case EPS_CONV_ABS:  eps->converged = EPSConvergedAbsolute; break;
808:     case EPS_CONV_REL:  eps->converged = EPSConvergedRelative; break;
809:     case EPS_CONV_NORM: eps->converged = EPSConvergedNorm; break;
810:     case EPS_CONV_USER:
811:       PetscCheck(eps->convergeduser,PetscObjectComm((PetscObject)eps),PETSC_ERR_ORDER,"Must call EPSSetConvergenceTestFunction() first");
812:       eps->converged = eps->convergeduser;
813:       break;
814:     default:
815:       SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid 'conv' value");
816:   }
817:   eps->conv = conv;
818:   PetscFunctionReturn(PETSC_SUCCESS);
819: }

821: /*@
822:    EPSGetConvergenceTest - Gets the method used to compute the error estimate
823:    used in the convergence test.

825:    Not Collective

827:    Input Parameter:
828: .  eps   - the linear eigensolver context

830:    Output Parameter:
831: .  conv  - the type of convergence test

833:    Level: intermediate

835: .seealso: [](ch:eps), `EPSSetConvergenceTest()`, `EPSConv`
836: @*/
837: PetscErrorCode EPSGetConvergenceTest(EPS eps,EPSConv *conv)
838: {
839:   PetscFunctionBegin;
841:   PetscAssertPointer(conv,2);
842:   *conv = eps->conv;
843:   PetscFunctionReturn(PETSC_SUCCESS);
844: }

846: /*@
847:    EPSSetStoppingTestFunction - Sets a function to decide when to stop the outer
848:    iteration of the eigensolver.

850:    Logically Collective

852:    Input Parameters:
853: +  eps     - the linear eigensolver context
854: .  func    - stopping test function, see `EPSStoppingTestFn` for the calling sequence
855: .  ctx     - context for private data for the stopping routine (may be `NULL`)
856: -  destroy - a routine for destroying the context (may be `NULL`), see `PetscCtxDestroyFn`
857:              for the calling sequence

859:    Note:
860:    When implementing a function for this, normal usage is to first call the
861:    default routine `EPSStoppingBasic()` and then set `reason` to `EPS_CONVERGED_USER`
862:    if some user-defined conditions have been met. To let the eigensolver continue
863:    iterating, the result must be left as `EPS_CONVERGED_ITERATING`.

865:    Level: advanced

867: .seealso: [](ch:eps), `EPSSetStoppingTest()`, `EPSStoppingBasic()`
868: @*/
869: PetscErrorCode EPSSetStoppingTestFunction(EPS eps,EPSStoppingTestFn *func,PetscCtx ctx,PetscCtxDestroyFn *destroy)
870: {
871:   PetscFunctionBegin;
873:   if (eps->stoppingdestroy) PetscCall((*eps->stoppingdestroy)(&eps->stoppingctx));
874:   eps->stoppinguser    = func;
875:   eps->stoppingdestroy = destroy;
876:   eps->stoppingctx     = ctx;
877:   if (func == EPSStoppingBasic) PetscCall(EPSSetStoppingTest(eps,EPS_STOP_BASIC));
878:   else if (func == EPSStoppingThreshold) PetscCall(EPSSetStoppingTest(eps,EPS_STOP_THRESHOLD));
879:   else {
880:     eps->stop     = EPS_STOP_USER;
881:     eps->stopping = eps->stoppinguser;
882:   }
883:   PetscFunctionReturn(PETSC_SUCCESS);
884: }

886: /*@
887:    EPSSetStoppingTest - Specifies how to decide the termination of the outer
888:    loop of the eigensolver.

890:    Logically Collective

892:    Input Parameters:
893: +  eps  - the linear eigensolver context
894: -  stop - the type of stopping test, see `EPSStop`

896:    Options Database Keys:
897: +  -eps_stop_basic     - sets the default stopping test
898: .  -eps_stop_threshold - sets the threshold stopping test
899: -  -eps_stop_user      - selects the user-defined stopping test

901:    Level: advanced

903: .seealso: [](ch:eps), `EPSGetStoppingTest()`, `EPSSetStoppingTestFunction()`, `EPSSetConvergenceTest()`, `EPSStop`
904: @*/
905: PetscErrorCode EPSSetStoppingTest(EPS eps,EPSStop stop)
906: {
907:   PetscFunctionBegin;
910:   switch (stop) {
911:     case EPS_STOP_BASIC: eps->stopping = EPSStoppingBasic; break;
912:     case EPS_STOP_THRESHOLD: eps->stopping = EPSStoppingThreshold; break;
913:     case EPS_STOP_USER:
914:       PetscCheck(eps->stoppinguser,PetscObjectComm((PetscObject)eps),PETSC_ERR_ORDER,"Must call EPSSetStoppingTestFunction() first");
915:       eps->stopping = eps->stoppinguser;
916:       break;
917:     default:
918:       SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid 'stop' value");
919:   }
920:   eps->stop = stop;
921:   PetscFunctionReturn(PETSC_SUCCESS);
922: }

924: /*@
925:    EPSGetStoppingTest - Gets the method used to decide the termination of the outer
926:    loop of the eigensolver.

928:    Not Collective

930:    Input Parameter:
931: .  eps   - the linear eigensolver context

933:    Output Parameter:
934: .  stop  - the type of stopping test

936:    Level: advanced

938: .seealso: [](ch:eps), `EPSSetStoppingTest()`, `EPSStop`
939: @*/
940: PetscErrorCode EPSGetStoppingTest(EPS eps,EPSStop *stop)
941: {
942:   PetscFunctionBegin;
944:   PetscAssertPointer(stop,2);
945:   *stop = eps->stop;
946:   PetscFunctionReturn(PETSC_SUCCESS);
947: }

949: /*@
950:    EPSSetProblemType - Specifies the type of the eigenvalue problem.

952:    Logically Collective

954:    Input Parameters:
955: +  eps  - the linear eigensolver context
956: -  type - a known type of eigenvalue problem

958:    Options Database Keys:
959: +  -eps_hermitian             - Hermitian eigenvalue problem
960: .  -eps_gen_hermitian         - generalized Hermitian eigenvalue problem
961: .  -eps_non_hermitian         - non-Hermitian eigenvalue problem
962: .  -eps_gen_non_hermitian     - generalized non-Hermitian eigenvalue problem
963: .  -eps_pos_gen_non_hermitian - generalized non-Hermitian eigenvalue problem
964:                                 with positive semi-definite $B$
965: .  -eps_gen_indefinite        - generalized Hermitian-indefinite eigenvalue problem
966: .  -eps_bse                   - structured Bethe-Salpeter eigenvalue problem
967: .  -eps_hamiltonian           - structured Hamiltonian eigenvalue problem
968: -  -eps_lrep                  - structured Linear Response eigenvalue problem

970:    Notes:
971:    This function must be used to instruct SLEPc to exploit symmetry or other
972:    kind of structure. If no
973:    problem type is specified, by default a non-Hermitian problem is assumed
974:    (either standard or generalized). If the user knows that the problem is
975:    Hermitian (i.e., $A=A^*$) or generalized Hermitian (i.e., $A=A^*$, $B=B^*$,
976:    and $B$ positive definite) then it is recommended to set the problem type so
977:    that the eigensolver can exploit these properties.

979:    If the user does not call this function, the solver will use a reasonable
980:    guess.

982:    For structured problem types such as `EPS_BSE`, the matrices passed in via
983:    `EPSSetOperators()` must have been created with the corresponding helper
984:    function, i.e., `MatCreateBSE()`.

986:    Level: intermediate

988: .seealso: [](ch:eps), `EPSSetOperators()`, `EPSSetType()`, `EPSGetProblemType()`, `EPSProblemType`
989: @*/
990: PetscErrorCode EPSSetProblemType(EPS eps,EPSProblemType type)
991: {
992:   PetscFunctionBegin;
995:   if (type == eps->problem_type) PetscFunctionReturn(PETSC_SUCCESS);
996:   switch (type) {
997:     case EPS_HEP:
998:       eps->isgeneralized = PETSC_FALSE;
999:       eps->ishermitian = PETSC_TRUE;
1000:       eps->ispositive = PETSC_FALSE;
1001:       eps->isstructured = PETSC_FALSE;
1002:       break;
1003:     case EPS_NHEP:
1004:       eps->isgeneralized = PETSC_FALSE;
1005:       eps->ishermitian = PETSC_FALSE;
1006:       eps->ispositive = PETSC_FALSE;
1007:       eps->isstructured = PETSC_FALSE;
1008:       break;
1009:     case EPS_GHEP:
1010:       eps->isgeneralized = PETSC_TRUE;
1011:       eps->ishermitian = PETSC_TRUE;
1012:       eps->ispositive = PETSC_TRUE;
1013:       eps->isstructured = PETSC_FALSE;
1014:       break;
1015:     case EPS_GNHEP:
1016:       eps->isgeneralized = PETSC_TRUE;
1017:       eps->ishermitian = PETSC_FALSE;
1018:       eps->ispositive = PETSC_FALSE;
1019:       eps->isstructured = PETSC_FALSE;
1020:       break;
1021:     case EPS_PGNHEP:
1022:       eps->isgeneralized = PETSC_TRUE;
1023:       eps->ishermitian = PETSC_FALSE;
1024:       eps->ispositive = PETSC_TRUE;
1025:       eps->isstructured = PETSC_FALSE;
1026:       break;
1027:     case EPS_GHIEP:
1028:       eps->isgeneralized = PETSC_TRUE;
1029:       eps->ishermitian = PETSC_TRUE;
1030:       eps->ispositive = PETSC_FALSE;
1031:       eps->isstructured = PETSC_FALSE;
1032:       break;
1033:     case EPS_BSE:
1034:       eps->isgeneralized = PETSC_FALSE;
1035:       eps->ishermitian = PETSC_FALSE;
1036:       eps->ispositive = PETSC_FALSE;
1037:       eps->isstructured = PETSC_TRUE;
1038:       break;
1039:     case EPS_HAMILT:
1040:       eps->isgeneralized = PETSC_FALSE;
1041:       eps->ishermitian = PETSC_FALSE;
1042:       eps->ispositive = PETSC_FALSE;
1043:       eps->isstructured = PETSC_TRUE;
1044:       break;
1045:     case EPS_LREP:
1046:       eps->isgeneralized = PETSC_FALSE;
1047:       eps->ishermitian = PETSC_FALSE;
1048:       eps->ispositive = PETSC_FALSE;
1049:       eps->isstructured = PETSC_TRUE;
1050:       break;
1051:     default:
1052:       SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_WRONG,"Unknown eigenvalue problem type");
1053:   }
1054:   eps->problem_type = type;
1055:   eps->state = EPS_STATE_INITIAL;
1056:   PetscFunctionReturn(PETSC_SUCCESS);
1057: }

1059: /*@
1060:    EPSGetProblemType - Gets the problem type from the `EPS` object.

1062:    Not Collective

1064:    Input Parameter:
1065: .  eps - the linear eigensolver context

1067:    Output Parameter:
1068: .  type - the problem type

1070:    Level: intermediate

1072: .seealso: [](ch:eps), `EPSSetProblemType()`, `EPSProblemType`
1073: @*/
1074: PetscErrorCode EPSGetProblemType(EPS eps,EPSProblemType *type)
1075: {
1076:   PetscFunctionBegin;
1078:   PetscAssertPointer(type,2);
1079:   *type = eps->problem_type;
1080:   PetscFunctionReturn(PETSC_SUCCESS);
1081: }

1083: /*@
1084:    EPSSetExtraction - Specifies the type of extraction technique to be employed
1085:    by the eigensolver.

1087:    Logically Collective

1089:    Input Parameters:
1090: +  eps  - the linear eigensolver context
1091: -  extr - a known type of extraction

1093:    Options Database Keys:
1094: +  -eps_ritz              - Rayleigh-Ritz extraction
1095: .  -eps_harmonic          - harmonic Ritz extraction
1096: .  -eps_harmonic_relative - harmonic Ritz extraction relative to the eigenvalue
1097: .  -eps_harmonic_right    - harmonic Ritz extraction for rightmost eigenvalues
1098: .  -eps_harmonic_largest  - harmonic Ritz extraction for largest magnitude (without target)
1099: .  -eps_refined           - refined Ritz extraction
1100: -  -eps_refined_harmonic  - refined harmonic Ritz extraction

1102:    Notes:
1103:    Not all eigensolvers support all types of extraction.

1105:    By default, a standard Rayleigh-Ritz extraction is used. Other extractions
1106:    may be useful when computing interior eigenvalues.

1108:    Harmonic-type extractions are used in combination with a target, see `EPSSetTarget()`.

1110:    Level: advanced

1112: .seealso: [](ch:eps), [](#sec:harmonic), `EPSSetTarget()`, `EPSGetExtraction()`, `EPSExtraction`
1113: @*/
1114: PetscErrorCode EPSSetExtraction(EPS eps,EPSExtraction extr)
1115: {
1116:   PetscFunctionBegin;
1119:   if (eps->extraction != extr) {
1120:     eps->state      = EPS_STATE_INITIAL;
1121:     eps->extraction = extr;
1122:   }
1123:   PetscFunctionReturn(PETSC_SUCCESS);
1124: }

1126: /*@
1127:    EPSGetExtraction - Gets the extraction type used by the `EPS` object.

1129:    Not Collective

1131:    Input Parameter:
1132: .  eps - the linear eigensolver context

1134:    Output Parameter:
1135: .  extr - name of extraction type

1137:    Level: advanced

1139: .seealso: [](ch:eps), `EPSSetExtraction()`, `EPSExtraction`
1140: @*/
1141: PetscErrorCode EPSGetExtraction(EPS eps,EPSExtraction *extr)
1142: {
1143:   PetscFunctionBegin;
1145:   PetscAssertPointer(extr,2);
1146:   *extr = eps->extraction;
1147:   PetscFunctionReturn(PETSC_SUCCESS);
1148: }

1150: /*@
1151:    EPSSetBalance - Specifies the balancing technique to be employed by the
1152:    eigensolver, and some parameters associated to it.

1154:    Logically Collective

1156:    Input Parameters:
1157: +  eps    - the linear eigensolver context
1158: .  bal    - the balancing method, see `EPSBalance` for possible values
1159: .  its    - number of iterations of the balancing algorithm
1160: -  cutoff - cutoff value

1162:    Options Database Keys:
1163: +  -eps_balance (none|oneside|twoside|user) - the balancing method
1164: .  -eps_balance_its its                     - number of iterations
1165: -  -eps_balance_cutoff cutoff               - cutoff value

1167:    Notes:
1168:    When balancing is enabled, the solver works implicitly with matrix $DAD^{-1}$,
1169:    where $D$ is an appropriate diagonal matrix. This improves the accuracy of
1170:    the computed results in some cases, see [](sec:balancing).

1172:    Balancing makes sense only for non-Hermitian problems when the required
1173:    precision is high (i.e., a small tolerance such as `1e-14`).

1175:    By default, balancing is disabled. The two-sided method is much more
1176:    effective than the one-sided counterpart, but it requires the system
1177:    matrices to have the `MatMultTranspose()` operation defined. The methods
1178:    are described in {cite:p}`Che00`.

1180:    The parameter `its` is the number of iterations performed by the method. The
1181:    `cutoff` value is used only in the two-side variant. Use `PETSC_DETERMINE` to assign
1182:    a reasonably good value, or `PETSC_CURRENT` to leave the value unchanged.

1184:    User-defined balancing is allowed provided that the corresponding matrix
1185:    is set via `STSetBalanceMatrix()`.

1187:    Level: intermediate

1189: .seealso: [](ch:eps), [](sec:balancing), `EPSGetBalance()`, `EPSBalance`, `STSetBalanceMatrix()`
1190: @*/
1191: PetscErrorCode EPSSetBalance(EPS eps,EPSBalance bal,PetscInt its,PetscReal cutoff)
1192: {
1193:   PetscFunctionBegin;
1198:   switch (bal) {
1199:     case EPS_BALANCE_NONE:
1200:     case EPS_BALANCE_ONESIDE:
1201:     case EPS_BALANCE_TWOSIDE:
1202:     case EPS_BALANCE_USER:
1203:       if (eps->balance != bal) {
1204:         eps->state = EPS_STATE_INITIAL;
1205:         eps->balance = bal;
1206:       }
1207:       break;
1208:     default:
1209:       SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid value of argument 'bal'");
1210:   }
1211:   if (its==PETSC_DETERMINE) eps->balance_its = 5;
1212:   else if (its!=PETSC_CURRENT) {
1213:     PetscCheck(its>0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of its. Must be > 0");
1214:     eps->balance_its = its;
1215:   }
1216:   if (cutoff==(PetscReal)PETSC_DETERMINE) eps->balance_cutoff = 1e-8;
1217:   else if (cutoff!=(PetscReal)PETSC_CURRENT) {
1218:     PetscCheck(cutoff>0.0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of cutoff. Must be > 0");
1219:     eps->balance_cutoff = cutoff;
1220:   }
1221:   PetscFunctionReturn(PETSC_SUCCESS);
1222: }

1224: /*@
1225:    EPSGetBalance - Gets the balancing type used by the `EPS` object, and the
1226:    associated parameters.

1228:    Not Collective

1230:    Input Parameter:
1231: .  eps - the linear eigensolver context

1233:    Output Parameters:
1234: +  bal    - the balancing method
1235: .  its    - number of iterations of the balancing algorithm
1236: -  cutoff - cutoff value

1238:    Level: intermediate

1240:    Note:
1241:    The user can specify `NULL` for any parameter that is not needed.

1243: .seealso: [](ch:eps), `EPSSetBalance()`, `EPSBalance`
1244: @*/
1245: PetscErrorCode EPSGetBalance(EPS eps,EPSBalance *bal,PetscInt *its,PetscReal *cutoff)
1246: {
1247:   PetscFunctionBegin;
1249:   if (bal)    *bal = eps->balance;
1250:   if (its)    *its = eps->balance_its;
1251:   if (cutoff) *cutoff = eps->balance_cutoff;
1252:   PetscFunctionReturn(PETSC_SUCCESS);
1253: }

1255: /*@
1256:    EPSSetTwoSided - Sets the solver to use a two-sided variant so that left
1257:    eigenvectors are also computed.

1259:    Logically Collective

1261:    Input Parameters:
1262: +  eps      - the linear eigensolver context
1263: -  twosided - whether the two-sided variant is to be used or not

1265:    Options Database Key:
1266: .  -eps_two_sided (true|false) - toggles the twosided flag

1268:    Notes:
1269:    If the user sets `twosided`=`PETSC_TRUE` then the solver uses a variant of
1270:    the algorithm that computes both right and left eigenvectors. This is
1271:    usually much more costly. This option is not available in all solvers,
1272:    see table [](#tab:support).

1274:    When using two-sided solvers, the problem matrices must have both the
1275:    `MATOP_MULT` and `MATOP_MULT_TRANSPOSE` operations defined.

1277:    Level: advanced

1279: .seealso: [](ch:eps), `EPSGetTwoSided()`, `EPSGetLeftEigenvector()`
1280: @*/
1281: PetscErrorCode EPSSetTwoSided(EPS eps,PetscBool twosided)
1282: {
1283:   PetscFunctionBegin;
1286:   if (twosided!=eps->twosided) {
1287:     eps->twosided = twosided;
1288:     eps->state    = EPS_STATE_INITIAL;
1289:   }
1290:   PetscFunctionReturn(PETSC_SUCCESS);
1291: }

1293: /*@
1294:    EPSGetTwoSided - Returns the flag indicating whether a two-sided variant
1295:    of the algorithm is being used or not.

1297:    Not Collective

1299:    Input Parameter:
1300: .  eps - the linear eigensolver context

1302:    Output Parameter:
1303: .  twosided - the returned flag

1305:    Level: advanced

1307: .seealso: [](ch:eps), `EPSSetTwoSided()`
1308: @*/
1309: PetscErrorCode EPSGetTwoSided(EPS eps,PetscBool *twosided)
1310: {
1311:   PetscFunctionBegin;
1313:   PetscAssertPointer(twosided,2);
1314:   *twosided = eps->twosided;
1315:   PetscFunctionReturn(PETSC_SUCCESS);
1316: }

1318: /*@
1319:    EPSSetTrueResidual - Specifies if the solver must compute the true residual
1320:    explicitly or not.

1322:    Logically Collective

1324:    Input Parameters:
1325: +  eps     - the linear eigensolver context
1326: -  trueres - whether true residuals are required or not

1328:    Options Database Key:
1329: .  -eps_true_residual (true|false) - toggles the true residual

1331:    Notes:
1332:    If the user sets `trueres`=`PETSC_TRUE` then the solver explicitly computes
1333:    the true residual for each eigenpair approximation, and uses it for
1334:    convergence testing. Computing the residual is usually an expensive
1335:    operation. Some solvers (e.g., Krylov solvers) can avoid this computation
1336:    by using a cheap estimate of the residual norm, but this may sometimes
1337:    give inaccurate results (especially if a spectral transform is being
1338:    used). On the contrary, preconditioned eigensolvers (e.g., Davidson solvers)
1339:    do rely on computing the true residual, so this option is irrelevant for them.

1341:    Level: advanced

1343: .seealso: [](ch:eps), `EPSGetTrueResidual()`
1344: @*/
1345: PetscErrorCode EPSSetTrueResidual(EPS eps,PetscBool trueres)
1346: {
1347:   PetscFunctionBegin;
1350:   eps->trueres = trueres;
1351:   PetscFunctionReturn(PETSC_SUCCESS);
1352: }

1354: /*@
1355:    EPSGetTrueResidual - Returns the flag indicating whether true
1356:    residuals must be computed explicitly or not.

1358:    Not Collective

1360:    Input Parameter:
1361: .  eps - the linear eigensolver context

1363:    Output Parameter:
1364: .  trueres - the returned flag

1366:    Level: advanced

1368: .seealso: [](ch:eps), `EPSSetTrueResidual()`
1369: @*/
1370: PetscErrorCode EPSGetTrueResidual(EPS eps,PetscBool *trueres)
1371: {
1372:   PetscFunctionBegin;
1374:   PetscAssertPointer(trueres,2);
1375:   *trueres = eps->trueres;
1376:   PetscFunctionReturn(PETSC_SUCCESS);
1377: }

1379: /*@
1380:    EPSSetTrackAll - Specifies if the solver must compute the residual norm of all
1381:    approximate eigenpairs or not.

1383:    Logically Collective

1385:    Input Parameters:
1386: +  eps      - the linear eigensolver context
1387: -  trackall - whether to compute all residuals or not

1389:    Notes:
1390:    If the user sets `trackall`=`PETSC_TRUE` then the solver computes (or estimates)
1391:    the residual norm for each eigenpair approximation. Computing the residual is
1392:    usually an expensive operation and solvers commonly compute only the residual
1393:    associated to the first unconverged eigenpair.

1395:    The option `-eps_monitor_all` automatically activates this option.

1397:    Level: developer

1399: .seealso: [](ch:eps), `EPSGetTrackAll()`
1400: @*/
1401: PetscErrorCode EPSSetTrackAll(EPS eps,PetscBool trackall)
1402: {
1403:   PetscFunctionBegin;
1406:   eps->trackall = trackall;
1407:   PetscFunctionReturn(PETSC_SUCCESS);
1408: }

1410: /*@
1411:    EPSGetTrackAll - Returns the flag indicating whether all residual norms must
1412:    be computed or not.

1414:    Not Collective

1416:    Input Parameter:
1417: .  eps - the linear eigensolver context

1419:    Output Parameter:
1420: .  trackall - the returned flag

1422:    Level: developer

1424: .seealso: [](ch:eps), `EPSSetTrackAll()`
1425: @*/
1426: PetscErrorCode EPSGetTrackAll(EPS eps,PetscBool *trackall)
1427: {
1428:   PetscFunctionBegin;
1430:   PetscAssertPointer(trackall,2);
1431:   *trackall = eps->trackall;
1432:   PetscFunctionReturn(PETSC_SUCCESS);
1433: }

1435: /*@
1436:    EPSSetPurify - Disable eigenvector purification (which is enabled by default).

1438:    Logically Collective

1440:    Input Parameters:
1441: +  eps    - the linear eigensolver context
1442: -  purify - whether purification is done or not, use `PETSC_FALSE` to disable it

1444:    Options Database Key:
1445: .  -eps_purify (true|false) - toggles the purification flag

1447:    Notes:
1448:    By default, eigenvectors of generalized symmetric eigenproblems are purified
1449:    in order to purge directions in the nullspace of matrix $B$. If the user knows
1450:    that $B$ is non-singular, then purification can be safely deactivated and some
1451:    computational cost is avoided (this is particularly important in interval computations).

1453:    More details are given in section [](#sec:purif).

1455:    Level: intermediate

1457: .seealso: [](ch:eps), [](#sec:purif), `EPSGetPurify()`, `EPSSetInterval()`
1458: @*/
1459: PetscErrorCode EPSSetPurify(EPS eps,PetscBool purify)
1460: {
1461:   PetscFunctionBegin;
1464:   if (purify!=eps->purify) {
1465:     eps->purify = purify;
1466:     eps->state  = EPS_STATE_INITIAL;
1467:   }
1468:   PetscFunctionReturn(PETSC_SUCCESS);
1469: }

1471: /*@
1472:    EPSGetPurify - Returns the flag indicating whether purification is activated
1473:    or not.

1475:    Not Collective

1477:    Input Parameter:
1478: .  eps - the linear eigensolver context

1480:    Output Parameter:
1481: .  purify - the returned flag

1483:    Level: intermediate

1485: .seealso: [](ch:eps), `EPSSetPurify()`
1486: @*/
1487: PetscErrorCode EPSGetPurify(EPS eps,PetscBool *purify)
1488: {
1489:   PetscFunctionBegin;
1491:   PetscAssertPointer(purify,2);
1492:   *purify = eps->purify;
1493:   PetscFunctionReturn(PETSC_SUCCESS);
1494: }

1496: /*@
1497:    EPSSetOptionsPrefix - Sets the prefix used for searching for all
1498:    `EPS` options in the database.

1500:    Logically Collective

1502:    Input Parameters:
1503: +  eps    - the linear eigensolver context
1504: -  prefix - the prefix string to prepend to all `EPS` option requests

1506:    Notes:
1507:    A hyphen (-) must NOT be given at the beginning of the prefix name.
1508:    The first character of all runtime options is AUTOMATICALLY the
1509:    hyphen.

1511:    For example, to distinguish between the runtime options for two
1512:    different `EPS` contexts, one could call
1513: .vb
1514:    EPSSetOptionsPrefix(eps1,"eig1_")
1515:    EPSSetOptionsPrefix(eps2,"eig2_")
1516: .ve

1518:    Level: advanced

1520: .seealso: [](ch:eps), `EPSAppendOptionsPrefix()`, `EPSGetOptionsPrefix()`
1521: @*/
1522: PetscErrorCode EPSSetOptionsPrefix(EPS eps,const char prefix[])
1523: {
1524:   PetscFunctionBegin;
1526:   if (!eps->st) PetscCall(EPSGetST(eps,&eps->st));
1527:   PetscCall(STSetOptionsPrefix(eps->st,prefix));
1528:   if (!eps->V) PetscCall(EPSGetBV(eps,&eps->V));
1529:   PetscCall(BVSetOptionsPrefix(eps->V,prefix));
1530:   if (!eps->ds) PetscCall(EPSGetDS(eps,&eps->ds));
1531:   PetscCall(DSSetOptionsPrefix(eps->ds,prefix));
1532:   if (!eps->rg) PetscCall(EPSGetRG(eps,&eps->rg));
1533:   PetscCall(RGSetOptionsPrefix(eps->rg,prefix));
1534:   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)eps,prefix));
1535:   PetscFunctionReturn(PETSC_SUCCESS);
1536: }

1538: /*@
1539:    EPSAppendOptionsPrefix - Appends to the prefix used for searching for all
1540:    `EPS` options in the database.

1542:    Logically Collective

1544:    Input Parameters:
1545: +  eps    - the linear eigensolver context
1546: -  prefix - the prefix string to prepend to all `EPS` option requests

1548:    Notes:
1549:    A hyphen (-) must NOT be given at the beginning of the prefix name.
1550:    The first character of all runtime options is AUTOMATICALLY the hyphen.

1552:    Level: advanced

1554: .seealso: [](ch:eps), `EPSSetOptionsPrefix()`, `EPSGetOptionsPrefix()`
1555: @*/
1556: PetscErrorCode EPSAppendOptionsPrefix(EPS eps,const char prefix[])
1557: {
1558:   PetscFunctionBegin;
1560:   if (!eps->st) PetscCall(EPSGetST(eps,&eps->st));
1561:   PetscCall(STAppendOptionsPrefix(eps->st,prefix));
1562:   if (!eps->V) PetscCall(EPSGetBV(eps,&eps->V));
1563:   PetscCall(BVAppendOptionsPrefix(eps->V,prefix));
1564:   if (!eps->ds) PetscCall(EPSGetDS(eps,&eps->ds));
1565:   PetscCall(DSAppendOptionsPrefix(eps->ds,prefix));
1566:   if (!eps->rg) PetscCall(EPSGetRG(eps,&eps->rg));
1567:   PetscCall(RGAppendOptionsPrefix(eps->rg,prefix));
1568:   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)eps,prefix));
1569:   PetscFunctionReturn(PETSC_SUCCESS);
1570: }

1572: /*@
1573:    EPSGetOptionsPrefix - Gets the prefix used for searching for all
1574:    `EPS` options in the database.

1576:    Not Collective

1578:    Input Parameter:
1579: .  eps - the linear eigensolver context

1581:    Output Parameter:
1582: .  prefix - pointer to the prefix string used is returned

1584:    Level: advanced

1586: .seealso: [](ch:eps), `EPSSetOptionsPrefix()`, `EPSAppendOptionsPrefix()`
1587: @*/
1588: PetscErrorCode EPSGetOptionsPrefix(EPS eps,const char *prefix[])
1589: {
1590:   PetscFunctionBegin;
1592:   PetscAssertPointer(prefix,2);
1593:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)eps,prefix));
1594:   PetscFunctionReturn(PETSC_SUCCESS);
1595: }