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: /*@C
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[],void *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(PetscOptionsBoolGroupEnd("-eps_hamiltonian","Structured Hamiltonian eigenvalue problem","EPSSetProblemType",&flg));
116: if (flg) PetscCall(EPSSetProblemType(eps,EPS_HAMILT));
118: PetscCall(PetscOptionsBoolGroupBegin("-eps_ritz","Rayleigh-Ritz extraction","EPSSetExtraction",&flg));
119: if (flg) PetscCall(EPSSetExtraction(eps,EPS_RITZ));
120: PetscCall(PetscOptionsBoolGroup("-eps_harmonic","Harmonic Ritz extraction","EPSSetExtraction",&flg));
121: if (flg) PetscCall(EPSSetExtraction(eps,EPS_HARMONIC));
122: PetscCall(PetscOptionsBoolGroup("-eps_harmonic_relative","Relative harmonic Ritz extraction","EPSSetExtraction",&flg));
123: if (flg) PetscCall(EPSSetExtraction(eps,EPS_HARMONIC_RELATIVE));
124: PetscCall(PetscOptionsBoolGroup("-eps_harmonic_right","Right harmonic Ritz extraction","EPSSetExtraction",&flg));
125: if (flg) PetscCall(EPSSetExtraction(eps,EPS_HARMONIC_RIGHT));
126: PetscCall(PetscOptionsBoolGroup("-eps_harmonic_largest","Largest harmonic Ritz extraction","EPSSetExtraction",&flg));
127: if (flg) PetscCall(EPSSetExtraction(eps,EPS_HARMONIC_LARGEST));
128: PetscCall(PetscOptionsBoolGroup("-eps_refined","Refined Ritz extraction","EPSSetExtraction",&flg));
129: if (flg) PetscCall(EPSSetExtraction(eps,EPS_REFINED));
130: PetscCall(PetscOptionsBoolGroupEnd("-eps_refined_harmonic","Refined harmonic Ritz extraction","EPSSetExtraction",&flg));
131: if (flg) PetscCall(EPSSetExtraction(eps,EPS_REFINED_HARMONIC));
133: bal = eps->balance;
134: PetscCall(PetscOptionsEnum("-eps_balance","Balancing method","EPSSetBalance",EPSBalanceTypes,(PetscEnum)bal,(PetscEnum*)&bal,&flg1));
135: j = eps->balance_its;
136: PetscCall(PetscOptionsInt("-eps_balance_its","Number of iterations in balancing","EPSSetBalance",eps->balance_its,&j,&flg2));
137: r = eps->balance_cutoff;
138: PetscCall(PetscOptionsReal("-eps_balance_cutoff","Cutoff value in balancing","EPSSetBalance",eps->balance_cutoff,&r,&flg3));
139: if (flg1 || flg2 || flg3) PetscCall(EPSSetBalance(eps,bal,j,r));
141: i = eps->max_it;
142: PetscCall(PetscOptionsInt("-eps_max_it","Maximum number of iterations","EPSSetTolerances",eps->max_it,&i,&flg1));
143: r = eps->tol;
144: PetscCall(PetscOptionsReal("-eps_tol","Tolerance","EPSSetTolerances",SlepcDefaultTol(eps->tol),&r,&flg2));
145: if (flg1 || flg2) PetscCall(EPSSetTolerances(eps,r,i));
147: r = eps->thres;
148: PetscCall(PetscOptionsReal("-eps_threshold_absolute","Absolute threshold","EPSSetThreshold",r,&r,&flg));
149: if (flg) PetscCall(EPSSetThreshold(eps,r,PETSC_FALSE));
150: PetscCall(PetscOptionsReal("-eps_threshold_relative","Relative threshold","EPSSetThreshold",r,&r,&flg));
151: if (flg) PetscCall(EPSSetThreshold(eps,r,PETSC_TRUE));
153: PetscCall(PetscOptionsBoolGroupBegin("-eps_conv_rel","Relative error convergence test","EPSSetConvergenceTest",&flg));
154: if (flg) PetscCall(EPSSetConvergenceTest(eps,EPS_CONV_REL));
155: PetscCall(PetscOptionsBoolGroup("-eps_conv_norm","Convergence test relative to the eigenvalue and the matrix norms","EPSSetConvergenceTest",&flg));
156: if (flg) PetscCall(EPSSetConvergenceTest(eps,EPS_CONV_NORM));
157: PetscCall(PetscOptionsBoolGroup("-eps_conv_abs","Absolute error convergence test","EPSSetConvergenceTest",&flg));
158: if (flg) PetscCall(EPSSetConvergenceTest(eps,EPS_CONV_ABS));
159: PetscCall(PetscOptionsBoolGroupEnd("-eps_conv_user","User-defined convergence test","EPSSetConvergenceTest",&flg));
160: if (flg) PetscCall(EPSSetConvergenceTest(eps,EPS_CONV_USER));
162: PetscCall(PetscOptionsBoolGroupBegin("-eps_stop_basic","Stop iteration if all eigenvalues converged or max_it reached","EPSSetStoppingTest",&flg));
163: if (flg) PetscCall(EPSSetStoppingTest(eps,EPS_STOP_BASIC));
164: PetscCall(PetscOptionsBoolGroup("-eps_stop_threshold","Stop iteration if a converged eigenvalue is below/above the threshold","EPSSetStoppingTest",&flg));
165: if (flg) PetscCall(EPSSetStoppingTest(eps,EPS_STOP_THRESHOLD));
166: PetscCall(PetscOptionsBoolGroupEnd("-eps_stop_user","User-defined stopping test","EPSSetStoppingTest",&flg));
167: if (flg) PetscCall(EPSSetStoppingTest(eps,EPS_STOP_USER));
169: i = eps->nev;
170: PetscCall(PetscOptionsInt("-eps_nev","Number of eigenvalues to compute","EPSSetDimensions",eps->nev,&i,&flg1));
171: if (!flg1) i = PETSC_CURRENT;
172: j = eps->ncv;
173: PetscCall(PetscOptionsInt("-eps_ncv","Number of basis vectors","EPSSetDimensions",eps->ncv,&j,&flg2));
174: k = eps->mpd;
175: PetscCall(PetscOptionsInt("-eps_mpd","Maximum dimension of projected problem","EPSSetDimensions",eps->mpd,&k,&flg3));
176: if (flg1 || flg2 || flg3) PetscCall(EPSSetDimensions(eps,i,j,k));
178: PetscCall(PetscOptionsBoolGroupBegin("-eps_largest_magnitude","Compute largest eigenvalues in magnitude","EPSSetWhichEigenpairs",&flg));
179: if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_LARGEST_MAGNITUDE));
180: PetscCall(PetscOptionsBoolGroup("-eps_smallest_magnitude","Compute smallest eigenvalues in magnitude","EPSSetWhichEigenpairs",&flg));
181: if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_SMALLEST_MAGNITUDE));
182: PetscCall(PetscOptionsBoolGroup("-eps_largest_real","Compute eigenvalues with largest real parts","EPSSetWhichEigenpairs",&flg));
183: if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_LARGEST_REAL));
184: PetscCall(PetscOptionsBoolGroup("-eps_smallest_real","Compute eigenvalues with smallest real parts","EPSSetWhichEigenpairs",&flg));
185: if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_SMALLEST_REAL));
186: PetscCall(PetscOptionsBoolGroup("-eps_largest_imaginary","Compute eigenvalues with largest imaginary parts","EPSSetWhichEigenpairs",&flg));
187: if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_LARGEST_IMAGINARY));
188: PetscCall(PetscOptionsBoolGroup("-eps_smallest_imaginary","Compute eigenvalues with smallest imaginary parts","EPSSetWhichEigenpairs",&flg));
189: if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_SMALLEST_IMAGINARY));
190: PetscCall(PetscOptionsBoolGroup("-eps_target_magnitude","Compute eigenvalues closest to target","EPSSetWhichEigenpairs",&flg));
191: if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_TARGET_MAGNITUDE));
192: PetscCall(PetscOptionsBoolGroup("-eps_target_real","Compute eigenvalues with real parts closest to target","EPSSetWhichEigenpairs",&flg));
193: if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_TARGET_REAL));
194: PetscCall(PetscOptionsBoolGroup("-eps_target_imaginary","Compute eigenvalues with imaginary parts closest to target","EPSSetWhichEigenpairs",&flg));
195: if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_TARGET_IMAGINARY));
196: PetscCall(PetscOptionsBoolGroupEnd("-eps_all","Compute all eigenvalues in an interval or a region","EPSSetWhichEigenpairs",&flg));
197: if (flg) PetscCall(EPSSetWhichEigenpairs(eps,EPS_ALL));
199: PetscCall(PetscOptionsScalar("-eps_target","Value of the target","EPSSetTarget",eps->target,&s,&flg));
200: if (flg) {
201: if (eps->which!=EPS_TARGET_REAL && eps->which!=EPS_TARGET_IMAGINARY) PetscCall(EPSSetWhichEigenpairs(eps,EPS_TARGET_MAGNITUDE));
202: PetscCall(EPSSetTarget(eps,s));
203: }
205: k = 2;
206: PetscCall(PetscOptionsRealArray("-eps_interval","Computational interval (two real values separated with a comma without spaces)","EPSSetInterval",array,&k,&flg));
207: if (flg) {
208: PetscCheck(k>1,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_SIZ,"Must pass two values in -eps_interval (comma-separated without spaces)");
209: PetscCall(EPSSetWhichEigenpairs(eps,EPS_ALL));
210: PetscCall(EPSSetInterval(eps,array[0],array[1]));
211: }
213: PetscCall(PetscOptionsBool("-eps_true_residual","Compute true residuals explicitly","EPSSetTrueResidual",eps->trueres,&eps->trueres,NULL));
214: PetscCall(PetscOptionsBool("-eps_purify","Postprocess eigenvectors for purification","EPSSetPurify",eps->purify,&bval,&flg));
215: if (flg) PetscCall(EPSSetPurify(eps,bval));
216: PetscCall(PetscOptionsBool("-eps_two_sided","Use two-sided variant (to compute left eigenvectors)","EPSSetTwoSided",eps->twosided,&bval,&flg));
217: if (flg) PetscCall(EPSSetTwoSided(eps,bval));
219: /* -----------------------------------------------------------------------*/
220: /*
221: Cancels all monitors hardwired into code before call to EPSSetFromOptions()
222: */
223: PetscCall(PetscOptionsBool("-eps_monitor_cancel","Remove any hardwired monitor routines","EPSMonitorCancel",PETSC_FALSE,&flg,&set));
224: if (set && flg) PetscCall(EPSMonitorCancel(eps));
225: PetscCall(EPSMonitorSetFromOptions(eps,"-eps_monitor","first_approximation",NULL,PETSC_FALSE));
226: PetscCall(EPSMonitorSetFromOptions(eps,"-eps_monitor_all","all_approximations",NULL,PETSC_TRUE));
227: PetscCall(EPSMonitorSetFromOptions(eps,"-eps_monitor_conv","convergence_history",NULL,PETSC_FALSE));
229: /* -----------------------------------------------------------------------*/
230: PetscCall(PetscOptionsName("-eps_view","Print detailed information on solver used","EPSView",&set));
231: PetscCall(PetscOptionsName("-eps_view_vectors","View computed eigenvectors","EPSVectorsView",&set));
232: PetscCall(PetscOptionsName("-eps_view_values","View computed eigenvalues","EPSValuesView",&set));
233: PetscCall(PetscOptionsName("-eps_converged_reason","Print reason for convergence, and number of iterations","EPSConvergedReasonView",&set));
234: PetscCall(PetscOptionsName("-eps_error_absolute","Print absolute errors of each eigenpair","EPSErrorView",&set));
235: PetscCall(PetscOptionsName("-eps_error_relative","Print relative errors of each eigenpair","EPSErrorView",&set));
236: PetscCall(PetscOptionsName("-eps_error_backward","Print backward errors of each eigenpair","EPSErrorView",&set));
238: PetscTryTypeMethod(eps,setfromoptions,PetscOptionsObject);
239: PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)eps,PetscOptionsObject));
240: PetscOptionsEnd();
242: if (!eps->V) PetscCall(EPSGetBV(eps,&eps->V));
243: PetscCall(BVSetFromOptions(eps->V));
244: if (!eps->rg) PetscCall(EPSGetRG(eps,&eps->rg));
245: PetscCall(RGSetFromOptions(eps->rg));
246: if (eps->useds) {
247: if (!eps->ds) PetscCall(EPSGetDS(eps,&eps->ds));
248: PetscCall(EPSSetDSType(eps));
249: PetscCall(DSSetFromOptions(eps->ds));
250: }
251: if (!eps->st) PetscCall(EPSGetST(eps,&eps->st));
252: PetscCall(EPSSetDefaultST(eps));
253: PetscCall(STSetFromOptions(eps->st));
254: PetscFunctionReturn(PETSC_SUCCESS);
255: }
257: /*@
258: EPSGetTolerances - Gets the tolerance and maximum iteration count used
259: by the `EPS` convergence tests.
261: Not Collective
263: Input Parameter:
264: . eps - the linear eigensolver context
266: Output Parameters:
267: + tol - the convergence tolerance
268: - maxits - maximum number of iterations
270: Notes:
271: The user can specify `NULL` for any parameter that is not needed.
273: Level: intermediate
275: .seealso: [](ch:eps), `EPSSetTolerances()`
276: @*/
277: PetscErrorCode EPSGetTolerances(EPS eps,PetscReal *tol,PetscInt *maxits)
278: {
279: PetscFunctionBegin;
281: if (tol) *tol = eps->tol;
282: if (maxits) *maxits = eps->max_it;
283: PetscFunctionReturn(PETSC_SUCCESS);
284: }
286: /*@
287: EPSSetTolerances - Sets the tolerance and maximum iteration count used
288: by the `EPS` convergence tests.
290: Logically Collective
292: Input Parameters:
293: + eps - the linear eigensolver context
294: . tol - the convergence tolerance
295: - maxits - maximum number of iterations to use
297: Options Database Keys:
298: + -eps_tol \<tol\> - sets the convergence tolerance
299: - -eps_max_it \<maxits\> - sets the maximum number of iterations allowed
301: Note:
302: Use `PETSC_CURRENT` to retain the current value of any of the parameters.
303: Use `PETSC_DETERMINE` for either argument to assign a default value computed
304: internally (may be different in each solver).
305: For `maxits` use `PETSC_UNLIMITED` to indicate there is no upper bound on this value.
307: Level: intermediate
309: .seealso: [](ch:eps), `EPSGetTolerances()`
310: @*/
311: PetscErrorCode EPSSetTolerances(EPS eps,PetscReal tol,PetscInt maxits)
312: {
313: PetscFunctionBegin;
317: if (tol == (PetscReal)PETSC_DETERMINE) {
318: eps->tol = PETSC_DETERMINE;
319: eps->state = EPS_STATE_INITIAL;
320: } else if (tol != (PetscReal)PETSC_CURRENT) {
321: PetscCheck(tol>0.0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of tol. Must be > 0");
322: eps->tol = tol;
323: }
324: if (maxits == PETSC_DETERMINE) {
325: eps->max_it = PETSC_DETERMINE;
326: eps->state = EPS_STATE_INITIAL;
327: } else if (maxits == PETSC_UNLIMITED) {
328: eps->max_it = PETSC_INT_MAX;
329: } else if (maxits != PETSC_CURRENT) {
330: PetscCheck(maxits>0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of maxits. Must be > 0");
331: eps->max_it = maxits;
332: }
333: PetscFunctionReturn(PETSC_SUCCESS);
334: }
336: /*@
337: EPSGetDimensions - Gets the number of eigenvalues to compute
338: and the dimension of the subspace.
340: Not Collective
342: Input Parameter:
343: . eps - the linear eigensolver context
345: Output Parameters:
346: + nev - number of eigenvalues to compute
347: . ncv - the maximum dimension of the subspace to be used by the solver
348: - mpd - the maximum dimension allowed for the projected problem
350: Level: intermediate
352: .seealso: [](ch:eps), `EPSSetDimensions()`
353: @*/
354: PetscErrorCode EPSGetDimensions(EPS eps,PetscInt *nev,PetscInt *ncv,PetscInt *mpd)
355: {
356: PetscFunctionBegin;
358: if (nev) *nev = eps->nev? eps->nev: 1;
359: if (ncv) *ncv = eps->ncv;
360: if (mpd) *mpd = eps->mpd;
361: PetscFunctionReturn(PETSC_SUCCESS);
362: }
364: /*@
365: EPSSetDimensions - Sets the number of eigenvalues to compute
366: and the dimension of the subspace.
368: Logically Collective
370: Input Parameters:
371: + eps - the linear eigensolver context
372: . nev - number of eigenvalues to compute
373: . ncv - the maximum dimension of the subspace to be used by the solver
374: - mpd - the maximum dimension allowed for the projected problem
376: Options Database Keys:
377: + -eps_nev \<nev\> - sets the number of eigenvalues
378: . -eps_ncv \<ncv\> - sets the dimension of the subspace
379: - -eps_mpd \<mpd\> - sets the maximum projected dimension
381: Notes:
382: Use `PETSC_DETERMINE` for `ncv` and `mpd` to assign a reasonably good value, which is
383: dependent on the solution method. For any of the arguments, use `PETSC_CURRENT`
384: to preserve the current value.
386: The parameters `ncv` and `mpd` are intimately related, so that the user is advised
387: to set one of them at most. Normal usage is\:
389: 1. In cases where `nev` is small, the user sets `ncv` (a reasonable default is `2*nev`).
390: 2. In cases where `nev` is large, the user sets `mpd`.
392: The value of `ncv` should always be between `nev` and `(nev+mpd)`, typically
393: `ncv=nev+mpd`. If `nev` is not too large, `mpd=nev` is a reasonable choice, otherwise
394: a smaller value should be used.
396: When computing all eigenvalues in an interval, see `EPSSetInterval()`, these
397: parameters lose relevance, and tuning must be done with
398: `EPSKrylovSchurSetDimensions()`.
400: Level: intermediate
402: .seealso: [](ch:eps), `EPSGetDimensions()`, `EPSSetInterval()`, `EPSKrylovSchurSetDimensions()`
403: @*/
404: PetscErrorCode EPSSetDimensions(EPS eps,PetscInt nev,PetscInt ncv,PetscInt mpd)
405: {
406: PetscFunctionBegin;
411: if (nev != PETSC_CURRENT) {
412: PetscCheck(nev>0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of nev. Must be > 0");
413: eps->nev = nev;
414: }
415: if (ncv == PETSC_DETERMINE) {
416: eps->ncv = PETSC_DETERMINE;
417: } else if (ncv != PETSC_CURRENT) {
418: PetscCheck(ncv>0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of ncv. Must be > 0");
419: eps->ncv = ncv;
420: }
421: if (mpd == PETSC_DETERMINE) {
422: eps->mpd = PETSC_DETERMINE;
423: } else if (mpd != PETSC_CURRENT) {
424: PetscCheck(mpd>0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of mpd. Must be > 0");
425: eps->mpd = mpd;
426: }
427: eps->state = EPS_STATE_INITIAL;
428: PetscFunctionReturn(PETSC_SUCCESS);
429: }
431: /*@
432: EPSSetWhichEigenpairs - Specifies which portion of the spectrum is
433: to be sought.
435: Logically Collective
437: Input Parameters:
438: + eps - the linear eigensolver context
439: - which - the portion of the spectrum to be sought, see `EPSWhich` for possible values
441: Options Database Keys:
442: + -eps_largest_magnitude - sets largest eigenvalues in magnitude
443: . -eps_smallest_magnitude - sets smallest eigenvalues in magnitude
444: . -eps_largest_real - sets largest real parts
445: . -eps_smallest_real - sets smallest real parts
446: . -eps_largest_imaginary - sets largest imaginary parts
447: . -eps_smallest_imaginary - sets smallest imaginary parts
448: . -eps_target_magnitude - sets eigenvalues closest to target
449: . -eps_target_real - sets real parts closest to target
450: . -eps_target_imaginary - sets imaginary parts closest to target
451: - -eps_all - sets all eigenvalues in an interval or region
453: Notes:
454: Not all eigensolvers implemented in `EPS` account for all the possible values
455: of `which`. Also, some values make sense only for certain types of
456: problems. If SLEPc is compiled for real numbers `EPS_LARGEST_IMAGINARY`
457: and `EPS_SMALLEST_IMAGINARY` use the absolute value of the imaginary part
458: for eigenvalue selection.
460: The target is a scalar value provided with `EPSSetTarget()`.
462: The criterion `EPS_TARGET_IMAGINARY` is available only in case PETSc and
463: SLEPc have been built with complex scalars.
465: `EPS_ALL` is intended for use in combination with an interval (see
466: `EPSSetInterval()`), when all eigenvalues within the interval are requested,
467: or in the context of the `EPSCISS` solver for computing all eigenvalues in a region.
469: Level: intermediate
471: .seealso: [](ch:eps), `EPSGetWhichEigenpairs()`, `EPSSetTarget()`, `EPSSetInterval()`, `EPSSetDimensions()`, `EPSSetEigenvalueComparison()`, `EPSWhich`
472: @*/
473: PetscErrorCode EPSSetWhichEigenpairs(EPS eps,EPSWhich which)
474: {
475: PetscFunctionBegin;
478: switch (which) {
479: case EPS_LARGEST_MAGNITUDE:
480: case EPS_SMALLEST_MAGNITUDE:
481: case EPS_LARGEST_REAL:
482: case EPS_SMALLEST_REAL:
483: case EPS_LARGEST_IMAGINARY:
484: case EPS_SMALLEST_IMAGINARY:
485: case EPS_TARGET_MAGNITUDE:
486: case EPS_TARGET_REAL:
487: #if defined(PETSC_USE_COMPLEX)
488: case EPS_TARGET_IMAGINARY:
489: #endif
490: case EPS_ALL:
491: case EPS_WHICH_USER:
492: if (eps->which != which) {
493: eps->state = EPS_STATE_INITIAL;
494: eps->which = which;
495: }
496: break;
497: #if !defined(PETSC_USE_COMPLEX)
498: case EPS_TARGET_IMAGINARY:
499: SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"EPS_TARGET_IMAGINARY can be used only with complex scalars");
500: #endif
501: default:
502: SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid 'which' value");
503: }
504: PetscFunctionReturn(PETSC_SUCCESS);
505: }
507: /*@
508: EPSGetWhichEigenpairs - Returns which portion of the spectrum is to be
509: sought.
511: Not Collective
513: Input Parameter:
514: . eps - the linear eigensolver context
516: Output Parameter:
517: . which - the portion of the spectrum to be sought, see `EPSWhich` for possible values
519: Level: intermediate
521: .seealso: [](ch:eps), `EPSSetWhichEigenpairs()`, `EPSWhich`
522: @*/
523: PetscErrorCode EPSGetWhichEigenpairs(EPS eps,EPSWhich *which)
524: {
525: PetscFunctionBegin;
527: PetscAssertPointer(which,2);
528: *which = eps->which;
529: PetscFunctionReturn(PETSC_SUCCESS);
530: }
532: /*@
533: EPSSetThreshold - Sets the threshold used in the threshold stopping test.
535: Logically Collective
537: Input Parameters:
538: + eps - the linear eigensolver context
539: . thres - the threshold value
540: - rel - whether the threshold is relative or not
542: Options Database Keys:
543: + -eps_threshold_absolute \<thres\> - sets an absolute threshold
544: - -eps_threshold_relative \<thres\> - sets a relative threshold
546: Notes:
547: This function internally calls `EPSSetStoppingTest()` to set a special stopping
548: test based on the threshold, where eigenvalues are computed in sequence until
549: one of the computed eigenvalues is below the threshold `thres` (in magnitude).
550: This is the interpretation in case of searching for largest eigenvalues in magnitude,
551: see `EPSSetWhichEigenpairs()`.
553: If the solver is configured to compute smallest magnitude eigenvalues, then the
554: threshold must be interpreted in the opposite direction, i.e., the computation
555: will stop when one of the computed values is above the threshold (in magnitude).
557: The threshold can also be used when computing largest/smallest real eigenvalues
558: (i.e, rightmost or leftmost), in which case the threshold is allowed to be
559: negative. The solver will stop when one of the computed eigenvalues is above
560: or below the threshold (considering the real part of the eigenvalue). This mode
561: is allowed only in problem types whose eigenvalues are always real (e.g., `EPS_HEP`).
563: In the case of largest magnitude eigenvalues, the threshold can be made relative
564: with respect to the dominant eigenvalue. Otherwise, the argument `rel` should be
565: `PETSC_FALSE`.
567: An additional use case is with target magnitude selection of eigenvalues (e.g.,
568: with shift-and-invert), but this must be used with caution to avoid unexpected
569: behavior. With an absolute threshold, the solver will assume that leftmost
570: eigenvalues are being computed (e.g., with `target`=0 for a problem with real
571: positive eigenvalues). In case of a relative threshold, a value of `thres`<1
572: implies that the wanted eigenvalues are the largest ones, and otherwise the
573: solver assumes that smallest eigenvalues are being computed.
575: The test against the threshold is done for converged eigenvalues, which
576: implies that the final number of converged eigenvalues will be at least
577: one more than the actual number of values below/above the threshold.
579: Since the number of computed eigenvalues is not known a priori, the solver
580: will need to reallocate the basis of vectors internally, to have enough room
581: to accommodate all the eigenvectors. Hence, this option must be used with
582: caution to avoid out-of-memory problems. The recommendation is to set the value
583: of `ncv` to be larger than the estimated number of eigenvalues, to minimize the
584: number of reallocations.
586: If a number of wanted eigenvalues has been set with `EPSSetDimensions()`
587: it is also taken into account and the solver will stop when one of the two
588: conditions (threshold or number of converged values) is met.
590: Use `EPSSetStoppingTest()` to return to the usual computation of a fixed number
591: of eigenvalues.
593: Level: advanced
595: .seealso: [](ch:eps), `EPSGetThreshold()`, `EPSSetStoppingTest()`, `EPSSetDimensions()`, `EPSSetWhichEigenpairs()`, `EPSSetProblemType()`
596: @*/
597: PetscErrorCode EPSSetThreshold(EPS eps,PetscReal thres,PetscBool rel)
598: {
599: PetscFunctionBegin;
603: if (eps->thres != thres || eps->threlative != rel) {
604: eps->thres = thres;
605: eps->threlative = rel;
606: eps->state = EPS_STATE_INITIAL;
607: PetscCall(EPSSetStoppingTest(eps,EPS_STOP_THRESHOLD));
608: }
609: PetscFunctionReturn(PETSC_SUCCESS);
610: }
612: /*@
613: EPSGetThreshold - Gets the threshold used by the threshold stopping test.
615: Not Collective
617: Input Parameter:
618: . eps - the linear eigensolver context
620: Output Parameters:
621: + thres - the threshold
622: - rel - whether the threshold is relative or not
624: Level: advanced
626: .seealso: [](ch:eps), `EPSSetThreshold()`
627: @*/
628: PetscErrorCode EPSGetThreshold(EPS eps,PetscReal *thres,PetscBool *rel)
629: {
630: PetscFunctionBegin;
632: if (thres) *thres = eps->thres;
633: if (rel) *rel = eps->threlative;
634: PetscFunctionReturn(PETSC_SUCCESS);
635: }
637: /*@C
638: EPSSetEigenvalueComparison - Specifies the eigenvalue comparison function
639: when `EPSSetWhichEigenpairs()` is set to `EPS_WHICH_USER`.
641: Logically Collective
643: Input Parameters:
644: + eps - the linear eigensolver context
645: . func - the comparison function, see `SlepcEigenvalueComparisonFn` for the calling sequence
646: - ctx - a context pointer (the last parameter to the comparison function)
648: Level: advanced
650: .seealso: [](ch:eps), `EPSSetWhichEigenpairs()`, `EPSWhich`
651: @*/
652: PetscErrorCode EPSSetEigenvalueComparison(EPS eps,SlepcEigenvalueComparisonFn *func,void *ctx)
653: {
654: PetscFunctionBegin;
656: eps->sc->comparison = func;
657: eps->sc->comparisonctx = ctx;
658: eps->which = EPS_WHICH_USER;
659: PetscFunctionReturn(PETSC_SUCCESS);
660: }
662: /*@C
663: EPSSetArbitrarySelection - Specifies a function intended to look for
664: eigenvalues according to an arbitrary selection criterion. This criterion
665: can be based on a computation involving the current eigenvector approximation.
667: Logically Collective
669: Input Parameters:
670: + eps - the linear eigensolver context
671: . func - the arbitrary selection function, see `SlepcArbitrarySelectionFn` for a calling sequence
672: - ctx - a context pointer (the last parameter to the arbitrary selection function)
674: Notes:
675: This provides a mechanism to select eigenpairs by evaluating a user-defined
676: function. When a function has been provided, the default selection based on
677: sorting the eigenvalues is replaced by the sorting of the results of this
678: function (with the same sorting criterion given in `EPSSetWhichEigenpairs()`).
680: For instance, suppose you want to compute those eigenvectors that maximize
681: a certain computable expression. Then implement the computation using
682: the arguments `xr` and `xi`, and return the result in `rr`. Then set the standard
683: sorting by magnitude so that the eigenpair with largest value of `rr` is
684: selected.
686: This evaluation function is collective, that is, all processes call it and
687: it can use collective operations; furthermore, the computed result must
688: be the same in all processes.
690: The result of `func` is expressed as a complex number so that it is possible to
691: use the standard eigenvalue sorting functions, but normally only `rr` is used.
692: Set `ri` to zero unless it is meaningful in your application.
694: Level: advanced
696: .seealso: [](ch:eps), `EPSSetWhichEigenpairs()`
697: @*/
698: PetscErrorCode EPSSetArbitrarySelection(EPS eps,SlepcArbitrarySelectionFn *func,void *ctx)
699: {
700: PetscFunctionBegin;
702: eps->arbitrary = func;
703: eps->arbitraryctx = ctx;
704: eps->state = EPS_STATE_INITIAL;
705: PetscFunctionReturn(PETSC_SUCCESS);
706: }
708: /*@C
709: EPSSetConvergenceTestFunction - Sets a function to compute the error estimate
710: used in the convergence test.
712: Logically Collective
714: Input Parameters:
715: + eps - the linear eigensolver context
716: . func - convergence test function, see `EPSConvergenceTestFn` for the calling sequence
717: . ctx - context for private data for the convergence routine (may be `NULL`)
718: - destroy - a routine for destroying the context (may be `NULL`), see `PetscCtxDestroyFn`
719: for the calling sequence
721: Notes:
722: When this is called with a user-defined function, then the convergence
723: criterion is set to `EPS_CONV_USER`, see `EPSSetConvergenceTest()`.
725: If the error estimate returned by the convergence test function is less than
726: the tolerance, then the eigenvalue is accepted as converged.
728: Level: advanced
730: .seealso: [](ch:eps), `EPSSetConvergenceTest()`, `EPSSetTolerances()`
731: @*/
732: PetscErrorCode EPSSetConvergenceTestFunction(EPS eps,EPSConvergenceTestFn *func,void *ctx,PetscCtxDestroyFn *destroy)
733: {
734: PetscFunctionBegin;
736: if (eps->convergeddestroy) PetscCall((*eps->convergeddestroy)(&eps->convergedctx));
737: eps->convergeduser = func;
738: eps->convergeddestroy = destroy;
739: eps->convergedctx = ctx;
740: if (func == EPSConvergedRelative) eps->conv = EPS_CONV_REL;
741: else if (func == EPSConvergedNorm) eps->conv = EPS_CONV_NORM;
742: else if (func == EPSConvergedAbsolute) eps->conv = EPS_CONV_ABS;
743: else {
744: eps->conv = EPS_CONV_USER;
745: eps->converged = eps->convergeduser;
746: }
747: PetscFunctionReturn(PETSC_SUCCESS);
748: }
750: /*@
751: EPSSetConvergenceTest - Specifies how to compute the error estimate
752: used in the convergence test.
754: Logically Collective
756: Input Parameters:
757: + eps - the linear eigensolver context
758: - conv - the type of convergence test, see `EPSConv` for possible values
760: Options Database Keys:
761: + -eps_conv_abs - sets the absolute convergence test
762: . -eps_conv_rel - sets the convergence test relative to the eigenvalue
763: . -eps_conv_norm - sets the convergence test relative to the matrix norms
764: - -eps_conv_user - selects the user-defined convergence test
766: Level: intermediate
768: .seealso: [](ch:eps), `EPSGetConvergenceTest()`, `EPSSetConvergenceTestFunction()`, `EPSSetStoppingTest()`, `EPSConv`
769: @*/
770: PetscErrorCode EPSSetConvergenceTest(EPS eps,EPSConv conv)
771: {
772: PetscFunctionBegin;
775: switch (conv) {
776: case EPS_CONV_ABS: eps->converged = EPSConvergedAbsolute; break;
777: case EPS_CONV_REL: eps->converged = EPSConvergedRelative; break;
778: case EPS_CONV_NORM: eps->converged = EPSConvergedNorm; break;
779: case EPS_CONV_USER:
780: PetscCheck(eps->convergeduser,PetscObjectComm((PetscObject)eps),PETSC_ERR_ORDER,"Must call EPSSetConvergenceTestFunction() first");
781: eps->converged = eps->convergeduser;
782: break;
783: default:
784: SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid 'conv' value");
785: }
786: eps->conv = conv;
787: PetscFunctionReturn(PETSC_SUCCESS);
788: }
790: /*@
791: EPSGetConvergenceTest - Gets the method used to compute the error estimate
792: used in the convergence test.
794: Not Collective
796: Input Parameter:
797: . eps - the linear eigensolver context
799: Output Parameter:
800: . conv - the type of convergence test
802: Level: intermediate
804: .seealso: [](ch:eps), `EPSSetConvergenceTest()`, `EPSConv`
805: @*/
806: PetscErrorCode EPSGetConvergenceTest(EPS eps,EPSConv *conv)
807: {
808: PetscFunctionBegin;
810: PetscAssertPointer(conv,2);
811: *conv = eps->conv;
812: PetscFunctionReturn(PETSC_SUCCESS);
813: }
815: /*@C
816: EPSSetStoppingTestFunction - Sets a function to decide when to stop the outer
817: iteration of the eigensolver.
819: Logically Collective
821: Input Parameters:
822: + eps - the linear eigensolver context
823: . func - stopping test function, see `EPSStoppingTestFn` for the calling sequence
824: . ctx - context for private data for the stopping routine (may be `NULL`)
825: - destroy - a routine for destroying the context (may be `NULL`), see `PetscCtxDestroyFn`
826: for the calling sequence
828: Note:
829: When implementing a function for this, normal usage is to first call the
830: default routine `EPSStoppingBasic()` and then set `reason` to `EPS_CONVERGED_USER`
831: if some user-defined conditions have been met. To let the eigensolver continue
832: iterating, the result must be left as `EPS_CONVERGED_ITERATING`.
834: Level: advanced
836: .seealso: [](ch:eps), `EPSSetStoppingTest()`, `EPSStoppingBasic()`
837: @*/
838: PetscErrorCode EPSSetStoppingTestFunction(EPS eps,EPSStoppingTestFn *func,void *ctx,PetscCtxDestroyFn *destroy)
839: {
840: PetscFunctionBegin;
842: if (eps->stoppingdestroy) PetscCall((*eps->stoppingdestroy)(&eps->stoppingctx));
843: eps->stoppinguser = func;
844: eps->stoppingdestroy = destroy;
845: eps->stoppingctx = ctx;
846: if (func == EPSStoppingBasic) PetscCall(EPSSetStoppingTest(eps,EPS_STOP_BASIC));
847: else if (func == EPSStoppingThreshold) PetscCall(EPSSetStoppingTest(eps,EPS_STOP_THRESHOLD));
848: else {
849: eps->stop = EPS_STOP_USER;
850: eps->stopping = eps->stoppinguser;
851: }
852: PetscFunctionReturn(PETSC_SUCCESS);
853: }
855: /*@
856: EPSSetStoppingTest - Specifies how to decide the termination of the outer
857: loop of the eigensolver.
859: Logically Collective
861: Input Parameters:
862: + eps - the linear eigensolver context
863: - stop - the type of stopping test, see `EPSStop`
865: Options Database Keys:
866: + -eps_stop_basic - sets the default stopping test
867: . -eps_stop_threshold - sets the threshold stopping test
868: - -eps_stop_user - selects the user-defined stopping test
870: Level: advanced
872: .seealso: [](ch:eps), `EPSGetStoppingTest()`, `EPSSetStoppingTestFunction()`, `EPSSetConvergenceTest()`, `EPSStop`
873: @*/
874: PetscErrorCode EPSSetStoppingTest(EPS eps,EPSStop stop)
875: {
876: PetscFunctionBegin;
879: switch (stop) {
880: case EPS_STOP_BASIC: eps->stopping = EPSStoppingBasic; break;
881: case EPS_STOP_THRESHOLD: eps->stopping = EPSStoppingThreshold; break;
882: case EPS_STOP_USER:
883: PetscCheck(eps->stoppinguser,PetscObjectComm((PetscObject)eps),PETSC_ERR_ORDER,"Must call EPSSetStoppingTestFunction() first");
884: eps->stopping = eps->stoppinguser;
885: break;
886: default:
887: SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid 'stop' value");
888: }
889: eps->stop = stop;
890: PetscFunctionReturn(PETSC_SUCCESS);
891: }
893: /*@
894: EPSGetStoppingTest - Gets the method used to decide the termination of the outer
895: loop of the eigensolver.
897: Not Collective
899: Input Parameter:
900: . eps - the linear eigensolver context
902: Output Parameter:
903: . stop - the type of stopping test
905: Level: advanced
907: .seealso: [](ch:eps), `EPSSetStoppingTest()`, `EPSStop`
908: @*/
909: PetscErrorCode EPSGetStoppingTest(EPS eps,EPSStop *stop)
910: {
911: PetscFunctionBegin;
913: PetscAssertPointer(stop,2);
914: *stop = eps->stop;
915: PetscFunctionReturn(PETSC_SUCCESS);
916: }
918: /*@
919: EPSSetProblemType - Specifies the type of the eigenvalue problem.
921: Logically Collective
923: Input Parameters:
924: + eps - the linear eigensolver context
925: - type - a known type of eigenvalue problem
927: Options Database Keys:
928: + -eps_hermitian - Hermitian eigenvalue problem
929: . -eps_gen_hermitian - generalized Hermitian eigenvalue problem
930: . -eps_non_hermitian - non-Hermitian eigenvalue problem
931: . -eps_gen_non_hermitian - generalized non-Hermitian eigenvalue problem
932: . -eps_pos_gen_non_hermitian - generalized non-Hermitian eigenvalue problem
933: with positive semi-definite $B$
934: . -eps_gen_indefinite - generalized Hermitian-indefinite eigenvalue problem
935: . -eps_bse - structured Bethe-Salpeter eigenvalue problem
936: - -eps_hamiltonian - structured Hamiltonian eigenvalue problem
938: Notes:
939: This function must be used to instruct SLEPc to exploit symmetry or other
940: kind of structure. If no
941: problem type is specified, by default a non-Hermitian problem is assumed
942: (either standard or generalized). If the user knows that the problem is
943: Hermitian (i.e., $A=A^*$) or generalized Hermitian (i.e., $A=A^*$, $B=B^*$,
944: and $B$ positive definite) then it is recommended to set the problem type so
945: that the eigensolver can exploit these properties.
947: If the user does not call this function, the solver will use a reasonable
948: guess.
950: For structured problem types such as `EPS_BSE`, the matrices passed in via
951: `EPSSetOperators()` must have been created with the corresponding helper
952: function, i.e., `MatCreateBSE()`.
954: Level: intermediate
956: .seealso: [](ch:eps), `EPSSetOperators()`, `EPSSetType()`, `EPSGetProblemType()`, `EPSProblemType`
957: @*/
958: PetscErrorCode EPSSetProblemType(EPS eps,EPSProblemType type)
959: {
960: PetscFunctionBegin;
963: if (type == eps->problem_type) PetscFunctionReturn(PETSC_SUCCESS);
964: switch (type) {
965: case EPS_HEP:
966: eps->isgeneralized = PETSC_FALSE;
967: eps->ishermitian = PETSC_TRUE;
968: eps->ispositive = PETSC_FALSE;
969: eps->isstructured = PETSC_FALSE;
970: break;
971: case EPS_NHEP:
972: eps->isgeneralized = PETSC_FALSE;
973: eps->ishermitian = PETSC_FALSE;
974: eps->ispositive = PETSC_FALSE;
975: eps->isstructured = PETSC_FALSE;
976: break;
977: case EPS_GHEP:
978: eps->isgeneralized = PETSC_TRUE;
979: eps->ishermitian = PETSC_TRUE;
980: eps->ispositive = PETSC_TRUE;
981: eps->isstructured = PETSC_FALSE;
982: break;
983: case EPS_GNHEP:
984: eps->isgeneralized = PETSC_TRUE;
985: eps->ishermitian = PETSC_FALSE;
986: eps->ispositive = PETSC_FALSE;
987: eps->isstructured = PETSC_FALSE;
988: break;
989: case EPS_PGNHEP:
990: eps->isgeneralized = PETSC_TRUE;
991: eps->ishermitian = PETSC_FALSE;
992: eps->ispositive = PETSC_TRUE;
993: eps->isstructured = PETSC_FALSE;
994: break;
995: case EPS_GHIEP:
996: eps->isgeneralized = PETSC_TRUE;
997: eps->ishermitian = PETSC_TRUE;
998: eps->ispositive = PETSC_FALSE;
999: eps->isstructured = PETSC_FALSE;
1000: break;
1001: case EPS_BSE:
1002: eps->isgeneralized = PETSC_FALSE;
1003: eps->ishermitian = PETSC_FALSE;
1004: eps->ispositive = PETSC_FALSE;
1005: eps->isstructured = PETSC_TRUE;
1006: break;
1007: case EPS_HAMILT:
1008: eps->isgeneralized = PETSC_FALSE;
1009: eps->ishermitian = PETSC_FALSE;
1010: eps->ispositive = PETSC_FALSE;
1011: eps->isstructured = PETSC_TRUE;
1012: break;
1013: default:
1014: SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_WRONG,"Unknown eigenvalue problem type");
1015: }
1016: eps->problem_type = type;
1017: eps->state = EPS_STATE_INITIAL;
1018: PetscFunctionReturn(PETSC_SUCCESS);
1019: }
1021: /*@
1022: EPSGetProblemType - Gets the problem type from the `EPS` object.
1024: Not Collective
1026: Input Parameter:
1027: . eps - the linear eigensolver context
1029: Output Parameter:
1030: . type - the problem type
1032: Level: intermediate
1034: .seealso: [](ch:eps), `EPSSetProblemType()`, `EPSProblemType`
1035: @*/
1036: PetscErrorCode EPSGetProblemType(EPS eps,EPSProblemType *type)
1037: {
1038: PetscFunctionBegin;
1040: PetscAssertPointer(type,2);
1041: *type = eps->problem_type;
1042: PetscFunctionReturn(PETSC_SUCCESS);
1043: }
1045: /*@
1046: EPSSetExtraction - Specifies the type of extraction technique to be employed
1047: by the eigensolver.
1049: Logically Collective
1051: Input Parameters:
1052: + eps - the linear eigensolver context
1053: - extr - a known type of extraction
1055: Options Database Keys:
1056: + -eps_ritz - Rayleigh-Ritz extraction
1057: . -eps_harmonic - harmonic Ritz extraction
1058: . -eps_harmonic_relative - harmonic Ritz extraction relative to the eigenvalue
1059: . -eps_harmonic_right - harmonic Ritz extraction for rightmost eigenvalues
1060: . -eps_harmonic_largest - harmonic Ritz extraction for largest magnitude (without target)
1061: . -eps_refined - refined Ritz extraction
1062: - -eps_refined_harmonic - refined harmonic Ritz extraction
1064: Notes:
1065: Not all eigensolvers support all types of extraction.
1067: By default, a standard Rayleigh-Ritz extraction is used. Other extractions
1068: may be useful when computing interior eigenvalues.
1070: Harmonic-type extractions are used in combination with a target, see `EPSSetTarget()`.
1072: Level: advanced
1074: .seealso: [](ch:eps), [](#sec:harmonic), `EPSSetTarget()`, `EPSGetExtraction()`, `EPSExtraction`
1075: @*/
1076: PetscErrorCode EPSSetExtraction(EPS eps,EPSExtraction extr)
1077: {
1078: PetscFunctionBegin;
1081: if (eps->extraction != extr) {
1082: eps->state = EPS_STATE_INITIAL;
1083: eps->extraction = extr;
1084: }
1085: PetscFunctionReturn(PETSC_SUCCESS);
1086: }
1088: /*@
1089: EPSGetExtraction - Gets the extraction type used by the `EPS` object.
1091: Not Collective
1093: Input Parameter:
1094: . eps - the linear eigensolver context
1096: Output Parameter:
1097: . extr - name of extraction type
1099: Level: advanced
1101: .seealso: [](ch:eps), `EPSSetExtraction()`, `EPSExtraction`
1102: @*/
1103: PetscErrorCode EPSGetExtraction(EPS eps,EPSExtraction *extr)
1104: {
1105: PetscFunctionBegin;
1107: PetscAssertPointer(extr,2);
1108: *extr = eps->extraction;
1109: PetscFunctionReturn(PETSC_SUCCESS);
1110: }
1112: /*@
1113: EPSSetBalance - Specifies the balancing technique to be employed by the
1114: eigensolver, and some parameters associated to it.
1116: Logically Collective
1118: Input Parameters:
1119: + eps - the linear eigensolver context
1120: . bal - the balancing method, see `EPSBalance` for possible values
1121: . its - number of iterations of the balancing algorithm
1122: - cutoff - cutoff value
1124: Options Database Keys:
1125: + -eps_balance \<bal\> - the balancing method, one of `none`, `oneside`, `twoside`, or `user`
1126: . -eps_balance_its \<its\> - number of iterations
1127: - -eps_balance_cutoff \<cutoff\> - cutoff value
1129: Notes:
1130: When balancing is enabled, the solver works implicitly with matrix $DAD^{-1}$,
1131: where $D$ is an appropriate diagonal matrix. This improves the accuracy of
1132: the computed results in some cases, see [](sec:balancing).
1134: Balancing makes sense only for non-Hermitian problems when the required
1135: precision is high (i.e., a small tolerance such as `1e-14`).
1137: By default, balancing is disabled. The two-sided method is much more
1138: effective than the one-sided counterpart, but it requires the system
1139: matrices to have the `MatMultTranspose()` operation defined. The methods
1140: are described in {cite:p}`Che00`.
1142: The parameter `its` is the number of iterations performed by the method. The
1143: `cutoff` value is used only in the two-side variant. Use `PETSC_DETERMINE` to assign
1144: a reasonably good value, or `PETSC_CURRENT` to leave the value unchanged.
1146: User-defined balancing is allowed provided that the corresponding matrix
1147: is set via `STSetBalanceMatrix()`.
1149: Level: intermediate
1151: .seealso: [](ch:eps), [](sec:balancing), `EPSGetBalance()`, `EPSBalance`, `STSetBalanceMatrix()`
1152: @*/
1153: PetscErrorCode EPSSetBalance(EPS eps,EPSBalance bal,PetscInt its,PetscReal cutoff)
1154: {
1155: PetscFunctionBegin;
1160: switch (bal) {
1161: case EPS_BALANCE_NONE:
1162: case EPS_BALANCE_ONESIDE:
1163: case EPS_BALANCE_TWOSIDE:
1164: case EPS_BALANCE_USER:
1165: if (eps->balance != bal) {
1166: eps->state = EPS_STATE_INITIAL;
1167: eps->balance = bal;
1168: }
1169: break;
1170: default:
1171: SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid value of argument 'bal'");
1172: }
1173: if (its==PETSC_DETERMINE) eps->balance_its = 5;
1174: else if (its!=PETSC_CURRENT) {
1175: PetscCheck(its>0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of its. Must be > 0");
1176: eps->balance_its = its;
1177: }
1178: if (cutoff==(PetscReal)PETSC_DETERMINE) eps->balance_cutoff = 1e-8;
1179: else if (cutoff!=(PetscReal)PETSC_CURRENT) {
1180: PetscCheck(cutoff>0.0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of cutoff. Must be > 0");
1181: eps->balance_cutoff = cutoff;
1182: }
1183: PetscFunctionReturn(PETSC_SUCCESS);
1184: }
1186: /*@
1187: EPSGetBalance - Gets the balancing type used by the `EPS` object, and the
1188: associated parameters.
1190: Not Collective
1192: Input Parameter:
1193: . eps - the linear eigensolver context
1195: Output Parameters:
1196: + bal - the balancing method
1197: . its - number of iterations of the balancing algorithm
1198: - cutoff - cutoff value
1200: Level: intermediate
1202: Note:
1203: The user can specify `NULL` for any parameter that is not needed.
1205: .seealso: [](ch:eps), `EPSSetBalance()`, `EPSBalance`
1206: @*/
1207: PetscErrorCode EPSGetBalance(EPS eps,EPSBalance *bal,PetscInt *its,PetscReal *cutoff)
1208: {
1209: PetscFunctionBegin;
1211: if (bal) *bal = eps->balance;
1212: if (its) *its = eps->balance_its;
1213: if (cutoff) *cutoff = eps->balance_cutoff;
1214: PetscFunctionReturn(PETSC_SUCCESS);
1215: }
1217: /*@
1218: EPSSetTwoSided - Sets the solver to use a two-sided variant so that left
1219: eigenvectors are also computed.
1221: Logically Collective
1223: Input Parameters:
1224: + eps - the linear eigensolver context
1225: - twosided - whether the two-sided variant is to be used or not
1227: Options Database Key:
1228: . -eps_two_sided - toggles the twosided flag
1230: Notes:
1231: If the user sets `twosided`=`PETSC_TRUE` then the solver uses a variant of
1232: the algorithm that computes both right and left eigenvectors. This is
1233: usually much more costly. This option is not available in all solvers,
1234: see table [](#tab:support).
1236: When using two-sided solvers, the problem matrices must have both the
1237: `MATOP_MULT` and `MATOP_MULT_TRANSPOSE` operations defined.
1239: Level: advanced
1241: .seealso: [](ch:eps), `EPSGetTwoSided()`, `EPSGetLeftEigenvector()`
1242: @*/
1243: PetscErrorCode EPSSetTwoSided(EPS eps,PetscBool twosided)
1244: {
1245: PetscFunctionBegin;
1248: if (twosided!=eps->twosided) {
1249: eps->twosided = twosided;
1250: eps->state = EPS_STATE_INITIAL;
1251: }
1252: PetscFunctionReturn(PETSC_SUCCESS);
1253: }
1255: /*@
1256: EPSGetTwoSided - Returns the flag indicating whether a two-sided variant
1257: of the algorithm is being used or not.
1259: Not Collective
1261: Input Parameter:
1262: . eps - the linear eigensolver context
1264: Output Parameter:
1265: . twosided - the returned flag
1267: Level: advanced
1269: .seealso: [](ch:eps), `EPSSetTwoSided()`
1270: @*/
1271: PetscErrorCode EPSGetTwoSided(EPS eps,PetscBool *twosided)
1272: {
1273: PetscFunctionBegin;
1275: PetscAssertPointer(twosided,2);
1276: *twosided = eps->twosided;
1277: PetscFunctionReturn(PETSC_SUCCESS);
1278: }
1280: /*@
1281: EPSSetTrueResidual - Specifies if the solver must compute the true residual
1282: explicitly or not.
1284: Logically Collective
1286: Input Parameters:
1287: + eps - the linear eigensolver context
1288: - trueres - whether true residuals are required or not
1290: Options Database Key:
1291: . -eps_true_residual - toggles the true residual
1293: Notes:
1294: If the user sets `trueres`=`PETSC_TRUE` then the solver explicitly computes
1295: the true residual for each eigenpair approximation, and uses it for
1296: convergence testing. Computing the residual is usually an expensive
1297: operation. Some solvers (e.g., Krylov solvers) can avoid this computation
1298: by using a cheap estimate of the residual norm, but this may sometimes
1299: give inaccurate results (especially if a spectral transform is being
1300: used). On the contrary, preconditioned eigensolvers (e.g., Davidson solvers)
1301: do rely on computing the true residual, so this option is irrelevant for them.
1303: Level: advanced
1305: .seealso: [](ch:eps), `EPSGetTrueResidual()`
1306: @*/
1307: PetscErrorCode EPSSetTrueResidual(EPS eps,PetscBool trueres)
1308: {
1309: PetscFunctionBegin;
1312: eps->trueres = trueres;
1313: PetscFunctionReturn(PETSC_SUCCESS);
1314: }
1316: /*@
1317: EPSGetTrueResidual - Returns the flag indicating whether true
1318: residuals must be computed explicitly or not.
1320: Not Collective
1322: Input Parameter:
1323: . eps - the linear eigensolver context
1325: Output Parameter:
1326: . trueres - the returned flag
1328: Level: advanced
1330: .seealso: [](ch:eps), `EPSSetTrueResidual()`
1331: @*/
1332: PetscErrorCode EPSGetTrueResidual(EPS eps,PetscBool *trueres)
1333: {
1334: PetscFunctionBegin;
1336: PetscAssertPointer(trueres,2);
1337: *trueres = eps->trueres;
1338: PetscFunctionReturn(PETSC_SUCCESS);
1339: }
1341: /*@
1342: EPSSetTrackAll - Specifies if the solver must compute the residual norm of all
1343: approximate eigenpairs or not.
1345: Logically Collective
1347: Input Parameters:
1348: + eps - the linear eigensolver context
1349: - trackall - whether to compute all residuals or not
1351: Notes:
1352: If the user sets `trackall`=`PETSC_TRUE` then the solver computes (or estimates)
1353: the residual norm for each eigenpair approximation. Computing the residual is
1354: usually an expensive operation and solvers commonly compute only the residual
1355: associated to the first unconverged eigenpair.
1357: The option `-eps_monitor_all` automatically activates this option.
1359: Level: developer
1361: .seealso: [](ch:eps), `EPSGetTrackAll()`
1362: @*/
1363: PetscErrorCode EPSSetTrackAll(EPS eps,PetscBool trackall)
1364: {
1365: PetscFunctionBegin;
1368: eps->trackall = trackall;
1369: PetscFunctionReturn(PETSC_SUCCESS);
1370: }
1372: /*@
1373: EPSGetTrackAll - Returns the flag indicating whether all residual norms must
1374: be computed or not.
1376: Not Collective
1378: Input Parameter:
1379: . eps - the linear eigensolver context
1381: Output Parameter:
1382: . trackall - the returned flag
1384: Level: developer
1386: .seealso: [](ch:eps), `EPSSetTrackAll()`
1387: @*/
1388: PetscErrorCode EPSGetTrackAll(EPS eps,PetscBool *trackall)
1389: {
1390: PetscFunctionBegin;
1392: PetscAssertPointer(trackall,2);
1393: *trackall = eps->trackall;
1394: PetscFunctionReturn(PETSC_SUCCESS);
1395: }
1397: /*@
1398: EPSSetPurify - Disable eigenvector purification (which is enabled by default).
1400: Logically Collective
1402: Input Parameters:
1403: + eps - the linear eigensolver context
1404: - purify - whether purification is done or not, use `PETSC_FALSE` to disable it
1406: Options Database Key:
1407: . -eps_purify - toggles the purification flag
1409: Notes:
1410: By default, eigenvectors of generalized symmetric eigenproblems are purified
1411: in order to purge directions in the nullspace of matrix $B$. If the user knows
1412: that $B$ is non-singular, then purification can be safely deactivated and some
1413: computational cost is avoided (this is particularly important in interval computations).
1415: More details are given in section [](#sec:purif).
1417: Level: intermediate
1419: .seealso: [](ch:eps), [](#sec:purif), `EPSGetPurify()`, `EPSSetInterval()`
1420: @*/
1421: PetscErrorCode EPSSetPurify(EPS eps,PetscBool purify)
1422: {
1423: PetscFunctionBegin;
1426: if (purify!=eps->purify) {
1427: eps->purify = purify;
1428: eps->state = EPS_STATE_INITIAL;
1429: }
1430: PetscFunctionReturn(PETSC_SUCCESS);
1431: }
1433: /*@
1434: EPSGetPurify - Returns the flag indicating whether purification is activated
1435: or not.
1437: Not Collective
1439: Input Parameter:
1440: . eps - the linear eigensolver context
1442: Output Parameter:
1443: . purify - the returned flag
1445: Level: intermediate
1447: .seealso: [](ch:eps), `EPSSetPurify()`
1448: @*/
1449: PetscErrorCode EPSGetPurify(EPS eps,PetscBool *purify)
1450: {
1451: PetscFunctionBegin;
1453: PetscAssertPointer(purify,2);
1454: *purify = eps->purify;
1455: PetscFunctionReturn(PETSC_SUCCESS);
1456: }
1458: /*@
1459: EPSSetOptionsPrefix - Sets the prefix used for searching for all
1460: `EPS` options in the database.
1462: Logically Collective
1464: Input Parameters:
1465: + eps - the linear eigensolver context
1466: - prefix - the prefix string to prepend to all `EPS` option requests
1468: Notes:
1469: A hyphen (-) must NOT be given at the beginning of the prefix name.
1470: The first character of all runtime options is AUTOMATICALLY the
1471: hyphen.
1473: For example, to distinguish between the runtime options for two
1474: different `EPS` contexts, one could call
1475: .vb
1476: EPSSetOptionsPrefix(eps1,"eig1_")
1477: EPSSetOptionsPrefix(eps2,"eig2_")
1478: .ve
1480: Level: advanced
1482: .seealso: [](ch:eps), `EPSAppendOptionsPrefix()`, `EPSGetOptionsPrefix()`
1483: @*/
1484: PetscErrorCode EPSSetOptionsPrefix(EPS eps,const char prefix[])
1485: {
1486: PetscFunctionBegin;
1488: if (!eps->st) PetscCall(EPSGetST(eps,&eps->st));
1489: PetscCall(STSetOptionsPrefix(eps->st,prefix));
1490: if (!eps->V) PetscCall(EPSGetBV(eps,&eps->V));
1491: PetscCall(BVSetOptionsPrefix(eps->V,prefix));
1492: if (!eps->ds) PetscCall(EPSGetDS(eps,&eps->ds));
1493: PetscCall(DSSetOptionsPrefix(eps->ds,prefix));
1494: if (!eps->rg) PetscCall(EPSGetRG(eps,&eps->rg));
1495: PetscCall(RGSetOptionsPrefix(eps->rg,prefix));
1496: PetscCall(PetscObjectSetOptionsPrefix((PetscObject)eps,prefix));
1497: PetscFunctionReturn(PETSC_SUCCESS);
1498: }
1500: /*@
1501: EPSAppendOptionsPrefix - Appends to the prefix used for searching for all
1502: `EPS` options in the database.
1504: Logically Collective
1506: Input Parameters:
1507: + eps - the linear eigensolver context
1508: - prefix - the prefix string to prepend to all `EPS` option requests
1510: Notes:
1511: A hyphen (-) must NOT be given at the beginning of the prefix name.
1512: The first character of all runtime options is AUTOMATICALLY the hyphen.
1514: Level: advanced
1516: .seealso: [](ch:eps), `EPSSetOptionsPrefix()`, `EPSGetOptionsPrefix()`
1517: @*/
1518: PetscErrorCode EPSAppendOptionsPrefix(EPS eps,const char prefix[])
1519: {
1520: PetscFunctionBegin;
1522: if (!eps->st) PetscCall(EPSGetST(eps,&eps->st));
1523: PetscCall(STAppendOptionsPrefix(eps->st,prefix));
1524: if (!eps->V) PetscCall(EPSGetBV(eps,&eps->V));
1525: PetscCall(BVAppendOptionsPrefix(eps->V,prefix));
1526: if (!eps->ds) PetscCall(EPSGetDS(eps,&eps->ds));
1527: PetscCall(DSAppendOptionsPrefix(eps->ds,prefix));
1528: if (!eps->rg) PetscCall(EPSGetRG(eps,&eps->rg));
1529: PetscCall(RGAppendOptionsPrefix(eps->rg,prefix));
1530: PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)eps,prefix));
1531: PetscFunctionReturn(PETSC_SUCCESS);
1532: }
1534: /*@
1535: EPSGetOptionsPrefix - Gets the prefix used for searching for all
1536: `EPS` options in the database.
1538: Not Collective
1540: Input Parameter:
1541: . eps - the linear eigensolver context
1543: Output Parameter:
1544: . prefix - pointer to the prefix string used is returned
1546: Level: advanced
1548: .seealso: [](ch:eps), `EPSSetOptionsPrefix()`, `EPSAppendOptionsPrefix()`
1549: @*/
1550: PetscErrorCode EPSGetOptionsPrefix(EPS eps,const char *prefix[])
1551: {
1552: PetscFunctionBegin;
1554: PetscAssertPointer(prefix,2);
1555: PetscCall(PetscObjectGetOptionsPrefix((PetscObject)eps,prefix));
1556: PetscFunctionReturn(PETSC_SUCCESS);
1557: }