Actual source code: pepbasic.c

slepc-3.15.1 2021-05-28
Report Typos and Errors
  1: /*
  2:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3:    SLEPc - Scalable Library for Eigenvalue Problem Computations
  4:    Copyright (c) 2002-2021, 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;

 20: /* List of registered PEP routines */
 21: PetscFunctionList PEPList = 0;
 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: .  pep - 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: {
 51:   PEP            pep;

 55:   *outpep = 0;
 56:   PEPInitializePackage();
 57:   SlepcHeaderCreate(pep,PEP_CLASSID,"PEP","Polynomial Eigenvalue Problem","PEP",comm,PEPDestroy,PEPView);

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

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

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

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

125:   PetscNewLog(pep,&pep->sc);
126:   *outpep = pep;
127:   return(0);
128: }

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

133:    Logically Collective on pep

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

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

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

147:    Normally, it is best to use the PEPSetFromOptions() command and
148:    then set the PEP 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 PEPSetType() 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: PEPType
158: @*/
159: PetscErrorCode PEPSetType(PEP pep,PEPType type)
160: {
161:   PetscErrorCode ierr,(*r)(PEP);
162:   PetscBool      match;


168:   PetscObjectTypeCompare((PetscObject)pep,type,&match);
169:   if (match) return(0);

171:   PetscFunctionListFind(PEPList,type,&r);
172:   if (!r) SETERRQ1(PetscObjectComm((PetscObject)pep),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown PEP type given: %s",type);

174:   if (pep->ops->destroy) { (*pep->ops->destroy)(pep); }
175:   PetscMemzero(pep->ops,sizeof(struct _PEPOps));

177:   pep->state = PEP_STATE_INITIAL;
178:   PetscObjectChangeTypeName((PetscObject)pep,type);
179:   (*r)(pep);
180:   return(0);
181: }

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

186:    Not Collective

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

191:    Output Parameter:
192: .  name - name of PEP method

194:    Level: intermediate

196: .seealso: PEPSetType()
197: @*/
198: PetscErrorCode PEPGetType(PEP pep,PEPType *type)
199: {
203:   *type = ((PetscObject)pep)->type_name;
204:   return(0);
205: }

207: /*@C
208:    PEPRegister - Adds a method to the polynomial 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:    PEPRegister() may be called multiple times to add several user-defined solvers.

219:    Sample usage:
220: .vb
221:     PEPRegister("my_solver",MySolverCreate);
222: .ve

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

229:    Level: advanced

231: .seealso: PEPRegisterAll()
232: @*/
233: PetscErrorCode PEPRegister(const char *name,PetscErrorCode (*function)(PEP))
234: {

238:   PEPInitializePackage();
239:   PetscFunctionListAdd(&PEPList,name,function);
240:   return(0);
241: }

243: /*@C
244:    PEPMonitorRegister - Adds PEP monitor routine.

246:    Not Collective

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

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

259:    Sample usage:
260: .vb
261:    PEPMonitorRegister("my_monitor",PETSCVIEWERASCII,PETSC_VIEWER_ASCII_INFO_DETAIL,MyMonitor,NULL,NULL);
262: .ve

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

269:    Level: advanced

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

279:   PEPInitializePackage();
280:   SlepcMonitorMakeKey_Internal(name,vtype,format,key);
281:   PetscFunctionListAdd(&PEPMonitorList,key,monitor);
282:   if (create)  { PetscFunctionListAdd(&PEPMonitorCreateList,key,create); }
283:   if (destroy) { PetscFunctionListAdd(&PEPMonitorDestroyList,key,destroy); }
284:   return(0);
285: }

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

291:    Collective on pep

293:    Input Parameter:
294: .  pep - eigensolver context obtained from PEPCreate()

296:    Level: advanced

298: .seealso: PEPDestroy()
299: @*/
300: PetscErrorCode PEPReset(PEP pep)
301: {

306:   if (!pep) return(0);
307:   if (pep->ops->reset) { (pep->ops->reset)(pep); }
308:   if (pep->st) { STReset(pep->st); }
309:   if (pep->refineksp) { KSPReset(pep->refineksp); }
310:   if (pep->nmat) {
311:     MatDestroyMatrices(pep->nmat,&pep->A);
312:     PetscFree2(pep->pbc,pep->nrma);
313:     PetscFree(pep->solvematcoeffs);
314:     pep->nmat = 0;
315:   }
316:   VecDestroy(&pep->Dl);
317:   VecDestroy(&pep->Dr);
318:   BVDestroy(&pep->V);
319:   VecDestroyVecs(pep->nwork,&pep->work);
320:   pep->nwork = 0;
321:   pep->state = PEP_STATE_INITIAL;
322:   return(0);
323: }

325: /*@C
326:    PEPDestroy - Destroys the PEP context.

328:    Collective on pep

330:    Input Parameter:
331: .  pep - eigensolver context obtained from PEPCreate()

333:    Level: beginner

335: .seealso: PEPCreate(), PEPSetUp(), PEPSolve()
336: @*/
337: PetscErrorCode PEPDestroy(PEP *pep)
338: {

342:   if (!*pep) return(0);
344:   if (--((PetscObject)(*pep))->refct > 0) { *pep = 0; return(0); }
345:   PEPReset(*pep);
346:   if ((*pep)->ops->destroy) { (*(*pep)->ops->destroy)(*pep); }
347:   if ((*pep)->eigr) {
348:     PetscFree4((*pep)->eigr,(*pep)->eigi,(*pep)->errest,(*pep)->perm);
349:   }
350:   STDestroy(&(*pep)->st);
351:   RGDestroy(&(*pep)->rg);
352:   DSDestroy(&(*pep)->ds);
353:   KSPDestroy(&(*pep)->refineksp);
354:   PetscSubcommDestroy(&(*pep)->refinesubc);
355:   PetscFree((*pep)->sc);
356:   /* just in case the initial vectors have not been used */
357:   SlepcBasisDestroy_Private(&(*pep)->nini,&(*pep)->IS);
358:   if ((*pep)->convergeddestroy) {
359:     (*(*pep)->convergeddestroy)((*pep)->convergedctx);
360:   }
361:   PEPMonitorCancel(*pep);
362:   PetscHeaderDestroy(pep);
363:   return(0);
364: }

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

369:    Collective on pep

371:    Input Parameters:
372: +  pep - eigensolver context obtained from PEPCreate()
373: -  bv  - the basis vectors object

375:    Note:
376:    Use PEPGetBV() to retrieve the basis vectors context (for example,
377:    to free it at the end of the computations).

379:    Level: advanced

381: .seealso: PEPGetBV()
382: @*/
383: PetscErrorCode PEPSetBV(PEP pep,BV bv)
384: {

391:   PetscObjectReference((PetscObject)bv);
392:   BVDestroy(&pep->V);
393:   pep->V = bv;
394:   PetscLogObjectParent((PetscObject)pep,(PetscObject)pep->V);
395:   return(0);
396: }

398: /*@
399:    PEPGetBV - Obtain the basis vectors object associated to the polynomial
400:    eigensolver object.

402:    Not Collective

404:    Input Parameters:
405: .  pep - eigensolver context obtained from PEPCreate()

407:    Output Parameter:
408: .  bv - basis vectors context

410:    Level: advanced

412: .seealso: PEPSetBV()
413: @*/
414: PetscErrorCode PEPGetBV(PEP pep,BV *bv)
415: {

421:   if (!pep->V) {
422:     BVCreate(PetscObjectComm((PetscObject)pep),&pep->V);
423:     PetscObjectIncrementTabLevel((PetscObject)pep->V,(PetscObject)pep,0);
424:     PetscLogObjectParent((PetscObject)pep,(PetscObject)pep->V);
425:     PetscObjectSetOptions((PetscObject)pep->V,((PetscObject)pep)->options);
426:   }
427:   *bv = pep->V;
428:   return(0);
429: }

431: /*@
432:    PEPSetRG - Associates a region object to the polynomial eigensolver.

434:    Collective on pep

436:    Input Parameters:
437: +  pep - eigensolver context obtained from PEPCreate()
438: -  rg  - the region object

440:    Note:
441:    Use PEPGetRG() to retrieve the region context (for example,
442:    to free it at the end of the computations).

444:    Level: advanced

446: .seealso: PEPGetRG()
447: @*/
448: PetscErrorCode PEPSetRG(PEP pep,RG rg)
449: {

456:   PetscObjectReference((PetscObject)rg);
457:   RGDestroy(&pep->rg);
458:   pep->rg = rg;
459:   PetscLogObjectParent((PetscObject)pep,(PetscObject)pep->rg);
460:   return(0);
461: }

463: /*@
464:    PEPGetRG - Obtain the region object associated to the
465:    polynomial eigensolver object.

467:    Not Collective

469:    Input Parameters:
470: .  pep - eigensolver context obtained from PEPCreate()

472:    Output Parameter:
473: .  rg - region context

475:    Level: advanced

477: .seealso: PEPSetRG()
478: @*/
479: PetscErrorCode PEPGetRG(PEP pep,RG *rg)
480: {

486:   if (!pep->rg) {
487:     RGCreate(PetscObjectComm((PetscObject)pep),&pep->rg);
488:     PetscObjectIncrementTabLevel((PetscObject)pep->rg,(PetscObject)pep,0);
489:     PetscLogObjectParent((PetscObject)pep,(PetscObject)pep->rg);
490:     PetscObjectSetOptions((PetscObject)pep->rg,((PetscObject)pep)->options);
491:   }
492:   *rg = pep->rg;
493:   return(0);
494: }

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

499:    Collective on pep

501:    Input Parameters:
502: +  pep - eigensolver context obtained from PEPCreate()
503: -  ds  - the direct solver object

505:    Note:
506:    Use PEPGetDS() to retrieve the direct solver context (for example,
507:    to free it at the end of the computations).

509:    Level: advanced

511: .seealso: PEPGetDS()
512: @*/
513: PetscErrorCode PEPSetDS(PEP pep,DS ds)
514: {

521:   PetscObjectReference((PetscObject)ds);
522:   DSDestroy(&pep->ds);
523:   pep->ds = ds;
524:   PetscLogObjectParent((PetscObject)pep,(PetscObject)pep->ds);
525:   return(0);
526: }

528: /*@
529:    PEPGetDS - Obtain the direct solver object associated to the
530:    polynomial eigensolver object.

532:    Not Collective

534:    Input Parameters:
535: .  pep - eigensolver context obtained from PEPCreate()

537:    Output Parameter:
538: .  ds - direct solver context

540:    Level: advanced

542: .seealso: PEPSetDS()
543: @*/
544: PetscErrorCode PEPGetDS(PEP pep,DS *ds)
545: {

551:   if (!pep->ds) {
552:     DSCreate(PetscObjectComm((PetscObject)pep),&pep->ds);
553:     PetscObjectIncrementTabLevel((PetscObject)pep->ds,(PetscObject)pep,0);
554:     PetscLogObjectParent((PetscObject)pep,(PetscObject)pep->ds);
555:     PetscObjectSetOptions((PetscObject)pep->ds,((PetscObject)pep)->options);
556:   }
557:   *ds = pep->ds;
558:   return(0);
559: }

561: /*@
562:    PEPSetST - Associates a spectral transformation object to the eigensolver.

564:    Collective on pep

566:    Input Parameters:
567: +  pep - eigensolver context obtained from PEPCreate()
568: -  st   - the spectral transformation object

570:    Note:
571:    Use PEPGetST() to retrieve the spectral transformation context (for example,
572:    to free it at the end of the computations).

574:    Level: advanced

576: .seealso: PEPGetST()
577: @*/
578: PetscErrorCode PEPSetST(PEP pep,ST st)
579: {

586:   PetscObjectReference((PetscObject)st);
587:   STDestroy(&pep->st);
588:   pep->st = st;
589:   PetscLogObjectParent((PetscObject)pep,(PetscObject)pep->st);
590:   return(0);
591: }

593: /*@
594:    PEPGetST - Obtain the spectral transformation (ST) object associated
595:    to the eigensolver object.

597:    Not Collective

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

602:    Output Parameter:
603: .  st - spectral transformation context

605:    Level: intermediate

607: .seealso: PEPSetST()
608: @*/
609: PetscErrorCode PEPGetST(PEP pep,ST *st)
610: {

616:   if (!pep->st) {
617:     STCreate(PetscObjectComm((PetscObject)pep),&pep->st);
618:     PetscObjectIncrementTabLevel((PetscObject)pep->st,(PetscObject)pep,0);
619:     PetscLogObjectParent((PetscObject)pep,(PetscObject)pep->st);
620:     PetscObjectSetOptions((PetscObject)pep->st,((PetscObject)pep)->options);
621:   }
622:   *st = pep->st;
623:   return(0);
624: }

626: /*@
627:    PEPRefineGetKSP - Obtain the ksp object used by the eigensolver
628:    object in the refinement phase.

630:    Not Collective

632:    Input Parameters:
633: .  pep - eigensolver context obtained from PEPCreate()

635:    Output Parameter:
636: .  ksp - ksp context

638:    Level: advanced

640: .seealso: PEPSetRefine()
641: @*/
642: PetscErrorCode PEPRefineGetKSP(PEP pep,KSP *ksp)
643: {

649:   if (!pep->refineksp) {
650:     if (pep->npart>1) {
651:       /* Split in subcomunicators */
652:       PetscSubcommCreate(PetscObjectComm((PetscObject)pep),&pep->refinesubc);
653:       PetscSubcommSetNumber(pep->refinesubc,pep->npart);
654:       PetscSubcommSetType(pep->refinesubc,PETSC_SUBCOMM_CONTIGUOUS);
655:       PetscLogObjectMemory((PetscObject)pep,sizeof(PetscSubcomm));
656:     }
657:     KSPCreate((pep->npart==1)?PetscObjectComm((PetscObject)pep):PetscSubcommChild(pep->refinesubc),&pep->refineksp);
658:     PetscObjectIncrementTabLevel((PetscObject)pep->refineksp,(PetscObject)pep,0);
659:     PetscLogObjectParent((PetscObject)pep,(PetscObject)pep->refineksp);
660:     PetscObjectSetOptions((PetscObject)pep->refineksp,((PetscObject)pep)->options);
661:     KSPSetOptionsPrefix(*ksp,((PetscObject)pep)->prefix);
662:     KSPAppendOptionsPrefix(*ksp,"pep_refine_");
663:     KSPSetTolerances(pep->refineksp,SLEPC_DEFAULT_TOL,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);
664:   }
665:   *ksp = pep->refineksp;
666:   return(0);
667: }

669: /*@
670:    PEPSetTarget - Sets the value of the target.

672:    Logically Collective on pep

674:    Input Parameters:
675: +  pep    - eigensolver context
676: -  target - the value of the target

678:    Options Database Key:
679: .  -pep_target <scalar> - the value of the target

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

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

689:    Level: intermediate

691: .seealso: PEPGetTarget(), PEPSetWhichEigenpairs()
692: @*/
693: PetscErrorCode PEPSetTarget(PEP pep,PetscScalar target)
694: {

700:   pep->target = target;
701:   if (!pep->st) { PEPGetST(pep,&pep->st); }
702:   STSetDefaultShift(pep->st,target);
703:   return(0);
704: }

706: /*@
707:    PEPGetTarget - Gets the value of the target.

709:    Not Collective

711:    Input Parameter:
712: .  pep - eigensolver context

714:    Output Parameter:
715: .  target - the value of the target

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

720:    Level: intermediate

722: .seealso: PEPSetTarget()
723: @*/
724: PetscErrorCode PEPGetTarget(PEP pep,PetscScalar* target)
725: {
729:   *target = pep->target;
730:   return(0);
731: }

733: /*@
734:    PEPSetInterval - Defines the computational interval for spectrum slicing.

736:    Logically Collective on pep

738:    Input Parameters:
739: +  pep  - eigensolver context
740: .  inta - left end of the interval
741: -  intb - right end of the interval

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

746:    Notes:
747:    Spectrum slicing is a technique employed for computing all eigenvalues of
748:    symmetric eigenproblems in a given interval. This function provides the
749:    interval to be considered. It must be used in combination with PEP_ALL, see
750:    PEPSetWhichEigenpairs().

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

757:    Level: intermediate

759: .seealso: PEPGetInterval(), PEPSetWhichEigenpairs()
760: @*/
761: PetscErrorCode PEPSetInterval(PEP pep,PetscReal inta,PetscReal intb)
762: {
767:   if (inta>=intb) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_ARG_WRONG,"Badly defined interval, must be inta<intb");
768:   if (pep->inta != inta || pep->intb != intb) {
769:     pep->inta = inta;
770:     pep->intb = intb;
771:     pep->state = PEP_STATE_INITIAL;
772:   }
773:   return(0);
774: }

776: /*@
777:    PEPGetInterval - Gets the computational interval for spectrum slicing.

779:    Not Collective

781:    Input Parameter:
782: .  pep - eigensolver context

784:    Output Parameters:
785: +  inta - left end of the interval
786: -  intb - right end of the interval

788:    Level: intermediate

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

793: .seealso: PEPSetInterval()
794: @*/
795: PetscErrorCode PEPGetInterval(PEP pep,PetscReal* inta,PetscReal* intb)
796: {
799:   if (inta) *inta = pep->inta;
800:   if (intb) *intb = pep->intb;
801:   return(0);
802: }