Date: 2021-02-01T14:41:54+00:00

Actual source code: epsopts.c
slepc-3.14.2 2021-02-01
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:    EPS routines related to options that can be set via the command-line
     12:    or procedurally.
     13: */

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

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

     22:    Collective on eps

     24:    Input Parameters:
     25: +  eps      - 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
     30: -  trackall - whether this monitor tracks all eigenvalues or not

     32:    Level: developer

     34: .seealso: EPSMonitorSet(), EPSSetTrackAll(), EPSConvMonitorSetFromOptions()
     35: @*/
     36: PetscErrorCode EPSMonitorSetFromOptions(EPS eps,const char name[],const char help[],const char manual[],PetscErrorCode (*monitor)(EPS,PetscInt,PetscInt,PetscScalar*,PetscScalar*,PetscReal*,PetscInt,PetscViewerAndFormat*),PetscBool trackall)
     37: {
     38:   PetscErrorCode       ierr;
     39:   PetscBool            flg;
     40:   PetscViewer          viewer;
     41:   PetscViewerFormat    format;
     42:   PetscViewerAndFormat *vf;

     45:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)eps),((PetscObject)eps)->options,((PetscObject)eps)->prefix,name,&viewer,&format,&flg);
     46:   if (flg) {
     47:     PetscViewerAndFormatCreate(viewer,format,&vf);
     48:     PetscObjectDereference((PetscObject)viewer);
     49:     EPSMonitorSet(eps,(PetscErrorCode (*)(EPS,PetscInt,PetscInt,PetscScalar*,PetscScalar*,PetscReal*,PetscInt,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);
     50:     if (trackall) {
     51:       EPSSetTrackAll(eps,PETSC_TRUE);
     52:     }
     53:   }
     54:   return(0);
     55: }

     57: /*@C
     58:    EPSConvMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type
     59:    indicated by the user (for monitors that only show iteration numbers of convergence).

     61:    Collective on eps

     63:    Input Parameters:
     64: +  eps      - the eigensolver context
     65: .  name     - the monitor option name
     66: .  help     - message indicating what monitoring is done
     67: .  manual   - manual page for the monitor
     68: -  monitor  - the monitor function, whose context is a SlepcConvMonitor

     70:    Level: developer

     72: .seealso: EPSMonitorSet(), EPSMonitorSetFromOptions()
     73: @*/
     74: PetscErrorCode EPSConvMonitorSetFromOptions(EPS eps,const char name[],const char help[],const char manual[],PetscErrorCode (*monitor)(EPS,PetscInt,PetscInt,PetscScalar*,PetscScalar*,PetscReal*,PetscInt,SlepcConvMonitor))
     75: {
     76:   PetscErrorCode    ierr;
     77:   PetscBool         flg;
     78:   PetscViewer       viewer;
     79:   PetscViewerFormat format;
     80:   SlepcConvMonitor  ctx;

     83:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)eps),((PetscObject)eps)->options,((PetscObject)eps)->prefix,name,&viewer,&format,&flg);
     84:   if (flg) {
     85:     SlepcConvMonitorCreate(viewer,format,&ctx);
     86:     PetscObjectDereference((PetscObject)viewer);
     87:     EPSMonitorSet(eps,(PetscErrorCode (*)(EPS,PetscInt,PetscInt,PetscScalar*,PetscScalar*,PetscReal*,PetscInt,void*))monitor,ctx,(PetscErrorCode (*)(void**))SlepcConvMonitorDestroy);
     88:   }
     89:   return(0);
     90: }

     92: /*@
     93:    EPSSetFromOptions - Sets EPS options from the options database.
     94:    This routine must be called before EPSSetUp() if the user is to be
     95:    allowed to set the solver type.

     97:    Collective on eps

     99:    Input Parameters:
    100: .  eps - the eigensolver context

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

    105:    Level: beginner
    106: @*/
    107: PetscErrorCode EPSSetFromOptions(EPS eps)
    108: {
    110:   char           type[256];
    111:   PetscBool      set,flg,flg1,flg2,flg3,bval;
    112:   PetscReal      r,array[2]={0,0};
    113:   PetscScalar    s;
    114:   PetscInt       i,j,k;
    115:   PetscDrawLG    lg;
    116:   EPSBalance     bal;

    120:   EPSRegisterAll();
    121:   PetscObjectOptionsBegin((PetscObject)eps);
    122:     PetscOptionsFList("-eps_type","Eigensolver method","EPSSetType",EPSList,(char*)(((PetscObject)eps)->type_name?((PetscObject)eps)->type_name:EPSKRYLOVSCHUR),type,sizeof(type),&flg);
    123:     if (flg) {
    124:       EPSSetType(eps,type);
    125:     } else if (!((PetscObject)eps)->type_name) {
    126:       EPSSetType(eps,EPSKRYLOVSCHUR);
    127:     }

    129:     PetscOptionsBoolGroupBegin("-eps_hermitian","Hermitian eigenvalue problem","EPSSetProblemType",&flg);
    130:     if (flg) { EPSSetProblemType(eps,EPS_HEP); }
    131:     PetscOptionsBoolGroup("-eps_gen_hermitian","Generalized Hermitian eigenvalue problem","EPSSetProblemType",&flg);
    132:     if (flg) { EPSSetProblemType(eps,EPS_GHEP); }
    133:     PetscOptionsBoolGroup("-eps_non_hermitian","Non-Hermitian eigenvalue problem","EPSSetProblemType",&flg);
    134:     if (flg) { EPSSetProblemType(eps,EPS_NHEP); }
    135:     PetscOptionsBoolGroup("-eps_gen_non_hermitian","Generalized non-Hermitian eigenvalue problem","EPSSetProblemType",&flg);
    136:     if (flg) { EPSSetProblemType(eps,EPS_GNHEP); }
    137:     PetscOptionsBoolGroup("-eps_pos_gen_non_hermitian","Generalized non-Hermitian eigenvalue problem with positive semi-definite B","EPSSetProblemType",&flg);
    138:     if (flg) { EPSSetProblemType(eps,EPS_PGNHEP); }
    139:     PetscOptionsBoolGroupEnd("-eps_gen_indefinite","Generalized Hermitian-indefinite eigenvalue problem","EPSSetProblemType",&flg);
    140:     if (flg) { EPSSetProblemType(eps,EPS_GHIEP); }

    142:     PetscOptionsBoolGroupBegin("-eps_ritz","Rayleigh-Ritz extraction","EPSSetExtraction",&flg);
    143:     if (flg) { EPSSetExtraction(eps,EPS_RITZ); }
    144:     PetscOptionsBoolGroup("-eps_harmonic","Harmonic Ritz extraction","EPSSetExtraction",&flg);
    145:     if (flg) { EPSSetExtraction(eps,EPS_HARMONIC); }
    146:     PetscOptionsBoolGroup("-eps_harmonic_relative","Relative harmonic Ritz extraction","EPSSetExtraction",&flg);
    147:     if (flg) { EPSSetExtraction(eps,EPS_HARMONIC_RELATIVE); }
    148:     PetscOptionsBoolGroup("-eps_harmonic_right","Right harmonic Ritz extraction","EPSSetExtraction",&flg);
    149:     if (flg) { EPSSetExtraction(eps,EPS_HARMONIC_RIGHT); }
    150:     PetscOptionsBoolGroup("-eps_harmonic_largest","Largest harmonic Ritz extraction","EPSSetExtraction",&flg);
    151:     if (flg) { EPSSetExtraction(eps,EPS_HARMONIC_LARGEST); }
    152:     PetscOptionsBoolGroup("-eps_refined","Refined Ritz extraction","EPSSetExtraction",&flg);
    153:     if (flg) { EPSSetExtraction(eps,EPS_REFINED); }
    154:     PetscOptionsBoolGroupEnd("-eps_refined_harmonic","Refined harmonic Ritz extraction","EPSSetExtraction",&flg);
    155:     if (flg) { EPSSetExtraction(eps,EPS_REFINED_HARMONIC); }

    157:     bal = eps->balance;
    158:     PetscOptionsEnum("-eps_balance","Balancing method","EPSSetBalance",EPSBalanceTypes,(PetscEnum)bal,(PetscEnum*)&bal,&flg1);
    159:     j = eps->balance_its;
    160:     PetscOptionsInt("-eps_balance_its","Number of iterations in balancing","EPSSetBalance",eps->balance_its,&j,&flg2);
    161:     r = eps->balance_cutoff;
    162:     PetscOptionsReal("-eps_balance_cutoff","Cutoff value in balancing","EPSSetBalance",eps->balance_cutoff,&r,&flg3);
    163:     if (flg1 || flg2 || flg3) { EPSSetBalance(eps,bal,j,r); }

    165:     i = eps->max_it;
    166:     PetscOptionsInt("-eps_max_it","Maximum number of iterations","EPSSetTolerances",eps->max_it,&i,&flg1);
    167:     r = eps->tol;
    168:     PetscOptionsReal("-eps_tol","Tolerance","EPSSetTolerances",eps->tol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL:eps->tol,&r,&flg2);
    169:     if (flg1 || flg2) { EPSSetTolerances(eps,r,i); }

    171:     PetscOptionsBoolGroupBegin("-eps_conv_rel","Relative error convergence test","EPSSetConvergenceTest",&flg);
    172:     if (flg) { EPSSetConvergenceTest(eps,EPS_CONV_REL); }
    173:     PetscOptionsBoolGroup("-eps_conv_norm","Convergence test relative to the eigenvalue and the matrix norms","EPSSetConvergenceTest",&flg);
    174:     if (flg) { EPSSetConvergenceTest(eps,EPS_CONV_NORM); }
    175:     PetscOptionsBoolGroup("-eps_conv_abs","Absolute error convergence test","EPSSetConvergenceTest",&flg);
    176:     if (flg) { EPSSetConvergenceTest(eps,EPS_CONV_ABS); }
    177:     PetscOptionsBoolGroupEnd("-eps_conv_user","User-defined convergence test","EPSSetConvergenceTest",&flg);
    178:     if (flg) { EPSSetConvergenceTest(eps,EPS_CONV_USER); }

    180:     PetscOptionsBoolGroupBegin("-eps_stop_basic","Stop iteration if all eigenvalues converged or max_it reached","EPSSetStoppingTest",&flg);
    181:     if (flg) { EPSSetStoppingTest(eps,EPS_STOP_BASIC); }
    182:     PetscOptionsBoolGroupEnd("-eps_stop_user","User-defined stopping test","EPSSetStoppingTest",&flg);
    183:     if (flg) { EPSSetStoppingTest(eps,EPS_STOP_USER); }

    185:     i = eps->nev;
    186:     PetscOptionsInt("-eps_nev","Number of eigenvalues to compute","EPSSetDimensions",eps->nev,&i,&flg1);
    187:     j = eps->ncv;
    188:     PetscOptionsInt("-eps_ncv","Number of basis vectors","EPSSetDimensions",eps->ncv,&j,&flg2);
    189:     k = eps->mpd;
    190:     PetscOptionsInt("-eps_mpd","Maximum dimension of projected problem","EPSSetDimensions",eps->mpd,&k,&flg3);
    191:     if (flg1 || flg2 || flg3) { EPSSetDimensions(eps,i,j,k); }

    193:     PetscOptionsBoolGroupBegin("-eps_largest_magnitude","Compute largest eigenvalues in magnitude","EPSSetWhichEigenpairs",&flg);
    194:     if (flg) { EPSSetWhichEigenpairs(eps,EPS_LARGEST_MAGNITUDE); }
    195:     PetscOptionsBoolGroup("-eps_smallest_magnitude","Compute smallest eigenvalues in magnitude","EPSSetWhichEigenpairs",&flg);
    196:     if (flg) { EPSSetWhichEigenpairs(eps,EPS_SMALLEST_MAGNITUDE); }
    197:     PetscOptionsBoolGroup("-eps_largest_real","Compute eigenvalues with largest real parts","EPSSetWhichEigenpairs",&flg);
    198:     if (flg) { EPSSetWhichEigenpairs(eps,EPS_LARGEST_REAL); }
    199:     PetscOptionsBoolGroup("-eps_smallest_real","Compute eigenvalues with smallest real parts","EPSSetWhichEigenpairs",&flg);
    200:     if (flg) { EPSSetWhichEigenpairs(eps,EPS_SMALLEST_REAL); }
    201:     PetscOptionsBoolGroup("-eps_largest_imaginary","Compute eigenvalues with largest imaginary parts","EPSSetWhichEigenpairs",&flg);
    202:     if (flg) { EPSSetWhichEigenpairs(eps,EPS_LARGEST_IMAGINARY); }
    203:     PetscOptionsBoolGroup("-eps_smallest_imaginary","Compute eigenvalues with smallest imaginary parts","EPSSetWhichEigenpairs",&flg);
    204:     if (flg) { EPSSetWhichEigenpairs(eps,EPS_SMALLEST_IMAGINARY); }
    205:     PetscOptionsBoolGroup("-eps_target_magnitude","Compute eigenvalues closest to target","EPSSetWhichEigenpairs",&flg);
    206:     if (flg) { EPSSetWhichEigenpairs(eps,EPS_TARGET_MAGNITUDE); }
    207:     PetscOptionsBoolGroup("-eps_target_real","Compute eigenvalues with real parts closest to target","EPSSetWhichEigenpairs",&flg);
    208:     if (flg) { EPSSetWhichEigenpairs(eps,EPS_TARGET_REAL); }
    209:     PetscOptionsBoolGroup("-eps_target_imaginary","Compute eigenvalues with imaginary parts closest to target","EPSSetWhichEigenpairs",&flg);
    210:     if (flg) { EPSSetWhichEigenpairs(eps,EPS_TARGET_IMAGINARY); }
    211:     PetscOptionsBoolGroupEnd("-eps_all","Compute all eigenvalues in an interval or a region","EPSSetWhichEigenpairs",&flg);
    212:     if (flg) { EPSSetWhichEigenpairs(eps,EPS_ALL); }

    214:     PetscOptionsScalar("-eps_target","Value of the target","EPSSetTarget",eps->target,&s,&flg);
    215:     if (flg) {
    216:       if (eps->which!=EPS_TARGET_REAL && eps->which!=EPS_TARGET_IMAGINARY) {
    217:         EPSSetWhichEigenpairs(eps,EPS_TARGET_MAGNITUDE);
    218:       }
    219:       EPSSetTarget(eps,s);
    220:     }

    222:     k = 2;
    223:     PetscOptionsRealArray("-eps_interval","Computational interval (two real values separated with a comma without spaces)","EPSSetInterval",array,&k,&flg);
    224:     if (flg) {
    225:       if (k<2) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_SIZ,"Must pass two values in -eps_interval (comma-separated without spaces)");
    226:       EPSSetWhichEigenpairs(eps,EPS_ALL);
    227:       EPSSetInterval(eps,array[0],array[1]);
    228:     }

    230:     PetscOptionsBool("-eps_true_residual","Compute true residuals explicitly","EPSSetTrueResidual",eps->trueres,&eps->trueres,NULL);
    231:     PetscOptionsBool("-eps_purify","Postprocess eigenvectors for purification","EPSSetPurify",eps->purify,&bval,&flg);
    232:     if (flg) { EPSSetPurify(eps,bval); }
    233:     PetscOptionsBool("-eps_two_sided","Use two-sided variant (to compute left eigenvectors)","EPSSetTwoSided",eps->twosided,&bval,&flg);
    234:     if (flg) { EPSSetTwoSided(eps,bval); }

    236:     /* -----------------------------------------------------------------------*/
    237:     /*
    238:       Cancels all monitors hardwired into code before call to EPSSetFromOptions()
    239:     */
    240:     PetscOptionsBool("-eps_monitor_cancel","Remove any hardwired monitor routines","EPSMonitorCancel",PETSC_FALSE,&flg,&set);
    241:     if (set && flg) {
    242:       EPSMonitorCancel(eps);
    243:     }
    244:     /*
    245:       Text monitors
    246:     */
    247:     EPSMonitorSetFromOptions(eps,"-eps_monitor","Monitor first unconverged approximate eigenvalue and error estimate","EPSMonitorFirst",EPSMonitorFirst,PETSC_FALSE);
    248:     EPSConvMonitorSetFromOptions(eps,"-eps_monitor_conv","Monitor approximate eigenvalues and error estimates as they converge","EPSMonitorConverged",EPSMonitorConverged);
    249:     EPSMonitorSetFromOptions(eps,"-eps_monitor_all","Monitor approximate eigenvalues and error estimates","EPSMonitorAll",EPSMonitorAll,PETSC_TRUE);
    250:     /*
    251:       Line graph monitors
    252:     */
    253:     PetscOptionsBool("-eps_monitor_lg","Monitor first unconverged approximate eigenvalue and error estimate graphically","EPSMonitorSet",PETSC_FALSE,&flg,&set);
    254:     if (set && flg) {
    255:       EPSMonitorLGCreate(PetscObjectComm((PetscObject)eps),NULL,"Error estimates",PETSC_DECIDE,PETSC_DECIDE,300,300,&lg);
    256:       EPSMonitorSet(eps,EPSMonitorLG,lg,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);
    257:     }
    258:     PetscOptionsBool("-eps_monitor_lg_all","Monitor error estimates graphically","EPSMonitorSet",PETSC_FALSE,&flg,&set);
    259:     if (set && flg) {
    260:       EPSMonitorLGCreate(PetscObjectComm((PetscObject)eps),NULL,"Error estimates",PETSC_DECIDE,PETSC_DECIDE,300,300,&lg);
    261:       EPSMonitorSet(eps,EPSMonitorLGAll,lg,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);
    262:       EPSSetTrackAll(eps,PETSC_TRUE);
    263:     }

    265:     /* -----------------------------------------------------------------------*/
    266:     PetscOptionsName("-eps_view","Print detailed information on solver used","EPSView",NULL);
    267:     PetscOptionsName("-eps_view_vectors","View computed eigenvectors","EPSVectorsView",NULL);
    268:     PetscOptionsName("-eps_view_values","View computed eigenvalues","EPSValuesView",NULL);
    269:     PetscOptionsName("-eps_converged_reason","Print reason for convergence, and number of iterations","EPSConvergedReasonView",NULL);
    270:     PetscOptionsName("-eps_error_absolute","Print absolute errors of each eigenpair","EPSErrorView",NULL);
    271:     PetscOptionsName("-eps_error_relative","Print relative errors of each eigenpair","EPSErrorView",NULL);
    272:     PetscOptionsName("-eps_error_backward","Print backward errors of each eigenpair","EPSErrorView",NULL);

    274:     if (eps->ops->setfromoptions) {
    275:       (*eps->ops->setfromoptions)(PetscOptionsObject,eps);
    276:     }
    277:     PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)eps);
    278:   PetscOptionsEnd();

    280:   if (!eps->V) { EPSGetBV(eps,&eps->V); }
    281:   BVSetFromOptions(eps->V);
    282:   if (!eps->rg) { EPSGetRG(eps,&eps->rg); }
    283:   RGSetFromOptions(eps->rg);
    284:   if (eps->useds) {
    285:     if (!eps->ds) { EPSGetDS(eps,&eps->ds); }
    286:     DSSetFromOptions(eps->ds);
    287:   }
    288:   if (!eps->st) { EPSGetST(eps,&eps->st); }
    289:   EPSSetDefaultST(eps);
    290:   STSetFromOptions(eps->st);
    291:   return(0);
    292: }

    294: /*@C
    295:    EPSGetTolerances - Gets the tolerance and maximum iteration count used
    296:    by the EPS convergence tests.

    298:    Not Collective

    300:    Input Parameter:
    301: .  eps - the eigensolver context

    303:    Output Parameters:
    304: +  tol - the convergence tolerance
    305: -  maxits - maximum number of iterations

    307:    Notes:
    308:    The user can specify NULL for any parameter that is not needed.

    310:    Level: intermediate

    312: .seealso: EPSSetTolerances()
    313: @*/
    314: PetscErrorCode EPSGetTolerances(EPS eps,PetscReal *tol,PetscInt *maxits)
    315: {
    318:   if (tol)    *tol    = eps->tol;
    319:   if (maxits) *maxits = eps->max_it;
    320:   return(0);
    321: }

    323: /*@
    324:    EPSSetTolerances - Sets the tolerance and maximum iteration count used
    325:    by the EPS convergence tests.

    327:    Logically Collective on eps

    329:    Input Parameters:
    330: +  eps - the eigensolver context
    331: .  tol - the convergence tolerance
    332: -  maxits - maximum number of iterations to use

    334:    Options Database Keys:
    335: +  -eps_tol <tol> - Sets the convergence tolerance
    336: -  -eps_max_it <maxits> - Sets the maximum number of iterations allowed

    338:    Notes:
    339:    Use PETSC_DEFAULT for either argument to assign a reasonably good value.

    341:    Level: intermediate

    343: .seealso: EPSGetTolerances()
    344: @*/
    345: PetscErrorCode EPSSetTolerances(EPS eps,PetscReal tol,PetscInt maxits)
    346: {
    351:   if (tol == PETSC_DEFAULT) {
    352:     eps->tol   = PETSC_DEFAULT;
    353:     eps->state = EPS_STATE_INITIAL;
    354:   } else {
    355:     if (tol <= 0.0) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of tol. Must be > 0");
    356:     eps->tol = tol;
    357:   }
    358:   if (maxits == PETSC_DEFAULT || maxits == PETSC_DECIDE) {
    359:     eps->max_it = PETSC_DEFAULT;
    360:     eps->state  = EPS_STATE_INITIAL;
    361:   } else {
    362:     if (maxits <= 0) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of maxits. Must be > 0");
    363:     eps->max_it = maxits;
    364:   }
    365:   return(0);
    366: }

    368: /*@C
    369:    EPSGetDimensions - Gets the number of eigenvalues to compute
    370:    and the dimension of the subspace.

    372:    Not Collective

    374:    Input Parameter:
    375: .  eps - the eigensolver context

    377:    Output Parameters:
    378: +  nev - number of eigenvalues to compute
    379: .  ncv - the maximum dimension of the subspace to be used by the solver
    380: -  mpd - the maximum dimension allowed for the projected problem

    382:    Level: intermediate

    384: .seealso: EPSSetDimensions()
    385: @*/
    386: PetscErrorCode EPSGetDimensions(EPS eps,PetscInt *nev,PetscInt *ncv,PetscInt *mpd)
    387: {
    390:   if (nev) *nev = eps->nev;
    391:   if (ncv) *ncv = eps->ncv;
    392:   if (mpd) *mpd = eps->mpd;
    393:   return(0);
    394: }

    396: /*@
    397:    EPSSetDimensions - Sets the number of eigenvalues to compute
    398:    and the dimension of the subspace.

    400:    Logically Collective on eps

    402:    Input Parameters:
    403: +  eps - the eigensolver context
    404: .  nev - number of eigenvalues to compute
    405: .  ncv - the maximum dimension of the subspace to be used by the solver
    406: -  mpd - the maximum dimension allowed for the projected problem

    408:    Options Database Keys:
    409: +  -eps_nev <nev> - Sets the number of eigenvalues
    410: .  -eps_ncv <ncv> - Sets the dimension of the subspace
    411: -  -eps_mpd <mpd> - Sets the maximum projected dimension

    413:    Notes:
    414:    Use PETSC_DEFAULT for ncv and mpd to assign a reasonably good value, which is
    415:    dependent on the solution method.

    417:    The parameters ncv and mpd are intimately related, so that the user is advised
    418:    to set one of them at most. Normal usage is that
    419:    (a) in cases where nev is small, the user sets ncv (a reasonable default is 2*nev); and
    420:    (b) in cases where nev is large, the user sets mpd.

    422:    The value of ncv should always be between nev and (nev+mpd), typically
    423:    ncv=nev+mpd. If nev is not too large, mpd=nev is a reasonable choice, otherwise
    424:    a smaller value should be used.

    426:    When computing all eigenvalues in an interval, see EPSSetInterval(), these
    427:    parameters lose relevance, and tuning must be done with
    428:    EPSKrylovSchurSetDimensions().

    430:    Level: intermediate

    432: .seealso: EPSGetDimensions(), EPSSetInterval(), EPSKrylovSchurSetDimensions()
    433: @*/
    434: PetscErrorCode EPSSetDimensions(EPS eps,PetscInt nev,PetscInt ncv,PetscInt mpd)
    435: {
    441:   if (nev<1) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of nev. Must be > 0");
    442:   eps->nev = nev;
    443:   if (ncv == PETSC_DECIDE || ncv == PETSC_DEFAULT) {
    444:     eps->ncv = PETSC_DEFAULT;
    445:   } else {
    446:     if (ncv<1) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of ncv. Must be > 0");
    447:     eps->ncv = ncv;
    448:   }
    449:   if (mpd == PETSC_DECIDE || mpd == PETSC_DEFAULT) {
    450:     eps->mpd = PETSC_DEFAULT;
    451:   } else {
    452:     if (mpd<1) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of mpd. Must be > 0");
    453:     eps->mpd = mpd;
    454:   }
    455:   eps->state = EPS_STATE_INITIAL;
    456:   return(0);
    457: }

    459: /*@
    460:    EPSSetWhichEigenpairs - Specifies which portion of the spectrum is
    461:    to be sought.

    463:    Logically Collective on eps

    465:    Input Parameters:
    466: +  eps   - eigensolver context obtained from EPSCreate()
    467: -  which - the portion of the spectrum to be sought

    469:    Possible values:
    470:    The parameter 'which' can have one of these values

    472: +     EPS_LARGEST_MAGNITUDE - largest eigenvalues in magnitude (default)
    473: .     EPS_SMALLEST_MAGNITUDE - smallest eigenvalues in magnitude
    474: .     EPS_LARGEST_REAL - largest real parts
    475: .     EPS_SMALLEST_REAL - smallest real parts
    476: .     EPS_LARGEST_IMAGINARY - largest imaginary parts
    477: .     EPS_SMALLEST_IMAGINARY - smallest imaginary parts
    478: .     EPS_TARGET_MAGNITUDE - eigenvalues closest to the target (in magnitude)
    479: .     EPS_TARGET_REAL - eigenvalues with real part closest to target
    480: .     EPS_TARGET_IMAGINARY - eigenvalues with imaginary part closest to target
    481: .     EPS_ALL - all eigenvalues contained in a given interval or region
    482: -     EPS_WHICH_USER - user defined ordering set with EPSSetEigenvalueComparison()

    484:    Options Database Keys:
    485: +   -eps_largest_magnitude - Sets largest eigenvalues in magnitude
    486: .   -eps_smallest_magnitude - Sets smallest eigenvalues in magnitude
    487: .   -eps_largest_real - Sets largest real parts
    488: .   -eps_smallest_real - Sets smallest real parts
    489: .   -eps_largest_imaginary - Sets largest imaginary parts
    490: .   -eps_smallest_imaginary - Sets smallest imaginary parts
    491: .   -eps_target_magnitude - Sets eigenvalues closest to target
    492: .   -eps_target_real - Sets real parts closest to target
    493: .   -eps_target_imaginary - Sets imaginary parts closest to target
    494: -   -eps_all - Sets all eigenvalues in an interval or region

    496:    Notes:
    497:    Not all eigensolvers implemented in EPS account for all the possible values
    498:    stated above. Also, some values make sense only for certain types of
    499:    problems. If SLEPc is compiled for real numbers EPS_LARGEST_IMAGINARY
    500:    and EPS_SMALLEST_IMAGINARY use the absolute value of the imaginary part
    501:    for eigenvalue selection.

    503:    The target is a scalar value provided with EPSSetTarget().

    505:    The criterion EPS_TARGET_IMAGINARY is available only in case PETSc and
    506:    SLEPc have been built with complex scalars.

    508:    EPS_ALL is intended for use in combination with an interval (see
    509:    EPSSetInterval()), when all eigenvalues within the interval are requested,
    510:    or in the context of the CISS solver for computing all eigenvalues in a region.
    511:    In those cases, the number of eigenvalues is unknown, so the nev parameter
    512:    has a different sense, see EPSSetDimensions().

    514:    Level: intermediate

    516: .seealso: EPSGetWhichEigenpairs(), EPSSetTarget(), EPSSetInterval(),
    517:           EPSSetDimensions(), EPSSetEigenvalueComparison(), EPSWhich
    518: @*/
    519: PetscErrorCode EPSSetWhichEigenpairs(EPS eps,EPSWhich which)
    520: {
    524:   switch (which) {
    525:     case EPS_LARGEST_MAGNITUDE:
    526:     case EPS_SMALLEST_MAGNITUDE:
    527:     case EPS_LARGEST_REAL:
    528:     case EPS_SMALLEST_REAL:
    529:     case EPS_LARGEST_IMAGINARY:
    530:     case EPS_SMALLEST_IMAGINARY:
    531:     case EPS_TARGET_MAGNITUDE:
    532:     case EPS_TARGET_REAL:
    533: #if defined(PETSC_USE_COMPLEX)
    534:     case EPS_TARGET_IMAGINARY:
    535: #endif
    536:     case EPS_ALL:
    537:     case EPS_WHICH_USER:
    538:       if (eps->which != which) {
    539:         eps->state = EPS_STATE_INITIAL;
    540:         eps->which = which;
    541:       }
    542:       break;
    543: #if !defined(PETSC_USE_COMPLEX)
    544:     case EPS_TARGET_IMAGINARY:
    545:       SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"EPS_TARGET_IMAGINARY can be used only with complex scalars");
    546: #endif
    547:     default:
    548:       SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid 'which' value");
    549:   }
    550:   return(0);
    551: }

    553: /*@
    554:    EPSGetWhichEigenpairs - Returns which portion of the spectrum is to be
    555:    sought.

    557:    Not Collective

    559:    Input Parameter:
    560: .  eps - eigensolver context obtained from EPSCreate()

    562:    Output Parameter:
    563: .  which - the portion of the spectrum to be sought

    565:    Notes:
    566:    See EPSSetWhichEigenpairs() for possible values of 'which'.

    568:    Level: intermediate

    570: .seealso: EPSSetWhichEigenpairs(), EPSWhich
    571: @*/
    572: PetscErrorCode EPSGetWhichEigenpairs(EPS eps,EPSWhich *which)
    573: {
    577:   *which = eps->which;
    578:   return(0);
    579: }

    581: /*@C
    582:    EPSSetEigenvalueComparison - Specifies the eigenvalue comparison function
    583:    when EPSSetWhichEigenpairs() is set to EPS_WHICH_USER.

    585:    Logically Collective on eps

    587:    Input Parameters:
    588: +  eps  - eigensolver context obtained from EPSCreate()
    589: .  func - a pointer to the comparison function
    590: -  ctx  - a context pointer (the last parameter to the comparison function)

    592:    Calling Sequence of func:
    593: $   func(PetscScalar ar,PetscScalar ai,PetscScalar br,PetscScalar bi,PetscInt *res,void *ctx)

    595: +   ar     - real part of the 1st eigenvalue
    596: .   ai     - imaginary part of the 1st eigenvalue
    597: .   br     - real part of the 2nd eigenvalue
    598: .   bi     - imaginary part of the 2nd eigenvalue
    599: .   res    - result of comparison
    600: -   ctx    - optional context, as set by EPSSetEigenvalueComparison()

    602:    Note:
    603:    The returning parameter 'res' can be
    604: +  negative - if the 1st eigenvalue is preferred to the 2st one
    605: .  zero     - if both eigenvalues are equally preferred
    606: -  positive - if the 2st eigenvalue is preferred to the 1st one

    608:    Level: advanced

    610: .seealso: EPSSetWhichEigenpairs(), EPSWhich
    611: @*/
    612: PetscErrorCode EPSSetEigenvalueComparison(EPS eps,PetscErrorCode (*func)(PetscScalar,PetscScalar,PetscScalar,PetscScalar,PetscInt*,void*),void* ctx)
    613: {
    616:   eps->sc->comparison    = func;
    617:   eps->sc->comparisonctx = ctx;
    618:   eps->which             = EPS_WHICH_USER;
    619:   return(0);
    620: }

    622: /*@C
    623:    EPSSetArbitrarySelection - Specifies a function intended to look for
    624:    eigenvalues according to an arbitrary selection criterion. This criterion
    625:    can be based on a computation involving the current eigenvector approximation.

    627:    Logically Collective on eps

    629:    Input Parameters:
    630: +  eps  - eigensolver context obtained from EPSCreate()
    631: .  func - a pointer to the evaluation function
    632: -  ctx  - a context pointer (the last parameter to the evaluation function)

    634:    Calling Sequence of func:
    635: $   func(PetscScalar er,PetscScalar ei,Vec xr,Vec xi,PetscScalar *rr,PetscScalar *ri,void *ctx)

    637: +   er     - real part of the current eigenvalue approximation
    638: .   ei     - imaginary part of the current eigenvalue approximation
    639: .   xr     - real part of the current eigenvector approximation
    640: .   xi     - imaginary part of the current eigenvector approximation
    641: .   rr     - result of evaluation (real part)
    642: .   ri     - result of evaluation (imaginary part)
    643: -   ctx    - optional context, as set by EPSSetArbitrarySelection()

    645:    Notes:
    646:    This provides a mechanism to select eigenpairs by evaluating a user-defined
    647:    function. When a function has been provided, the default selection based on
    648:    sorting the eigenvalues is replaced by the sorting of the results of this
    649:    function (with the same sorting criterion given in EPSSetWhichEigenpairs()).

    651:    For instance, suppose you want to compute those eigenvectors that maximize
    652:    a certain computable expression. Then implement the computation using
    653:    the arguments xr and xi, and return the result in rr. Then set the standard
    654:    sorting by magnitude so that the eigenpair with largest value of rr is
    655:    selected.

    657:    This evaluation function is collective, that is, all processes call it and
    658:    it can use collective operations; furthermore, the computed result must
    659:    be the same in all processes.

    661:    The result of func is expressed as a complex number so that it is possible to
    662:    use the standard eigenvalue sorting functions, but normally only rr is used.
    663:    Set ri to zero unless it is meaningful in your application.

    665:    Level: advanced

    667: .seealso: EPSSetWhichEigenpairs()
    668: @*/
    669: PetscErrorCode EPSSetArbitrarySelection(EPS eps,PetscErrorCode (*func)(PetscScalar,PetscScalar,Vec,Vec,PetscScalar*,PetscScalar*,void*),void* ctx)
    670: {
    673:   eps->arbitrary    = func;
    674:   eps->arbitraryctx = ctx;
    675:   eps->state        = EPS_STATE_INITIAL;
    676:   return(0);
    677: }

    679: /*@C
    680:    EPSSetConvergenceTestFunction - Sets a function to compute the error estimate
    681:    used in the convergence test.

    683:    Logically Collective on eps

    685:    Input Parameters:
    686: +  eps     - eigensolver context obtained from EPSCreate()
    687: .  func    - a pointer to the convergence test function
    688: .  ctx     - context for private data for the convergence routine (may be null)
    689: -  destroy - a routine for destroying the context (may be null)

    691:    Calling Sequence of func:
    692: $   func(EPS eps,PetscScalar eigr,PetscScalar eigi,PetscReal res,PetscReal *errest,void *ctx)

    694: +   eps    - eigensolver context obtained from EPSCreate()
    695: .   eigr   - real part of the eigenvalue
    696: .   eigi   - imaginary part of the eigenvalue
    697: .   res    - residual norm associated to the eigenpair
    698: .   errest - (output) computed error estimate
    699: -   ctx    - optional context, as set by EPSSetConvergenceTestFunction()

    701:    Note:
    702:    If the error estimate returned by the convergence test function is less than
    703:    the tolerance, then the eigenvalue is accepted as converged.

    705:    Level: advanced

    707: .seealso: EPSSetConvergenceTest(), EPSSetTolerances()
    708: @*/
    709: PetscErrorCode EPSSetConvergenceTestFunction(EPS eps,PetscErrorCode (*func)(EPS,PetscScalar,PetscScalar,PetscReal,PetscReal*,void*),void* ctx,PetscErrorCode (*destroy)(void*))
    710: {

    715:   if (eps->convergeddestroy) {
    716:     (*eps->convergeddestroy)(eps->convergedctx);
    717:   }
    718:   eps->convergeduser    = func;
    719:   eps->convergeddestroy = destroy;
    720:   eps->convergedctx     = ctx;
    721:   if (func == EPSConvergedRelative) eps->conv = EPS_CONV_REL;
    722:   else if (func == EPSConvergedNorm) eps->conv = EPS_CONV_NORM;
    723:   else if (func == EPSConvergedAbsolute) eps->conv = EPS_CONV_ABS;
    724:   else {
    725:     eps->conv      = EPS_CONV_USER;
    726:     eps->converged = eps->convergeduser;
    727:   }
    728:   return(0);
    729: }

    731: /*@
    732:    EPSSetConvergenceTest - Specifies how to compute the error estimate
    733:    used in the convergence test.

    735:    Logically Collective on eps

    737:    Input Parameters:
    738: +  eps  - eigensolver context obtained from EPSCreate()
    739: -  conv - the type of convergence test

    741:    Options Database Keys:
    742: +  -eps_conv_abs  - Sets the absolute convergence test
    743: .  -eps_conv_rel  - Sets the convergence test relative to the eigenvalue
    744: .  -eps_conv_norm - Sets the convergence test relative to the matrix norms
    745: -  -eps_conv_user - Selects the user-defined convergence test

    747:    Note:
    748:    The parameter 'conv' can have one of these values
    749: +     EPS_CONV_ABS  - absolute error ||r||
    750: .     EPS_CONV_REL  - error relative to the eigenvalue l, ||r||/|l|
    751: .     EPS_CONV_NORM - error relative to the matrix norms, ||r||/(||A||+|l|*||B||)
    752: -     EPS_CONV_USER - function set by EPSSetConvergenceTestFunction()

    754:    Level: intermediate

    756: .seealso: EPSGetConvergenceTest(), EPSSetConvergenceTestFunction(), EPSSetStoppingTest(), EPSConv
    757: @*/
    758: PetscErrorCode EPSSetConvergenceTest(EPS eps,EPSConv conv)
    759: {
    763:   switch (conv) {
    764:     case EPS_CONV_ABS:  eps->converged = EPSConvergedAbsolute; break;
    765:     case EPS_CONV_REL:  eps->converged = EPSConvergedRelative; break;
    766:     case EPS_CONV_NORM: eps->converged = EPSConvergedNorm; break;
    767:     case EPS_CONV_USER:
    768:       if (!eps->convergeduser) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ORDER,"Must call EPSSetConvergenceTestFunction() first");
    769:       eps->converged = eps->convergeduser;
    770:       break;
    771:     default:
    772:       SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid 'conv' value");
    773:   }
    774:   eps->conv = conv;
    775:   return(0);
    776: }

    778: /*@
    779:    EPSGetConvergenceTest - Gets the method used to compute the error estimate
    780:    used in the convergence test.

    782:    Not Collective

    784:    Input Parameters:
    785: .  eps   - eigensolver context obtained from EPSCreate()

    787:    Output Parameters:
    788: .  conv  - the type of convergence test

    790:    Level: intermediate

    792: .seealso: EPSSetConvergenceTest(), EPSConv
    793: @*/
    794: PetscErrorCode EPSGetConvergenceTest(EPS eps,EPSConv *conv)
    795: {
    799:   *conv = eps->conv;
    800:   return(0);
    801: }

    803: /*@C
    804:    EPSSetStoppingTestFunction - Sets a function to decide when to stop the outer
    805:    iteration of the eigensolver.

    807:    Logically Collective on eps

    809:    Input Parameters:
    810: +  eps     - eigensolver context obtained from EPSCreate()
    811: .  func    - pointer to the stopping test function
    812: .  ctx     - context for private data for the stopping routine (may be null)
    813: -  destroy - a routine for destroying the context (may be null)

    815:    Calling Sequence of func:
    816: $   func(EPS eps,PetscInt its,PetscInt max_it,PetscInt nconv,PetscInt nev,EPSConvergedReason *reason,void *ctx)

    818: +   eps    - eigensolver context obtained from EPSCreate()
    819: .   its    - current number of iterations
    820: .   max_it - maximum number of iterations
    821: .   nconv  - number of currently converged eigenpairs
    822: .   nev    - number of requested eigenpairs
    823: .   reason - (output) result of the stopping test
    824: -   ctx    - optional context, as set by EPSSetStoppingTestFunction()

    826:    Note:
    827:    Normal usage is to first call the default routine EPSStoppingBasic() and then
    828:    set reason to EPS_CONVERGED_USER if some user-defined conditions have been
    829:    met. To let the eigensolver continue iterating, the result must be left as
    830:    EPS_CONVERGED_ITERATING.

    832:    Level: advanced

    834: .seealso: EPSSetStoppingTest(), EPSStoppingBasic()
    835: @*/
    836: PetscErrorCode EPSSetStoppingTestFunction(EPS eps,PetscErrorCode (*func)(EPS,PetscInt,PetscInt,PetscInt,PetscInt,EPSConvergedReason*,void*),void* ctx,PetscErrorCode (*destroy)(void*))
    837: {

    842:   if (eps->stoppingdestroy) {
    843:     (*eps->stoppingdestroy)(eps->stoppingctx);
    844:   }
    845:   eps->stoppinguser    = func;
    846:   eps->stoppingdestroy = destroy;
    847:   eps->stoppingctx     = ctx;
    848:   if (func == EPSStoppingBasic) eps->stop = EPS_STOP_BASIC;
    849:   else {
    850:     eps->stop     = EPS_STOP_USER;
    851:     eps->stopping = eps->stoppinguser;
    852:   }
    853:   return(0);
    854: }

    856: /*@
    857:    EPSSetStoppingTest - Specifies how to decide the termination of the outer
    858:    loop of the eigensolver.

    860:    Logically Collective on eps

    862:    Input Parameters:
    863: +  eps  - eigensolver context obtained from EPSCreate()
    864: -  stop - the type of stopping test

    866:    Options Database Keys:
    867: +  -eps_stop_basic - Sets the default stopping test
    868: -  -eps_stop_user  - Selects the user-defined stopping test

    870:    Note:
    871:    The parameter 'stop' can have one of these values
    872: +     EPS_STOP_BASIC - default stopping test
    873: -     EPS_STOP_USER  - function set by EPSSetStoppingTestFunction()

    875:    Level: advanced

    877: .seealso: EPSGetStoppingTest(), EPSSetStoppingTestFunction(), EPSSetConvergenceTest(), EPSStop
    878: @*/
    879: PetscErrorCode EPSSetStoppingTest(EPS eps,EPSStop stop)
    880: {
    884:   switch (stop) {
    885:     case EPS_STOP_BASIC: eps->stopping = EPSStoppingBasic; break;
    886:     case EPS_STOP_USER:
    887:       if (!eps->stoppinguser) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ORDER,"Must call EPSSetStoppingTestFunction() first");
    888:       eps->stopping = eps->stoppinguser;
    889:       break;
    890:     default:
    891:       SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid 'stop' value");
    892:   }
    893:   eps->stop = stop;
    894:   return(0);
    895: }

    897: /*@
    898:    EPSGetStoppingTest - Gets the method used to decide the termination of the outer
    899:    loop of the eigensolver.

    901:    Not Collective

    903:    Input Parameters:
    904: .  eps   - eigensolver context obtained from EPSCreate()

    906:    Output Parameters:
    907: .  stop  - the type of stopping test

    909:    Level: advanced

    911: .seealso: EPSSetStoppingTest(), EPSStop
    912: @*/
    913: PetscErrorCode EPSGetStoppingTest(EPS eps,EPSStop *stop)
    914: {
    918:   *stop = eps->stop;
    919:   return(0);
    920: }

    922: /*@
    923:    EPSSetProblemType - Specifies the type of the eigenvalue problem.

    925:    Logically Collective on eps

    927:    Input Parameters:
    928: +  eps      - the eigensolver context
    929: -  type     - a known type of eigenvalue problem

    931:    Options Database Keys:
    932: +  -eps_hermitian - Hermitian eigenvalue problem
    933: .  -eps_gen_hermitian - generalized Hermitian eigenvalue problem
    934: .  -eps_non_hermitian - non-Hermitian eigenvalue problem
    935: .  -eps_gen_non_hermitian - generalized non-Hermitian eigenvalue problem
    936: -  -eps_pos_gen_non_hermitian - generalized non-Hermitian eigenvalue problem
    937:    with positive semi-definite B

    939:    Notes:
    940:    Allowed values for the problem type are: Hermitian (EPS_HEP), non-Hermitian
    941:    (EPS_NHEP), generalized Hermitian (EPS_GHEP), generalized non-Hermitian
    942:    (EPS_GNHEP), generalized non-Hermitian with positive semi-definite B
    943:    (EPS_PGNHEP), and generalized Hermitian-indefinite (EPS_GHIEP).

    945:    This function must be used to instruct SLEPc to exploit symmetry. If no
    946:    problem type is specified, by default a non-Hermitian problem is assumed
    947:    (either standard or generalized). If the user knows that the problem is
    948:    Hermitian (i.e. A=A^H) or generalized Hermitian (i.e. A=A^H, B=B^H, and
    949:    B positive definite) then it is recommended to set the problem type so
    950:    that eigensolver can exploit these properties.

    952:    Level: intermediate

    954: .seealso: EPSSetOperators(), EPSSetType(), EPSGetProblemType(), EPSProblemType
    955: @*/
    956: PetscErrorCode EPSSetProblemType(EPS eps,EPSProblemType type)
    957: {
    961:   if (type == eps->problem_type) return(0);
    962:   switch (type) {
    963:     case EPS_HEP:
    964:       eps->isgeneralized = PETSC_FALSE;
    965:       eps->ishermitian = PETSC_TRUE;
    966:       eps->ispositive = PETSC_FALSE;
    967:       break;
    968:     case EPS_NHEP:
    969:       eps->isgeneralized = PETSC_FALSE;
    970:       eps->ishermitian = PETSC_FALSE;
    971:       eps->ispositive = PETSC_FALSE;
    972:       break;
    973:     case EPS_GHEP:
    974:       eps->isgeneralized = PETSC_TRUE;
    975:       eps->ishermitian = PETSC_TRUE;
    976:       eps->ispositive = PETSC_TRUE;
    977:       break;
    978:     case EPS_GNHEP:
    979:       eps->isgeneralized = PETSC_TRUE;
    980:       eps->ishermitian = PETSC_FALSE;
    981:       eps->ispositive = PETSC_FALSE;
    982:       break;
    983:     case EPS_PGNHEP:
    984:       eps->isgeneralized = PETSC_TRUE;
    985:       eps->ishermitian = PETSC_FALSE;
    986:       eps->ispositive = PETSC_TRUE;
    987:       break;
    988:     case EPS_GHIEP:
    989:       eps->isgeneralized = PETSC_TRUE;
    990:       eps->ishermitian = PETSC_TRUE;
    991:       eps->ispositive = PETSC_FALSE;
    992:       break;
    993:     default:
    994:       SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_WRONG,"Unknown eigenvalue problem type");
    995:   }
    996:   eps->problem_type = type;
    997:   eps->state = EPS_STATE_INITIAL;
    998:   return(0);
    999: }

    1001: /*@
    1002:    EPSGetProblemType - Gets the problem type from the EPS object.

    1004:    Not Collective

    1006:    Input Parameter:
    1007: .  eps - the eigensolver context

    1009:    Output Parameter:
    1010: .  type - the problem type

    1012:    Level: intermediate

    1014: .seealso: EPSSetProblemType(), EPSProblemType
    1015: @*/
    1016: PetscErrorCode EPSGetProblemType(EPS eps,EPSProblemType *type)
    1017: {
    1021:   *type = eps->problem_type;
    1022:   return(0);
    1023: }

    1025: /*@
    1026:    EPSSetExtraction - Specifies the type of extraction technique to be employed
    1027:    by the eigensolver.

    1029:    Logically Collective on eps

    1031:    Input Parameters:
    1032: +  eps  - the eigensolver context
    1033: -  extr - a known type of extraction

    1035:    Options Database Keys:
    1036: +  -eps_ritz - Rayleigh-Ritz extraction
    1037: .  -eps_harmonic - harmonic Ritz extraction
    1038: .  -eps_harmonic_relative - harmonic Ritz extraction relative to the eigenvalue
    1039: .  -eps_harmonic_right - harmonic Ritz extraction for rightmost eigenvalues
    1040: .  -eps_harmonic_largest - harmonic Ritz extraction for largest magnitude
    1041:    (without target)
    1042: .  -eps_refined - refined Ritz extraction
    1043: -  -eps_refined_harmonic - refined harmonic Ritz extraction

    1045:    Notes:
    1046:    Not all eigensolvers support all types of extraction. See the SLEPc
    1047:    Users Manual for details.

    1049:    By default, a standard Rayleigh-Ritz extraction is used. Other extractions
    1050:    may be useful when computing interior eigenvalues.

    1052:    Harmonic-type extractions are used in combination with a 'target'.

    1054:    Level: advanced

    1056: .seealso: EPSSetTarget(), EPSGetExtraction(), EPSExtraction
    1057: @*/
    1058: PetscErrorCode EPSSetExtraction(EPS eps,EPSExtraction extr)
    1059: {
    1063:   eps->extraction = extr;
    1064:   return(0);
    1065: }

    1067: /*@
    1068:    EPSGetExtraction - Gets the extraction type used by the EPS object.

    1070:    Not Collective

    1072:    Input Parameter:
    1073: .  eps - the eigensolver context

    1075:    Output Parameter:
    1076: .  extr - name of extraction type

    1078:    Level: advanced

    1080: .seealso: EPSSetExtraction(), EPSExtraction
    1081: @*/
    1082: PetscErrorCode EPSGetExtraction(EPS eps,EPSExtraction *extr)
    1083: {
    1087:   *extr = eps->extraction;
    1088:   return(0);
    1089: }

    1091: /*@
    1092:    EPSSetBalance - Specifies the balancing technique to be employed by the
    1093:    eigensolver, and some parameters associated to it.

    1095:    Logically Collective on eps

    1097:    Input Parameters:
    1098: +  eps    - the eigensolver context
    1099: .  bal    - the balancing method, one of EPS_BALANCE_NONE, EPS_BALANCE_ONESIDE,
    1100:             EPS_BALANCE_TWOSIDE, or EPS_BALANCE_USER
    1101: .  its    - number of iterations of the balancing algorithm
    1102: -  cutoff - cutoff value

    1104:    Options Database Keys:
    1105: +  -eps_balance <method> - the balancing method, where <method> is one of
    1106:                            'none', 'oneside', 'twoside', or 'user'
    1107: .  -eps_balance_its <its> - number of iterations
    1108: -  -eps_balance_cutoff <cutoff> - cutoff value

    1110:    Notes:
    1111:    When balancing is enabled, the solver works implicitly with matrix DAD^-1,
    1112:    where D is an appropriate diagonal matrix. This improves the accuracy of
    1113:    the computed results in some cases. See the SLEPc Users Manual for details.

    1115:    Balancing makes sense only for non-Hermitian problems when the required
    1116:    precision is high (i.e. a small tolerance such as 1e-15).

    1118:    By default, balancing is disabled. The two-sided method is much more
    1119:    effective than the one-sided counterpart, but it requires the system
    1120:    matrices to have the MatMultTranspose operation defined.

    1122:    The parameter 'its' is the number of iterations performed by the method. The
    1123:    cutoff value is used only in the two-side variant. Use PETSC_DEFAULT to assign
    1124:    a reasonably good value.

    1126:    User-defined balancing is allowed provided that the corresponding matrix
    1127:    is set via STSetBalanceMatrix.

    1129:    Level: intermediate

    1131: .seealso: EPSGetBalance(), EPSBalance, STSetBalanceMatrix()
    1132: @*/
    1133: PetscErrorCode EPSSetBalance(EPS eps,EPSBalance bal,PetscInt its,PetscReal cutoff)
    1134: {
    1140:   switch (bal) {
    1141:     case EPS_BALANCE_NONE:
    1142:     case EPS_BALANCE_ONESIDE:
    1143:     case EPS_BALANCE_TWOSIDE:
    1144:     case EPS_BALANCE_USER:
    1145:       if (eps->balance != bal) {
    1146:         eps->state = EPS_STATE_INITIAL;
    1147:         eps->balance = bal;
    1148:       }
    1149:       break;
    1150:     default:
    1151:       SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid value of argument 'bal'");
    1152:   }
    1153:   if (its==PETSC_DECIDE || its==PETSC_DEFAULT) eps->balance_its = 5;
    1154:   else {
    1155:     if (its <= 0) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of its. Must be > 0");
    1156:     eps->balance_its = its;
    1157:   }
    1158:   if (cutoff==PETSC_DECIDE || cutoff==PETSC_DEFAULT) eps->balance_cutoff = 1e-8;
    1159:   else {
    1160:     if (cutoff <= 0.0) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of cutoff. Must be > 0");
    1161:     eps->balance_cutoff = cutoff;
    1162:   }
    1163:   return(0);
    1164: }

    1166: /*@C
    1167:    EPSGetBalance - Gets the balancing type used by the EPS object, and the
    1168:    associated parameters.

    1170:    Not Collective

    1172:    Input Parameter:
    1173: .  eps - the eigensolver context

    1175:    Output Parameters:
    1176: +  bal    - the balancing method
    1177: .  its    - number of iterations of the balancing algorithm
    1178: -  cutoff - cutoff value

    1180:    Level: intermediate

    1182:    Note:
    1183:    The user can specify NULL for any parameter that is not needed.

    1185: .seealso: EPSSetBalance(), EPSBalance
    1186: @*/
    1187: PetscErrorCode EPSGetBalance(EPS eps,EPSBalance *bal,PetscInt *its,PetscReal *cutoff)
    1188: {
    1191:   if (bal)    *bal = eps->balance;
    1192:   if (its)    *its = eps->balance_its;
    1193:   if (cutoff) *cutoff = eps->balance_cutoff;
    1194:   return(0);
    1195: }

    1197: /*@
    1198:    EPSSetTwoSided - Sets the solver to use a two-sided variant so that left
    1199:    eigenvectors are also computed.

    1201:    Logically Collective on eps

    1203:    Input Parameters:
    1204: +  eps      - the eigensolver context
    1205: -  twosided - whether the two-sided variant is to be used or not

    1207:    Options Database Keys:
    1208: .  -eps_two_sided <boolean> - Sets/resets the twosided flag

    1210:    Notes:
    1211:    If the user sets twosided=PETSC_TRUE then the solver uses a variant of
    1212:    the algorithm that computes both right and left eigenvectors. This is
    1213:    usually much more costly. This option is not available in all solvers.

    1215:    When using two-sided solvers, the problem matrices must have both the
    1216:    MatMult and MatMultTranspose operations defined.

    1218:    Level: advanced

    1220: .seealso: EPSGetTwoSided(), EPSGetLeftEigenvector()
    1221: @*/
    1222: PetscErrorCode EPSSetTwoSided(EPS eps,PetscBool twosided)
    1223: {
    1227:   if (twosided!=eps->twosided) {
    1228:     eps->twosided = twosided;
    1229:     eps->state    = EPS_STATE_INITIAL;
    1230:   }
    1231:   return(0);
    1232: }

    1234: /*@
    1235:    EPSGetTwoSided - Returns the flag indicating whether a two-sided variant
    1236:    of the algorithm is being used or not.

    1238:    Not Collective

    1240:    Input Parameter:
    1241: .  eps - the eigensolver context

    1243:    Output Parameter:
    1244: .  twosided - the returned flag

    1246:    Level: advanced

    1248: .seealso: EPSSetTwoSided()
    1249: @*/
    1250: PetscErrorCode EPSGetTwoSided(EPS eps,PetscBool *twosided)
    1251: {
    1255:   *twosided = eps->twosided;
    1256:   return(0);
    1257: }

    1259: /*@
    1260:    EPSSetTrueResidual - Specifies if the solver must compute the true residual
    1261:    explicitly or not.

    1263:    Logically Collective on eps

    1265:    Input Parameters:
    1266: +  eps     - the eigensolver context
    1267: -  trueres - whether true residuals are required or not

    1269:    Options Database Keys:
    1270: .  -eps_true_residual <boolean> - Sets/resets the boolean flag 'trueres'

    1272:    Notes:
    1273:    If the user sets trueres=PETSC_TRUE then the solver explicitly computes
    1274:    the true residual for each eigenpair approximation, and uses it for
    1275:    convergence testing. Computing the residual is usually an expensive
    1276:    operation. Some solvers (e.g., Krylov solvers) can avoid this computation
    1277:    by using a cheap estimate of the residual norm, but this may sometimes
    1278:    give inaccurate results (especially if a spectral transform is being
    1279:    used). On the contrary, preconditioned eigensolvers (e.g., Davidson solvers)
    1280:    do rely on computing the true residual, so this option is irrelevant for them.

    1282:    Level: advanced

    1284: .seealso: EPSGetTrueResidual()
    1285: @*/
    1286: PetscErrorCode EPSSetTrueResidual(EPS eps,PetscBool trueres)
    1287: {
    1291:   eps->trueres = trueres;
    1292:   return(0);
    1293: }

    1295: /*@
    1296:    EPSGetTrueResidual - Returns the flag indicating whether true
    1297:    residuals must be computed explicitly or not.

    1299:    Not Collective

    1301:    Input Parameter:
    1302: .  eps - the eigensolver context

    1304:    Output Parameter:
    1305: .  trueres - the returned flag

    1307:    Level: advanced

    1309: .seealso: EPSSetTrueResidual()
    1310: @*/
    1311: PetscErrorCode EPSGetTrueResidual(EPS eps,PetscBool *trueres)
    1312: {
    1316:   *trueres = eps->trueres;
    1317:   return(0);
    1318: }

    1320: /*@
    1321:    EPSSetTrackAll - Specifies if the solver must compute the residual norm of all
    1322:    approximate eigenpairs or not.

    1324:    Logically Collective on eps

    1326:    Input Parameters:
    1327: +  eps      - the eigensolver context
    1328: -  trackall - whether to compute all residuals or not

    1330:    Notes:
    1331:    If the user sets trackall=PETSC_TRUE then the solver computes (or estimates)
    1332:    the residual norm for each eigenpair approximation. Computing the residual is
    1333:    usually an expensive operation and solvers commonly compute only the residual
    1334:    associated to the first unconverged eigenpair.

    1336:    The options '-eps_monitor_all' and '-eps_monitor_lg_all' automatically
    1337:    activate this option.

    1339:    Level: developer

    1341: .seealso: EPSGetTrackAll()
    1342: @*/
    1343: PetscErrorCode EPSSetTrackAll(EPS eps,PetscBool trackall)
    1344: {
    1348:   eps->trackall = trackall;
    1349:   return(0);
    1350: }

    1352: /*@
    1353:    EPSGetTrackAll - Returns the flag indicating whether all residual norms must
    1354:    be computed or not.

    1356:    Not Collective

    1358:    Input Parameter:
    1359: .  eps - the eigensolver context

    1361:    Output Parameter:
    1362: .  trackall - the returned flag

    1364:    Level: developer

    1366: .seealso: EPSSetTrackAll()
    1367: @*/
    1368: PetscErrorCode EPSGetTrackAll(EPS eps,PetscBool *trackall)
    1369: {
    1373:   *trackall = eps->trackall;
    1374:   return(0);
    1375: }

    1377: /*@
    1378:    EPSSetPurify - Deactivate eigenvector purification (which is activated by default).

    1380:    Logically Collective on eps

    1382:    Input Parameters:
    1383: +  eps    - the eigensolver context
    1384: -  purify - whether purification is required or not

    1386:    Options Database Keys:
    1387: .  -eps_purify <boolean> - Sets/resets the boolean flag 'purify'

    1389:    Notes:
    1390:    By default, eigenvectors of generalized symmetric eigenproblems are purified
    1391:    in order to purge directions in the nullspace of matrix B. If the user knows
    1392:    that B is non-singular, then purification can be safely deactivated and some
    1393:    computational cost is avoided (this is particularly important in interval computations).

    1395:    Level: intermediate

    1397: .seealso: EPSGetPurify(), EPSSetInterval()
    1398: @*/
    1399: PetscErrorCode EPSSetPurify(EPS eps,PetscBool purify)
    1400: {
    1404:   if (purify!=eps->purify) {
    1405:     eps->purify = purify;
    1406:     eps->state  = EPS_STATE_INITIAL;
    1407:   }
    1408:   return(0);
    1409: }

    1411: /*@
    1412:    EPSGetPurify - Returns the flag indicating whether purification is activated
    1413:    or not.

    1415:    Not Collective

    1417:    Input Parameter:
    1418: .  eps - the eigensolver context

    1420:    Output Parameter:
    1421: .  purify - the returned flag

    1423:    Level: intermediate

    1425: .seealso: EPSSetPurify()
    1426: @*/
    1427: PetscErrorCode EPSGetPurify(EPS eps,PetscBool *purify)
    1428: {
    1432:   *purify = eps->purify;
    1433:   return(0);
    1434: }

    1436: /*@C
    1437:    EPSSetOptionsPrefix - Sets the prefix used for searching for all
    1438:    EPS options in the database.

    1440:    Logically Collective on eps

    1442:    Input Parameters:
    1443: +  eps - the eigensolver context
    1444: -  prefix - the prefix string to prepend to all EPS option requests

    1446:    Notes:
    1447:    A hyphen (-) must NOT be given at the beginning of the prefix name.
    1448:    The first character of all runtime options is AUTOMATICALLY the
    1449:    hyphen.

    1451:    For example, to distinguish between the runtime options for two
    1452:    different EPS contexts, one could call
    1453: .vb
    1454:       EPSSetOptionsPrefix(eps1,"eig1_")
    1455:       EPSSetOptionsPrefix(eps2,"eig2_")
    1456: .ve

    1458:    Level: advanced

    1460: .seealso: EPSAppendOptionsPrefix(), EPSGetOptionsPrefix()
    1461: @*/
    1462: PetscErrorCode EPSSetOptionsPrefix(EPS eps,const char *prefix)
    1463: {

    1468:   if (!eps->st) { EPSGetST(eps,&eps->st); }
    1469:   STSetOptionsPrefix(eps->st,prefix);
    1470:   if (!eps->V) { EPSGetBV(eps,&eps->V); }
    1471:   BVSetOptionsPrefix(eps->V,prefix);
    1472:   if (!eps->ds) { EPSGetDS(eps,&eps->ds); }
    1473:   DSSetOptionsPrefix(eps->ds,prefix);
    1474:   if (!eps->rg) { EPSGetRG(eps,&eps->rg); }
    1475:   RGSetOptionsPrefix(eps->rg,prefix);
    1476:   PetscObjectSetOptionsPrefix((PetscObject)eps,prefix);
    1477:   return(0);
    1478: }

    1480: /*@C
    1481:    EPSAppendOptionsPrefix - Appends to the prefix used for searching for all
    1482:    EPS options in the database.

    1484:    Logically Collective on eps

    1486:    Input Parameters:
    1487: +  eps - the eigensolver context
    1488: -  prefix - the prefix string to prepend to all EPS option requests

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

    1494:    Level: advanced

    1496: .seealso: EPSSetOptionsPrefix(), EPSGetOptionsPrefix()
    1497: @*/
    1498: PetscErrorCode EPSAppendOptionsPrefix(EPS eps,const char *prefix)
    1499: {

    1504:   if (!eps->st) { EPSGetST(eps,&eps->st); }
    1505:   STAppendOptionsPrefix(eps->st,prefix);
    1506:   if (!eps->V) { EPSGetBV(eps,&eps->V); }
    1507:   BVAppendOptionsPrefix(eps->V,prefix);
    1508:   if (!eps->ds) { EPSGetDS(eps,&eps->ds); }
    1509:   DSAppendOptionsPrefix(eps->ds,prefix);
    1510:   if (!eps->rg) { EPSGetRG(eps,&eps->rg); }
    1511:   RGAppendOptionsPrefix(eps->rg,prefix);
    1512:   PetscObjectAppendOptionsPrefix((PetscObject)eps,prefix);
    1513:   return(0);
    1514: }

    1516: /*@C
    1517:    EPSGetOptionsPrefix - Gets the prefix used for searching for all
    1518:    EPS options in the database.

    1520:    Not Collective

    1522:    Input Parameters:
    1523: .  eps - the eigensolver context

    1525:    Output Parameters:
    1526: .  prefix - pointer to the prefix string used is returned

    1528:    Note:
    1529:    On the Fortran side, the user should pass in a string 'prefix' of
    1530:    sufficient length to hold the prefix.

    1532:    Level: advanced

    1534: .seealso: EPSSetOptionsPrefix(), EPSAppendOptionsPrefix()
    1535: @*/
    1536: PetscErrorCode EPSGetOptionsPrefix(EPS eps,const char *prefix[])
    1537: {

    1543:   PetscObjectGetOptionsPrefix((PetscObject)eps,prefix);
    1544:   return(0);
    1545: }