1: /*
2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3: SLEPc - Scalable Library for Eigenvalue Problem Computations
4: Copyright (c) 2002-2019, 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: LME routines related to options that can be set via the command-line
12: or procedurally
13: */
15: #include <slepc/private/lmeimpl.h> /*I "slepclme.h" I*/
16: #include <petscdraw.h>
18: /*@C
19: LMEMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type
20: indicated by the user.
22: Collective on LME 24: Input Parameters:
25: + lme - 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
31: Level: developer
33: .seealso: LMEMonitorSet()
34: @*/
35: PetscErrorCode LMEMonitorSetFromOptions(LME lme,const char name[],const char help[],const char manual[],PetscErrorCode (*monitor)(LME,PetscInt,PetscReal,PetscViewerAndFormat*)) 36: {
37: PetscErrorCode ierr;
38: PetscBool flg;
39: PetscViewer viewer;
40: PetscViewerFormat format;
41: PetscViewerAndFormat *vf;
44: PetscOptionsGetViewer(PetscObjectComm((PetscObject)lme),((PetscObject)lme)->options,((PetscObject)lme)->prefix,name,&viewer,&format,&flg);
45: if (flg) {
46: PetscViewerAndFormatCreate(viewer,format,&vf);
47: PetscObjectDereference((PetscObject)viewer);
48: LMEMonitorSet(lme,(PetscErrorCode (*)(LME,PetscInt,PetscReal,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);
49: }
50: return(0);
51: }
53: /*@
54: LMESetFromOptions - Sets LME options from the options database.
55: This routine must be called before LMESetUp() if the user is to be
56: allowed to set the solver type.
58: Collective on LME 60: Input Parameters:
61: . lme - the linear matrix equation solver context
63: Notes:
64: To see all options, run your program with the -help option.
66: Level: beginner
67: @*/
68: PetscErrorCode LMESetFromOptions(LME lme) 69: {
71: char type[256];
72: PetscBool set,flg,flg1,flg2;
73: PetscReal r;
74: PetscInt i;
75: PetscDrawLG lg;
79: LMERegisterAll();
80: PetscObjectOptionsBegin((PetscObject)lme);
81: PetscOptionsFList("-lme_type","Linear matrix equation","LMESetType",LMEList,(char*)(((PetscObject)lme)->type_name?((PetscObject)lme)->type_name:LMEKRYLOV),type,256,&flg);
82: if (flg) {
83: LMESetType(lme,type);
84: } else if (!((PetscObject)lme)->type_name) {
85: LMESetType(lme,LMEKRYLOV);
86: }
88: PetscOptionsBoolGroupBegin("-lme_lyapunov","Continuous-time Lyapunov equation","LMESetProblemType",&flg);
89: if (flg) { LMESetProblemType(lme,LME_LYAPUNOV); }
90: PetscOptionsBoolGroup("-lme_sylvester","Continuous-time Sylvester equation","LMESetProblemType",&flg);
91: if (flg) { LMESetProblemType(lme,LME_SYLVESTER); }
92: PetscOptionsBoolGroup("-lme_gen_lyapunov","Generalized Lyapunov equation","LMESetProblemType",&flg);
93: if (flg) { LMESetProblemType(lme,LME_GEN_LYAPUNOV); }
94: PetscOptionsBoolGroup("-lme_gen_sylvester","Generalized Sylvester equation","LMESetProblemType",&flg);
95: if (flg) { LMESetProblemType(lme,LME_GEN_SYLVESTER); }
96: PetscOptionsBoolGroup("-lme_dt_lyapunov","Discrete-time Lyapunov equation","LMESetProblemType",&flg);
97: if (flg) { LMESetProblemType(lme,LME_DT_LYAPUNOV); }
98: PetscOptionsBoolGroupEnd("-lme_stein","Stein equation","LMESetProblemType",&flg);
99: if (flg) { LMESetProblemType(lme,LME_STEIN); }
101: i = lme->max_it;
102: PetscOptionsInt("-lme_max_it","Maximum number of iterations","LMESetTolerances",lme->max_it,&i,&flg1);
103: if (!flg1) i = PETSC_DEFAULT;
104: r = lme->tol;
105: PetscOptionsReal("-lme_tol","Tolerance","LMESetTolerances",lme->tol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL:lme->tol,&r,&flg2);
106: if (flg1 || flg2) { LMESetTolerances(lme,r,i); }
108: PetscOptionsInt("-lme_ncv","Number of basis vectors","LMESetDimensions",lme->ncv,&i,&flg);
109: if (flg) { LMESetDimensions(lme,i); }
111: PetscOptionsBool("-lme_error_if_not_converged","Generate error if solver does not converge","LMESetErrorIfNotConverged",lme->errorifnotconverged,&lme->errorifnotconverged,NULL);
113: /* -----------------------------------------------------------------------*/
114: /*
115: Cancels all monitors hardwired into code before call to LMESetFromOptions()
116: */
117: PetscOptionsBool("-lme_monitor_cancel","Remove any hardwired monitor routines","LMEMonitorCancel",PETSC_FALSE,&flg,&set);
118: if (set && flg) {
119: LMEMonitorCancel(lme);
120: }
121: /*
122: Text monitors
123: */
124: LMEMonitorSetFromOptions(lme,"-lme_monitor","Monitor error estimate","LMEMonitorDefault",LMEMonitorDefault);
125: /*
126: Line graph monitors
127: */
128: PetscOptionsBool("-lme_monitor_lg","Monitor error estimate graphically","LMEMonitorSet",PETSC_FALSE,&flg,&set);
129: if (set && flg) {
130: LMEMonitorLGCreate(PetscObjectComm((PetscObject)lme),NULL,"Error estimate",PETSC_DECIDE,PETSC_DECIDE,300,300,&lg);
131: LMEMonitorSet(lme,LMEMonitorLG,lg,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);
132: }
134: /* -----------------------------------------------------------------------*/
135: PetscOptionsName("-lme_view","Print detailed information on solver used","LMEView",NULL);
137: if (lme->ops->setfromoptions) {
138: (*lme->ops->setfromoptions)(PetscOptionsObject,lme);
139: }
140: PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)lme);
141: PetscOptionsEnd();
143: if (!lme->V) { LMEGetBV(lme,&lme->V); }
144: BVSetFromOptions(lme->V);
145: return(0);
146: }
148: /*@
149: LMESetProblemType - Specifies the type of matrix equation to be solved.
151: Logically Collective on LME153: Input Parameters:
154: + lme - the linear matrix equation solver context
155: - type - a known type of matrix equation
157: Options Database Keys:
158: + -lme_lyapunov - continuous-time Lyapunov equation A*X+X*A'=-C
159: . -lme_sylvester - continuous-time Sylvester equation A*X+X*B=C
160: . -lme_gen_lyapunov - generalized Lyapunov equation A*X*D'+D*X*A'=-C
161: . -lme_gen_sylvester - generalized Sylvester equation A*X*E+D*X*B=C
162: . -lme_dt_lyapunov - discrete-time Lyapunov equation A*X*A'-X=-C
163: - -lme_stein - Stein equation A*X*E+X=C
165: Notes:
166: The coefficient matrices A, B, D, E must be provided via LMESetCoefficients(),
167: but some of them are optional depending on the matrix equation.
169: .vb
170: equation A B D E
171: ----------------- --- --- --- ---
172: LME_LYAPUNOV A*X+X*A'=-C yes (A-t) - -
173: LME_SYLVESTER A*X+X*B=C yes yes - -
174: LME_GEN_LYAPUNOV A*X*D'+D*X*A'=-C yes (A-t) yes (D-t)
175: LME_GEN_SYLVESTER A*X*E+D*X*B=C yes yes yes yes
176: LME_DT_LYAPUNOV A*X*A'-X=-C yes - - (A-t)
177: LME_STEIN A*X*E+X=C yes - - yes
178: .ve
180: In the above table, the notation (A-t) means that this matrix need
181: not be passed, but the user may choose to pass an explicit transpose
182: of matrix A (for improved efficiency).
184: Also note that some of the equation types impose restrictions on the
185: properties of the coefficient matrices and possibly on the right-hand
186: side C.
188: Level: beginner
190: .seealso: LMESetCoefficients(), LMESetType(), LMEGetProblemType(), LMEProblemType191: @*/
192: PetscErrorCode LMESetProblemType(LME lme,LMEProblemType type)193: {
197: if (type == lme->problem_type) return(0);
198: switch (type) {
199: case LME_LYAPUNOV:
200: case LME_SYLVESTER:
201: case LME_GEN_LYAPUNOV:
202: case LME_GEN_SYLVESTER:
203: case LME_DT_LYAPUNOV:
204: case LME_STEIN:
205: break;
206: default:207: SETERRQ(PetscObjectComm((PetscObject)lme),PETSC_ERR_ARG_WRONG,"Unknown matrix equation type");
208: }
209: lme->problem_type = type;
210: lme->setupcalled = PETSC_FALSE;
211: return(0);
212: }
214: /*@
215: LMEGetProblemType - Gets the matrix equation type from the LME object.
217: Not Collective
219: Input Parameter:
220: . lme - the linear matrix equation solver context
222: Output Parameter:
223: . type - name of LME problem type
225: Level: intermediate
227: .seealso: LMESetProblemType(), LMEProblemType228: @*/
229: PetscErrorCode LMEGetProblemType(LME lme,LMEProblemType *type)230: {
234: *type = lme->problem_type;
235: return(0);
236: }
238: /*@C
239: LMEGetTolerances - Gets the tolerance and maximum iteration count used
240: by the LME convergence tests.
242: Not Collective
244: Input Parameter:
245: . lme - the linear matrix equation solver context
247: Output Parameters:
248: + tol - the convergence tolerance
249: - maxits - maximum number of iterations
251: Notes:
252: The user can specify NULL for any parameter that is not needed.
254: Level: intermediate
256: .seealso: LMESetTolerances()
257: @*/
258: PetscErrorCode LMEGetTolerances(LME lme,PetscReal *tol,PetscInt *maxits)259: {
262: if (tol) *tol = lme->tol;
263: if (maxits) *maxits = lme->max_it;
264: return(0);
265: }
267: /*@
268: LMESetTolerances - Sets the tolerance and maximum iteration count used
269: by the LME convergence tests.
271: Logically Collective on LME273: Input Parameters:
274: + lme - the linear matrix equation solver context
275: . tol - the convergence tolerance
276: - maxits - maximum number of iterations to use
278: Options Database Keys:
279: + -lme_tol <tol> - Sets the convergence tolerance
280: - -lme_max_it <maxits> - Sets the maximum number of iterations allowed
282: Notes:
283: Use PETSC_DEFAULT for either argument to assign a reasonably good value.
285: Level: intermediate
287: .seealso: LMEGetTolerances()
288: @*/
289: PetscErrorCode LMESetTolerances(LME lme,PetscReal tol,PetscInt maxits)290: {
295: if (tol == PETSC_DEFAULT) {
296: lme->tol = PETSC_DEFAULT;
297: lme->setupcalled = 0;
298: } else {
299: if (tol <= 0.0) SETERRQ(PetscObjectComm((PetscObject)lme),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of tol. Must be > 0");
300: lme->tol = tol;
301: }
302: if (maxits == PETSC_DEFAULT || maxits == PETSC_DECIDE) {
303: lme->max_it = 0;
304: lme->setupcalled = 0;
305: } else {
306: if (maxits <= 0) SETERRQ(PetscObjectComm((PetscObject)lme),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of maxits. Must be > 0");
307: lme->max_it = maxits;
308: }
309: return(0);
310: }
312: /*@
313: LMEGetDimensions - Gets the dimension of the subspace used by the solver.
315: Not Collective
317: Input Parameter:
318: . lme - the linear matrix equation solver context
320: Output Parameter:
321: . ncv - the maximum dimension of the subspace to be used by the solver
323: Level: intermediate
325: .seealso: LMESetDimensions()
326: @*/
327: PetscErrorCode LMEGetDimensions(LME lme,PetscInt *ncv)328: {
332: *ncv = lme->ncv;
333: return(0);
334: }
336: /*@
337: LMESetDimensions - Sets the dimension of the subspace to be used by the solver.
339: Logically Collective on LME341: Input Parameters:
342: + lme - the linear matrix equation solver context
343: - ncv - the maximum dimension of the subspace to be used by the solver
345: Options Database Keys:
346: . -lme_ncv <ncv> - Sets the dimension of the subspace
348: Notes:
349: Use PETSC_DEFAULT for ncv to assign a reasonably good value, which is
350: dependent on the solution method.
352: Level: intermediate
354: .seealso: LMEGetDimensions()
355: @*/
356: PetscErrorCode LMESetDimensions(LME lme,PetscInt ncv)357: {
361: if (ncv == PETSC_DECIDE || ncv == PETSC_DEFAULT) {
362: lme->ncv = 0;
363: } else {
364: if (ncv<1) SETERRQ(PetscObjectComm((PetscObject)lme),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of ncv. Must be > 0");
365: lme->ncv = ncv;
366: }
367: lme->setupcalled = 0;
368: return(0);
369: }
371: /*@
372: LMESetErrorIfNotConverged - Causes LMESolve() to generate an error if the
373: solver has not converged.
375: Logically Collective on LME377: Input Parameters:
378: + lme - the linear matrix equation solver context
379: - flg - PETSC_TRUE indicates you want the error generated
381: Options Database Keys:
382: . -lme_error_if_not_converged - this takes an optional truth value (0/1/no/yes/true/false)
384: Level: intermediate
386: Note:
387: Normally SLEPc continues if the solver fails to converge, you can call
388: LMEGetConvergedReason() after a LMESolve() to determine if it has converged.
390: .seealso: LMEGetErrorIfNotConverged()
391: @*/
392: PetscErrorCode LMESetErrorIfNotConverged(LME lme,PetscBool flg)393: {
397: lme->errorifnotconverged = flg;
398: return(0);
399: }
401: /*@
402: LMEGetErrorIfNotConverged - Return a flag indicating whether LMESolve() will
403: generate an error if the solver does not converge.
405: Not Collective
407: Input Parameter:
408: . lme - the linear matrix equation solver context
410: Output Parameter:
411: . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
413: Level: intermediate
415: .seealso: LMESetErrorIfNotConverged()
416: @*/
417: PetscErrorCode LMEGetErrorIfNotConverged(LME lme,PetscBool *flag)418: {
422: *flag = lme->errorifnotconverged;
423: return(0);
424: }
426: /*@C
427: LMESetOptionsPrefix - Sets the prefix used for searching for all
428: LME options in the database.
430: Logically Collective on LME432: Input Parameters:
433: + lme - the linear matrix equation solver context
434: - prefix - the prefix string to prepend to all LME option requests
436: Notes:
437: A hyphen (-) must NOT be given at the beginning of the prefix name.
438: The first character of all runtime options is AUTOMATICALLY the
439: hyphen.
441: For example, to distinguish between the runtime options for two
442: different LME contexts, one could call
443: .vb
444: LMESetOptionsPrefix(lme1,"fun1_")
445: LMESetOptionsPrefix(lme2,"fun2_")
446: .ve
448: Level: advanced
450: .seealso: LMEAppendOptionsPrefix(), LMEGetOptionsPrefix()
451: @*/
452: PetscErrorCode LMESetOptionsPrefix(LME lme,const char *prefix)453: {
458: if (!lme->V) { LMEGetBV(lme,&lme->V); }
459: BVSetOptionsPrefix(lme->V,prefix);
460: PetscObjectSetOptionsPrefix((PetscObject)lme,prefix);
461: return(0);
462: }
464: /*@C
465: LMEAppendOptionsPrefix - Appends to the prefix used for searching for all
466: LME options in the database.
468: Logically Collective on LME470: Input Parameters:
471: + lme - the linear matrix equation solver context
472: - prefix - the prefix string to prepend to all LME option requests
474: Notes:
475: A hyphen (-) must NOT be given at the beginning of the prefix name.
476: The first character of all runtime options is AUTOMATICALLY the hyphen.
478: Level: advanced
480: .seealso: LMESetOptionsPrefix(), LMEGetOptionsPrefix()
481: @*/
482: PetscErrorCode LMEAppendOptionsPrefix(LME lme,const char *prefix)483: {
488: if (!lme->V) { LMEGetBV(lme,&lme->V); }
489: BVAppendOptionsPrefix(lme->V,prefix);
490: PetscObjectAppendOptionsPrefix((PetscObject)lme,prefix);
491: return(0);
492: }
494: /*@C
495: LMEGetOptionsPrefix - Gets the prefix used for searching for all
496: LME options in the database.
498: Not Collective
500: Input Parameters:
501: . lme - the linear matrix equation solver context
503: Output Parameters:
504: . prefix - pointer to the prefix string used is returned
506: Note:
507: On the Fortran side, the user should pass in a string 'prefix' of
508: sufficient length to hold the prefix.
510: Level: advanced
512: .seealso: LMESetOptionsPrefix(), LMEAppendOptionsPrefix()
513: @*/
514: PetscErrorCode LMEGetOptionsPrefix(LME lme,const char *prefix[])515: {
521: PetscObjectGetOptionsPrefix((PetscObject)lme,prefix);
522: return(0);
523: }