Actual source code: pepbasic.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 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:   *outpep = NULL;
     55:   PetscCall(PEPInitializePackage());
     56:   PetscCall(SlepcHeaderCreate(pep,PEP_CLASSID,"PEP","Polynomial Eigenvalue Problem","PEP",comm,PEPDestroy,PEPView));

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

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

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

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

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

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

    132:    Logically Collective

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

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

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

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

    154:    Level: intermediate

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

    163:   PetscFunctionBegin;
    165:   PetscAssertPointer(type,2);

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

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

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

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

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

    185:    Not Collective

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

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

    193:    Level: intermediate

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

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

    209:    Not Collective

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

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

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

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

    228:    Level: advanced

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

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

    243:    Not Collective

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

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

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

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

    266:    Level: advanced

    268: .seealso: PEPMonitorRegisterAll()
    269: @*/
    270: 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**))
    271: {
    272:   char           key[PETSC_MAX_PATH_LEN];

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

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

    287:    Collective

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

    292:    Level: advanced

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

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

    322:    Collective

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

    327:    Level: beginner

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

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

    357:    Collective

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

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

    367:    Level: advanced

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

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

    387:    Not Collective

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

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

    395:    Level: advanced

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

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

    416:    Collective

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

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

    426:    Level: advanced

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

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

    448:    Not Collective

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

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

    456:    Level: advanced

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

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

    477:    Collective

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

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

    487:    Level: advanced

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

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

    507:    Not Collective

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

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

    515:    Level: advanced

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

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

    536:    Collective

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

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

    546:    Level: advanced

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

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

    566:    Not Collective

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

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

    574:    Level: intermediate

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

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

    596:    Collective

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

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

    604:    Level: advanced

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

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

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

    637:    Logically Collective

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

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

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

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

    654:    Level: intermediate

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

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

    672:    Not Collective

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

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

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

    683:    Level: intermediate

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

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

    699:    Logically Collective

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

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

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

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

    720:    Level: intermediate

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

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

    742:    Not Collective

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

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

    751:    Level: intermediate

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

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