Date: 2024-12-02T08:57:36+00:00

Actual source code: pepbasic.c
slepc-3.22.2 2024-12-02
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 PEP routines
     12: */

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

     16: /* Logging support */
     17: PetscClassId      PEP_CLASSID = 0;
     18: PetscLogEvent     PEP_SetUp = 0,PEP_Solve = 0,PEP_Refine = 0,PEP_CISS_SVD = 0;

     20: /* List of registered PEP routines */
     21: PetscFunctionList PEPList = NULL;
     22: PetscBool         PEPRegisterAllCalled = PETSC_FALSE;

     24: /* List of registered PEP monitors */
     25: PetscFunctionList PEPMonitorList              = NULL;
     26: PetscFunctionList PEPMonitorCreateList        = NULL;
     27: PetscFunctionList PEPMonitorDestroyList       = NULL;
     28: PetscBool         PEPMonitorRegisterAllCalled = PETSC_FALSE;

     30: /*@
     31:    PEPCreate - Creates the default PEP context.

     33:    Collective

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

     38:    Output Parameter:
     39: .  outpep - location to put the PEP context

     41:    Note:
     42:    The default PEP type is PEPTOAR

     44:    Level: beginner

     46: .seealso: PEPSetUp(), PEPSolve(), PEPDestroy(), PEP
     47: @*/
     48: PetscErrorCode PEPCreate(MPI_Comm comm,PEP *outpep)
     49: {
     50:   PEP            pep;

     52:   PetscFunctionBegin;
     53:   PetscAssertPointer(outpep,2);
     54:   PetscCall(PEPInitializePackage());
     55:   PetscCall(SlepcHeaderCreate(pep,PEP_CLASSID,"PEP","Polynomial Eigenvalue Problem","PEP",comm,PEPDestroy,PEPView));

     57:   pep->max_it          = PETSC_DETERMINE;
     58:   pep->nev             = 1;
     59:   pep->ncv             = PETSC_DETERMINE;
     60:   pep->mpd             = PETSC_DETERMINE;
     61:   pep->nini            = 0;
     62:   pep->target          = 0.0;
     63:   pep->tol             = PETSC_DETERMINE;
     64:   pep->conv            = PEP_CONV_REL;
     65:   pep->stop            = PEP_STOP_BASIC;
     66:   pep->which           = (PEPWhich)0;
     67:   pep->basis           = PEP_BASIS_MONOMIAL;
     68:   pep->problem_type    = (PEPProblemType)0;
     69:   pep->scale           = PEP_SCALE_NONE;
     70:   pep->sfactor         = 1.0;
     71:   pep->dsfactor        = 1.0;
     72:   pep->sits            = 5;
     73:   pep->slambda         = 1.0;
     74:   pep->refine          = PEP_REFINE_NONE;
     75:   pep->npart           = 1;
     76:   pep->rtol            = PETSC_DETERMINE;
     77:   pep->rits            = PETSC_DETERMINE;
     78:   pep->scheme          = (PEPRefineScheme)0;
     79:   pep->extract         = (PEPExtract)0;
     80:   pep->trackall        = PETSC_FALSE;

     82:   pep->converged       = PEPConvergedRelative;
     83:   pep->convergeduser   = NULL;
     84:   pep->convergeddestroy= NULL;
     85:   pep->stopping        = PEPStoppingBasic;
     86:   pep->stoppinguser    = NULL;
     87:   pep->stoppingdestroy = NULL;
     88:   pep->convergedctx    = NULL;
     89:   pep->stoppingctx     = NULL;
     90:   pep->numbermonitors  = 0;

     92:   pep->st              = NULL;
     93:   pep->ds              = NULL;
     94:   pep->V               = NULL;
     95:   pep->rg              = NULL;
     96:   pep->A               = NULL;
     97:   pep->nmat            = 0;
     98:   pep->Dl              = NULL;
     99:   pep->Dr              = NULL;
    100:   pep->IS              = NULL;
    101:   pep->eigr            = NULL;
    102:   pep->eigi            = NULL;
    103:   pep->errest          = NULL;
    104:   pep->perm            = NULL;
    105:   pep->pbc             = NULL;
    106:   pep->solvematcoeffs  = NULL;
    107:   pep->nwork           = 0;
    108:   pep->work            = NULL;
    109:   pep->refineksp       = NULL;
    110:   pep->refinesubc      = NULL;
    111:   pep->data            = NULL;

    113:   pep->state           = PEP_STATE_INITIAL;
    114:   pep->nconv           = 0;
    115:   pep->its             = 0;
    116:   pep->n               = 0;
    117:   pep->nloc            = 0;
    118:   pep->nrma            = NULL;
    119:   pep->sfactor_set     = PETSC_FALSE;
    120:   pep->lineariz        = PETSC_FALSE;
    121:   pep->reason          = PEP_CONVERGED_ITERATING;

    123:   PetscCall(PetscNew(&pep->sc));
    124:   *outpep = pep;
    125:   PetscFunctionReturn(PETSC_SUCCESS);
    126: }

    128: /*@
    129:    PEPSetType - Selects the particular solver to be used in the PEP object.

    131:    Logically Collective

    133:    Input Parameters:
    134: +  pep      - the polynomial eigensolver context
    135: -  type     - a known method

    137:    Options Database Key:
    138: .  -pep_type <method> - Sets the method; use -help for a list
    139:     of available methods

    141:    Notes:
    142:    See "slepc/include/slepcpep.h" for available methods. The default
    143:    is PEPTOAR.

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

    153:    Level: intermediate

    155: .seealso: PEPType
    156: @*/
    157: PetscErrorCode PEPSetType(PEP pep,PEPType type)
    158: {
    159:   PetscErrorCode (*r)(PEP);
    160:   PetscBool      match;

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

    166:   PetscCall(PetscObjectTypeCompare((PetscObject)pep,type,&match));
    167:   if (match) PetscFunctionReturn(PETSC_SUCCESS);

    169:   PetscCall(PetscFunctionListFind(PEPList,type,&r));
    170:   PetscCheck(r,PetscObjectComm((PetscObject)pep),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown PEP type given: %s",type);

    172:   PetscTryTypeMethod(pep,destroy);
    173:   PetscCall(PetscMemzero(pep->ops,sizeof(struct _PEPOps)));

    175:   pep->state = PEP_STATE_INITIAL;
    176:   PetscCall(PetscObjectChangeTypeName((PetscObject)pep,type));
    177:   PetscCall((*r)(pep));
    178:   PetscFunctionReturn(PETSC_SUCCESS);
    179: }

    181: /*@
    182:    PEPGetType - Gets the PEP type as a string from the PEP object.

    184:    Not Collective

    186:    Input Parameter:
    187: .  pep - the eigensolver context

    189:    Output Parameter:
    190: .  type - name of PEP method

    192:    Level: intermediate

    194: .seealso: PEPSetType()
    195: @*/
    196: PetscErrorCode PEPGetType(PEP pep,PEPType *type)
    197: {
    198:   PetscFunctionBegin;
    200:   PetscAssertPointer(type,2);
    201:   *type = ((PetscObject)pep)->type_name;
    202:   PetscFunctionReturn(PETSC_SUCCESS);
    203: }

    205: /*@C
    206:    PEPRegister - Adds a method to the polynomial eigenproblem solver package.

    208:    Not Collective

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

    214:    Notes:
    215:    PEPRegister() may be called multiple times to add several user-defined solvers.

    217:    Example Usage:
    218: .vb
    219:     PEPRegister("my_solver",MySolverCreate);
    220: .ve

    222:    Then, your solver can be chosen with the procedural interface via
    223: $     PEPSetType(pep,"my_solver")
    224:    or at runtime via the option
    225: $     -pep_type my_solver

    227:    Level: advanced

    229: .seealso: PEPRegisterAll()
    230: @*/
    231: PetscErrorCode PEPRegister(const char *name,PetscErrorCode (*function)(PEP))
    232: {
    233:   PetscFunctionBegin;
    234:   PetscCall(PEPInitializePackage());
    235:   PetscCall(PetscFunctionListAdd(&PEPList,name,function));
    236:   PetscFunctionReturn(PETSC_SUCCESS);
    237: }

    239: /*@C
    240:    PEPMonitorRegister - Adds PEP monitor routine.

    242:    Not Collective

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

    252:    Notes:
    253:    PEPMonitorRegister() may be called multiple times to add several user-defined monitors.

    255:    Example Usage:
    256: .vb
    257:    PEPMonitorRegister("my_monitor",PETSCVIEWERASCII,PETSC_VIEWER_ASCII_INFO_DETAIL,MyMonitor,NULL,NULL);
    258: .ve

    260:    Then, your monitor can be chosen with the procedural interface via
    261: $      PEPMonitorSetFromOptions(pep,"-pep_monitor_my_monitor","my_monitor",NULL)
    262:    or at runtime via the option
    263: $      -pep_monitor_my_monitor

    265:    Level: advanced

    267: .seealso: PEPMonitorRegisterAll()
    268: @*/
    269: PetscErrorCode PEPMonitorRegister(const char name[],PetscViewerType vtype,PetscViewerFormat format,PetscErrorCode (*monitor)(PEP,PetscInt,PetscInt,PetscScalar*,PetscScalar*,PetscReal*,PetscInt,PetscViewerAndFormat*),PetscErrorCode (*create)(PetscViewer,PetscViewerFormat,void*,PetscViewerAndFormat**),PetscErrorCode (*destroy)(PetscViewerAndFormat**))
    270: {
    271:   char           key[PETSC_MAX_PATH_LEN];

    273:   PetscFunctionBegin;
    274:   PetscCall(PEPInitializePackage());
    275:   PetscCall(SlepcMonitorMakeKey_Internal(name,vtype,format,key));
    276:   PetscCall(PetscFunctionListAdd(&PEPMonitorList,key,monitor));
    277:   if (create)  PetscCall(PetscFunctionListAdd(&PEPMonitorCreateList,key,create));
    278:   if (destroy) PetscCall(PetscFunctionListAdd(&PEPMonitorDestroyList,key,destroy));
    279:   PetscFunctionReturn(PETSC_SUCCESS);
    280: }

    282: /*@
    283:    PEPReset - Resets the PEP context to the initial state (prior to setup)
    284:    and destroys any allocated Vecs and Mats.

    286:    Collective

    288:    Input Parameter:
    289: .  pep - eigensolver context obtained from PEPCreate()

    291:    Level: advanced

    293: .seealso: PEPDestroy()
    294: @*/
    295: PetscErrorCode PEPReset(PEP pep)
    296: {
    297:   PetscFunctionBegin;
    299:   if (!pep) PetscFunctionReturn(PETSC_SUCCESS);
    300:   PetscTryTypeMethod(pep,reset);
    301:   if (pep->st) PetscCall(STReset(pep->st));
    302:   if (pep->refineksp) PetscCall(KSPReset(pep->refineksp));
    303:   if (pep->nmat) {
    304:     PetscCall(MatDestroyMatrices(pep->nmat,&pep->A));
    305:     PetscCall(PetscFree2(pep->pbc,pep->nrma));
    306:     PetscCall(PetscFree(pep->solvematcoeffs));
    307:     pep->nmat = 0;
    308:   }
    309:   PetscCall(VecDestroy(&pep->Dl));
    310:   PetscCall(VecDestroy(&pep->Dr));
    311:   PetscCall(BVDestroy(&pep->V));
    312:   PetscCall(VecDestroyVecs(pep->nwork,&pep->work));
    313:   pep->nwork = 0;
    314:   pep->state = PEP_STATE_INITIAL;
    315:   PetscFunctionReturn(PETSC_SUCCESS);
    316: }

    318: /*@
    319:    PEPDestroy - Destroys the PEP context.

    321:    Collective

    323:    Input Parameter:
    324: .  pep - eigensolver context obtained from PEPCreate()

    326:    Level: beginner

    328: .seealso: PEPCreate(), PEPSetUp(), PEPSolve()
    329: @*/
    330: PetscErrorCode PEPDestroy(PEP *pep)
    331: {
    332:   PetscFunctionBegin;
    333:   if (!*pep) PetscFunctionReturn(PETSC_SUCCESS);
    335:   if (--((PetscObject)*pep)->refct > 0) { *pep = NULL; PetscFunctionReturn(PETSC_SUCCESS); }
    336:   PetscCall(PEPReset(*pep));
    337:   PetscTryTypeMethod(*pep,destroy);
    338:   if ((*pep)->eigr) PetscCall(PetscFree4((*pep)->eigr,(*pep)->eigi,(*pep)->errest,(*pep)->perm));
    339:   PetscCall(STDestroy(&(*pep)->st));
    340:   PetscCall(RGDestroy(&(*pep)->rg));
    341:   PetscCall(DSDestroy(&(*pep)->ds));
    342:   PetscCall(KSPDestroy(&(*pep)->refineksp));
    343:   PetscCall(PetscSubcommDestroy(&(*pep)->refinesubc));
    344:   PetscCall(PetscFree((*pep)->sc));
    345:   /* just in case the initial vectors have not been used */
    346:   PetscCall(SlepcBasisDestroy_Private(&(*pep)->nini,&(*pep)->IS));
    347:   if ((*pep)->convergeddestroy) PetscCall((*(*pep)->convergeddestroy)((*pep)->convergedctx));
    348:   PetscCall(PEPMonitorCancel(*pep));
    349:   PetscCall(PetscHeaderDestroy(pep));
    350:   PetscFunctionReturn(PETSC_SUCCESS);
    351: }

    353: /*@
    354:    PEPSetBV - Associates a basis vectors object to the polynomial eigensolver.

    356:    Collective

    358:    Input Parameters:
    359: +  pep - eigensolver context obtained from PEPCreate()
    360: -  bv  - the basis vectors object

    362:    Note:
    363:    Use PEPGetBV() to retrieve the basis vectors context (for example,
    364:    to free it at the end of the computations).

    366:    Level: advanced

    368: .seealso: PEPGetBV()
    369: @*/
    370: PetscErrorCode PEPSetBV(PEP pep,BV bv)
    371: {
    372:   PetscFunctionBegin;
    375:   PetscCheckSameComm(pep,1,bv,2);
    376:   PetscCall(PetscObjectReference((PetscObject)bv));
    377:   PetscCall(BVDestroy(&pep->V));
    378:   pep->V = bv;
    379:   PetscFunctionReturn(PETSC_SUCCESS);
    380: }

    382: /*@
    383:    PEPGetBV - Obtain the basis vectors object associated to the polynomial
    384:    eigensolver object.

    386:    Not Collective

    388:    Input Parameters:
    389: .  pep - eigensolver context obtained from PEPCreate()

    391:    Output Parameter:
    392: .  bv - basis vectors context

    394:    Level: advanced

    396: .seealso: PEPSetBV()
    397: @*/
    398: PetscErrorCode PEPGetBV(PEP pep,BV *bv)
    399: {
    400:   PetscFunctionBegin;
    402:   PetscAssertPointer(bv,2);
    403:   if (!pep->V) {
    404:     PetscCall(BVCreate(PetscObjectComm((PetscObject)pep),&pep->V));
    405:     PetscCall(PetscObjectIncrementTabLevel((PetscObject)pep->V,(PetscObject)pep,0));
    406:     PetscCall(PetscObjectSetOptions((PetscObject)pep->V,((PetscObject)pep)->options));
    407:   }
    408:   *bv = pep->V;
    409:   PetscFunctionReturn(PETSC_SUCCESS);
    410: }

    412: /*@
    413:    PEPSetRG - Associates a region object to the polynomial eigensolver.

    415:    Collective

    417:    Input Parameters:
    418: +  pep - eigensolver context obtained from PEPCreate()
    419: -  rg  - the region object

    421:    Note:
    422:    Use PEPGetRG() to retrieve the region context (for example,
    423:    to free it at the end of the computations).

    425:    Level: advanced

    427: .seealso: PEPGetRG()
    428: @*/
    429: PetscErrorCode PEPSetRG(PEP pep,RG rg)
    430: {
    431:   PetscFunctionBegin;
    433:   if (rg) {
    435:     PetscCheckSameComm(pep,1,rg,2);
    436:   }
    437:   PetscCall(PetscObjectReference((PetscObject)rg));
    438:   PetscCall(RGDestroy(&pep->rg));
    439:   pep->rg = rg;
    440:   PetscFunctionReturn(PETSC_SUCCESS);
    441: }

    443: /*@
    444:    PEPGetRG - Obtain the region object associated to the
    445:    polynomial eigensolver object.

    447:    Not Collective

    449:    Input Parameters:
    450: .  pep - eigensolver context obtained from PEPCreate()

    452:    Output Parameter:
    453: .  rg - region context

    455:    Level: advanced

    457: .seealso: PEPSetRG()
    458: @*/
    459: PetscErrorCode PEPGetRG(PEP pep,RG *rg)
    460: {
    461:   PetscFunctionBegin;
    463:   PetscAssertPointer(rg,2);
    464:   if (!pep->rg) {
    465:     PetscCall(RGCreate(PetscObjectComm((PetscObject)pep),&pep->rg));
    466:     PetscCall(PetscObjectIncrementTabLevel((PetscObject)pep->rg,(PetscObject)pep,0));
    467:     PetscCall(PetscObjectSetOptions((PetscObject)pep->rg,((PetscObject)pep)->options));
    468:   }
    469:   *rg = pep->rg;
    470:   PetscFunctionReturn(PETSC_SUCCESS);
    471: }

    473: /*@
    474:    PEPSetDS - Associates a direct solver object to the polynomial eigensolver.

    476:    Collective

    478:    Input Parameters:
    479: +  pep - eigensolver context obtained from PEPCreate()
    480: -  ds  - the direct solver object

    482:    Note:
    483:    Use PEPGetDS() to retrieve the direct solver context (for example,
    484:    to free it at the end of the computations).

    486:    Level: advanced

    488: .seealso: PEPGetDS()
    489: @*/
    490: PetscErrorCode PEPSetDS(PEP pep,DS ds)
    491: {
    492:   PetscFunctionBegin;
    495:   PetscCheckSameComm(pep,1,ds,2);
    496:   PetscCall(PetscObjectReference((PetscObject)ds));
    497:   PetscCall(DSDestroy(&pep->ds));
    498:   pep->ds = ds;
    499:   PetscFunctionReturn(PETSC_SUCCESS);
    500: }

    502: /*@
    503:    PEPGetDS - Obtain the direct solver object associated to the
    504:    polynomial eigensolver object.

    506:    Not Collective

    508:    Input Parameters:
    509: .  pep - eigensolver context obtained from PEPCreate()

    511:    Output Parameter:
    512: .  ds - direct solver context

    514:    Level: advanced

    516: .seealso: PEPSetDS()
    517: @*/
    518: PetscErrorCode PEPGetDS(PEP pep,DS *ds)
    519: {
    520:   PetscFunctionBegin;
    522:   PetscAssertPointer(ds,2);
    523:   if (!pep->ds) {
    524:     PetscCall(DSCreate(PetscObjectComm((PetscObject)pep),&pep->ds));
    525:     PetscCall(PetscObjectIncrementTabLevel((PetscObject)pep->ds,(PetscObject)pep,0));
    526:     PetscCall(PetscObjectSetOptions((PetscObject)pep->ds,((PetscObject)pep)->options));
    527:   }
    528:   *ds = pep->ds;
    529:   PetscFunctionReturn(PETSC_SUCCESS);
    530: }

    532: /*@
    533:    PEPSetST - Associates a spectral transformation object to the eigensolver.

    535:    Collective

    537:    Input Parameters:
    538: +  pep - eigensolver context obtained from PEPCreate()
    539: -  st   - the spectral transformation object

    541:    Note:
    542:    Use PEPGetST() to retrieve the spectral transformation context (for example,
    543:    to free it at the end of the computations).

    545:    Level: advanced

    547: .seealso: PEPGetST()
    548: @*/
    549: PetscErrorCode PEPSetST(PEP pep,ST st)
    550: {
    551:   PetscFunctionBegin;
    554:   PetscCheckSameComm(pep,1,st,2);
    555:   PetscCall(PetscObjectReference((PetscObject)st));
    556:   PetscCall(STDestroy(&pep->st));
    557:   pep->st = st;
    558:   PetscFunctionReturn(PETSC_SUCCESS);
    559: }

    561: /*@
    562:    PEPGetST - Obtain the spectral transformation (ST) object associated
    563:    to the eigensolver object.

    565:    Not Collective

    567:    Input Parameters:
    568: .  pep - eigensolver context obtained from PEPCreate()

    570:    Output Parameter:
    571: .  st - spectral transformation context

    573:    Level: intermediate

    575: .seealso: PEPSetST()
    576: @*/
    577: PetscErrorCode PEPGetST(PEP pep,ST *st)
    578: {
    579:   PetscFunctionBegin;
    581:   PetscAssertPointer(st,2);
    582:   if (!pep->st) {
    583:     PetscCall(STCreate(PetscObjectComm((PetscObject)pep),&pep->st));
    584:     PetscCall(PetscObjectIncrementTabLevel((PetscObject)pep->st,(PetscObject)pep,0));
    585:     PetscCall(PetscObjectSetOptions((PetscObject)pep->st,((PetscObject)pep)->options));
    586:   }
    587:   *st = pep->st;
    588:   PetscFunctionReturn(PETSC_SUCCESS);
    589: }

    591: /*@
    592:    PEPRefineGetKSP - Obtain the ksp object used by the eigensolver
    593:    object in the refinement phase.

    595:    Collective

    597:    Input Parameters:
    598: .  pep - eigensolver context obtained from PEPCreate()

    600:    Output Parameter:
    601: .  ksp - ksp context

    603:    Level: advanced

    605: .seealso: PEPSetRefine()
    606: @*/
    607: PetscErrorCode PEPRefineGetKSP(PEP pep,KSP *ksp)
    608: {
    609:   MPI_Comm       comm;

    611:   PetscFunctionBegin;
    613:   PetscAssertPointer(ksp,2);
    614:   if (!pep->refineksp) {
    615:     if (pep->npart>1) {
    616:       /* Split in subcomunicators */
    617:       PetscCall(PetscSubcommCreate(PetscObjectComm((PetscObject)pep),&pep->refinesubc));
    618:       PetscCall(PetscSubcommSetNumber(pep->refinesubc,pep->npart));
    619:       PetscCall(PetscSubcommSetType(pep->refinesubc,PETSC_SUBCOMM_CONTIGUOUS));
    620:       PetscCall(PetscSubcommGetChild(pep->refinesubc,&comm));
    621:     } else PetscCall(PetscObjectGetComm((PetscObject)pep,&comm));
    622:     PetscCall(KSPCreate(comm,&pep->refineksp));
    623:     PetscCall(PetscObjectIncrementTabLevel((PetscObject)pep->refineksp,(PetscObject)pep,0));
    624:     PetscCall(PetscObjectSetOptions((PetscObject)pep->refineksp,((PetscObject)pep)->options));
    625:     PetscCall(KSPSetOptionsPrefix(*ksp,((PetscObject)pep)->prefix));
    626:     PetscCall(KSPAppendOptionsPrefix(*ksp,"pep_refine_"));
    627:     PetscCall(KSPSetTolerances(pep->refineksp,SlepcDefaultTol(pep->rtol),PETSC_CURRENT,PETSC_CURRENT,PETSC_CURRENT));
    628:   }
    629:   *ksp = pep->refineksp;
    630:   PetscFunctionReturn(PETSC_SUCCESS);
    631: }

    633: /*@
    634:    PEPSetTarget - Sets the value of the target.

    636:    Logically Collective

    638:    Input Parameters:
    639: +  pep    - eigensolver context
    640: -  target - the value of the target

    642:    Options Database Key:
    643: .  -pep_target <scalar> - the value of the target

    645:    Notes:
    646:    The target is a scalar value used to determine the portion of the spectrum
    647:    of interest. It is used in combination with PEPSetWhichEigenpairs().

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

    653:    Level: intermediate

    655: .seealso: PEPGetTarget(), PEPSetWhichEigenpairs()
    656: @*/
    657: PetscErrorCode PEPSetTarget(PEP pep,PetscScalar target)
    658: {
    659:   PetscFunctionBegin;
    662:   pep->target = target;
    663:   if (!pep->st) PetscCall(PEPGetST(pep,&pep->st));
    664:   PetscCall(STSetDefaultShift(pep->st,target));
    665:   PetscFunctionReturn(PETSC_SUCCESS);
    666: }

    668: /*@
    669:    PEPGetTarget - Gets the value of the target.

    671:    Not Collective

    673:    Input Parameter:
    674: .  pep - eigensolver context

    676:    Output Parameter:
    677: .  target - the value of the target

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

    682:    Level: intermediate

    684: .seealso: PEPSetTarget()
    685: @*/
    686: PetscErrorCode PEPGetTarget(PEP pep,PetscScalar* target)
    687: {
    688:   PetscFunctionBegin;
    690:   PetscAssertPointer(target,2);
    691:   *target = pep->target;
    692:   PetscFunctionReturn(PETSC_SUCCESS);
    693: }

    695: /*@
    696:    PEPSetInterval - Defines the computational interval for spectrum slicing.

    698:    Logically Collective

    700:    Input Parameters:
    701: +  pep  - eigensolver context
    702: .  inta - left end of the interval
    703: -  intb - right end of the interval

    705:    Options Database Key:
    706: .  -pep_interval <a,b> - set [a,b] as the interval of interest

    708:    Notes:
    709:    Spectrum slicing is a technique employed for computing all eigenvalues of
    710:    symmetric eigenproblems in a given interval. This function provides the
    711:    interval to be considered. It must be used in combination with PEP_ALL, see
    712:    PEPSetWhichEigenpairs().

    714:    In the command-line option, two values must be provided. For an open interval,
    715:    one can give an infinite, e.g., -pep_interval 1.0,inf or -pep_interval -inf,1.0.
    716:    An open interval in the programmatic interface can be specified with
    717:    PETSC_MAX_REAL and -PETSC_MAX_REAL.

    719:    Level: intermediate

    721: .seealso: PEPGetInterval(), PEPSetWhichEigenpairs()
    722: @*/
    723: PetscErrorCode PEPSetInterval(PEP pep,PetscReal inta,PetscReal intb)
    724: {
    725:   PetscFunctionBegin;
    729:   PetscCheck(inta<intb,PetscObjectComm((PetscObject)pep),PETSC_ERR_ARG_WRONG,"Badly defined interval, must be inta<intb");
    730:   if (pep->inta != inta || pep->intb != intb) {
    731:     pep->inta = inta;
    732:     pep->intb = intb;
    733:     pep->state = PEP_STATE_INITIAL;
    734:   }
    735:   PetscFunctionReturn(PETSC_SUCCESS);
    736: }

    738: /*@
    739:    PEPGetInterval - Gets the computational interval for spectrum slicing.

    741:    Not Collective

    743:    Input Parameter:
    744: .  pep - eigensolver context

    746:    Output Parameters:
    747: +  inta - left end of the interval
    748: -  intb - right end of the interval

    750:    Level: intermediate

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

    755: .seealso: PEPSetInterval()
    756: @*/
    757: PetscErrorCode PEPGetInterval(PEP pep,PetscReal* inta,PetscReal* intb)
    758: {
    759:   PetscFunctionBegin;
    761:   if (inta) *inta = pep->inta;
    762:   if (intb) *intb = pep->intb;
    763:   PetscFunctionReturn(PETSC_SUCCESS);
    764: }