Date: 2020-01-13T12:02:16+00:00

Actual source code: lmeopts.c
slepc-3.12.2 2020-01-13
Report Typos and Errors

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