Actual source code: lmeopts.c

slepc-3.16.0 2021-09-30
Report Typos and Errors
  1: /*
  2:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3:    SLEPc - Scalable Library for Eigenvalue Problem Computations
  4:    Copyright (c) 2002-2021, 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>
 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 linear matrix equation 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

 30:    Level: developer

 32: .seealso: LMEMonitorSet()
 33: @*/
 34: PetscErrorCode LMEMonitorSetFromOptions(LME lme,const char opt[],const char name[],void *ctx)
 35: {
 36:   PetscErrorCode       (*mfunc)(LME,PetscInt,PetscReal,void*);
 37:   PetscErrorCode       (*cfunc)(PetscViewer,PetscViewerFormat,void*,PetscViewerAndFormat**);
 38:   PetscErrorCode       (*dfunc)(PetscViewerAndFormat**);
 39:   PetscViewerAndFormat *vf;
 40:   PetscViewer          viewer;
 41:   PetscViewerFormat    format;
 42:   PetscViewerType      vtype;
 43:   char                 key[PETSC_MAX_PATH_LEN];
 44:   PetscBool            flg;
 45:   PetscErrorCode       ierr;

 48:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)lme),((PetscObject)lme)->options,((PetscObject)lme)->prefix,opt,&viewer,&format,&flg);
 49:   if (!flg) return(0);

 51:   PetscViewerGetType(viewer,&vtype);
 52:   SlepcMonitorMakeKey_Internal(name,vtype,format,key);
 53:   PetscFunctionListFind(LMEMonitorList,key,&mfunc);
 54:   PetscFunctionListFind(LMEMonitorCreateList,key,&cfunc);
 55:   PetscFunctionListFind(LMEMonitorDestroyList,key,&dfunc);
 56:   if (!cfunc) cfunc = PetscViewerAndFormatCreate_Internal;
 57:   if (!dfunc) dfunc = PetscViewerAndFormatDestroy;

 59:   (*cfunc)(viewer,format,ctx,&vf);
 60:   PetscObjectDereference((PetscObject)viewer);
 61:   LMEMonitorSet(lme,mfunc,vf,(PetscErrorCode(*)(void **))dfunc);
 62:   return(0);
 63: }

 65: /*@
 66:    LMESetFromOptions - Sets LME options from the options database.
 67:    This routine must be called before LMESetUp() if the user is to be
 68:    allowed to set the solver type.

 70:    Collective on lme

 72:    Input Parameters:
 73: .  lme - the linear matrix equation solver context

 75:    Notes:
 76:    To see all options, run your program with the -help option.

 78:    Level: beginner
 79: @*/
 80: PetscErrorCode LMESetFromOptions(LME lme)
 81: {
 83:   char           type[256];
 84:   PetscBool      set,flg,flg1,flg2;
 85:   PetscReal      r;
 86:   PetscInt       i;

 90:   LMERegisterAll();
 91:   PetscObjectOptionsBegin((PetscObject)lme);
 92:     PetscOptionsFList("-lme_type","Linear matrix equation","LMESetType",LMEList,(char*)(((PetscObject)lme)->type_name?((PetscObject)lme)->type_name:LMEKRYLOV),type,sizeof(type),&flg);
 93:     if (flg) {
 94:       LMESetType(lme,type);
 95:     } else if (!((PetscObject)lme)->type_name) {
 96:       LMESetType(lme,LMEKRYLOV);
 97:     }

 99:     PetscOptionsBoolGroupBegin("-lme_lyapunov","Continuous-time Lyapunov equation","LMESetProblemType",&flg);
100:     if (flg) { LMESetProblemType(lme,LME_LYAPUNOV); }
101:     PetscOptionsBoolGroup("-lme_sylvester","Continuous-time Sylvester equation","LMESetProblemType",&flg);
102:     if (flg) { LMESetProblemType(lme,LME_SYLVESTER); }
103:     PetscOptionsBoolGroup("-lme_gen_lyapunov","Generalized Lyapunov equation","LMESetProblemType",&flg);
104:     if (flg) { LMESetProblemType(lme,LME_GEN_LYAPUNOV); }
105:     PetscOptionsBoolGroup("-lme_gen_sylvester","Generalized Sylvester equation","LMESetProblemType",&flg);
106:     if (flg) { LMESetProblemType(lme,LME_GEN_SYLVESTER); }
107:     PetscOptionsBoolGroup("-lme_dt_lyapunov","Discrete-time Lyapunov equation","LMESetProblemType",&flg);
108:     if (flg) { LMESetProblemType(lme,LME_DT_LYAPUNOV); }
109:     PetscOptionsBoolGroupEnd("-lme_stein","Stein equation","LMESetProblemType",&flg);
110:     if (flg) { LMESetProblemType(lme,LME_STEIN); }

112:     i = lme->max_it;
113:     PetscOptionsInt("-lme_max_it","Maximum number of iterations","LMESetTolerances",lme->max_it,&i,&flg1);
114:     if (!flg1) i = PETSC_DEFAULT;
115:     r = lme->tol;
116:     PetscOptionsReal("-lme_tol","Tolerance","LMESetTolerances",SlepcDefaultTol(lme->tol),&r,&flg2);
117:     if (flg1 || flg2) { LMESetTolerances(lme,r,i); }

119:     PetscOptionsInt("-lme_ncv","Number of basis vectors","LMESetDimensions",lme->ncv,&i,&flg);
120:     if (flg) { LMESetDimensions(lme,i); }

122:     PetscOptionsBool("-lme_error_if_not_converged","Generate error if solver does not converge","LMESetErrorIfNotConverged",lme->errorifnotconverged,&lme->errorifnotconverged,NULL);

124:     /* -----------------------------------------------------------------------*/
125:     /*
126:       Cancels all monitors hardwired into code before call to LMESetFromOptions()
127:     */
128:     PetscOptionsBool("-lme_monitor_cancel","Remove any hardwired monitor routines","LMEMonitorCancel",PETSC_FALSE,&flg,&set);
129:     if (set && flg) { LMEMonitorCancel(lme); }
130:     LMEMonitorSetFromOptions(lme,"-lme_monitor","error_estimate",NULL);

132:     /* -----------------------------------------------------------------------*/
133:     PetscOptionsName("-lme_view","Print detailed information on solver used","LMEView",NULL);

135:     if (lme->ops->setfromoptions) {
136:       (*lme->ops->setfromoptions)(PetscOptionsObject,lme);
137:     }
138:     PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)lme);
139:   PetscOptionsEnd();

141:   if (!lme->V) { LMEGetBV(lme,&lme->V); }
142:   BVSetFromOptions(lme->V);
143:   return(0);
144: }

146: /*@
147:    LMESetProblemType - Specifies the type of matrix equation to be solved.

149:    Logically Collective on lme

151:    Input Parameters:
152: +  lme  - the linear matrix equation solver context
153: -  type - a known type of matrix equation

155:    Options Database Keys:
156: +  -lme_lyapunov - continuous-time Lyapunov equation A*X+X*A'=-C
157: .  -lme_sylvester - continuous-time Sylvester equation A*X+X*B=C
158: .  -lme_gen_lyapunov - generalized Lyapunov equation A*X*D'+D*X*A'=-C
159: .  -lme_gen_sylvester - generalized Sylvester equation A*X*E+D*X*B=C
160: .  -lme_dt_lyapunov - discrete-time Lyapunov equation A*X*A'-X=-C
161: -  -lme_stein - Stein equation A*X*E+X=C

163:    Notes:
164:    The coefficient matrices A, B, D, E must be provided via LMESetCoefficients(),
165:    but some of them are optional depending on the matrix equation.

167: .vb
168:                             equation              A    B    D    E
169:                           -----------------      ---  ---  ---  ---
170:        LME_LYAPUNOV        A*X+X*A'=-C           yes (A-t)  -    -
171:        LME_SYLVESTER       A*X+X*B=C             yes  yes   -    -
172:        LME_GEN_LYAPUNOV    A*X*D'+D*X*A'=-C      yes (A-t) yes (D-t)
173:        LME_GEN_SYLVESTER   A*X*E+D*X*B=C         yes  yes  yes  yes
174:        LME_DT_LYAPUNOV     A*X*A'-X=-C           yes   -    -  (A-t)
175:        LME_STEIN           A*X*E+X=C             yes   -    -   yes
176: .ve

178:    In the above table, the notation (A-t) means that this matrix need
179:    not be passed, but the user may choose to pass an explicit transpose
180:    of matrix A (for improved efficiency).

182:    Also note that some of the equation types impose restrictions on the
183:    properties of the coefficient matrices and possibly on the right-hand
184:    side C.

186:    Level: beginner

188: .seealso: LMESetCoefficients(), LMESetType(), LMEGetProblemType(), LMEProblemType
189: @*/
190: PetscErrorCode LMESetProblemType(LME lme,LMEProblemType type)
191: {
195:   if (type == lme->problem_type) return(0);
196:   switch (type) {
197:     case LME_LYAPUNOV:
198:     case LME_SYLVESTER:
199:     case LME_GEN_LYAPUNOV:
200:     case LME_GEN_SYLVESTER:
201:     case LME_DT_LYAPUNOV:
202:     case LME_STEIN:
203:       break;
204:     default:
205:       SETERRQ(PetscObjectComm((PetscObject)lme),PETSC_ERR_ARG_WRONG,"Unknown matrix equation type");
206:   }
207:   lme->problem_type = type;
208:   lme->setupcalled  = PETSC_FALSE;
209:   return(0);
210: }

212: /*@
213:    LMEGetProblemType - Gets the matrix equation type from the LME object.

215:    Not Collective

217:    Input Parameter:
218: .  lme - the linear matrix equation solver context

220:    Output Parameter:
221: .  type - name of LME problem type

223:    Level: intermediate

225: .seealso: LMESetProblemType(), LMEProblemType
226: @*/
227: PetscErrorCode LMEGetProblemType(LME lme,LMEProblemType *type)
228: {
232:   *type = lme->problem_type;
233:   return(0);
234: }

236: /*@C
237:    LMEGetTolerances - Gets the tolerance and maximum iteration count used
238:    by the LME convergence tests.

240:    Not Collective

242:    Input Parameter:
243: .  lme - the linear matrix equation solver context

245:    Output Parameters:
246: +  tol - the convergence tolerance
247: -  maxits - maximum number of iterations

249:    Notes:
250:    The user can specify NULL for any parameter that is not needed.

252:    Level: intermediate

254: .seealso: LMESetTolerances()
255: @*/
256: PetscErrorCode LMEGetTolerances(LME lme,PetscReal *tol,PetscInt *maxits)
257: {
260:   if (tol)    *tol    = lme->tol;
261:   if (maxits) *maxits = lme->max_it;
262:   return(0);
263: }

265: /*@
266:    LMESetTolerances - Sets the tolerance and maximum iteration count used
267:    by the LME convergence tests.

269:    Logically Collective on lme

271:    Input Parameters:
272: +  lme - the linear matrix equation solver context
273: .  tol - the convergence tolerance
274: -  maxits - maximum number of iterations to use

276:    Options Database Keys:
277: +  -lme_tol <tol> - Sets the convergence tolerance
278: -  -lme_max_it <maxits> - Sets the maximum number of iterations allowed

280:    Notes:
281:    Use PETSC_DEFAULT for either argument to assign a reasonably good value.

283:    Level: intermediate

285: .seealso: LMEGetTolerances()
286: @*/
287: PetscErrorCode LMESetTolerances(LME lme,PetscReal tol,PetscInt maxits)
288: {
293:   if (tol == PETSC_DEFAULT) {
294:     lme->tol = PETSC_DEFAULT;
295:     lme->setupcalled = 0;
296:   } else {
297:     if (tol <= 0.0) SETERRQ(PetscObjectComm((PetscObject)lme),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of tol. Must be > 0");
298:     lme->tol = tol;
299:   }
300:   if (maxits == PETSC_DEFAULT || maxits == PETSC_DECIDE) {
301:     lme->max_it = PETSC_DEFAULT;
302:     lme->setupcalled = 0;
303:   } else {
304:     if (maxits <= 0) SETERRQ(PetscObjectComm((PetscObject)lme),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of maxits. Must be > 0");
305:     lme->max_it = maxits;
306:   }
307:   return(0);
308: }

310: /*@
311:    LMEGetDimensions - Gets the dimension of the subspace used by the solver.

313:    Not Collective

315:    Input Parameter:
316: .  lme - the linear matrix equation solver context

318:    Output Parameter:
319: .  ncv - the maximum dimension of the subspace to be used by the solver

321:    Level: intermediate

323: .seealso: LMESetDimensions()
324: @*/
325: PetscErrorCode LMEGetDimensions(LME lme,PetscInt *ncv)
326: {
330:   *ncv = lme->ncv;
331:   return(0);
332: }

334: /*@
335:    LMESetDimensions - Sets the dimension of the subspace to be used by the solver.

337:    Logically Collective on lme

339:    Input Parameters:
340: +  lme - the linear matrix equation solver context
341: -  ncv - the maximum dimension of the subspace to be used by the solver

343:    Options Database Keys:
344: .  -lme_ncv <ncv> - Sets the dimension of the subspace

346:    Notes:
347:    Use PETSC_DEFAULT for ncv to assign a reasonably good value, which is
348:    dependent on the solution method.

350:    Level: intermediate

352: .seealso: LMEGetDimensions()
353: @*/
354: PetscErrorCode LMESetDimensions(LME lme,PetscInt ncv)
355: {
359:   if (ncv == PETSC_DECIDE || ncv == PETSC_DEFAULT) {
360:     lme->ncv = PETSC_DEFAULT;
361:   } else {
362:     if (ncv<1) SETERRQ(PetscObjectComm((PetscObject)lme),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of ncv. Must be > 0");
363:     lme->ncv = ncv;
364:   }
365:   lme->setupcalled = 0;
366:   return(0);
367: }

369: /*@
370:    LMESetErrorIfNotConverged - Causes LMESolve() to generate an error if the
371:    solver has not converged.

373:    Logically Collective on lme

375:    Input Parameters:
376: +  lme - the linear matrix equation solver context
377: -  flg - PETSC_TRUE indicates you want the error generated

379:    Options Database Keys:
380: .  -lme_error_if_not_converged - this takes an optional truth value (0/1/no/yes/true/false)

382:    Level: intermediate

384:    Note:
385:    Normally SLEPc continues if the solver fails to converge, you can call
386:    LMEGetConvergedReason() after a LMESolve() to determine if it has converged.

388: .seealso: LMEGetErrorIfNotConverged()
389: @*/
390: PetscErrorCode LMESetErrorIfNotConverged(LME lme,PetscBool flg)
391: {
395:   lme->errorifnotconverged = flg;
396:   return(0);
397: }

399: /*@
400:    LMEGetErrorIfNotConverged - Return a flag indicating whether LMESolve() will
401:    generate an error if the solver does not converge.

403:    Not Collective

405:    Input Parameter:
406: .  lme - the linear matrix equation solver context

408:    Output Parameter:
409: .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE

411:    Level: intermediate

413: .seealso:  LMESetErrorIfNotConverged()
414: @*/
415: PetscErrorCode LMEGetErrorIfNotConverged(LME lme,PetscBool *flag)
416: {
420:   *flag = lme->errorifnotconverged;
421:   return(0);
422: }

424: /*@C
425:    LMESetOptionsPrefix - Sets the prefix used for searching for all
426:    LME options in the database.

428:    Logically Collective on lme

430:    Input Parameters:
431: +  lme - the linear matrix equation solver context
432: -  prefix - the prefix string to prepend to all LME option requests

434:    Notes:
435:    A hyphen (-) must NOT be given at the beginning of the prefix name.
436:    The first character of all runtime options is AUTOMATICALLY the
437:    hyphen.

439:    For example, to distinguish between the runtime options for two
440:    different LME contexts, one could call
441: .vb
442:       LMESetOptionsPrefix(lme1,"fun1_")
443:       LMESetOptionsPrefix(lme2,"fun2_")
444: .ve

446:    Level: advanced

448: .seealso: LMEAppendOptionsPrefix(), LMEGetOptionsPrefix()
449: @*/
450: PetscErrorCode LMESetOptionsPrefix(LME lme,const char *prefix)
451: {

456:   if (!lme->V) { LMEGetBV(lme,&lme->V); }
457:   BVSetOptionsPrefix(lme->V,prefix);
458:   PetscObjectSetOptionsPrefix((PetscObject)lme,prefix);
459:   return(0);
460: }

462: /*@C
463:    LMEAppendOptionsPrefix - Appends to the prefix used for searching for all
464:    LME options in the database.

466:    Logically Collective on lme

468:    Input Parameters:
469: +  lme - the linear matrix equation solver context
470: -  prefix - the prefix string to prepend to all LME option requests

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

476:    Level: advanced

478: .seealso: LMESetOptionsPrefix(), LMEGetOptionsPrefix()
479: @*/
480: PetscErrorCode LMEAppendOptionsPrefix(LME lme,const char *prefix)
481: {

486:   if (!lme->V) { LMEGetBV(lme,&lme->V); }
487:   BVAppendOptionsPrefix(lme->V,prefix);
488:   PetscObjectAppendOptionsPrefix((PetscObject)lme,prefix);
489:   return(0);
490: }

492: /*@C
493:    LMEGetOptionsPrefix - Gets the prefix used for searching for all
494:    LME options in the database.

496:    Not Collective

498:    Input Parameters:
499: .  lme - the linear matrix equation solver context

501:    Output Parameters:
502: .  prefix - pointer to the prefix string used is returned

504:    Note:
505:    On the Fortran side, the user should pass in a string 'prefix' of
506:    sufficient length to hold the prefix.

508:    Level: advanced

510: .seealso: LMESetOptionsPrefix(), LMEAppendOptionsPrefix()
511: @*/
512: PetscErrorCode LMEGetOptionsPrefix(LME lme,const char *prefix[])
513: {

519:   PetscObjectGetOptionsPrefix((PetscObject)lme,prefix);
520:   return(0);
521: }