Actual source code: lmeopts.c

slepc-3.17.0 2022-03-31
Report Typos and Errors
  1: /*
  2:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3:    SLEPc - Scalable Library for Eigenvalue Problem Computations
  4:    Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain

  6:    This file is part of SLEPc.
  7:    SLEPc is distributed under a 2-clause BSD license (see LICENSE).
  8:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  9: */
 10: /*
 11:    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;

 46:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)lme),((PetscObject)lme)->options,((PetscObject)lme)->prefix,opt,&viewer,&format,&flg);
 47:   if (!flg) PetscFunctionReturn(0);

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

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

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

 69:    Collective on lme

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

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

 77:    Level: beginner

 79: .seealso: LMESetOptionsPrefix()
 80: @*/
 81: PetscErrorCode LMESetFromOptions(LME lme)
 82: {
 84:   char           type[256];
 85:   PetscBool      set,flg,flg1,flg2;
 86:   PetscReal      r;
 87:   PetscInt       i;

 90:   LMERegisterAll();
 91:   ierr = 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) LMESetType(lme,type);
 94:     else if (!((PetscObject)lme)->type_name) LMESetType(lme,LMEKRYLOV);

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

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

116:     PetscOptionsInt("-lme_ncv","Number of basis vectors","LMESetDimensions",lme->ncv,&i,&flg);
117:     if (flg) LMESetDimensions(lme,i);

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

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

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

132:     if (lme->ops->setfromoptions) (*lme->ops->setfromoptions)(PetscOptionsObject,lme);
133:     PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)lme);
134:   ierr = PetscOptionsEnd();

136:   if (!lme->V) LMEGetBV(lme,&lme->V);
137:   BVSetFromOptions(lme->V);
138:   PetscFunctionReturn(0);
139: }

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

144:    Logically Collective on lme

146:    Input Parameters:
147: +  lme  - the linear matrix equation solver context
148: -  type - a known type of matrix equation

150:    Options Database Keys:
151: +  -lme_lyapunov - continuous-time Lyapunov equation A*X+X*A'=-C
152: .  -lme_sylvester - continuous-time Sylvester equation A*X+X*B=C
153: .  -lme_gen_lyapunov - generalized Lyapunov equation A*X*D'+D*X*A'=-C
154: .  -lme_gen_sylvester - generalized Sylvester equation A*X*E+D*X*B=C
155: .  -lme_dt_lyapunov - discrete-time Lyapunov equation A*X*A'-X=-C
156: -  -lme_stein - Stein equation A*X*E+X=C

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

162: .vb
163:                             equation              A    B    D    E
164:                           -----------------      ---  ---  ---  ---
165:        LME_LYAPUNOV        A*X+X*A'=-C           yes (A-t)  -    -
166:        LME_SYLVESTER       A*X+X*B=C             yes  yes   -    -
167:        LME_GEN_LYAPUNOV    A*X*D'+D*X*A'=-C      yes (A-t) yes (D-t)
168:        LME_GEN_SYLVESTER   A*X*E+D*X*B=C         yes  yes  yes  yes
169:        LME_DT_LYAPUNOV     A*X*A'-X=-C           yes   -    -  (A-t)
170:        LME_STEIN           A*X*E+X=C             yes   -    -   yes
171: .ve

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

177:    Also note that some of the equation types impose restrictions on the
178:    properties of the coefficient matrices and possibly on the right-hand
179:    side C.

181:    Level: beginner

183: .seealso: LMESetCoefficients(), LMESetType(), LMEGetProblemType(), LMEProblemType
184: @*/
185: PetscErrorCode LMESetProblemType(LME lme,LMEProblemType type)
186: {
189:   if (type == lme->problem_type) PetscFunctionReturn(0);
190:   switch (type) {
191:     case LME_LYAPUNOV:
192:     case LME_SYLVESTER:
193:     case LME_GEN_LYAPUNOV:
194:     case LME_GEN_SYLVESTER:
195:     case LME_DT_LYAPUNOV:
196:     case LME_STEIN:
197:       break;
198:     default:
199:       SETERRQ(PetscObjectComm((PetscObject)lme),PETSC_ERR_ARG_WRONG,"Unknown matrix equation type");
200:   }
201:   lme->problem_type = type;
202:   lme->setupcalled  = PETSC_FALSE;
203:   PetscFunctionReturn(0);
204: }

206: /*@
207:    LMEGetProblemType - Gets the matrix equation type from the LME object.

209:    Not Collective

211:    Input Parameter:
212: .  lme - the linear matrix equation solver context

214:    Output Parameter:
215: .  type - name of LME problem type

217:    Level: intermediate

219: .seealso: LMESetProblemType(), LMEProblemType
220: @*/
221: PetscErrorCode LMEGetProblemType(LME lme,LMEProblemType *type)
222: {
225:   *type = lme->problem_type;
226:   PetscFunctionReturn(0);
227: }

229: /*@C
230:    LMEGetTolerances - Gets the tolerance and maximum iteration count used
231:    by the LME convergence tests.

233:    Not Collective

235:    Input Parameter:
236: .  lme - the linear matrix equation solver context

238:    Output Parameters:
239: +  tol - the convergence tolerance
240: -  maxits - maximum number of iterations

242:    Notes:
243:    The user can specify NULL for any parameter that is not needed.

245:    Level: intermediate

247: .seealso: LMESetTolerances()
248: @*/
249: PetscErrorCode LMEGetTolerances(LME lme,PetscReal *tol,PetscInt *maxits)
250: {
252:   if (tol)    *tol    = lme->tol;
253:   if (maxits) *maxits = lme->max_it;
254:   PetscFunctionReturn(0);
255: }

257: /*@
258:    LMESetTolerances - Sets the tolerance and maximum iteration count used
259:    by the LME convergence tests.

261:    Logically Collective on lme

263:    Input Parameters:
264: +  lme - the linear matrix equation solver context
265: .  tol - the convergence tolerance
266: -  maxits - maximum number of iterations to use

268:    Options Database Keys:
269: +  -lme_tol <tol> - Sets the convergence tolerance
270: -  -lme_max_it <maxits> - Sets the maximum number of iterations allowed

272:    Notes:
273:    Use PETSC_DEFAULT for either argument to assign a reasonably good value.

275:    Level: intermediate

277: .seealso: LMEGetTolerances()
278: @*/
279: PetscErrorCode LMESetTolerances(LME lme,PetscReal tol,PetscInt maxits)
280: {
284:   if (tol == PETSC_DEFAULT) {
285:     lme->tol = PETSC_DEFAULT;
286:     lme->setupcalled = 0;
287:   } else {
289:     lme->tol = tol;
290:   }
291:   if (maxits == PETSC_DEFAULT || maxits == PETSC_DECIDE) {
292:     lme->max_it = PETSC_DEFAULT;
293:     lme->setupcalled = 0;
294:   } else {
296:     lme->max_it = maxits;
297:   }
298:   PetscFunctionReturn(0);
299: }

301: /*@
302:    LMEGetDimensions - Gets the dimension of the subspace used by the solver.

304:    Not Collective

306:    Input Parameter:
307: .  lme - the linear matrix equation solver context

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

312:    Level: intermediate

314: .seealso: LMESetDimensions()
315: @*/
316: PetscErrorCode LMEGetDimensions(LME lme,PetscInt *ncv)
317: {
320:   *ncv = lme->ncv;
321:   PetscFunctionReturn(0);
322: }

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

327:    Logically Collective on lme

329:    Input Parameters:
330: +  lme - the linear matrix equation solver context
331: -  ncv - the maximum dimension of the subspace to be used by the solver

333:    Options Database Keys:
334: .  -lme_ncv <ncv> - Sets the dimension of the subspace

336:    Notes:
337:    Use PETSC_DEFAULT for ncv to assign a reasonably good value, which is
338:    dependent on the solution method.

340:    Level: intermediate

342: .seealso: LMEGetDimensions()
343: @*/
344: PetscErrorCode LMESetDimensions(LME lme,PetscInt ncv)
345: {
348:   if (ncv == PETSC_DECIDE || ncv == PETSC_DEFAULT) {
349:     lme->ncv = PETSC_DEFAULT;
350:   } else {
352:     lme->ncv = ncv;
353:   }
354:   lme->setupcalled = 0;
355:   PetscFunctionReturn(0);
356: }

358: /*@
359:    LMESetErrorIfNotConverged - Causes LMESolve() to generate an error if the
360:    solver has not converged.

362:    Logically Collective on lme

364:    Input Parameters:
365: +  lme - the linear matrix equation solver context
366: -  flg - PETSC_TRUE indicates you want the error generated

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

371:    Level: intermediate

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

377: .seealso: LMEGetErrorIfNotConverged()
378: @*/
379: PetscErrorCode LMESetErrorIfNotConverged(LME lme,PetscBool flg)
380: {
383:   lme->errorifnotconverged = flg;
384:   PetscFunctionReturn(0);
385: }

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

391:    Not Collective

393:    Input Parameter:
394: .  lme - the linear matrix equation solver context

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

399:    Level: intermediate

401: .seealso: LMESetErrorIfNotConverged()
402: @*/
403: PetscErrorCode LMEGetErrorIfNotConverged(LME lme,PetscBool *flag)
404: {
407:   *flag = lme->errorifnotconverged;
408:   PetscFunctionReturn(0);
409: }

411: /*@C
412:    LMESetOptionsPrefix - Sets the prefix used for searching for all
413:    LME options in the database.

415:    Logically Collective on lme

417:    Input Parameters:
418: +  lme - the linear matrix equation solver context
419: -  prefix - the prefix string to prepend to all LME option requests

421:    Notes:
422:    A hyphen (-) must NOT be given at the beginning of the prefix name.
423:    The first character of all runtime options is AUTOMATICALLY the
424:    hyphen.

426:    For example, to distinguish between the runtime options for two
427:    different LME contexts, one could call
428: .vb
429:       LMESetOptionsPrefix(lme1,"fun1_")
430:       LMESetOptionsPrefix(lme2,"fun2_")
431: .ve

433:    Level: advanced

435: .seealso: LMEAppendOptionsPrefix(), LMEGetOptionsPrefix()
436: @*/
437: PetscErrorCode LMESetOptionsPrefix(LME lme,const char *prefix)
438: {
440:   if (!lme->V) LMEGetBV(lme,&lme->V);
441:   BVSetOptionsPrefix(lme->V,prefix);
442:   PetscObjectSetOptionsPrefix((PetscObject)lme,prefix);
443:   PetscFunctionReturn(0);
444: }

446: /*@C
447:    LMEAppendOptionsPrefix - Appends to the prefix used for searching for all
448:    LME options in the database.

450:    Logically Collective on lme

452:    Input Parameters:
453: +  lme - the linear matrix equation solver context
454: -  prefix - the prefix string to prepend to all LME option requests

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

460:    Level: advanced

462: .seealso: LMESetOptionsPrefix(), LMEGetOptionsPrefix()
463: @*/
464: PetscErrorCode LMEAppendOptionsPrefix(LME lme,const char *prefix)
465: {
467:   if (!lme->V) LMEGetBV(lme,&lme->V);
468:   BVAppendOptionsPrefix(lme->V,prefix);
469:   PetscObjectAppendOptionsPrefix((PetscObject)lme,prefix);
470:   PetscFunctionReturn(0);
471: }

473: /*@C
474:    LMEGetOptionsPrefix - Gets the prefix used for searching for all
475:    LME options in the database.

477:    Not Collective

479:    Input Parameters:
480: .  lme - the linear matrix equation solver context

482:    Output Parameters:
483: .  prefix - pointer to the prefix string used is returned

485:    Note:
486:    On the Fortran side, the user should pass in a string 'prefix' of
487:    sufficient length to hold the prefix.

489:    Level: advanced

491: .seealso: LMESetOptionsPrefix(), LMEAppendOptionsPrefix()
492: @*/
493: PetscErrorCode LMEGetOptionsPrefix(LME lme,const char *prefix[])
494: {
497:   PetscObjectGetOptionsPrefix((PetscObject)lme,prefix);
498:   PetscFunctionReturn(0);
499: }