Actual source code: epsbasic.c
slepc-3.21.1 2024-04-26
Report Typos and Errors

      1: /*
      2:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      3:    SLEPc - Scalable Library for Eigenvalue Problem Computations
      4:    Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain

      6:    This file is part of SLEPc.
      7:    SLEPc is distributed under a 2-clause BSD license (see LICENSE).
      8:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      9: */
     10: /*
     11:    Basic EPS routines
     12: */

     14: #include <slepc/private/epsimpl.h>

     16: /* Logging support */
     17: PetscClassId      EPS_CLASSID = 0;
     18: PetscLogEvent     EPS_SetUp = 0,EPS_Solve = 0,EPS_CISS_SVD = 0;

     20: /* List of registered EPS routines */
     21: PetscFunctionList EPSList = NULL;
     22: PetscBool         EPSRegisterAllCalled = PETSC_FALSE;

     24: /* List of registered EPS monitors */
     25: PetscFunctionList EPSMonitorList              = NULL;
     26: PetscFunctionList EPSMonitorCreateList        = NULL;
     27: PetscFunctionList EPSMonitorDestroyList       = NULL;
     28: PetscBool         EPSMonitorRegisterAllCalled = PETSC_FALSE;

     30: /*@
     31:    EPSCreate - Creates the default EPS context.

     33:    Collective

     35:    Input Parameter:
     36: .  comm - MPI communicator

     38:    Output Parameter:
     39: .  outeps - location to put the EPS context

     41:    Note:
     42:    The default EPS type is EPSKRYLOVSCHUR

     44:    Level: beginner

     46: .seealso: EPSSetUp(), EPSSolve(), EPSDestroy(), EPS
     47: @*/
     48: PetscErrorCode EPSCreate(MPI_Comm comm,EPS *outeps)
     49: {
     50:   EPS            eps;

     52:   PetscFunctionBegin;
     53:   PetscAssertPointer(outeps,2);
     54:   *outeps = NULL;
     55:   PetscCall(EPSInitializePackage());
     56:   PetscCall(SlepcHeaderCreate(eps,EPS_CLASSID,"EPS","Eigenvalue Problem Solver","EPS",comm,EPSDestroy,EPSView));

     58:   eps->max_it          = PETSC_DEFAULT;
     59:   eps->nev             = 1;
     60:   eps->ncv             = PETSC_DEFAULT;
     61:   eps->mpd             = PETSC_DEFAULT;
     62:   eps->nini            = 0;
     63:   eps->nds             = 0;
     64:   eps->target          = 0.0;
     65:   eps->tol             = PETSC_DEFAULT;
     66:   eps->conv            = EPS_CONV_REL;
     67:   eps->stop            = EPS_STOP_BASIC;
     68:   eps->which           = (EPSWhich)0;
     69:   eps->inta            = 0.0;
     70:   eps->intb            = 0.0;
     71:   eps->problem_type    = (EPSProblemType)0;
     72:   eps->extraction      = EPS_RITZ;
     73:   eps->balance         = EPS_BALANCE_NONE;
     74:   eps->balance_its     = 5;
     75:   eps->balance_cutoff  = 1e-8;
     76:   eps->trueres         = PETSC_FALSE;
     77:   eps->trackall        = PETSC_FALSE;
     78:   eps->purify          = PETSC_TRUE;
     79:   eps->twosided        = PETSC_FALSE;

     81:   eps->converged       = EPSConvergedRelative;
     82:   eps->convergeduser   = NULL;
     83:   eps->convergeddestroy= NULL;
     84:   eps->stopping        = EPSStoppingBasic;
     85:   eps->stoppinguser    = NULL;
     86:   eps->stoppingdestroy = NULL;
     87:   eps->arbitrary       = NULL;
     88:   eps->convergedctx    = NULL;
     89:   eps->stoppingctx     = NULL;
     90:   eps->arbitraryctx    = NULL;
     91:   eps->numbermonitors  = 0;

     93:   eps->st              = NULL;
     94:   eps->ds              = NULL;
     95:   eps->V               = NULL;
     96:   eps->W               = NULL;
     97:   eps->rg              = NULL;
     98:   eps->D               = NULL;
     99:   eps->IS              = NULL;
    100:   eps->ISL             = NULL;
    101:   eps->defl            = NULL;
    102:   eps->eigr            = NULL;
    103:   eps->eigi            = NULL;
    104:   eps->errest          = NULL;
    105:   eps->rr              = NULL;
    106:   eps->ri              = NULL;
    107:   eps->perm            = NULL;
    108:   eps->nwork           = 0;
    109:   eps->work            = NULL;
    110:   eps->data            = NULL;

    112:   eps->state           = EPS_STATE_INITIAL;
    113:   eps->categ           = EPS_CATEGORY_KRYLOV;
    114:   eps->nconv           = 0;
    115:   eps->its             = 0;
    116:   eps->nloc            = 0;
    117:   eps->nrma            = 0.0;
    118:   eps->nrmb            = 0.0;
    119:   eps->useds           = PETSC_FALSE;
    120:   eps->isgeneralized   = PETSC_FALSE;
    121:   eps->ispositive      = PETSC_FALSE;
    122:   eps->ishermitian     = PETSC_FALSE;
    123:   eps->reason          = EPS_CONVERGED_ITERATING;

    125:   PetscCall(PetscNew(&eps->sc));
    126:   *outeps = eps;
    127:   PetscFunctionReturn(PETSC_SUCCESS);
    128: }

    130: /*@C
    131:    EPSSetType - Selects the particular solver to be used in the EPS object.

    133:    Logically Collective

    135:    Input Parameters:
    136: +  eps  - the eigensolver context
    137: -  type - a known method

    139:    Options Database Key:
    140: .  -eps_type <method> - Sets the method; use -help for a list
    141:     of available methods

    143:    Notes:
    144:    See "slepc/include/slepceps.h" for available methods. The default
    145:    is EPSKRYLOVSCHUR.

    147:    Normally, it is best to use the EPSSetFromOptions() command and
    148:    then set the EPS type from the options database rather than by using
    149:    this routine.  Using the options database provides the user with
    150:    maximum flexibility in evaluating the different available methods.
    151:    The EPSSetType() routine is provided for those situations where it
    152:    is necessary to set the iterative solver independently of the command
    153:    line or options database.

    155:    Level: intermediate

    157: .seealso: STSetType(), EPSType
    158: @*/
    159: PetscErrorCode EPSSetType(EPS eps,EPSType type)
    160: {
    161:   PetscErrorCode (*r)(EPS);
    162:   PetscBool      match;

    164:   PetscFunctionBegin;
    166:   PetscAssertPointer(type,2);

    168:   PetscCall(PetscObjectTypeCompare((PetscObject)eps,type,&match));
    169:   if (match) PetscFunctionReturn(PETSC_SUCCESS);

    171:   PetscCall(PetscFunctionListFind(EPSList,type,&r));
    172:   PetscCheck(r,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown EPS type given: %s",type);

    174:   PetscTryTypeMethod(eps,destroy);
    175:   PetscCall(PetscMemzero(eps->ops,sizeof(struct _EPSOps)));

    177:   eps->state = EPS_STATE_INITIAL;
    178:   PetscCall(PetscObjectChangeTypeName((PetscObject)eps,type));
    179:   PetscCall((*r)(eps));
    180:   PetscFunctionReturn(PETSC_SUCCESS);
    181: }

    183: /*@C
    184:    EPSGetType - Gets the EPS type as a string from the EPS object.

    186:    Not Collective

    188:    Input Parameter:
    189: .  eps - the eigensolver context

    191:    Output Parameter:
    192: .  type - name of EPS method

    194:    Level: intermediate

    196: .seealso: EPSSetType()
    197: @*/
    198: PetscErrorCode EPSGetType(EPS eps,EPSType *type)
    199: {
    200:   PetscFunctionBegin;
    202:   PetscAssertPointer(type,2);
    203:   *type = ((PetscObject)eps)->type_name;
    204:   PetscFunctionReturn(PETSC_SUCCESS);
    205: }

    207: /*@C
    208:    EPSRegister - Adds a method to the eigenproblem solver package.

    210:    Not Collective

    212:    Input Parameters:
    213: +  name - name of a new user-defined solver
    214: -  function - routine to create the solver context

    216:    Notes:
    217:    EPSRegister() may be called multiple times to add several user-defined solvers.

    219:    Example Usage:
    220: .vb
    221:     EPSRegister("my_solver",MySolverCreate);
    222: .ve

    224:    Then, your solver can be chosen with the procedural interface via
    225: $     EPSSetType(eps,"my_solver")
    226:    or at runtime via the option
    227: $     -eps_type my_solver

    229:    Level: advanced

    231: .seealso: EPSRegisterAll()
    232: @*/
    233: PetscErrorCode EPSRegister(const char *name,PetscErrorCode (*function)(EPS))
    234: {
    235:   PetscFunctionBegin;
    236:   PetscCall(EPSInitializePackage());
    237:   PetscCall(PetscFunctionListAdd(&EPSList,name,function));
    238:   PetscFunctionReturn(PETSC_SUCCESS);
    239: }

    241: /*@C
    242:    EPSMonitorRegister - Adds EPS monitor routine.

    244:    Not Collective

    246:    Input Parameters:
    247: +  name    - name of a new monitor routine
    248: .  vtype   - a PetscViewerType for the output
    249: .  format  - a PetscViewerFormat for the output
    250: .  monitor - monitor routine
    251: .  create  - creation routine, or NULL
    252: -  destroy - destruction routine, or NULL

    254:    Notes:
    255:    EPSMonitorRegister() may be called multiple times to add several user-defined monitors.

    257:    Example Usage:
    258: .vb
    259:    EPSMonitorRegister("my_monitor",PETSCVIEWERASCII,PETSC_VIEWER_ASCII_INFO_DETAIL,MyMonitor,NULL,NULL);
    260: .ve

    262:    Then, your monitor can be chosen with the procedural interface via
    263: $      EPSMonitorSetFromOptions(eps,"-eps_monitor_my_monitor","my_monitor",NULL)
    264:    or at runtime via the option
    265: $      -eps_monitor_my_monitor

    267:    Level: advanced

    269: .seealso: EPSMonitorRegisterAll()
    270: @*/
    271: PetscErrorCode EPSMonitorRegister(const char name[],PetscViewerType vtype,PetscViewerFormat format,PetscErrorCode (*monitor)(EPS,PetscInt,PetscInt,PetscScalar*,PetscScalar*,PetscReal*,PetscInt,PetscViewerAndFormat*),PetscErrorCode (*create)(PetscViewer,PetscViewerFormat,void*,PetscViewerAndFormat**),PetscErrorCode (*destroy)(PetscViewerAndFormat**))
    272: {
    273:   char           key[PETSC_MAX_PATH_LEN];

    275:   PetscFunctionBegin;
    276:   PetscCall(EPSInitializePackage());
    277:   PetscCall(SlepcMonitorMakeKey_Internal(name,vtype,format,key));
    278:   PetscCall(PetscFunctionListAdd(&EPSMonitorList,key,monitor));
    279:   if (create)  PetscCall(PetscFunctionListAdd(&EPSMonitorCreateList,key,create));
    280:   if (destroy) PetscCall(PetscFunctionListAdd(&EPSMonitorDestroyList,key,destroy));
    281:   PetscFunctionReturn(PETSC_SUCCESS);
    282: }

    284: /*@
    285:    EPSReset - Resets the EPS context to the initial state (prior to setup)
    286:    and destroys any allocated Vecs and Mats.

    288:    Collective

    290:    Input Parameter:
    291: .  eps - eigensolver context obtained from EPSCreate()

    293:    Note:
    294:    This can be used when a problem of different matrix size wants to be solved.
    295:    All options that have previously been set are preserved, so in a next use
    296:    the solver configuration is the same, but new sizes for matrices and vectors
    297:    are allowed.

    299:    Level: advanced

    301: .seealso: EPSDestroy()
    302: @*/
    303: PetscErrorCode EPSReset(EPS eps)
    304: {
    305:   PetscFunctionBegin;
    307:   if (!eps) PetscFunctionReturn(PETSC_SUCCESS);
    308:   PetscTryTypeMethod(eps,reset);
    309:   if (eps->st) PetscCall(STReset(eps->st));
    310:   PetscCall(VecDestroy(&eps->D));
    311:   PetscCall(BVDestroy(&eps->V));
    312:   PetscCall(BVDestroy(&eps->W));
    313:   PetscCall(VecDestroyVecs(eps->nwork,&eps->work));
    314:   eps->nwork = 0;
    315:   eps->state = EPS_STATE_INITIAL;
    316:   PetscFunctionReturn(PETSC_SUCCESS);
    317: }

    319: /*@C
    320:    EPSDestroy - Destroys the EPS context.

    322:    Collective

    324:    Input Parameter:
    325: .  eps - eigensolver context obtained from EPSCreate()

    327:    Level: beginner

    329: .seealso: EPSCreate(), EPSSetUp(), EPSSolve()
    330: @*/
    331: PetscErrorCode EPSDestroy(EPS *eps)
    332: {
    333:   PetscFunctionBegin;
    334:   if (!*eps) PetscFunctionReturn(PETSC_SUCCESS);
    336:   if (--((PetscObject)*eps)->refct > 0) { *eps = NULL; PetscFunctionReturn(PETSC_SUCCESS); }
    337:   PetscCall(EPSReset(*eps));
    338:   PetscTryTypeMethod(*eps,destroy);
    339:   if ((*eps)->eigr) PetscCall(PetscFree4((*eps)->eigr,(*eps)->eigi,(*eps)->errest,(*eps)->perm));
    340:   if ((*eps)->rr) PetscCall(PetscFree2((*eps)->rr,(*eps)->ri));
    341:   PetscCall(STDestroy(&(*eps)->st));
    342:   PetscCall(RGDestroy(&(*eps)->rg));
    343:   PetscCall(DSDestroy(&(*eps)->ds));
    344:   PetscCall(PetscFree((*eps)->sc));
    345:   /* just in case the initial vectors have not been used */
    346:   PetscCall(SlepcBasisDestroy_Private(&(*eps)->nds,&(*eps)->defl));
    347:   PetscCall(SlepcBasisDestroy_Private(&(*eps)->nini,&(*eps)->IS));
    348:   PetscCall(SlepcBasisDestroy_Private(&(*eps)->ninil,&(*eps)->ISL));
    349:   if ((*eps)->convergeddestroy) PetscCall((*(*eps)->convergeddestroy)((*eps)->convergedctx));
    350:   PetscCall(EPSMonitorCancel(*eps));
    351:   PetscCall(PetscHeaderDestroy(eps));
    352:   PetscFunctionReturn(PETSC_SUCCESS);
    353: }

    355: /*@
    356:    EPSSetTarget - Sets the value of the target.

    358:    Logically Collective

    360:    Input Parameters:
    361: +  eps    - eigensolver context
    362: -  target - the value of the target

    364:    Options Database Key:
    365: .  -eps_target <scalar> - the value of the target

    367:    Notes:
    368:    The target is a scalar value used to determine the portion of the spectrum
    369:    of interest. It is used in combination with EPSSetWhichEigenpairs().

    371:    In the case of complex scalars, a complex value can be provided in the
    372:    command line with [+/-][realnumber][+/-]realnumberi with no spaces, e.g.
    373:    -eps_target 1.0+2.0i

    375:    Level: intermediate

    377: .seealso: EPSGetTarget(), EPSSetWhichEigenpairs()
    378: @*/
    379: PetscErrorCode EPSSetTarget(EPS eps,PetscScalar target)
    380: {
    381:   PetscFunctionBegin;
    384:   eps->target = target;
    385:   if (!eps->st) PetscCall(EPSGetST(eps,&eps->st));
    386:   PetscCall(STSetDefaultShift(eps->st,target));
    387:   PetscFunctionReturn(PETSC_SUCCESS);
    388: }

    390: /*@
    391:    EPSGetTarget - Gets the value of the target.

    393:    Not Collective

    395:    Input Parameter:
    396: .  eps - eigensolver context

    398:    Output Parameter:
    399: .  target - the value of the target

    401:    Note:
    402:    If the target was not set by the user, then zero is returned.

    404:    Level: intermediate

    406: .seealso: EPSSetTarget()
    407: @*/
    408: PetscErrorCode EPSGetTarget(EPS eps,PetscScalar* target)
    409: {
    410:   PetscFunctionBegin;
    412:   PetscAssertPointer(target,2);
    413:   *target = eps->target;
    414:   PetscFunctionReturn(PETSC_SUCCESS);
    415: }

    417: /*@
    418:    EPSSetInterval - Defines the computational interval for spectrum slicing.

    420:    Logically Collective

    422:    Input Parameters:
    423: +  eps  - eigensolver context
    424: .  inta - left end of the interval
    425: -  intb - right end of the interval

    427:    Options Database Key:
    428: .  -eps_interval <a,b> - set [a,b] as the interval of interest

    430:    Notes:
    431:    Spectrum slicing is a technique employed for computing all eigenvalues of
    432:    symmetric eigenproblems in a given interval. This function provides the
    433:    interval to be considered. It must be used in combination with EPS_ALL, see
    434:    EPSSetWhichEigenpairs().

    436:    In the command-line option, two values must be provided. For an open interval,
    437:    one can give an infinite, e.g., -eps_interval 1.0,inf or -eps_interval -inf,1.0.
    438:    An open interval in the programmatic interface can be specified with
    439:    PETSC_MAX_REAL and -PETSC_MAX_REAL.

    441:    Level: intermediate

    443: .seealso: EPSGetInterval(), EPSSetWhichEigenpairs()
    444: @*/
    445: PetscErrorCode EPSSetInterval(EPS eps,PetscReal inta,PetscReal intb)
    446: {
    447:   PetscFunctionBegin;
    451:   PetscCheck(inta<intb,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_WRONG,"Badly defined interval, must be inta<intb");
    452:   if (eps->inta != inta || eps->intb != intb) {
    453:     eps->inta = inta;
    454:     eps->intb = intb;
    455:     eps->state = EPS_STATE_INITIAL;
    456:   }
    457:   PetscFunctionReturn(PETSC_SUCCESS);
    458: }

    460: /*@
    461:    EPSGetInterval - Gets the computational interval for spectrum slicing.

    463:    Not Collective

    465:    Input Parameter:
    466: .  eps - eigensolver context

    468:    Output Parameters:
    469: +  inta - left end of the interval
    470: -  intb - right end of the interval

    472:    Level: intermediate

    474:    Note:
    475:    If the interval was not set by the user, then zeros are returned.

    477: .seealso: EPSSetInterval()
    478: @*/
    479: PetscErrorCode EPSGetInterval(EPS eps,PetscReal* inta,PetscReal* intb)
    480: {
    481:   PetscFunctionBegin;
    483:   if (inta) *inta = eps->inta;
    484:   if (intb) *intb = eps->intb;
    485:   PetscFunctionReturn(PETSC_SUCCESS);
    486: }

    488: /*@
    489:    EPSSetST - Associates a spectral transformation object to the eigensolver.

    491:    Collective

    493:    Input Parameters:
    494: +  eps - eigensolver context obtained from EPSCreate()
    495: -  st   - the spectral transformation object

    497:    Note:
    498:    Use EPSGetST() to retrieve the spectral transformation context (for example,
    499:    to free it at the end of the computations).

    501:    Level: advanced

    503: .seealso: EPSGetST()
    504: @*/
    505: PetscErrorCode EPSSetST(EPS eps,ST st)
    506: {
    507:   PetscFunctionBegin;
    510:   PetscCheckSameComm(eps,1,st,2);
    511:   PetscCall(PetscObjectReference((PetscObject)st));
    512:   PetscCall(STDestroy(&eps->st));
    513:   eps->st = st;
    514:   PetscFunctionReturn(PETSC_SUCCESS);
    515: }

    517: /*@
    518:    EPSGetST - Obtain the spectral transformation (ST) object associated
    519:    to the eigensolver object.

    521:    Not Collective

    523:    Input Parameters:
    524: .  eps - eigensolver context obtained from EPSCreate()

    526:    Output Parameter:
    527: .  st - spectral transformation context

    529:    Level: intermediate

    531: .seealso: EPSSetST()
    532: @*/
    533: PetscErrorCode EPSGetST(EPS eps,ST *st)
    534: {
    535:   PetscFunctionBegin;
    537:   PetscAssertPointer(st,2);
    538:   if (!eps->st) {
    539:     PetscCall(STCreate(PetscObjectComm((PetscObject)eps),&eps->st));
    540:     PetscCall(PetscObjectIncrementTabLevel((PetscObject)eps->st,(PetscObject)eps,0));
    541:     PetscCall(PetscObjectSetOptions((PetscObject)eps->st,((PetscObject)eps)->options));
    542:   }
    543:   *st = eps->st;
    544:   PetscFunctionReturn(PETSC_SUCCESS);
    545: }

    547: /*@
    548:    EPSSetBV - Associates a basis vectors object to the eigensolver.

    550:    Collective

    552:    Input Parameters:
    553: +  eps - eigensolver context obtained from EPSCreate()
    554: -  V   - the basis vectors object

    556:    Level: advanced

    558: .seealso: EPSGetBV()
    559: @*/
    560: PetscErrorCode EPSSetBV(EPS eps,BV V)
    561: {
    562:   PetscFunctionBegin;
    565:   PetscCheckSameComm(eps,1,V,2);
    566:   PetscCall(PetscObjectReference((PetscObject)V));
    567:   PetscCall(BVDestroy(&eps->V));
    568:   eps->V = V;
    569:   PetscFunctionReturn(PETSC_SUCCESS);
    570: }

    572: /*@
    573:    EPSGetBV - Obtain the basis vectors object associated to the eigensolver object.

    575:    Not Collective

    577:    Input Parameters:
    578: .  eps - eigensolver context obtained from EPSCreate()

    580:    Output Parameter:
    581: .  V - basis vectors context

    583:    Level: advanced

    585: .seealso: EPSSetBV()
    586: @*/
    587: PetscErrorCode EPSGetBV(EPS eps,BV *V)
    588: {
    589:   PetscFunctionBegin;
    591:   PetscAssertPointer(V,2);
    592:   if (!eps->V) {
    593:     PetscCall(BVCreate(PetscObjectComm((PetscObject)eps),&eps->V));
    594:     PetscCall(PetscObjectIncrementTabLevel((PetscObject)eps->V,(PetscObject)eps,0));
    595:     PetscCall(PetscObjectSetOptions((PetscObject)eps->V,((PetscObject)eps)->options));
    596:   }
    597:   *V = eps->V;
    598:   PetscFunctionReturn(PETSC_SUCCESS);
    599: }

    601: /*@
    602:    EPSSetRG - Associates a region object to the eigensolver.

    604:    Collective

    606:    Input Parameters:
    607: +  eps - eigensolver context obtained from EPSCreate()
    608: -  rg  - the region object

    610:    Note:
    611:    Use EPSGetRG() to retrieve the region context (for example,
    612:    to free it at the end of the computations).

    614:    Level: advanced

    616: .seealso: EPSGetRG()
    617: @*/
    618: PetscErrorCode EPSSetRG(EPS eps,RG rg)
    619: {
    620:   PetscFunctionBegin;
    622:   if (rg) {
    624:     PetscCheckSameComm(eps,1,rg,2);
    625:   }
    626:   PetscCall(PetscObjectReference((PetscObject)rg));
    627:   PetscCall(RGDestroy(&eps->rg));
    628:   eps->rg = rg;
    629:   PetscFunctionReturn(PETSC_SUCCESS);
    630: }

    632: /*@
    633:    EPSGetRG - Obtain the region object associated to the eigensolver.

    635:    Not Collective

    637:    Input Parameters:
    638: .  eps - eigensolver context obtained from EPSCreate()

    640:    Output Parameter:
    641: .  rg - region context

    643:    Level: advanced

    645: .seealso: EPSSetRG()
    646: @*/
    647: PetscErrorCode EPSGetRG(EPS eps,RG *rg)
    648: {
    649:   PetscFunctionBegin;
    651:   PetscAssertPointer(rg,2);
    652:   if (!eps->rg) {
    653:     PetscCall(RGCreate(PetscObjectComm((PetscObject)eps),&eps->rg));
    654:     PetscCall(PetscObjectIncrementTabLevel((PetscObject)eps->rg,(PetscObject)eps,0));
    655:     PetscCall(PetscObjectSetOptions((PetscObject)eps->rg,((PetscObject)eps)->options));
    656:   }
    657:   *rg = eps->rg;
    658:   PetscFunctionReturn(PETSC_SUCCESS);
    659: }

    661: /*@
    662:    EPSSetDS - Associates a direct solver object to the eigensolver.

    664:    Collective

    666:    Input Parameters:
    667: +  eps - eigensolver context obtained from EPSCreate()
    668: -  ds  - the direct solver object

    670:    Note:
    671:    Use EPSGetDS() to retrieve the direct solver context (for example,
    672:    to free it at the end of the computations).

    674:    Level: advanced

    676: .seealso: EPSGetDS()
    677: @*/
    678: PetscErrorCode EPSSetDS(EPS eps,DS ds)
    679: {
    680:   PetscFunctionBegin;
    683:   PetscCheckSameComm(eps,1,ds,2);
    684:   PetscCall(PetscObjectReference((PetscObject)ds));
    685:   PetscCall(DSDestroy(&eps->ds));
    686:   eps->ds = ds;
    687:   PetscFunctionReturn(PETSC_SUCCESS);
    688: }

    690: /*@
    691:    EPSGetDS - Obtain the direct solver object associated to the eigensolver object.

    693:    Not Collective

    695:    Input Parameters:
    696: .  eps - eigensolver context obtained from EPSCreate()

    698:    Output Parameter:
    699: .  ds - direct solver context

    701:    Level: advanced

    703: .seealso: EPSSetDS()
    704: @*/
    705: PetscErrorCode EPSGetDS(EPS eps,DS *ds)
    706: {
    707:   PetscFunctionBegin;
    709:   PetscAssertPointer(ds,2);
    710:   if (!eps->ds) {
    711:     PetscCall(DSCreate(PetscObjectComm((PetscObject)eps),&eps->ds));
    712:     PetscCall(PetscObjectIncrementTabLevel((PetscObject)eps->ds,(PetscObject)eps,0));
    713:     PetscCall(PetscObjectSetOptions((PetscObject)eps->ds,((PetscObject)eps)->options));
    714:   }
    715:   *ds = eps->ds;
    716:   PetscFunctionReturn(PETSC_SUCCESS);
    717: }

    719: /*@
    720:    EPSIsGeneralized - Ask if the EPS object corresponds to a generalized
    721:    eigenvalue problem.

    723:    Not Collective

    725:    Input Parameter:
    726: .  eps - the eigenproblem solver context

    728:    Output Parameter:
    729: .  is - the answer

    731:    Level: intermediate

    733: .seealso: EPSIsHermitian(), EPSIsPositive()
    734: @*/
    735: PetscErrorCode EPSIsGeneralized(EPS eps,PetscBool* is)
    736: {
    737:   PetscFunctionBegin;
    739:   PetscAssertPointer(is,2);
    740:   *is = eps->isgeneralized;
    741:   PetscFunctionReturn(PETSC_SUCCESS);
    742: }

    744: /*@
    745:    EPSIsHermitian - Ask if the EPS object corresponds to a Hermitian
    746:    eigenvalue problem.

    748:    Not Collective

    750:    Input Parameter:
    751: .  eps - the eigenproblem solver context

    753:    Output Parameter:
    754: .  is - the answer

    756:    Level: intermediate

    758: .seealso: EPSIsGeneralized(), EPSIsPositive()
    759: @*/
    760: PetscErrorCode EPSIsHermitian(EPS eps,PetscBool* is)
    761: {
    762:   PetscFunctionBegin;
    764:   PetscAssertPointer(is,2);
    765:   *is = eps->ishermitian;
    766:   PetscFunctionReturn(PETSC_SUCCESS);
    767: }

    769: /*@
    770:    EPSIsPositive - Ask if the EPS object corresponds to an eigenvalue
    771:    problem type that requires a positive (semi-) definite matrix B.

    773:    Not Collective

    775:    Input Parameter:
    776: .  eps - the eigenproblem solver context

    778:    Output Parameter:
    779: .  is - the answer

    781:    Level: intermediate

    783: .seealso: EPSIsGeneralized(), EPSIsHermitian()
    784: @*/
    785: PetscErrorCode EPSIsPositive(EPS eps,PetscBool* is)
    786: {
    787:   PetscFunctionBegin;
    789:   PetscAssertPointer(is,2);
    790:   *is = eps->ispositive;
    791:   PetscFunctionReturn(PETSC_SUCCESS);
    792: }