Actual source code: epsbasic.c

  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:   PetscCall(EPSInitializePackage());
 55:   PetscCall(SlepcHeaderCreate(eps,EPS_CLASSID,"EPS","Eigenvalue Problem Solver","EPS",comm,EPSDestroy,EPSView));

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

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

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

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

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

132: /*@
133:    EPSSetType - Selects the particular solver to be used in the EPS object.

135:    Logically Collective

137:    Input Parameters:
138: +  eps  - the eigensolver context
139: -  type - a known method

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

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

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

157:    Level: intermediate

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

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

170:   PetscCall(PetscObjectTypeCompare((PetscObject)eps,type,&match));
171:   if (match) PetscFunctionReturn(PETSC_SUCCESS);

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

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

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

185: /*@
186:    EPSGetType - Gets the EPS type as a string from the EPS object.

188:    Not Collective

190:    Input Parameter:
191: .  eps - the eigensolver context

193:    Output Parameter:
194: .  type - name of EPS method

196:    Level: intermediate

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

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

212:    Not Collective

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

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

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

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

231:    Level: advanced

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

243: /*@C
244:    EPSMonitorRegister - Registers an EPS monitor routine that may be accessed with EPSMonitorSetFromOptions().

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, see EPSMonitorRegisterFn
253: .  create  - creation routine, or NULL
254: -  destroy - destruction routine, or NULL

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

259:    The calling sequence for the given function matches the calling sequence of EPSMonitorFn
260:    functions passed to EPSMonitorSet() with the additional requirement that its final argument
261:    be a PetscViewerAndFormat.

263:    Example Usage:
264: .vb
265:    EPSMonitorRegister("my_monitor",PETSCVIEWERASCII,PETSC_VIEWER_ASCII_INFO_DETAIL,MyMonitor,NULL,NULL);
266: .ve

268:    Then, your monitor can be chosen with the procedural interface via
269: $      EPSMonitorSetFromOptions(eps,"-eps_monitor_my_monitor","my_monitor",NULL)
270:    or at runtime via the option
271: $      -eps_monitor_my_monitor

273:    Level: advanced

275: .seealso: `EPSMonitorSet()`, `EPSMonitorRegisterAll()`
276: @*/
277: PetscErrorCode EPSMonitorRegister(const char name[],PetscViewerType vtype,PetscViewerFormat format,EPSMonitorRegisterFn *monitor,EPSMonitorRegisterCreateFn *create,EPSMonitorRegisterDestroyFn *destroy)
278: {
279:   char           key[PETSC_MAX_PATH_LEN];

281:   PetscFunctionBegin;
282:   PetscCall(EPSInitializePackage());
283:   PetscCall(SlepcMonitorMakeKey_Internal(name,vtype,format,key));
284:   PetscCall(PetscFunctionListAdd(&EPSMonitorList,key,monitor));
285:   if (create)  PetscCall(PetscFunctionListAdd(&EPSMonitorCreateList,key,create));
286:   if (destroy) PetscCall(PetscFunctionListAdd(&EPSMonitorDestroyList,key,destroy));
287:   PetscFunctionReturn(PETSC_SUCCESS);
288: }

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

294:    Collective

296:    Input Parameter:
297: .  eps - eigensolver context obtained from EPSCreate()

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

305:    Level: advanced

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

325: /*@
326:    EPSDestroy - Destroys the EPS context.

328:    Collective

330:    Input Parameter:
331: .  eps - eigensolver context obtained from EPSCreate()

333:    Level: beginner

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

362: /*@
363:    EPSSetTarget - Sets the value of the target.

365:    Logically Collective

367:    Input Parameters:
368: +  eps    - eigensolver context
369: -  target - the value of the target

371:    Options Database Key:
372: .  -eps_target <scalar> - the value of the target

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

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

382:    Level: intermediate

384: .seealso: `EPSGetTarget()`, `EPSSetWhichEigenpairs()`
385: @*/
386: PetscErrorCode EPSSetTarget(EPS eps,PetscScalar target)
387: {
388:   PetscFunctionBegin;
391:   eps->target = target;
392:   if (!eps->st) PetscCall(EPSGetST(eps,&eps->st));
393:   PetscCall(STSetDefaultShift(eps->st,target));
394:   PetscFunctionReturn(PETSC_SUCCESS);
395: }

397: /*@
398:    EPSGetTarget - Gets the value of the target.

400:    Not Collective

402:    Input Parameter:
403: .  eps - eigensolver context

405:    Output Parameter:
406: .  target - the value of the target

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

411:    Level: intermediate

413: .seealso: `EPSSetTarget()`
414: @*/
415: PetscErrorCode EPSGetTarget(EPS eps,PetscScalar* target)
416: {
417:   PetscFunctionBegin;
419:   PetscAssertPointer(target,2);
420:   *target = eps->target;
421:   PetscFunctionReturn(PETSC_SUCCESS);
422: }

424: /*@
425:    EPSSetInterval - Defines the computational interval for spectrum slicing.

427:    Logically Collective

429:    Input Parameters:
430: +  eps  - eigensolver context
431: .  inta - left end of the interval
432: -  intb - right end of the interval

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

437:    Notes:
438:    Spectrum slicing is a technique employed for computing all eigenvalues of
439:    symmetric eigenproblems in a given interval. This function provides the
440:    interval to be considered. It must be used in combination with EPS_ALL, see
441:    EPSSetWhichEigenpairs().

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

448:    Level: intermediate

450: .seealso: `EPSGetInterval()`, `EPSSetWhichEigenpairs()`
451: @*/
452: PetscErrorCode EPSSetInterval(EPS eps,PetscReal inta,PetscReal intb)
453: {
454:   PetscFunctionBegin;
458:   PetscCheck(inta<intb,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_WRONG,"Badly defined interval, must be inta<intb");
459:   if (eps->inta != inta || eps->intb != intb) {
460:     eps->inta = inta;
461:     eps->intb = intb;
462:     eps->state = EPS_STATE_INITIAL;
463:   }
464:   PetscFunctionReturn(PETSC_SUCCESS);
465: }

467: /*@
468:    EPSGetInterval - Gets the computational interval for spectrum slicing.

470:    Not Collective

472:    Input Parameter:
473: .  eps - eigensolver context

475:    Output Parameters:
476: +  inta - left end of the interval
477: -  intb - right end of the interval

479:    Level: intermediate

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

484: .seealso: `EPSSetInterval()`
485: @*/
486: PetscErrorCode EPSGetInterval(EPS eps,PetscReal* inta,PetscReal* intb)
487: {
488:   PetscFunctionBegin;
490:   if (inta) *inta = eps->inta;
491:   if (intb) *intb = eps->intb;
492:   PetscFunctionReturn(PETSC_SUCCESS);
493: }

495: /*@
496:    EPSSetST - Associates a spectral transformation object to the eigensolver.

498:    Collective

500:    Input Parameters:
501: +  eps - eigensolver context obtained from EPSCreate()
502: -  st   - the spectral transformation object

504:    Note:
505:    Use EPSGetST() to retrieve the spectral transformation context (for example,
506:    to free it at the end of the computations).

508:    Level: advanced

510: .seealso: `EPSGetST()`
511: @*/
512: PetscErrorCode EPSSetST(EPS eps,ST st)
513: {
514:   PetscFunctionBegin;
517:   PetscCheckSameComm(eps,1,st,2);
518:   PetscCall(PetscObjectReference((PetscObject)st));
519:   PetscCall(STDestroy(&eps->st));
520:   eps->st = st;
521:   PetscFunctionReturn(PETSC_SUCCESS);
522: }

524: /*@
525:    EPSGetST - Obtain the spectral transformation (ST) object associated
526:    to the eigensolver object.

528:    Not Collective

530:    Input Parameters:
531: .  eps - eigensolver context obtained from EPSCreate()

533:    Output Parameter:
534: .  st - spectral transformation context

536:    Level: intermediate

538: .seealso: `EPSSetST()`
539: @*/
540: PetscErrorCode EPSGetST(EPS eps,ST *st)
541: {
542:   PetscFunctionBegin;
544:   PetscAssertPointer(st,2);
545:   if (!eps->st) {
546:     PetscCall(STCreate(PetscObjectComm((PetscObject)eps),&eps->st));
547:     PetscCall(PetscObjectIncrementTabLevel((PetscObject)eps->st,(PetscObject)eps,0));
548:     PetscCall(PetscObjectSetOptions((PetscObject)eps->st,((PetscObject)eps)->options));
549:   }
550:   *st = eps->st;
551:   PetscFunctionReturn(PETSC_SUCCESS);
552: }

554: /*@
555:    EPSSetBV - Associates a basis vectors object to the eigensolver.

557:    Collective

559:    Input Parameters:
560: +  eps - eigensolver context obtained from EPSCreate()
561: -  V   - the basis vectors object

563:    Level: advanced

565: .seealso: `EPSGetBV()`
566: @*/
567: PetscErrorCode EPSSetBV(EPS eps,BV V)
568: {
569:   PetscFunctionBegin;
572:   PetscCheckSameComm(eps,1,V,2);
573:   PetscCall(PetscObjectReference((PetscObject)V));
574:   PetscCall(BVDestroy(&eps->V));
575:   eps->V = V;
576:   PetscFunctionReturn(PETSC_SUCCESS);
577: }

579: /*@
580:    EPSGetBV - Obtain the basis vectors object associated to the eigensolver object.

582:    Not Collective

584:    Input Parameters:
585: .  eps - eigensolver context obtained from EPSCreate()

587:    Output Parameter:
588: .  V - basis vectors context

590:    Level: advanced

592: .seealso: `EPSSetBV()`
593: @*/
594: PetscErrorCode EPSGetBV(EPS eps,BV *V)
595: {
596:   PetscFunctionBegin;
598:   PetscAssertPointer(V,2);
599:   if (!eps->V) {
600:     PetscCall(BVCreate(PetscObjectComm((PetscObject)eps),&eps->V));
601:     PetscCall(PetscObjectIncrementTabLevel((PetscObject)eps->V,(PetscObject)eps,0));
602:     PetscCall(PetscObjectSetOptions((PetscObject)eps->V,((PetscObject)eps)->options));
603:   }
604:   *V = eps->V;
605:   PetscFunctionReturn(PETSC_SUCCESS);
606: }

608: /*@
609:    EPSSetRG - Associates a region object to the eigensolver.

611:    Collective

613:    Input Parameters:
614: +  eps - eigensolver context obtained from EPSCreate()
615: -  rg  - the region object

617:    Note:
618:    Use EPSGetRG() to retrieve the region context (for example,
619:    to free it at the end of the computations).

621:    Level: advanced

623: .seealso: `EPSGetRG()`
624: @*/
625: PetscErrorCode EPSSetRG(EPS eps,RG rg)
626: {
627:   PetscFunctionBegin;
629:   if (rg) {
631:     PetscCheckSameComm(eps,1,rg,2);
632:   }
633:   PetscCall(PetscObjectReference((PetscObject)rg));
634:   PetscCall(RGDestroy(&eps->rg));
635:   eps->rg = rg;
636:   PetscFunctionReturn(PETSC_SUCCESS);
637: }

639: /*@
640:    EPSGetRG - Obtain the region object associated to the eigensolver.

642:    Not Collective

644:    Input Parameters:
645: .  eps - eigensolver context obtained from EPSCreate()

647:    Output Parameter:
648: .  rg - region context

650:    Level: advanced

652: .seealso: `EPSSetRG()`
653: @*/
654: PetscErrorCode EPSGetRG(EPS eps,RG *rg)
655: {
656:   PetscFunctionBegin;
658:   PetscAssertPointer(rg,2);
659:   if (!eps->rg) {
660:     PetscCall(RGCreate(PetscObjectComm((PetscObject)eps),&eps->rg));
661:     PetscCall(PetscObjectIncrementTabLevel((PetscObject)eps->rg,(PetscObject)eps,0));
662:     PetscCall(PetscObjectSetOptions((PetscObject)eps->rg,((PetscObject)eps)->options));
663:   }
664:   *rg = eps->rg;
665:   PetscFunctionReturn(PETSC_SUCCESS);
666: }

668: /*@
669:    EPSSetDS - Associates a direct solver object to the eigensolver.

671:    Collective

673:    Input Parameters:
674: +  eps - eigensolver context obtained from EPSCreate()
675: -  ds  - the direct solver object

677:    Note:
678:    Use EPSGetDS() to retrieve the direct solver context (for example,
679:    to free it at the end of the computations).

681:    Level: advanced

683: .seealso: `EPSGetDS()`
684: @*/
685: PetscErrorCode EPSSetDS(EPS eps,DS ds)
686: {
687:   PetscFunctionBegin;
690:   PetscCheckSameComm(eps,1,ds,2);
691:   PetscCall(PetscObjectReference((PetscObject)ds));
692:   PetscCall(DSDestroy(&eps->ds));
693:   eps->ds = ds;
694:   PetscFunctionReturn(PETSC_SUCCESS);
695: }

697: /*@
698:    EPSGetDS - Obtain the direct solver object associated to the eigensolver object.

700:    Not Collective

702:    Input Parameters:
703: .  eps - eigensolver context obtained from EPSCreate()

705:    Output Parameter:
706: .  ds - direct solver context

708:    Level: advanced

710: .seealso: `EPSSetDS()`
711: @*/
712: PetscErrorCode EPSGetDS(EPS eps,DS *ds)
713: {
714:   PetscFunctionBegin;
716:   PetscAssertPointer(ds,2);
717:   if (!eps->ds) {
718:     PetscCall(DSCreate(PetscObjectComm((PetscObject)eps),&eps->ds));
719:     PetscCall(PetscObjectIncrementTabLevel((PetscObject)eps->ds,(PetscObject)eps,0));
720:     PetscCall(PetscObjectSetOptions((PetscObject)eps->ds,((PetscObject)eps)->options));
721:   }
722:   *ds = eps->ds;
723:   PetscFunctionReturn(PETSC_SUCCESS);
724: }

726: /*@
727:    EPSIsGeneralized - Ask if the EPS object corresponds to a generalized
728:    eigenvalue problem.

730:    Not Collective

732:    Input Parameter:
733: .  eps - the eigenproblem solver context

735:    Output Parameter:
736: .  is - the answer

738:    Level: intermediate

740: .seealso: `EPSIsHermitian()`, `EPSIsPositive()`, `EPSIsStructured()`
741: @*/
742: PetscErrorCode EPSIsGeneralized(EPS eps,PetscBool* is)
743: {
744:   PetscFunctionBegin;
746:   PetscAssertPointer(is,2);
747:   *is = eps->isgeneralized;
748:   PetscFunctionReturn(PETSC_SUCCESS);
749: }

751: /*@
752:    EPSIsHermitian - Ask if the EPS object corresponds to a Hermitian
753:    eigenvalue problem.

755:    Not Collective

757:    Input Parameter:
758: .  eps - the eigenproblem solver context

760:    Output Parameter:
761: .  is - the answer

763:    Level: intermediate

765: .seealso: `EPSIsGeneralized()`, `EPSIsPositive()`, `EPSIsStructured()`
766: @*/
767: PetscErrorCode EPSIsHermitian(EPS eps,PetscBool* is)
768: {
769:   PetscFunctionBegin;
771:   PetscAssertPointer(is,2);
772:   *is = eps->ishermitian;
773:   PetscFunctionReturn(PETSC_SUCCESS);
774: }

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

780:    Not Collective

782:    Input Parameter:
783: .  eps - the eigenproblem solver context

785:    Output Parameter:
786: .  is - the answer

788:    Level: intermediate

790: .seealso: `EPSIsGeneralized()`, `EPSIsHermitian()`, `EPSIsStructured()`
791: @*/
792: PetscErrorCode EPSIsPositive(EPS eps,PetscBool* is)
793: {
794:   PetscFunctionBegin;
796:   PetscAssertPointer(is,2);
797:   *is = eps->ispositive;
798:   PetscFunctionReturn(PETSC_SUCCESS);
799: }

801: /*@
802:    EPSIsStructured - Ask if the EPS object corresponds to a structured
803:    eigenvalue problem.

805:    Not Collective

807:    Input Parameter:
808: .  eps - the eigenproblem solver context

810:    Output Parameter:
811: .  is - the answer

813:    Note:
814:    The result will be true if the problem type has been set to some
815:    structured type such as EPS_BSE. This is independent of whether the
816:    input matrix has been built with a certain structure with a helper function.

818:    Level: intermediate

820: .seealso: `EPSIsGeneralized()`, `EPSIsHermitian()`, `EPSIsPositive()`, `EPSSetProblemType()`
821: @*/
822: PetscErrorCode EPSIsStructured(EPS eps,PetscBool* is)
823: {
824:   PetscFunctionBegin;
826:   PetscAssertPointer(is,2);
827:   *is = eps->isstructured;
828:   PetscFunctionReturn(PETSC_SUCCESS);
829: }