Date: 2026-03-09T09:12:02+00:00

Actual source code: mfnopts.c

      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:    MFN routines related to options that can be set via the command-line
     12:    or procedurally
     13: */

     15: #include <slepc/private/mfnimpl.h>
     16: #include <petscdraw.h>

     18: /*@C
     19:    MFNMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type
     20:    indicated by the user.

     22:    Collective

     24:    Input Parameters:
     25: +  mfn  - the matrix function solver 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: [](ch:mfn), `MFNMonitorSet()`
     33: @*/
     34: PetscErrorCode MFNMonitorSetFromOptions(MFN mfn,const char opt[],const char name[],void *ctx)
     35: {
     36:   PetscErrorCode       (*mfunc)(MFN,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:   PetscFunctionBegin;
     47:   PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)mfn),((PetscObject)mfn)->options,((PetscObject)mfn)->prefix,opt,&viewer,&format,&flg));
     48:   if (!flg) PetscFunctionReturn(PETSC_SUCCESS);

     50:   PetscCall(PetscViewerGetType(viewer,&vtype));
     51:   PetscCall(SlepcMonitorMakeKey_Internal(name,vtype,format,key));
     52:   PetscCall(PetscFunctionListFind(MFNMonitorList,key,&mfunc));
     53:   PetscCheck(mfunc,PetscObjectComm((PetscObject)mfn),PETSC_ERR_SUP,"Specified viewer and format not supported");
     54:   PetscCall(PetscFunctionListFind(MFNMonitorCreateList,key,&cfunc));
     55:   PetscCall(PetscFunctionListFind(MFNMonitorDestroyList,key,&dfunc));
     56:   if (!cfunc) cfunc = PetscViewerAndFormatCreate_Internal;
     57:   if (!dfunc) dfunc = PetscViewerAndFormatDestroy;

     59:   PetscCall((*cfunc)(viewer,format,ctx,&vf));
     60:   PetscCall(PetscViewerDestroy(&viewer));
     61:   PetscCall(MFNMonitorSet(mfn,mfunc,vf,(PetscCtxDestroyFn*)dfunc));
     62:   PetscFunctionReturn(PETSC_SUCCESS);
     63: }

     65: /*@
     66:    MFNSetFromOptions - Sets `MFN` options from the options database.
     67:    This routine must be called before `MFNSetUp()` if the user is to be
     68:    allowed to configure the solver.

     70:    Collective

     72:    Input Parameter:
     73: .  mfn - the matrix function solver context

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

     78:    Level: beginner

     80: .seealso: [](ch:mfn), `MFNSetOptionsPrefix()`
     81: @*/
     82: PetscErrorCode MFNSetFromOptions(MFN mfn)
     83: {
     84:   char           type[256];
     85:   PetscBool      set,flg,flg1,flg2;
     86:   PetscReal      r;
     87:   PetscInt       i;

     89:   PetscFunctionBegin;
     91:   PetscCall(MFNRegisterAll());
     92:   PetscObjectOptionsBegin((PetscObject)mfn);
     93:     PetscCall(PetscOptionsFList("-mfn_type","Matrix Function method","MFNSetType",MFNList,(char*)(((PetscObject)mfn)->type_name?((PetscObject)mfn)->type_name:MFNKRYLOV),type,sizeof(type),&flg));
     94:     if (flg) PetscCall(MFNSetType(mfn,type));
     95:     else if (!((PetscObject)mfn)->type_name) PetscCall(MFNSetType(mfn,MFNKRYLOV));

     97:     i = mfn->max_it;
     98:     PetscCall(PetscOptionsInt("-mfn_max_it","Maximum number of iterations","MFNSetTolerances",mfn->max_it,&i,&flg1));
     99:     if (!flg1) i = PETSC_DETERMINE;
    100:     r = mfn->tol;
    101:     PetscCall(PetscOptionsReal("-mfn_tol","Tolerance","MFNSetTolerances",SlepcDefaultTol(mfn->tol),&r,&flg2));
    102:     if (flg1 || flg2) PetscCall(MFNSetTolerances(mfn,r,i));

    104:     PetscCall(PetscOptionsInt("-mfn_ncv","Number of basis vectors","MFNSetDimensions",mfn->ncv,&i,&flg));
    105:     if (flg) PetscCall(MFNSetDimensions(mfn,i));

    107:     PetscCall(PetscOptionsBool("-mfn_error_if_not_converged","Generate error if solver does not converge","MFNSetErrorIfNotConverged",mfn->errorifnotconverged,&mfn->errorifnotconverged,NULL));

    109:     /* -----------------------------------------------------------------------*/
    110:     /*
    111:       Cancels all monitors hardwired into code before call to MFNSetFromOptions()
    112:     */
    113:     PetscCall(PetscOptionsBool("-mfn_monitor_cancel","Remove any hardwired monitor routines","MFNMonitorCancel",PETSC_FALSE,&flg,&set));
    114:     if (set && flg) PetscCall(MFNMonitorCancel(mfn));
    115:     PetscCall(MFNMonitorSetFromOptions(mfn,"-mfn_monitor","error_estimate",NULL));

    117:     /* -----------------------------------------------------------------------*/
    118:     PetscCall(PetscOptionsName("-mfn_view","Print detailed information on solver used","MFNView",&set));

    120:     PetscTryTypeMethod(mfn,setfromoptions,PetscOptionsObject);
    121:     PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)mfn,PetscOptionsObject));
    122:   PetscOptionsEnd();

    124:   if (!mfn->V) PetscCall(MFNGetBV(mfn,&mfn->V));
    125:   PetscCall(BVSetFromOptions(mfn->V));
    126:   if (!mfn->fn) PetscCall(MFNGetFN(mfn,&mfn->fn));
    127:   PetscCall(FNSetFromOptions(mfn->fn));
    128:   PetscFunctionReturn(PETSC_SUCCESS);
    129: }

    131: /*@
    132:    MFNGetTolerances - Gets the tolerance and maximum iteration count used
    133:    by the `MFN` convergence tests.

    135:    Not Collective

    137:    Input Parameter:
    138: .  mfn - the matrix function solver context

    140:    Output Parameters:
    141: +  tol - the convergence tolerance
    142: -  maxits - maximum number of iterations

    144:    Notes:
    145:    The user can specify `NULL` for any parameter that is not needed.

    147:    Level: intermediate

    149: .seealso: [](ch:mfn), `MFNSetTolerances()`
    150: @*/
    151: PetscErrorCode MFNGetTolerances(MFN mfn,PetscReal *tol,PetscInt *maxits)
    152: {
    153:   PetscFunctionBegin;
    155:   if (tol)    *tol    = mfn->tol;
    156:   if (maxits) *maxits = mfn->max_it;
    157:   PetscFunctionReturn(PETSC_SUCCESS);
    158: }

    160: /*@
    161:    MFNSetTolerances - Sets the tolerance and maximum iteration count used
    162:    by the `MFN` convergence tests.

    164:    Logically Collective

    166:    Input Parameters:
    167: +  mfn - the matrix function solver context
    168: .  tol - the convergence tolerance
    169: -  maxits - maximum number of iterations to use

    171:    Options Database Keys:
    172: +  -mfn_tol \<tol\>       - sets the convergence tolerance
    173: -  -mfn_max_it \<maxits\> - sets the maximum number of iterations allowed

    175:    Notes:
    176:    Use `PETSC_CURRENT` to retain the current value of any of the parameters.
    177:    Use `PETSC_DETERMINE` for either argument to assign a default value computed
    178:    internally (may be different in each solver).
    179:    For `maxits` use `PETSC_UNLIMITED` to indicate there is no upper bound on this value.

    181:    Level: intermediate

    183: .seealso: [](ch:mfn), `MFNGetTolerances()`
    184: @*/
    185: PetscErrorCode MFNSetTolerances(MFN mfn,PetscReal tol,PetscInt maxits)
    186: {
    187:   PetscFunctionBegin;
    191:   if (tol == (PetscReal)PETSC_DETERMINE) {
    192:     mfn->tol = PETSC_DETERMINE;
    193:     mfn->setupcalled = 0;
    194:   } else if (tol != (PetscReal)PETSC_CURRENT) {
    195:     PetscCheck(tol>0.0,PetscObjectComm((PetscObject)mfn),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of tol. Must be > 0");
    196:     mfn->tol = tol;
    197:   }
    198:   if (maxits == PETSC_DETERMINE) {
    199:     mfn->max_it = PETSC_DETERMINE;
    200:     mfn->setupcalled = 0;
    201:   } else if (maxits == PETSC_UNLIMITED) {
    202:     mfn->max_it = PETSC_INT_MAX;
    203:   } else if (maxits != PETSC_CURRENT) {
    204:     PetscCheck(maxits>0,PetscObjectComm((PetscObject)mfn),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of maxits. Must be > 0");
    205:     mfn->max_it = maxits;
    206:   }
    207:   PetscFunctionReturn(PETSC_SUCCESS);
    208: }

    210: /*@
    211:    MFNGetDimensions - Gets the dimension of the subspace used by the solver.

    213:    Not Collective

    215:    Input Parameter:
    216: .  mfn - the matrix function solver context

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

    221:    Level: intermediate

    223: .seealso: [](ch:mfn), `MFNSetDimensions()`
    224: @*/
    225: PetscErrorCode MFNGetDimensions(MFN mfn,PetscInt *ncv)
    226: {
    227:   PetscFunctionBegin;
    229:   PetscAssertPointer(ncv,2);
    230:   *ncv = mfn->ncv;
    231:   PetscFunctionReturn(PETSC_SUCCESS);
    232: }

    234: /*@
    235:    MFNSetDimensions - Sets the dimension of the subspace to be used by the solver.

    237:    Logically Collective

    239:    Input Parameters:
    240: +  mfn - the matrix function solver context
    241: -  ncv - the maximum dimension of the subspace to be used by the solver

    243:    Options Database Key:
    244: .  -mfn_ncv \<ncv\> - sets the dimension of the subspace

    246:    Notes:
    247:    Use `PETSC_DETERMINE` for `ncv` to assign a reasonably good value, which is
    248:    dependent on the solution method.

    250:    Level: intermediate

    252: .seealso: [](ch:mfn), `MFNGetDimensions()`
    253: @*/
    254: PetscErrorCode MFNSetDimensions(MFN mfn,PetscInt ncv)
    255: {
    256:   PetscFunctionBegin;
    259:   if (ncv == PETSC_DECIDE || ncv == PETSC_DEFAULT) {
    260:     mfn->ncv = PETSC_DETERMINE;
    261:   } else {
    262:     PetscCheck(ncv>0,PetscObjectComm((PetscObject)mfn),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of ncv. Must be > 0");
    263:     mfn->ncv = ncv;
    264:   }
    265:   mfn->setupcalled = 0;
    266:   PetscFunctionReturn(PETSC_SUCCESS);
    267: }

    269: /*@
    270:    MFNSetErrorIfNotConverged - Causes `MFNSolve()` to generate an error if the
    271:    solver has not converged.

    273:    Logically Collective

    275:    Input Parameters:
    276: +  mfn - the matrix function solver context
    277: -  flg - `PETSC_TRUE` indicates you want the error generated

    279:    Options Database Key:
    280: .  -mfn_error_if_not_converged - generate an error and stop the program

    282:    Note:
    283:    Normally SLEPc continues if the solver fails to converge, you can call
    284:    `MFNGetConvergedReason()` after a `MFNSolve()` to determine if it has converged.

    286:    Level: intermediate

    288: .seealso: [](ch:mfn), `MFNGetErrorIfNotConverged()`
    289: @*/
    290: PetscErrorCode MFNSetErrorIfNotConverged(MFN mfn,PetscBool flg)
    291: {
    292:   PetscFunctionBegin;
    295:   mfn->errorifnotconverged = flg;
    296:   PetscFunctionReturn(PETSC_SUCCESS);
    297: }

    299: /*@
    300:    MFNGetErrorIfNotConverged - Return a flag indicating whether `MFNSolve()` will
    301:    generate an error if the solver does not converge.

    303:    Not Collective

    305:    Input Parameter:
    306: .  mfn - the matrix function solver context

    308:    Output Parameter:
    309: .  flag - `PETSC_TRUE` if it will generate an error, else `PETSC_FALSE`

    311:    Level: intermediate

    313: .seealso: [](ch:mfn), `MFNSetErrorIfNotConverged()`
    314: @*/
    315: PetscErrorCode MFNGetErrorIfNotConverged(MFN mfn,PetscBool *flag)
    316: {
    317:   PetscFunctionBegin;
    319:   PetscAssertPointer(flag,2);
    320:   *flag = mfn->errorifnotconverged;
    321:   PetscFunctionReturn(PETSC_SUCCESS);
    322: }

    324: /*@
    325:    MFNSetOptionsPrefix - Sets the prefix used for searching for all
    326:    `MFN` options in the database.

    328:    Logically Collective

    330:    Input Parameters:
    331: +  mfn    - the matrix function solver context
    332: -  prefix - the prefix string to prepend to all `MFN` option requests

    334:    Notes:
    335:    A hyphen (-) must NOT be given at the beginning of the prefix name.
    336:    The first character of all runtime options is AUTOMATICALLY the
    337:    hyphen.

    339:    For example, to distinguish between the runtime options for two
    340:    different `MFN` contexts, one could call
    341: .vb
    342:    MFNSetOptionsPrefix(mfn1,"fun1_")
    343:    MFNSetOptionsPrefix(mfn2,"fun2_")
    344: .ve

    346:    Level: advanced

    348: .seealso: [](ch:mfn), `MFNAppendOptionsPrefix()`, `MFNGetOptionsPrefix()`
    349: @*/
    350: PetscErrorCode MFNSetOptionsPrefix(MFN mfn,const char prefix[])
    351: {
    352:   PetscFunctionBegin;
    354:   if (!mfn->V) PetscCall(MFNGetBV(mfn,&mfn->V));
    355:   PetscCall(BVSetOptionsPrefix(mfn->V,prefix));
    356:   if (!mfn->fn) PetscCall(MFNGetFN(mfn,&mfn->fn));
    357:   PetscCall(FNSetOptionsPrefix(mfn->fn,prefix));
    358:   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)mfn,prefix));
    359:   PetscFunctionReturn(PETSC_SUCCESS);
    360: }

    362: /*@
    363:    MFNAppendOptionsPrefix - Appends to the prefix used for searching for all
    364:    `MFN` options in the database.

    366:    Logically Collective

    368:    Input Parameters:
    369: +  mfn    - the matrix function solver context
    370: -  prefix - the prefix string to prepend to all `MFN` option requests

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

    376:    Level: advanced

    378: .seealso: [](ch:mfn), `MFNSetOptionsPrefix()`, `MFNGetOptionsPrefix()`
    379: @*/
    380: PetscErrorCode MFNAppendOptionsPrefix(MFN mfn,const char prefix[])
    381: {
    382:   PetscFunctionBegin;
    384:   if (!mfn->V) PetscCall(MFNGetBV(mfn,&mfn->V));
    385:   PetscCall(BVAppendOptionsPrefix(mfn->V,prefix));
    386:   if (!mfn->fn) PetscCall(MFNGetFN(mfn,&mfn->fn));
    387:   PetscCall(FNAppendOptionsPrefix(mfn->fn,prefix));
    388:   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)mfn,prefix));
    389:   PetscFunctionReturn(PETSC_SUCCESS);
    390: }

    392: /*@
    393:    MFNGetOptionsPrefix - Gets the prefix used for searching for all
    394:    `MFN` options in the database.

    396:    Not Collective

    398:    Input Parameter:
    399: .  mfn - the matrix function solver context

    401:    Output Parameter:
    402: .  prefix - pointer to the prefix string used is returned

    404:    Level: advanced

    406: .seealso: [](ch:mfn), `MFNSetOptionsPrefix()`, `MFNAppendOptionsPrefix()`
    407: @*/
    408: PetscErrorCode MFNGetOptionsPrefix(MFN mfn,const char *prefix[])
    409: {
    410:   PetscFunctionBegin;
    412:   PetscAssertPointer(prefix,2);
    413:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)mfn,prefix));
    414:   PetscFunctionReturn(PETSC_SUCCESS);
    415: }