Actual source code: lmeopts.c

slepc-3.13.3 2020-06-14
Report Typos and Errors
  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:    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 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 lme

153:    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(), LMEProblemType
191: @*/
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(), LMEProblemType
228: @*/
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 lme

273:    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 = PETSC_DEFAULT;
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 lme

341:    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 = PETSC_DEFAULT;
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 lme

377:    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 lme

432:    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 lme

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