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: }