1: /*
2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3: SLEPc - Scalable Library for Eigenvalue Problem Computations
4: Copyright (c) 2002-2020, 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 on eps
24: Input Parameters:
25: + eps - the eigensolver context
26: . name - the monitor option name
27: . help - message indicating what monitoring is done
28: . manual - manual page for the monitor
29: . monitor - the monitor function, whose context is a PetscViewerAndFormat
30: - trackall - whether this monitor tracks all eigenvalues or not
32: Level: developer
34: .seealso: EPSMonitorSet(), EPSSetTrackAll(), EPSConvMonitorSetFromOptions()
35: @*/
36: PetscErrorCode EPSMonitorSetFromOptions(EPS eps,const char name[],const char help[],const char manual[],PetscErrorCode (*monitor)(EPS,PetscInt,PetscInt,PetscScalar*,PetscScalar*,PetscReal*,PetscInt,PetscViewerAndFormat*),PetscBool trackall) 37: {
38: PetscErrorCode ierr;
39: PetscBool flg;
40: PetscViewer viewer;
41: PetscViewerFormat format;
42: PetscViewerAndFormat *vf;
45: PetscOptionsGetViewer(PetscObjectComm((PetscObject)eps),((PetscObject)eps)->options,((PetscObject)eps)->prefix,name,&viewer,&format,&flg);
46: if (flg) {
47: PetscViewerAndFormatCreate(viewer,format,&vf);
48: PetscObjectDereference((PetscObject)viewer);
49: EPSMonitorSet(eps,(PetscErrorCode (*)(EPS,PetscInt,PetscInt,PetscScalar*,PetscScalar*,PetscReal*,PetscInt,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);
50: if (trackall) {
51: EPSSetTrackAll(eps,PETSC_TRUE);
52: }
53: }
54: return(0);
55: }
57: /*@C
58: EPSConvMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type
59: indicated by the user (for monitors that only show iteration numbers of convergence).
61: Collective on eps
63: Input Parameters:
64: + eps - the eigensolver context
65: . name - the monitor option name
66: . help - message indicating what monitoring is done
67: . manual - manual page for the monitor
68: - monitor - the monitor function, whose context is a SlepcConvMonitor
70: Level: developer
72: .seealso: EPSMonitorSet(), EPSMonitorSetFromOptions()
73: @*/
74: PetscErrorCode EPSConvMonitorSetFromOptions(EPS eps,const char name[],const char help[],const char manual[],PetscErrorCode (*monitor)(EPS,PetscInt,PetscInt,PetscScalar*,PetscScalar*,PetscReal*,PetscInt,SlepcConvMonitor)) 75: {
76: PetscErrorCode ierr;
77: PetscBool flg;
78: PetscViewer viewer;
79: PetscViewerFormat format;
80: SlepcConvMonitor ctx;
83: PetscOptionsGetViewer(PetscObjectComm((PetscObject)eps),((PetscObject)eps)->options,((PetscObject)eps)->prefix,name,&viewer,&format,&flg);
84: if (flg) {
85: SlepcConvMonitorCreate(viewer,format,&ctx);
86: PetscObjectDereference((PetscObject)viewer);
87: EPSMonitorSet(eps,(PetscErrorCode (*)(EPS,PetscInt,PetscInt,PetscScalar*,PetscScalar*,PetscReal*,PetscInt,void*))monitor,ctx,(PetscErrorCode (*)(void**))SlepcConvMonitorDestroy);
88: }
89: return(0);
90: }
92: /*@
93: EPSSetFromOptions - Sets EPS options from the options database.
94: This routine must be called before EPSSetUp() if the user is to be
95: allowed to set the solver type.
97: Collective on eps
99: Input Parameters:
100: . eps - the eigensolver context
102: Notes:
103: To see all options, run your program with the -help option.
105: Level: beginner
106: @*/
107: PetscErrorCode EPSSetFromOptions(EPS eps)108: {
110: char type[256];
111: PetscBool set,flg,flg1,flg2,flg3,bval;
112: PetscReal r,array[2]={0,0};
113: PetscScalar s;
114: PetscInt i,j,k;
115: PetscDrawLG lg;
116: EPSBalance bal;
120: EPSRegisterAll();
121: PetscObjectOptionsBegin((PetscObject)eps);
122: PetscOptionsFList("-eps_type","Eigensolver method","EPSSetType",EPSList,(char*)(((PetscObject)eps)->type_name?((PetscObject)eps)->type_name:EPSKRYLOVSCHUR),type,sizeof(type),&flg);
123: if (flg) {
124: EPSSetType(eps,type);
125: } else if (!((PetscObject)eps)->type_name) {
126: EPSSetType(eps,EPSKRYLOVSCHUR);
127: }
129: PetscOptionsBoolGroupBegin("-eps_hermitian","Hermitian eigenvalue problem","EPSSetProblemType",&flg);
130: if (flg) { EPSSetProblemType(eps,EPS_HEP); }
131: PetscOptionsBoolGroup("-eps_gen_hermitian","Generalized Hermitian eigenvalue problem","EPSSetProblemType",&flg);
132: if (flg) { EPSSetProblemType(eps,EPS_GHEP); }
133: PetscOptionsBoolGroup("-eps_non_hermitian","Non-Hermitian eigenvalue problem","EPSSetProblemType",&flg);
134: if (flg) { EPSSetProblemType(eps,EPS_NHEP); }
135: PetscOptionsBoolGroup("-eps_gen_non_hermitian","Generalized non-Hermitian eigenvalue problem","EPSSetProblemType",&flg);
136: if (flg) { EPSSetProblemType(eps,EPS_GNHEP); }
137: PetscOptionsBoolGroup("-eps_pos_gen_non_hermitian","Generalized non-Hermitian eigenvalue problem with positive semi-definite B","EPSSetProblemType",&flg);
138: if (flg) { EPSSetProblemType(eps,EPS_PGNHEP); }
139: PetscOptionsBoolGroupEnd("-eps_gen_indefinite","Generalized Hermitian-indefinite eigenvalue problem","EPSSetProblemType",&flg);
140: if (flg) { EPSSetProblemType(eps,EPS_GHIEP); }
142: PetscOptionsBoolGroupBegin("-eps_ritz","Rayleigh-Ritz extraction","EPSSetExtraction",&flg);
143: if (flg) { EPSSetExtraction(eps,EPS_RITZ); }
144: PetscOptionsBoolGroup("-eps_harmonic","Harmonic Ritz extraction","EPSSetExtraction",&flg);
145: if (flg) { EPSSetExtraction(eps,EPS_HARMONIC); }
146: PetscOptionsBoolGroup("-eps_harmonic_relative","Relative harmonic Ritz extraction","EPSSetExtraction",&flg);
147: if (flg) { EPSSetExtraction(eps,EPS_HARMONIC_RELATIVE); }
148: PetscOptionsBoolGroup("-eps_harmonic_right","Right harmonic Ritz extraction","EPSSetExtraction",&flg);
149: if (flg) { EPSSetExtraction(eps,EPS_HARMONIC_RIGHT); }
150: PetscOptionsBoolGroup("-eps_harmonic_largest","Largest harmonic Ritz extraction","EPSSetExtraction",&flg);
151: if (flg) { EPSSetExtraction(eps,EPS_HARMONIC_LARGEST); }
152: PetscOptionsBoolGroup("-eps_refined","Refined Ritz extraction","EPSSetExtraction",&flg);
153: if (flg) { EPSSetExtraction(eps,EPS_REFINED); }
154: PetscOptionsBoolGroupEnd("-eps_refined_harmonic","Refined harmonic Ritz extraction","EPSSetExtraction",&flg);
155: if (flg) { EPSSetExtraction(eps,EPS_REFINED_HARMONIC); }
157: bal = eps->balance;
158: PetscOptionsEnum("-eps_balance","Balancing method","EPSSetBalance",EPSBalanceTypes,(PetscEnum)bal,(PetscEnum*)&bal,&flg1);
159: j = eps->balance_its;
160: PetscOptionsInt("-eps_balance_its","Number of iterations in balancing","EPSSetBalance",eps->balance_its,&j,&flg2);
161: r = eps->balance_cutoff;
162: PetscOptionsReal("-eps_balance_cutoff","Cutoff value in balancing","EPSSetBalance",eps->balance_cutoff,&r,&flg3);
163: if (flg1 || flg2 || flg3) { EPSSetBalance(eps,bal,j,r); }
165: i = eps->max_it;
166: PetscOptionsInt("-eps_max_it","Maximum number of iterations","EPSSetTolerances",eps->max_it,&i,&flg1);
167: r = eps->tol;
168: PetscOptionsReal("-eps_tol","Tolerance","EPSSetTolerances",eps->tol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL:eps->tol,&r,&flg2);
169: if (flg1 || flg2) { EPSSetTolerances(eps,r,i); }
171: PetscOptionsBoolGroupBegin("-eps_conv_rel","Relative error convergence test","EPSSetConvergenceTest",&flg);
172: if (flg) { EPSSetConvergenceTest(eps,EPS_CONV_REL); }
173: PetscOptionsBoolGroup("-eps_conv_norm","Convergence test relative to the eigenvalue and the matrix norms","EPSSetConvergenceTest",&flg);
174: if (flg) { EPSSetConvergenceTest(eps,EPS_CONV_NORM); }
175: PetscOptionsBoolGroup("-eps_conv_abs","Absolute error convergence test","EPSSetConvergenceTest",&flg);
176: if (flg) { EPSSetConvergenceTest(eps,EPS_CONV_ABS); }
177: PetscOptionsBoolGroupEnd("-eps_conv_user","User-defined convergence test","EPSSetConvergenceTest",&flg);
178: if (flg) { EPSSetConvergenceTest(eps,EPS_CONV_USER); }
180: PetscOptionsBoolGroupBegin("-eps_stop_basic","Stop iteration if all eigenvalues converged or max_it reached","EPSSetStoppingTest",&flg);
181: if (flg) { EPSSetStoppingTest(eps,EPS_STOP_BASIC); }
182: PetscOptionsBoolGroupEnd("-eps_stop_user","User-defined stopping test","EPSSetStoppingTest",&flg);
183: if (flg) { EPSSetStoppingTest(eps,EPS_STOP_USER); }
185: i = eps->nev;
186: PetscOptionsInt("-eps_nev","Number of eigenvalues to compute","EPSSetDimensions",eps->nev,&i,&flg1);
187: j = eps->ncv;
188: PetscOptionsInt("-eps_ncv","Number of basis vectors","EPSSetDimensions",eps->ncv,&j,&flg2);
189: k = eps->mpd;
190: PetscOptionsInt("-eps_mpd","Maximum dimension of projected problem","EPSSetDimensions",eps->mpd,&k,&flg3);
191: if (flg1 || flg2 || flg3) { EPSSetDimensions(eps,i,j,k); }
193: PetscOptionsBoolGroupBegin("-eps_largest_magnitude","Compute largest eigenvalues in magnitude","EPSSetWhichEigenpairs",&flg);
194: if (flg) { EPSSetWhichEigenpairs(eps,EPS_LARGEST_MAGNITUDE); }
195: PetscOptionsBoolGroup("-eps_smallest_magnitude","Compute smallest eigenvalues in magnitude","EPSSetWhichEigenpairs",&flg);
196: if (flg) { EPSSetWhichEigenpairs(eps,EPS_SMALLEST_MAGNITUDE); }
197: PetscOptionsBoolGroup("-eps_largest_real","Compute eigenvalues with largest real parts","EPSSetWhichEigenpairs",&flg);
198: if (flg) { EPSSetWhichEigenpairs(eps,EPS_LARGEST_REAL); }
199: PetscOptionsBoolGroup("-eps_smallest_real","Compute eigenvalues with smallest real parts","EPSSetWhichEigenpairs",&flg);
200: if (flg) { EPSSetWhichEigenpairs(eps,EPS_SMALLEST_REAL); }
201: PetscOptionsBoolGroup("-eps_largest_imaginary","Compute eigenvalues with largest imaginary parts","EPSSetWhichEigenpairs",&flg);
202: if (flg) { EPSSetWhichEigenpairs(eps,EPS_LARGEST_IMAGINARY); }
203: PetscOptionsBoolGroup("-eps_smallest_imaginary","Compute eigenvalues with smallest imaginary parts","EPSSetWhichEigenpairs",&flg);
204: if (flg) { EPSSetWhichEigenpairs(eps,EPS_SMALLEST_IMAGINARY); }
205: PetscOptionsBoolGroup("-eps_target_magnitude","Compute eigenvalues closest to target","EPSSetWhichEigenpairs",&flg);
206: if (flg) { EPSSetWhichEigenpairs(eps,EPS_TARGET_MAGNITUDE); }
207: PetscOptionsBoolGroup("-eps_target_real","Compute eigenvalues with real parts closest to target","EPSSetWhichEigenpairs",&flg);
208: if (flg) { EPSSetWhichEigenpairs(eps,EPS_TARGET_REAL); }
209: PetscOptionsBoolGroup("-eps_target_imaginary","Compute eigenvalues with imaginary parts closest to target","EPSSetWhichEigenpairs",&flg);
210: if (flg) { EPSSetWhichEigenpairs(eps,EPS_TARGET_IMAGINARY); }
211: PetscOptionsBoolGroupEnd("-eps_all","Compute all eigenvalues in an interval or a region","EPSSetWhichEigenpairs",&flg);
212: if (flg) { EPSSetWhichEigenpairs(eps,EPS_ALL); }
214: PetscOptionsScalar("-eps_target","Value of the target","EPSSetTarget",eps->target,&s,&flg);
215: if (flg) {
216: if (eps->which!=EPS_TARGET_REAL && eps->which!=EPS_TARGET_IMAGINARY) {
217: EPSSetWhichEigenpairs(eps,EPS_TARGET_MAGNITUDE);
218: }
219: EPSSetTarget(eps,s);
220: }
222: k = 2;
223: PetscOptionsRealArray("-eps_interval","Computational interval (two real values separated with a comma without spaces)","EPSSetInterval",array,&k,&flg);
224: if (flg) {
225: if (k<2) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_SIZ,"Must pass two values in -eps_interval (comma-separated without spaces)");
226: EPSSetWhichEigenpairs(eps,EPS_ALL);
227: EPSSetInterval(eps,array[0],array[1]);
228: }
230: PetscOptionsBool("-eps_true_residual","Compute true residuals explicitly","EPSSetTrueResidual",eps->trueres,&eps->trueres,NULL);
231: PetscOptionsBool("-eps_purify","Postprocess eigenvectors for purification","EPSSetPurify",eps->purify,&bval,&flg);
232: if (flg) { EPSSetPurify(eps,bval); }
233: PetscOptionsBool("-eps_two_sided","Use two-sided variant (to compute left eigenvectors)","EPSSetTwoSided",eps->twosided,&bval,&flg);
234: if (flg) { EPSSetTwoSided(eps,bval); }
236: /* -----------------------------------------------------------------------*/
237: /*
238: Cancels all monitors hardwired into code before call to EPSSetFromOptions()
239: */
240: PetscOptionsBool("-eps_monitor_cancel","Remove any hardwired monitor routines","EPSMonitorCancel",PETSC_FALSE,&flg,&set);
241: if (set && flg) {
242: EPSMonitorCancel(eps);
243: }
244: /*
245: Text monitors
246: */
247: EPSMonitorSetFromOptions(eps,"-eps_monitor","Monitor first unconverged approximate eigenvalue and error estimate","EPSMonitorFirst",EPSMonitorFirst,PETSC_FALSE);
248: EPSConvMonitorSetFromOptions(eps,"-eps_monitor_conv","Monitor approximate eigenvalues and error estimates as they converge","EPSMonitorConverged",EPSMonitorConverged);
249: EPSMonitorSetFromOptions(eps,"-eps_monitor_all","Monitor approximate eigenvalues and error estimates","EPSMonitorAll",EPSMonitorAll,PETSC_TRUE);
250: /*
251: Line graph monitors
252: */
253: PetscOptionsBool("-eps_monitor_lg","Monitor first unconverged approximate eigenvalue and error estimate graphically","EPSMonitorSet",PETSC_FALSE,&flg,&set);
254: if (set && flg) {
255: EPSMonitorLGCreate(PetscObjectComm((PetscObject)eps),NULL,"Error estimates",PETSC_DECIDE,PETSC_DECIDE,300,300,&lg);
256: EPSMonitorSet(eps,EPSMonitorLG,lg,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);
257: }
258: PetscOptionsBool("-eps_monitor_lg_all","Monitor error estimates graphically","EPSMonitorSet",PETSC_FALSE,&flg,&set);
259: if (set && flg) {
260: EPSMonitorLGCreate(PetscObjectComm((PetscObject)eps),NULL,"Error estimates",PETSC_DECIDE,PETSC_DECIDE,300,300,&lg);
261: EPSMonitorSet(eps,EPSMonitorLGAll,lg,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);
262: EPSSetTrackAll(eps,PETSC_TRUE);
263: }
265: /* -----------------------------------------------------------------------*/
266: PetscOptionsName("-eps_view","Print detailed information on solver used","EPSView",NULL);
267: PetscOptionsName("-eps_view_vectors","View computed eigenvectors","EPSVectorsView",NULL);
268: PetscOptionsName("-eps_view_values","View computed eigenvalues","EPSValuesView",NULL);
269: PetscOptionsName("-eps_converged_reason","Print reason for convergence, and number of iterations","EPSConvergedReasonView",NULL);
270: PetscOptionsName("-eps_error_absolute","Print absolute errors of each eigenpair","EPSErrorView",NULL);
271: PetscOptionsName("-eps_error_relative","Print relative errors of each eigenpair","EPSErrorView",NULL);
272: PetscOptionsName("-eps_error_backward","Print backward errors of each eigenpair","EPSErrorView",NULL);
274: if (eps->ops->setfromoptions) {
275: (*eps->ops->setfromoptions)(PetscOptionsObject,eps);
276: }
277: PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)eps);
278: PetscOptionsEnd();
280: if (!eps->V) { EPSGetBV(eps,&eps->V); }
281: BVSetFromOptions(eps->V);
282: if (!eps->rg) { EPSGetRG(eps,&eps->rg); }
283: RGSetFromOptions(eps->rg);
284: if (eps->useds) {
285: if (!eps->ds) { EPSGetDS(eps,&eps->ds); }
286: DSSetFromOptions(eps->ds);
287: }
288: if (!eps->st) { EPSGetST(eps,&eps->st); }
289: EPSSetDefaultST(eps);
290: STSetFromOptions(eps->st);
291: return(0);
292: }
294: /*@C
295: EPSGetTolerances - Gets the tolerance and maximum iteration count used
296: by the EPS convergence tests.
298: Not Collective
300: Input Parameter:
301: . eps - the eigensolver context
303: Output Parameters:
304: + tol - the convergence tolerance
305: - maxits - maximum number of iterations
307: Notes:
308: The user can specify NULL for any parameter that is not needed.
310: Level: intermediate
312: .seealso: EPSSetTolerances()
313: @*/
314: PetscErrorCode EPSGetTolerances(EPS eps,PetscReal *tol,PetscInt *maxits)315: {
318: if (tol) *tol = eps->tol;
319: if (maxits) *maxits = eps->max_it;
320: return(0);
321: }
323: /*@
324: EPSSetTolerances - Sets the tolerance and maximum iteration count used
325: by the EPS convergence tests.
327: Logically Collective on eps
329: Input Parameters:
330: + eps - the eigensolver context
331: . tol - the convergence tolerance
332: - maxits - maximum number of iterations to use
334: Options Database Keys:
335: + -eps_tol <tol> - Sets the convergence tolerance
336: - -eps_max_it <maxits> - Sets the maximum number of iterations allowed
338: Notes:
339: Use PETSC_DEFAULT for either argument to assign a reasonably good value.
341: Level: intermediate
343: .seealso: EPSGetTolerances()
344: @*/
345: PetscErrorCode EPSSetTolerances(EPS eps,PetscReal tol,PetscInt maxits)346: {
351: if (tol == PETSC_DEFAULT) {
352: eps->tol = PETSC_DEFAULT;
353: eps->state = EPS_STATE_INITIAL;
354: } else {
355: if (tol <= 0.0) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of tol. Must be > 0");
356: eps->tol = tol;
357: }
358: if (maxits == PETSC_DEFAULT || maxits == PETSC_DECIDE) {
359: eps->max_it = PETSC_DEFAULT;
360: eps->state = EPS_STATE_INITIAL;
361: } else {
362: if (maxits <= 0) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of maxits. Must be > 0");
363: eps->max_it = maxits;
364: }
365: return(0);
366: }
368: /*@C
369: EPSGetDimensions - Gets the number of eigenvalues to compute
370: and the dimension of the subspace.
372: Not Collective
374: Input Parameter:
375: . eps - the eigensolver context
377: Output Parameters:
378: + nev - number of eigenvalues to compute
379: . ncv - the maximum dimension of the subspace to be used by the solver
380: - mpd - the maximum dimension allowed for the projected problem
382: Level: intermediate
384: .seealso: EPSSetDimensions()
385: @*/
386: PetscErrorCode EPSGetDimensions(EPS eps,PetscInt *nev,PetscInt *ncv,PetscInt *mpd)387: {
390: if (nev) *nev = eps->nev;
391: if (ncv) *ncv = eps->ncv;
392: if (mpd) *mpd = eps->mpd;
393: return(0);
394: }
396: /*@
397: EPSSetDimensions - Sets the number of eigenvalues to compute
398: and the dimension of the subspace.
400: Logically Collective on eps
402: Input Parameters:
403: + eps - the eigensolver context
404: . nev - number of eigenvalues to compute
405: . ncv - the maximum dimension of the subspace to be used by the solver
406: - mpd - the maximum dimension allowed for the projected problem
408: Options Database Keys:
409: + -eps_nev <nev> - Sets the number of eigenvalues
410: . -eps_ncv <ncv> - Sets the dimension of the subspace
411: - -eps_mpd <mpd> - Sets the maximum projected dimension
413: Notes:
414: Use PETSC_DEFAULT for ncv and mpd to assign a reasonably good value, which is
415: dependent on the solution method.
417: The parameters ncv and mpd are intimately related, so that the user is advised
418: to set one of them at most. Normal usage is that
419: (a) in cases where nev is small, the user sets ncv (a reasonable default is 2*nev); and
420: (b) in cases where nev is large, the user sets mpd.
422: The value of ncv should always be between nev and (nev+mpd), typically
423: ncv=nev+mpd. If nev is not too large, mpd=nev is a reasonable choice, otherwise
424: a smaller value should be used.
426: When computing all eigenvalues in an interval, see EPSSetInterval(), these
427: parameters lose relevance, and tuning must be done with
428: EPSKrylovSchurSetDimensions().
430: Level: intermediate
432: .seealso: EPSGetDimensions(), EPSSetInterval(), EPSKrylovSchurSetDimensions()
433: @*/
434: PetscErrorCode EPSSetDimensions(EPS eps,PetscInt nev,PetscInt ncv,PetscInt mpd)435: {
441: if (nev<1) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of nev. Must be > 0");
442: eps->nev = nev;
443: if (ncv == PETSC_DECIDE || ncv == PETSC_DEFAULT) {
444: eps->ncv = PETSC_DEFAULT;
445: } else {
446: if (ncv<1) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of ncv. Must be > 0");
447: eps->ncv = ncv;
448: }
449: if (mpd == PETSC_DECIDE || mpd == PETSC_DEFAULT) {
450: eps->mpd = PETSC_DEFAULT;
451: } else {
452: if (mpd<1) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of mpd. Must be > 0");
453: eps->mpd = mpd;
454: }
455: eps->state = EPS_STATE_INITIAL;
456: return(0);
457: }
459: /*@
460: EPSSetWhichEigenpairs - Specifies which portion of the spectrum is
461: to be sought.
463: Logically Collective on eps
465: Input Parameters:
466: + eps - eigensolver context obtained from EPSCreate()
467: - which - the portion of the spectrum to be sought
469: Possible values:
470: The parameter 'which' can have one of these values
472: + EPS_LARGEST_MAGNITUDE - largest eigenvalues in magnitude (default)
473: . EPS_SMALLEST_MAGNITUDE - smallest eigenvalues in magnitude
474: . EPS_LARGEST_REAL - largest real parts
475: . EPS_SMALLEST_REAL - smallest real parts
476: . EPS_LARGEST_IMAGINARY - largest imaginary parts
477: . EPS_SMALLEST_IMAGINARY - smallest imaginary parts
478: . EPS_TARGET_MAGNITUDE - eigenvalues closest to the target (in magnitude)
479: . EPS_TARGET_REAL - eigenvalues with real part closest to target
480: . EPS_TARGET_IMAGINARY - eigenvalues with imaginary part closest to target
481: . EPS_ALL - all eigenvalues contained in a given interval or region
482: - EPS_WHICH_USER - user defined ordering set with EPSSetEigenvalueComparison()
484: Options Database Keys:
485: + -eps_largest_magnitude - Sets largest eigenvalues in magnitude
486: . -eps_smallest_magnitude - Sets smallest eigenvalues in magnitude
487: . -eps_largest_real - Sets largest real parts
488: . -eps_smallest_real - Sets smallest real parts
489: . -eps_largest_imaginary - Sets largest imaginary parts
490: . -eps_smallest_imaginary - Sets smallest imaginary parts
491: . -eps_target_magnitude - Sets eigenvalues closest to target
492: . -eps_target_real - Sets real parts closest to target
493: . -eps_target_imaginary - Sets imaginary parts closest to target
494: - -eps_all - Sets all eigenvalues in an interval or region
496: Notes:
497: Not all eigensolvers implemented in EPS account for all the possible values
498: stated above. Also, some values make sense only for certain types of
499: problems. If SLEPc is compiled for real numbers EPS_LARGEST_IMAGINARY500: and EPS_SMALLEST_IMAGINARY use the absolute value of the imaginary part
501: for eigenvalue selection.
503: The target is a scalar value provided with EPSSetTarget().
505: The criterion EPS_TARGET_IMAGINARY is available only in case PETSc and
506: SLEPc have been built with complex scalars.
508: EPS_ALL is intended for use in combination with an interval (see
509: EPSSetInterval()), when all eigenvalues within the interval are requested,
510: or in the context of the CISS solver for computing all eigenvalues in a region.
511: In those cases, the number of eigenvalues is unknown, so the nev parameter
512: has a different sense, see EPSSetDimensions().
514: Level: intermediate
516: .seealso: EPSGetWhichEigenpairs(), EPSSetTarget(), EPSSetInterval(),
517: EPSSetDimensions(), EPSSetEigenvalueComparison(), EPSWhich518: @*/
519: PetscErrorCode EPSSetWhichEigenpairs(EPS eps,EPSWhich which)520: {
524: switch (which) {
525: case EPS_LARGEST_MAGNITUDE:
526: case EPS_SMALLEST_MAGNITUDE:
527: case EPS_LARGEST_REAL:
528: case EPS_SMALLEST_REAL:
529: case EPS_LARGEST_IMAGINARY:
530: case EPS_SMALLEST_IMAGINARY:
531: case EPS_TARGET_MAGNITUDE:
532: case EPS_TARGET_REAL:
533: #if defined(PETSC_USE_COMPLEX)
534: case EPS_TARGET_IMAGINARY:
535: #endif
536: case EPS_ALL:
537: case EPS_WHICH_USER:
538: if (eps->which != which) {
539: eps->state = EPS_STATE_INITIAL;
540: eps->which = which;
541: }
542: break;
543: #if !defined(PETSC_USE_COMPLEX)
544: case EPS_TARGET_IMAGINARY:
545: SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"EPS_TARGET_IMAGINARY can be used only with complex scalars");
546: #endif
547: default:548: SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid 'which' value");
549: }
550: return(0);
551: }
553: /*@
554: EPSGetWhichEigenpairs - Returns which portion of the spectrum is to be
555: sought.
557: Not Collective
559: Input Parameter:
560: . eps - eigensolver context obtained from EPSCreate()
562: Output Parameter:
563: . which - the portion of the spectrum to be sought
565: Notes:
566: See EPSSetWhichEigenpairs() for possible values of 'which'.
568: Level: intermediate
570: .seealso: EPSSetWhichEigenpairs(), EPSWhich571: @*/
572: PetscErrorCode EPSGetWhichEigenpairs(EPS eps,EPSWhich *which)573: {
577: *which = eps->which;
578: return(0);
579: }
581: /*@C
582: EPSSetEigenvalueComparison - Specifies the eigenvalue comparison function
583: when EPSSetWhichEigenpairs() is set to EPS_WHICH_USER.
585: Logically Collective on eps
587: Input Parameters:
588: + eps - eigensolver context obtained from EPSCreate()
589: . func - a pointer to the comparison function
590: - ctx - a context pointer (the last parameter to the comparison function)
592: Calling Sequence of func:
593: $ func(PetscScalar ar,PetscScalar ai,PetscScalar br,PetscScalar bi,PetscInt *res,void *ctx)
595: + ar - real part of the 1st eigenvalue
596: . ai - imaginary part of the 1st eigenvalue
597: . br - real part of the 2nd eigenvalue
598: . bi - imaginary part of the 2nd eigenvalue
599: . res - result of comparison
600: - ctx - optional context, as set by EPSSetEigenvalueComparison()
602: Note:
603: The returning parameter 'res' can be
604: + negative - if the 1st eigenvalue is preferred to the 2st one
605: . zero - if both eigenvalues are equally preferred
606: - positive - if the 2st eigenvalue is preferred to the 1st one
608: Level: advanced
610: .seealso: EPSSetWhichEigenpairs(), EPSWhich611: @*/
612: PetscErrorCode EPSSetEigenvalueComparison(EPS eps,PetscErrorCode (*func)(PetscScalar,PetscScalar,PetscScalar,PetscScalar,PetscInt*,void*),void* ctx)613: {
616: eps->sc->comparison = func;
617: eps->sc->comparisonctx = ctx;
618: eps->which = EPS_WHICH_USER;
619: return(0);
620: }
622: /*@C
623: EPSSetArbitrarySelection - Specifies a function intended to look for
624: eigenvalues according to an arbitrary selection criterion. This criterion
625: can be based on a computation involving the current eigenvector approximation.
627: Logically Collective on eps
629: Input Parameters:
630: + eps - eigensolver context obtained from EPSCreate()
631: . func - a pointer to the evaluation function
632: - ctx - a context pointer (the last parameter to the evaluation function)
634: Calling Sequence of func:
635: $ func(PetscScalar er,PetscScalar ei,Vec xr,Vec xi,PetscScalar *rr,PetscScalar *ri,void *ctx)
637: + er - real part of the current eigenvalue approximation
638: . ei - imaginary part of the current eigenvalue approximation
639: . xr - real part of the current eigenvector approximation
640: . xi - imaginary part of the current eigenvector approximation
641: . rr - result of evaluation (real part)
642: . ri - result of evaluation (imaginary part)
643: - ctx - optional context, as set by EPSSetArbitrarySelection()
645: Notes:
646: This provides a mechanism to select eigenpairs by evaluating a user-defined
647: function. When a function has been provided, the default selection based on
648: sorting the eigenvalues is replaced by the sorting of the results of this
649: function (with the same sorting criterion given in EPSSetWhichEigenpairs()).
651: For instance, suppose you want to compute those eigenvectors that maximize
652: a certain computable expression. Then implement the computation using
653: the arguments xr and xi, and return the result in rr. Then set the standard
654: sorting by magnitude so that the eigenpair with largest value of rr is
655: selected.
657: This evaluation function is collective, that is, all processes call it and
658: it can use collective operations; furthermore, the computed result must
659: be the same in all processes.
661: The result of func is expressed as a complex number so that it is possible to
662: use the standard eigenvalue sorting functions, but normally only rr is used.
663: Set ri to zero unless it is meaningful in your application.
665: Level: advanced
667: .seealso: EPSSetWhichEigenpairs()
668: @*/
669: PetscErrorCode EPSSetArbitrarySelection(EPS eps,PetscErrorCode (*func)(PetscScalar,PetscScalar,Vec,Vec,PetscScalar*,PetscScalar*,void*),void* ctx)670: {
673: eps->arbitrary = func;
674: eps->arbitraryctx = ctx;
675: eps->state = EPS_STATE_INITIAL;
676: return(0);
677: }
679: /*@C
680: EPSSetConvergenceTestFunction - Sets a function to compute the error estimate
681: used in the convergence test.
683: Logically Collective on eps
685: Input Parameters:
686: + eps - eigensolver context obtained from EPSCreate()
687: . func - a pointer to the convergence test function
688: . ctx - context for private data for the convergence routine (may be null)
689: - destroy - a routine for destroying the context (may be null)
691: Calling Sequence of func:
692: $ func(EPS eps,PetscScalar eigr,PetscScalar eigi,PetscReal res,PetscReal *errest,void *ctx)
694: + eps - eigensolver context obtained from EPSCreate()
695: . eigr - real part of the eigenvalue
696: . eigi - imaginary part of the eigenvalue
697: . res - residual norm associated to the eigenpair
698: . errest - (output) computed error estimate
699: - ctx - optional context, as set by EPSSetConvergenceTestFunction()
701: Note:
702: If the error estimate returned by the convergence test function is less than
703: the tolerance, then the eigenvalue is accepted as converged.
705: Level: advanced
707: .seealso: EPSSetConvergenceTest(), EPSSetTolerances()
708: @*/
709: PetscErrorCode EPSSetConvergenceTestFunction(EPS eps,PetscErrorCode (*func)(EPS,PetscScalar,PetscScalar,PetscReal,PetscReal*,void*),void* ctx,PetscErrorCode (*destroy)(void*))710: {
715: if (eps->convergeddestroy) {
716: (*eps->convergeddestroy)(eps->convergedctx);
717: }
718: eps->convergeduser = func;
719: eps->convergeddestroy = destroy;
720: eps->convergedctx = ctx;
721: if (func == EPSConvergedRelative) eps->conv = EPS_CONV_REL;
722: else if (func == EPSConvergedNorm) eps->conv = EPS_CONV_NORM;
723: else if (func == EPSConvergedAbsolute) eps->conv = EPS_CONV_ABS;
724: else {
725: eps->conv = EPS_CONV_USER;
726: eps->converged = eps->convergeduser;
727: }
728: return(0);
729: }
731: /*@
732: EPSSetConvergenceTest - Specifies how to compute the error estimate
733: used in the convergence test.
735: Logically Collective on eps
737: Input Parameters:
738: + eps - eigensolver context obtained from EPSCreate()
739: - conv - the type of convergence test
741: Options Database Keys:
742: + -eps_conv_abs - Sets the absolute convergence test
743: . -eps_conv_rel - Sets the convergence test relative to the eigenvalue
744: . -eps_conv_norm - Sets the convergence test relative to the matrix norms
745: - -eps_conv_user - Selects the user-defined convergence test
747: Note:
748: The parameter 'conv' can have one of these values
749: + EPS_CONV_ABS - absolute error ||r||
750: . EPS_CONV_REL - error relative to the eigenvalue l, ||r||/|l|
751: . EPS_CONV_NORM - error relative to the matrix norms, ||r||/(||A||+|l|*||B||)
752: - EPS_CONV_USER - function set by EPSSetConvergenceTestFunction()
754: Level: intermediate
756: .seealso: EPSGetConvergenceTest(), EPSSetConvergenceTestFunction(), EPSSetStoppingTest(), EPSConv757: @*/
758: PetscErrorCode EPSSetConvergenceTest(EPS eps,EPSConv conv)759: {
763: switch (conv) {
764: case EPS_CONV_ABS: eps->converged = EPSConvergedAbsolute; break;
765: case EPS_CONV_REL: eps->converged = EPSConvergedRelative; break;
766: case EPS_CONV_NORM: eps->converged = EPSConvergedNorm; break;
767: case EPS_CONV_USER:
768: if (!eps->convergeduser) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ORDER,"Must call EPSSetConvergenceTestFunction() first");
769: eps->converged = eps->convergeduser;
770: break;
771: default:772: SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid 'conv' value");
773: }
774: eps->conv = conv;
775: return(0);
776: }
778: /*@
779: EPSGetConvergenceTest - Gets the method used to compute the error estimate
780: used in the convergence test.
782: Not Collective
784: Input Parameters:
785: . eps - eigensolver context obtained from EPSCreate()
787: Output Parameters:
788: . conv - the type of convergence test
790: Level: intermediate
792: .seealso: EPSSetConvergenceTest(), EPSConv793: @*/
794: PetscErrorCode EPSGetConvergenceTest(EPS eps,EPSConv *conv)795: {
799: *conv = eps->conv;
800: return(0);
801: }
803: /*@C
804: EPSSetStoppingTestFunction - Sets a function to decide when to stop the outer
805: iteration of the eigensolver.
807: Logically Collective on eps
809: Input Parameters:
810: + eps - eigensolver context obtained from EPSCreate()
811: . func - pointer to the stopping test function
812: . ctx - context for private data for the stopping routine (may be null)
813: - destroy - a routine for destroying the context (may be null)
815: Calling Sequence of func:
816: $ func(EPS eps,PetscInt its,PetscInt max_it,PetscInt nconv,PetscInt nev,EPSConvergedReason *reason,void *ctx)
818: + eps - eigensolver context obtained from EPSCreate()
819: . its - current number of iterations
820: . max_it - maximum number of iterations
821: . nconv - number of currently converged eigenpairs
822: . nev - number of requested eigenpairs
823: . reason - (output) result of the stopping test
824: - ctx - optional context, as set by EPSSetStoppingTestFunction()
826: Note:
827: Normal usage is to first call the default routine EPSStoppingBasic() and then
828: set reason to EPS_CONVERGED_USER if some user-defined conditions have been
829: met. To let the eigensolver continue iterating, the result must be left as
830: EPS_CONVERGED_ITERATING.
832: Level: advanced
834: .seealso: EPSSetStoppingTest(), EPSStoppingBasic()
835: @*/
836: PetscErrorCode EPSSetStoppingTestFunction(EPS eps,PetscErrorCode (*func)(EPS,PetscInt,PetscInt,PetscInt,PetscInt,EPSConvergedReason*,void*),void* ctx,PetscErrorCode (*destroy)(void*))837: {
842: if (eps->stoppingdestroy) {
843: (*eps->stoppingdestroy)(eps->stoppingctx);
844: }
845: eps->stoppinguser = func;
846: eps->stoppingdestroy = destroy;
847: eps->stoppingctx = ctx;
848: if (func == EPSStoppingBasic) eps->stop = EPS_STOP_BASIC;
849: else {
850: eps->stop = EPS_STOP_USER;
851: eps->stopping = eps->stoppinguser;
852: }
853: return(0);
854: }
856: /*@
857: EPSSetStoppingTest - Specifies how to decide the termination of the outer
858: loop of the eigensolver.
860: Logically Collective on eps
862: Input Parameters:
863: + eps - eigensolver context obtained from EPSCreate()
864: - stop - the type of stopping test
866: Options Database Keys:
867: + -eps_stop_basic - Sets the default stopping test
868: - -eps_stop_user - Selects the user-defined stopping test
870: Note:
871: The parameter 'stop' can have one of these values
872: + EPS_STOP_BASIC - default stopping test
873: - EPS_STOP_USER - function set by EPSSetStoppingTestFunction()
875: Level: advanced
877: .seealso: EPSGetStoppingTest(), EPSSetStoppingTestFunction(), EPSSetConvergenceTest(), EPSStop878: @*/
879: PetscErrorCode EPSSetStoppingTest(EPS eps,EPSStop stop)880: {
884: switch (stop) {
885: case EPS_STOP_BASIC: eps->stopping = EPSStoppingBasic; break;
886: case EPS_STOP_USER:
887: if (!eps->stoppinguser) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ORDER,"Must call EPSSetStoppingTestFunction() first");
888: eps->stopping = eps->stoppinguser;
889: break;
890: default:891: SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid 'stop' value");
892: }
893: eps->stop = stop;
894: return(0);
895: }
897: /*@
898: EPSGetStoppingTest - Gets the method used to decide the termination of the outer
899: loop of the eigensolver.
901: Not Collective
903: Input Parameters:
904: . eps - eigensolver context obtained from EPSCreate()
906: Output Parameters:
907: . stop - the type of stopping test
909: Level: advanced
911: .seealso: EPSSetStoppingTest(), EPSStop912: @*/
913: PetscErrorCode EPSGetStoppingTest(EPS eps,EPSStop *stop)914: {
918: *stop = eps->stop;
919: return(0);
920: }
922: /*@
923: EPSSetProblemType - Specifies the type of the eigenvalue problem.
925: Logically Collective on eps
927: Input Parameters:
928: + eps - the eigensolver context
929: - type - a known type of eigenvalue problem
931: Options Database Keys:
932: + -eps_hermitian - Hermitian eigenvalue problem
933: . -eps_gen_hermitian - generalized Hermitian eigenvalue problem
934: . -eps_non_hermitian - non-Hermitian eigenvalue problem
935: . -eps_gen_non_hermitian - generalized non-Hermitian eigenvalue problem
936: - -eps_pos_gen_non_hermitian - generalized non-Hermitian eigenvalue problem
937: with positive semi-definite B
939: Notes:
940: Allowed values for the problem type are: Hermitian (EPS_HEP), non-Hermitian
941: (EPS_NHEP), generalized Hermitian (EPS_GHEP), generalized non-Hermitian
942: (EPS_GNHEP), generalized non-Hermitian with positive semi-definite B
943: (EPS_PGNHEP), and generalized Hermitian-indefinite (EPS_GHIEP).
945: This function must be used to instruct SLEPc to exploit symmetry. If no
946: problem type is specified, by default a non-Hermitian problem is assumed
947: (either standard or generalized). If the user knows that the problem is
948: Hermitian (i.e. A=A^H) or generalized Hermitian (i.e. A=A^H, B=B^H, and
949: B positive definite) then it is recommended to set the problem type so
950: that eigensolver can exploit these properties.
952: Level: intermediate
954: .seealso: EPSSetOperators(), EPSSetType(), EPSGetProblemType(), EPSProblemType955: @*/
956: PetscErrorCode EPSSetProblemType(EPS eps,EPSProblemType type)957: {
961: if (type == eps->problem_type) return(0);
962: switch (type) {
963: case EPS_HEP:
964: eps->isgeneralized = PETSC_FALSE;
965: eps->ishermitian = PETSC_TRUE;
966: eps->ispositive = PETSC_FALSE;
967: break;
968: case EPS_NHEP:
969: eps->isgeneralized = PETSC_FALSE;
970: eps->ishermitian = PETSC_FALSE;
971: eps->ispositive = PETSC_FALSE;
972: break;
973: case EPS_GHEP:
974: eps->isgeneralized = PETSC_TRUE;
975: eps->ishermitian = PETSC_TRUE;
976: eps->ispositive = PETSC_TRUE;
977: break;
978: case EPS_GNHEP:
979: eps->isgeneralized = PETSC_TRUE;
980: eps->ishermitian = PETSC_FALSE;
981: eps->ispositive = PETSC_FALSE;
982: break;
983: case EPS_PGNHEP:
984: eps->isgeneralized = PETSC_TRUE;
985: eps->ishermitian = PETSC_FALSE;
986: eps->ispositive = PETSC_TRUE;
987: break;
988: case EPS_GHIEP:
989: eps->isgeneralized = PETSC_TRUE;
990: eps->ishermitian = PETSC_TRUE;
991: eps->ispositive = PETSC_FALSE;
992: break;
993: default:994: SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_WRONG,"Unknown eigenvalue problem type");
995: }
996: eps->problem_type = type;
997: eps->state = EPS_STATE_INITIAL;
998: return(0);
999: }
1001: /*@
1002: EPSGetProblemType - Gets the problem type from the EPS object.
1004: Not Collective
1006: Input Parameter:
1007: . eps - the eigensolver context
1009: Output Parameter:
1010: . type - the problem type
1012: Level: intermediate
1014: .seealso: EPSSetProblemType(), EPSProblemType1015: @*/
1016: PetscErrorCode EPSGetProblemType(EPS eps,EPSProblemType *type)1017: {
1021: *type = eps->problem_type;
1022: return(0);
1023: }
1025: /*@
1026: EPSSetExtraction - Specifies the type of extraction technique to be employed
1027: by the eigensolver.
1029: Logically Collective on eps
1031: Input Parameters:
1032: + eps - the eigensolver context
1033: - extr - a known type of extraction
1035: Options Database Keys:
1036: + -eps_ritz - Rayleigh-Ritz extraction
1037: . -eps_harmonic - harmonic Ritz extraction
1038: . -eps_harmonic_relative - harmonic Ritz extraction relative to the eigenvalue
1039: . -eps_harmonic_right - harmonic Ritz extraction for rightmost eigenvalues
1040: . -eps_harmonic_largest - harmonic Ritz extraction for largest magnitude
1041: (without target)
1042: . -eps_refined - refined Ritz extraction
1043: - -eps_refined_harmonic - refined harmonic Ritz extraction
1045: Notes:
1046: Not all eigensolvers support all types of extraction. See the SLEPc
1047: Users Manual for details.
1049: By default, a standard Rayleigh-Ritz extraction is used. Other extractions
1050: may be useful when computing interior eigenvalues.
1052: Harmonic-type extractions are used in combination with a 'target'.
1054: Level: advanced
1056: .seealso: EPSSetTarget(), EPSGetExtraction(), EPSExtraction1057: @*/
1058: PetscErrorCode EPSSetExtraction(EPS eps,EPSExtraction extr)1059: {
1063: eps->extraction = extr;
1064: return(0);
1065: }
1067: /*@
1068: EPSGetExtraction - Gets the extraction type used by the EPS object.
1070: Not Collective
1072: Input Parameter:
1073: . eps - the eigensolver context
1075: Output Parameter:
1076: . extr - name of extraction type
1078: Level: advanced
1080: .seealso: EPSSetExtraction(), EPSExtraction1081: @*/
1082: PetscErrorCode EPSGetExtraction(EPS eps,EPSExtraction *extr)1083: {
1087: *extr = eps->extraction;
1088: return(0);
1089: }
1091: /*@
1092: EPSSetBalance - Specifies the balancing technique to be employed by the
1093: eigensolver, and some parameters associated to it.
1095: Logically Collective on eps
1097: Input Parameters:
1098: + eps - the eigensolver context
1099: . bal - the balancing method, one of EPS_BALANCE_NONE, EPS_BALANCE_ONESIDE,
1100: EPS_BALANCE_TWOSIDE, or EPS_BALANCE_USER1101: . its - number of iterations of the balancing algorithm
1102: - cutoff - cutoff value
1104: Options Database Keys:
1105: + -eps_balance <method> - the balancing method, where <method> is one of
1106: 'none', 'oneside', 'twoside', or 'user'
1107: . -eps_balance_its <its> - number of iterations
1108: - -eps_balance_cutoff <cutoff> - cutoff value
1110: Notes:
1111: When balancing is enabled, the solver works implicitly with matrix DAD^-1,
1112: where D is an appropriate diagonal matrix. This improves the accuracy of
1113: the computed results in some cases. See the SLEPc Users Manual for details.
1115: Balancing makes sense only for non-Hermitian problems when the required
1116: precision is high (i.e. a small tolerance such as 1e-15).
1118: By default, balancing is disabled. The two-sided method is much more
1119: effective than the one-sided counterpart, but it requires the system
1120: matrices to have the MatMultTranspose operation defined.
1122: The parameter 'its' is the number of iterations performed by the method. The
1123: cutoff value is used only in the two-side variant. Use PETSC_DEFAULT to assign
1124: a reasonably good value.
1126: User-defined balancing is allowed provided that the corresponding matrix
1127: is set via STSetBalanceMatrix.
1129: Level: intermediate
1131: .seealso: EPSGetBalance(), EPSBalance, STSetBalanceMatrix()
1132: @*/
1133: PetscErrorCode EPSSetBalance(EPS eps,EPSBalance bal,PetscInt its,PetscReal cutoff)1134: {
1140: switch (bal) {
1141: case EPS_BALANCE_NONE:
1142: case EPS_BALANCE_ONESIDE:
1143: case EPS_BALANCE_TWOSIDE:
1144: case EPS_BALANCE_USER:
1145: if (eps->balance != bal) {
1146: eps->state = EPS_STATE_INITIAL;
1147: eps->balance = bal;
1148: }
1149: break;
1150: default:1151: SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid value of argument 'bal'");
1152: }
1153: if (its==PETSC_DECIDE || its==PETSC_DEFAULT) eps->balance_its = 5;
1154: else {
1155: if (its <= 0) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of its. Must be > 0");
1156: eps->balance_its = its;
1157: }
1158: if (cutoff==PETSC_DECIDE || cutoff==PETSC_DEFAULT) eps->balance_cutoff = 1e-8;
1159: else {
1160: if (cutoff <= 0.0) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of cutoff. Must be > 0");
1161: eps->balance_cutoff = cutoff;
1162: }
1163: return(0);
1164: }
1166: /*@C
1167: EPSGetBalance - Gets the balancing type used by the EPS object, and the
1168: associated parameters.
1170: Not Collective
1172: Input Parameter:
1173: . eps - the eigensolver context
1175: Output Parameters:
1176: + bal - the balancing method
1177: . its - number of iterations of the balancing algorithm
1178: - cutoff - cutoff value
1180: Level: intermediate
1182: Note:
1183: The user can specify NULL for any parameter that is not needed.
1185: .seealso: EPSSetBalance(), EPSBalance1186: @*/
1187: PetscErrorCode EPSGetBalance(EPS eps,EPSBalance *bal,PetscInt *its,PetscReal *cutoff)1188: {
1191: if (bal) *bal = eps->balance;
1192: if (its) *its = eps->balance_its;
1193: if (cutoff) *cutoff = eps->balance_cutoff;
1194: return(0);
1195: }
1197: /*@
1198: EPSSetTwoSided - Sets the solver to use a two-sided variant so that left
1199: eigenvectors are also computed.
1201: Logically Collective on eps
1203: Input Parameters:
1204: + eps - the eigensolver context
1205: - twosided - whether the two-sided variant is to be used or not
1207: Options Database Keys:
1208: . -eps_two_sided <boolean> - Sets/resets the twosided flag
1210: Notes:
1211: If the user sets twosided=PETSC_TRUE then the solver uses a variant of
1212: the algorithm that computes both right and left eigenvectors. This is
1213: usually much more costly. This option is not available in all solvers.
1215: When using two-sided solvers, the problem matrices must have both the
1216: MatMult and MatMultTranspose operations defined.
1218: Level: advanced
1220: .seealso: EPSGetTwoSided(), EPSGetLeftEigenvector()
1221: @*/
1222: PetscErrorCode EPSSetTwoSided(EPS eps,PetscBool twosided)1223: {
1227: if (twosided!=eps->twosided) {
1228: eps->twosided = twosided;
1229: eps->state = EPS_STATE_INITIAL;
1230: }
1231: return(0);
1232: }
1234: /*@
1235: EPSGetTwoSided - Returns the flag indicating whether a two-sided variant
1236: of the algorithm is being used or not.
1238: Not Collective
1240: Input Parameter:
1241: . eps - the eigensolver context
1243: Output Parameter:
1244: . twosided - the returned flag
1246: Level: advanced
1248: .seealso: EPSSetTwoSided()
1249: @*/
1250: PetscErrorCode EPSGetTwoSided(EPS eps,PetscBool *twosided)1251: {
1255: *twosided = eps->twosided;
1256: return(0);
1257: }
1259: /*@
1260: EPSSetTrueResidual - Specifies if the solver must compute the true residual
1261: explicitly or not.
1263: Logically Collective on eps
1265: Input Parameters:
1266: + eps - the eigensolver context
1267: - trueres - whether true residuals are required or not
1269: Options Database Keys:
1270: . -eps_true_residual <boolean> - Sets/resets the boolean flag 'trueres'
1272: Notes:
1273: If the user sets trueres=PETSC_TRUE then the solver explicitly computes
1274: the true residual for each eigenpair approximation, and uses it for
1275: convergence testing. Computing the residual is usually an expensive
1276: operation. Some solvers (e.g., Krylov solvers) can avoid this computation
1277: by using a cheap estimate of the residual norm, but this may sometimes
1278: give inaccurate results (especially if a spectral transform is being
1279: used). On the contrary, preconditioned eigensolvers (e.g., Davidson solvers)
1280: do rely on computing the true residual, so this option is irrelevant for them.
1282: Level: advanced
1284: .seealso: EPSGetTrueResidual()
1285: @*/
1286: PetscErrorCode EPSSetTrueResidual(EPS eps,PetscBool trueres)1287: {
1291: eps->trueres = trueres;
1292: return(0);
1293: }
1295: /*@
1296: EPSGetTrueResidual - Returns the flag indicating whether true
1297: residuals must be computed explicitly or not.
1299: Not Collective
1301: Input Parameter:
1302: . eps - the eigensolver context
1304: Output Parameter:
1305: . trueres - the returned flag
1307: Level: advanced
1309: .seealso: EPSSetTrueResidual()
1310: @*/
1311: PetscErrorCode EPSGetTrueResidual(EPS eps,PetscBool *trueres)1312: {
1316: *trueres = eps->trueres;
1317: return(0);
1318: }
1320: /*@
1321: EPSSetTrackAll - Specifies if the solver must compute the residual norm of all
1322: approximate eigenpairs or not.
1324: Logically Collective on eps
1326: Input Parameters:
1327: + eps - the eigensolver context
1328: - trackall - whether to compute all residuals or not
1330: Notes:
1331: If the user sets trackall=PETSC_TRUE then the solver computes (or estimates)
1332: the residual norm for each eigenpair approximation. Computing the residual is
1333: usually an expensive operation and solvers commonly compute only the residual
1334: associated to the first unconverged eigenpair.
1336: The options '-eps_monitor_all' and '-eps_monitor_lg_all' automatically
1337: activate this option.
1339: Level: developer
1341: .seealso: EPSGetTrackAll()
1342: @*/
1343: PetscErrorCode EPSSetTrackAll(EPS eps,PetscBool trackall)1344: {
1348: eps->trackall = trackall;
1349: return(0);
1350: }
1352: /*@
1353: EPSGetTrackAll - Returns the flag indicating whether all residual norms must
1354: be computed or not.
1356: Not Collective
1358: Input Parameter:
1359: . eps - the eigensolver context
1361: Output Parameter:
1362: . trackall - the returned flag
1364: Level: developer
1366: .seealso: EPSSetTrackAll()
1367: @*/
1368: PetscErrorCode EPSGetTrackAll(EPS eps,PetscBool *trackall)1369: {
1373: *trackall = eps->trackall;
1374: return(0);
1375: }
1377: /*@
1378: EPSSetPurify - Deactivate eigenvector purification (which is activated by default).
1380: Logically Collective on eps
1382: Input Parameters:
1383: + eps - the eigensolver context
1384: - purify - whether purification is required or not
1386: Options Database Keys:
1387: . -eps_purify <boolean> - Sets/resets the boolean flag 'purify'
1389: Notes:
1390: By default, eigenvectors of generalized symmetric eigenproblems are purified
1391: in order to purge directions in the nullspace of matrix B. If the user knows
1392: that B is non-singular, then purification can be safely deactivated and some
1393: computational cost is avoided (this is particularly important in interval computations).
1395: Level: intermediate
1397: .seealso: EPSGetPurify(), EPSSetInterval()
1398: @*/
1399: PetscErrorCode EPSSetPurify(EPS eps,PetscBool purify)1400: {
1404: if (purify!=eps->purify) {
1405: eps->purify = purify;
1406: eps->state = EPS_STATE_INITIAL;
1407: }
1408: return(0);
1409: }
1411: /*@
1412: EPSGetPurify - Returns the flag indicating whether purification is activated
1413: or not.
1415: Not Collective
1417: Input Parameter:
1418: . eps - the eigensolver context
1420: Output Parameter:
1421: . purify - the returned flag
1423: Level: intermediate
1425: .seealso: EPSSetPurify()
1426: @*/
1427: PetscErrorCode EPSGetPurify(EPS eps,PetscBool *purify)1428: {
1432: *purify = eps->purify;
1433: return(0);
1434: }
1436: /*@C
1437: EPSSetOptionsPrefix - Sets the prefix used for searching for all
1438: EPS options in the database.
1440: Logically Collective on eps
1442: Input Parameters:
1443: + eps - the eigensolver context
1444: - prefix - the prefix string to prepend to all EPS option requests
1446: Notes:
1447: A hyphen (-) must NOT be given at the beginning of the prefix name.
1448: The first character of all runtime options is AUTOMATICALLY the
1449: hyphen.
1451: For example, to distinguish between the runtime options for two
1452: different EPS contexts, one could call
1453: .vb
1454: EPSSetOptionsPrefix(eps1,"eig1_")
1455: EPSSetOptionsPrefix(eps2,"eig2_")
1456: .ve
1458: Level: advanced
1460: .seealso: EPSAppendOptionsPrefix(), EPSGetOptionsPrefix()
1461: @*/
1462: PetscErrorCode EPSSetOptionsPrefix(EPS eps,const char *prefix)1463: {
1468: if (!eps->st) { EPSGetST(eps,&eps->st); }
1469: STSetOptionsPrefix(eps->st,prefix);
1470: if (!eps->V) { EPSGetBV(eps,&eps->V); }
1471: BVSetOptionsPrefix(eps->V,prefix);
1472: if (!eps->ds) { EPSGetDS(eps,&eps->ds); }
1473: DSSetOptionsPrefix(eps->ds,prefix);
1474: if (!eps->rg) { EPSGetRG(eps,&eps->rg); }
1475: RGSetOptionsPrefix(eps->rg,prefix);
1476: PetscObjectSetOptionsPrefix((PetscObject)eps,prefix);
1477: return(0);
1478: }
1480: /*@C
1481: EPSAppendOptionsPrefix - Appends to the prefix used for searching for all
1482: EPS options in the database.
1484: Logically Collective on eps
1486: Input Parameters:
1487: + eps - the eigensolver context
1488: - prefix - the prefix string to prepend to all EPS option requests
1490: Notes:
1491: A hyphen (-) must NOT be given at the beginning of the prefix name.
1492: The first character of all runtime options is AUTOMATICALLY the hyphen.
1494: Level: advanced
1496: .seealso: EPSSetOptionsPrefix(), EPSGetOptionsPrefix()
1497: @*/
1498: PetscErrorCode EPSAppendOptionsPrefix(EPS eps,const char *prefix)1499: {
1504: if (!eps->st) { EPSGetST(eps,&eps->st); }
1505: STAppendOptionsPrefix(eps->st,prefix);
1506: if (!eps->V) { EPSGetBV(eps,&eps->V); }
1507: BVAppendOptionsPrefix(eps->V,prefix);
1508: if (!eps->ds) { EPSGetDS(eps,&eps->ds); }
1509: DSAppendOptionsPrefix(eps->ds,prefix);
1510: if (!eps->rg) { EPSGetRG(eps,&eps->rg); }
1511: RGAppendOptionsPrefix(eps->rg,prefix);
1512: PetscObjectAppendOptionsPrefix((PetscObject)eps,prefix);
1513: return(0);
1514: }
1516: /*@C
1517: EPSGetOptionsPrefix - Gets the prefix used for searching for all
1518: EPS options in the database.
1520: Not Collective
1522: Input Parameters:
1523: . eps - the eigensolver context
1525: Output Parameters:
1526: . prefix - pointer to the prefix string used is returned
1528: Note:
1529: On the Fortran side, the user should pass in a string 'prefix' of
1530: sufficient length to hold the prefix.
1532: Level: advanced
1534: .seealso: EPSSetOptionsPrefix(), EPSAppendOptionsPrefix()
1535: @*/
1536: PetscErrorCode EPSGetOptionsPrefix(EPS eps,const char *prefix[])1537: {
1543: PetscObjectGetOptionsPrefix((PetscObject)eps,prefix);
1544: return(0);
1545: }