Date: 2021-09-20T09:44:14+00:00

Actual source code: lmeopts.c
slepc-3.15.2 2021-09-20
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",lme->tol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL: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: }