Date: 2016-03-29T14:57:42+00:00

Actual source code: epsbasic.c
slepc-3.6.3 2016-03-29
Report Typos and Errors

      1: /*
      2:    The basic EPS routines, Create, Destroy, etc. are here.

      4:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      5:    SLEPc - Scalable Library for Eigenvalue Problem Computations
      6:    Copyright (c) 2002-2015, Universitat Politecnica de Valencia, Spain

      8:    This file is part of SLEPc.

     10:    SLEPc is free software: you can redistribute it and/or modify it under  the
     11:    terms of version 3 of the GNU Lesser General Public License as published by
     12:    the Free Software Foundation.

     14:    SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
     15:    WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
     16:    FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
     17:    more details.

     19:    You  should have received a copy of the GNU Lesser General  Public  License
     20:    along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
     21:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     22: */

     24: #include <slepc/private/epsimpl.h>      /*I "slepceps.h" I*/

     26: PetscFunctionList EPSList = 0;
     27: PetscBool         EPSRegisterAllCalled = PETSC_FALSE;
     28: PetscClassId      EPS_CLASSID = 0;
     29: PetscLogEvent     EPS_SetUp = 0,EPS_Solve = 0;

     33: /*@
     34:    EPSCreate - Creates the default EPS context.

     36:    Collective on MPI_Comm

     38:    Input Parameter:
     39: .  comm - MPI communicator

     41:    Output Parameter:
     42: .  eps - location to put the EPS context

     44:    Note:
     45:    The default EPS type is EPSKRYLOVSCHUR

     47:    Level: beginner

     49: .seealso: EPSSetUp(), EPSSolve(), EPSDestroy(), EPS
     50: @*/
     51: PetscErrorCode EPSCreate(MPI_Comm comm,EPS *outeps)
     52: {
     54:   EPS            eps;

     58:   *outeps = 0;
     59:   EPSInitializePackage();
     60:   SlepcHeaderCreate(eps,EPS_CLASSID,"EPS","Eigenvalue Problem Solver","EPS",comm,EPSDestroy,EPSView);

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

     83:   eps->converged       = EPSConvergedEigRelative;
     84:   eps->convergeddestroy= NULL;
     85:   eps->arbitrary       = NULL;
     86:   eps->convergedctx    = NULL;
     87:   eps->arbitraryctx    = NULL;
     88:   eps->numbermonitors  = 0;

     90:   eps->st              = NULL;
     91:   eps->ds              = NULL;
     92:   eps->V               = NULL;
     93:   eps->rg              = NULL;
     94:   eps->rand            = NULL;
     95:   eps->D               = NULL;
     96:   eps->IS              = NULL;
     97:   eps->defl            = NULL;
     98:   eps->eigr            = NULL;
     99:   eps->eigi            = NULL;
    100:   eps->errest          = NULL;
    101:   eps->rr              = NULL;
    102:   eps->ri              = NULL;
    103:   eps->perm            = NULL;
    104:   eps->nwork           = 0;
    105:   eps->work            = NULL;
    106:   eps->data            = NULL;

    108:   eps->state           = EPS_STATE_INITIAL;
    109:   eps->nconv           = 0;
    110:   eps->its             = 0;
    111:   eps->nloc            = 0;
    112:   eps->nrma            = 0.0;
    113:   eps->nrmb            = 0.0;
    114:   eps->isgeneralized   = PETSC_FALSE;
    115:   eps->ispositive      = PETSC_FALSE;
    116:   eps->ishermitian     = PETSC_FALSE;
    117:   eps->reason          = EPS_CONVERGED_ITERATING;

    119:   PetscNewLog(eps,&eps->sc);
    120:   PetscRandomCreate(comm,&eps->rand);
    121:   PetscRandomSetSeed(eps->rand,0x12345678);
    122:   PetscLogObjectParent((PetscObject)eps,(PetscObject)eps->rand);
    123:   *outeps = eps;
    124:   return(0);
    125: }

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

    132:    Logically Collective on EPS

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

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

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

    146:    Normally, it is best to use the EPSSetFromOptions() command and
    147:    then set the EPS 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 EPSSetType() 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: STSetType(), EPSType
    157: @*/
    158: PetscErrorCode EPSSetType(EPS eps,EPSType type)
    159: {
    160:   PetscErrorCode ierr,(*r)(EPS);
    161:   PetscBool      match;

    167:   PetscObjectTypeCompare((PetscObject)eps,type,&match);
    168:   if (match) return(0);

    170:   PetscFunctionListFind(EPSList,type,&r);
    171:   if (!r) SETERRQ1(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown EPS type given: %s",type);

    173:   if (eps->ops->destroy) { (*eps->ops->destroy)(eps); }
    174:   PetscMemzero(eps->ops,sizeof(struct _EPSOps));

    176:   eps->state = EPS_STATE_INITIAL;
    177:   PetscObjectChangeTypeName((PetscObject)eps,type);
    178:   (*r)(eps);
    179:   return(0);
    180: }

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

    187:    Not Collective

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

    192:    Output Parameter:
    193: .  name - name of EPS method

    195:    Level: intermediate

    197: .seealso: EPSSetType()
    198: @*/
    199: PetscErrorCode EPSGetType(EPS eps,EPSType *type)
    200: {
    204:   *type = ((PetscObject)eps)->type_name;
    205:   return(0);
    206: }

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

    213:    Not Collective

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

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

    222:    Sample usage:
    223: .vb
    224:    EPSRegister("my_solver",MySolverCreate);
    225: .ve

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

    232:    Level: advanced

    234: .seealso: EPSRegisterAll()
    235: @*/
    236: PetscErrorCode EPSRegister(const char *name,PetscErrorCode (*function)(EPS))
    237: {

    241:   PetscFunctionListAdd(&EPSList,name,function);
    242:   return(0);
    243: }

    247: /*@
    248:    EPSReset - Resets the EPS context to the initial state and removes any
    249:    allocated objects.

    251:    Collective on EPS

    253:    Input Parameter:
    254: .  eps - eigensolver context obtained from EPSCreate()

    256:    Level: advanced

    258: .seealso: EPSDestroy()
    259: @*/
    260: PetscErrorCode EPSReset(EPS eps)
    261: {
    263:   PetscInt       ncols;

    267:   if (eps->ops->reset) { (eps->ops->reset)(eps); }
    268:   if (eps->st) { STReset(eps->st); }
    269:   if (eps->ds) { DSReset(eps->ds); }
    270:   VecDestroy(&eps->D);
    271:   BVGetSizes(eps->V,NULL,NULL,&ncols);
    272:   if (ncols) {
    273:     PetscFree4(eps->eigr,eps->eigi,eps->errest,eps->perm);
    274:     PetscFree2(eps->rr,eps->ri);
    275:   }
    276:   BVDestroy(&eps->V);
    277:   VecDestroyVecs(eps->nwork,&eps->work);
    278:   eps->nwork = 0;
    279:   eps->state = EPS_STATE_INITIAL;
    280:   return(0);
    281: }

    285: /*@
    286:    EPSDestroy - Destroys the EPS context.

    288:    Collective on EPS

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

    293:    Level: beginner

    295: .seealso: EPSCreate(), EPSSetUp(), EPSSolve()
    296: @*/
    297: PetscErrorCode EPSDestroy(EPS *eps)
    298: {

    302:   if (!*eps) return(0);
    304:   if (--((PetscObject)(*eps))->refct > 0) { *eps = 0; return(0); }
    305:   EPSReset(*eps);
    306:   if ((*eps)->ops->destroy) { (*(*eps)->ops->destroy)(*eps); }
    307:   STDestroy(&(*eps)->st);
    308:   RGDestroy(&(*eps)->rg);
    309:   DSDestroy(&(*eps)->ds);
    310:   PetscRandomDestroy(&(*eps)->rand);
    311:   PetscFree((*eps)->sc);
    312:   /* just in case the initial vectors have not been used */
    313:   SlepcBasisDestroy_Private(&(*eps)->nds,&(*eps)->defl);
    314:   SlepcBasisDestroy_Private(&(*eps)->nini,&(*eps)->IS);
    315:   if ((*eps)->convergeddestroy) {
    316:     (*(*eps)->convergeddestroy)((*eps)->convergedctx);
    317:   }
    318:   EPSMonitorCancel(*eps);
    319:   PetscHeaderDestroy(eps);
    320:   return(0);
    321: }

    325: /*@
    326:    EPSSetTarget - Sets the value of the target.

    328:    Logically Collective on EPS

    330:    Input Parameters:
    331: +  eps    - eigensolver context
    332: -  target - the value of the target

    334:    Options Database Key:
    335: .  -eps_target <scalar> - the value of the target

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

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

    345:    Level: intermediate

    347: .seealso: EPSGetTarget(), EPSSetWhichEigenpairs()
    348: @*/
    349: PetscErrorCode EPSSetTarget(EPS eps,PetscScalar target)
    350: {

    356:   eps->target = target;
    357:   if (!eps->st) { EPSGetST(eps,&eps->st); }
    358:   STSetDefaultShift(eps->st,target);
    359:   return(0);
    360: }

    364: /*@
    365:    EPSGetTarget - Gets the value of the target.

    367:    Not Collective

    369:    Input Parameter:
    370: .  eps - eigensolver context

    372:    Output Parameter:
    373: .  target - the value of the target

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

    378:    Level: intermediate

    380: .seealso: EPSSetTarget()
    381: @*/
    382: PetscErrorCode EPSGetTarget(EPS eps,PetscScalar* target)
    383: {
    387:   *target = eps->target;
    388:   return(0);
    389: }

    393: /*@
    394:    EPSSetInterval - Defines the computational interval for spectrum slicing.

    396:    Logically Collective on EPS

    398:    Input Parameters:
    399: +  eps  - eigensolver context
    400: .  inta - left end of the interval
    401: -  intb - right end of the interval

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

    406:    Notes:
    407:    Spectrum slicing is a technique employed for computing all eigenvalues of
    408:    symmetric eigenproblems in a given interval. This function provides the
    409:    interval to be considered. It must be used in combination with EPS_ALL, see
    410:    EPSSetWhichEigenpairs().

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

    417:    Level: intermediate

    419: .seealso: EPSGetInterval(), EPSSetWhichEigenpairs()
    420: @*/
    421: PetscErrorCode EPSSetInterval(EPS eps,PetscReal inta,PetscReal intb)
    422: {
    427:   if (inta>=intb) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_WRONG,"Badly defined interval, must be inta<intb");
    428:   eps->inta = inta;
    429:   eps->intb = intb;
    430:   eps->state = EPS_STATE_INITIAL;
    431:   return(0);
    432: }

    436: /*@
    437:    EPSGetInterval - Gets the computational interval for spectrum slicing.

    439:    Not Collective

    441:    Input Parameter:
    442: .  eps - eigensolver context

    444:    Output Parameters:
    445: +  inta - left end of the interval
    446: -  intb - right end of the interval

    448:    Level: intermediate

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

    453: .seealso: EPSSetInterval()
    454: @*/
    455: PetscErrorCode EPSGetInterval(EPS eps,PetscReal* inta,PetscReal* intb)
    456: {
    461:   if (inta) *inta = eps->inta;
    462:   if (intb) *intb = eps->intb;
    463:   return(0);
    464: }

    468: /*@
    469:    EPSSetST - Associates a spectral transformation object to the eigensolver.

    471:    Collective on EPS

    473:    Input Parameters:
    474: +  eps - eigensolver context obtained from EPSCreate()
    475: -  st   - the spectral transformation object

    477:    Note:
    478:    Use EPSGetST() to retrieve the spectral transformation context (for example,
    479:    to free it at the end of the computations).

    481:    Level: advanced

    483: .seealso: EPSGetST()
    484: @*/
    485: PetscErrorCode EPSSetST(EPS eps,ST st)
    486: {

    493:   PetscObjectReference((PetscObject)st);
    494:   STDestroy(&eps->st);
    495:   eps->st = st;
    496:   PetscLogObjectParent((PetscObject)eps,(PetscObject)eps->st);
    497:   return(0);
    498: }

    502: /*@
    503:    EPSGetST - Obtain the spectral transformation (ST) object associated
    504:    to the eigensolver object.

    506:    Not Collective

    508:    Input Parameters:
    509: .  eps - eigensolver context obtained from EPSCreate()

    511:    Output Parameter:
    512: .  st - spectral transformation context

    514:    Level: intermediate

    516: .seealso: EPSSetST()
    517: @*/
    518: PetscErrorCode EPSGetST(EPS eps,ST *st)
    519: {

    525:   if (!eps->st) {
    526:     STCreate(PetscObjectComm((PetscObject)eps),&eps->st);
    527:     PetscLogObjectParent((PetscObject)eps,(PetscObject)eps->st);
    528:   }
    529:   *st = eps->st;
    530:   return(0);
    531: }

    535: /*@
    536:    EPSSetBV - Associates a basis vectors object to the eigensolver.

    538:    Collective on EPS

    540:    Input Parameters:
    541: +  eps - eigensolver context obtained from EPSCreate()
    542: -  V   - the basis vectors object

    544:    Note:
    545:    Use EPSGetBV() to retrieve the basis vectors context (for example,
    546:    to free them at the end of the computations).

    548:    Level: advanced

    550: .seealso: EPSGetBV()
    551: @*/
    552: PetscErrorCode EPSSetBV(EPS eps,BV V)
    553: {

    560:   PetscObjectReference((PetscObject)V);
    561:   BVDestroy(&eps->V);
    562:   eps->V = V;
    563:   PetscLogObjectParent((PetscObject)eps,(PetscObject)eps->V);
    564:   return(0);
    565: }

    569: /*@
    570:    EPSGetBV - Obtain the basis vectors object associated to the eigensolver object.

    572:    Not Collective

    574:    Input Parameters:
    575: .  eps - eigensolver context obtained from EPSCreate()

    577:    Output Parameter:
    578: .  V - basis vectors context

    580:    Level: advanced

    582: .seealso: EPSSetBV()
    583: @*/
    584: PetscErrorCode EPSGetBV(EPS eps,BV *V)
    585: {

    591:   if (!eps->V) {
    592:     BVCreate(PetscObjectComm((PetscObject)eps),&eps->V);
    593:     PetscLogObjectParent((PetscObject)eps,(PetscObject)eps->V);
    594:   }
    595:   *V = eps->V;
    596:   return(0);
    597: }

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

    604:    Collective on EPS

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

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

    614:    Level: advanced

    616: .seealso: EPSGetRG()
    617: @*/
    618: PetscErrorCode EPSSetRG(EPS eps,RG rg)
    619: {

    626:   PetscObjectReference((PetscObject)rg);
    627:   RGDestroy(&eps->rg);
    628:   eps->rg = rg;
    629:   PetscLogObjectParent((PetscObject)eps,(PetscObject)eps->rg);
    630:   return(0);
    631: }

    635: /*@
    636:    EPSGetRG - Obtain the region object associated to the eigensolver.

    638:    Not Collective

    640:    Input Parameters:
    641: .  eps - eigensolver context obtained from EPSCreate()

    643:    Output Parameter:
    644: .  rg - region context

    646:    Level: advanced

    648: .seealso: EPSSetRG()
    649: @*/
    650: PetscErrorCode EPSGetRG(EPS eps,RG *rg)
    651: {

    657:   if (!eps->rg) {
    658:     RGCreate(PetscObjectComm((PetscObject)eps),&eps->rg);
    659:     PetscLogObjectParent((PetscObject)eps,(PetscObject)eps->rg);
    660:   }
    661:   *rg = eps->rg;
    662:   return(0);
    663: }

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

    670:    Collective on EPS

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

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

    680:    Level: advanced

    682: .seealso: EPSGetDS()
    683: @*/
    684: PetscErrorCode EPSSetDS(EPS eps,DS ds)
    685: {

    692:   PetscObjectReference((PetscObject)ds);
    693:   DSDestroy(&eps->ds);
    694:   eps->ds = ds;
    695:   PetscLogObjectParent((PetscObject)eps,(PetscObject)eps->ds);
    696:   return(0);
    697: }

    701: /*@
    702:    EPSGetDS - Obtain the direct solver object associated to the eigensolver object.

    704:    Not Collective

    706:    Input Parameters:
    707: .  eps - eigensolver context obtained from EPSCreate()

    709:    Output Parameter:
    710: .  ds - direct solver context

    712:    Level: advanced

    714: .seealso: EPSSetDS()
    715: @*/
    716: PetscErrorCode EPSGetDS(EPS eps,DS *ds)
    717: {

    723:   if (!eps->ds) {
    724:     DSCreate(PetscObjectComm((PetscObject)eps),&eps->ds);
    725:     PetscLogObjectParent((PetscObject)eps,(PetscObject)eps->ds);
    726:   }
    727:   *ds = eps->ds;
    728:   return(0);
    729: }

    733: /*@
    734:    EPSIsGeneralized - Ask if the EPS object corresponds to a generalized
    735:    eigenvalue problem.

    737:    Not collective

    739:    Input Parameter:
    740: .  eps - the eigenproblem solver context

    742:    Output Parameter:
    743: .  is - the answer

    745:    Level: intermediate

    747: .seealso: EPSIsHermitian(), EPSIsPositive()
    748: @*/
    749: PetscErrorCode EPSIsGeneralized(EPS eps,PetscBool* is)
    750: {
    754:   *is = eps->isgeneralized;
    755:   return(0);
    756: }

    760: /*@
    761:    EPSIsHermitian - Ask if the EPS object corresponds to a Hermitian
    762:    eigenvalue problem.

    764:    Not collective

    766:    Input Parameter:
    767: .  eps - the eigenproblem solver context

    769:    Output Parameter:
    770: .  is - the answer

    772:    Level: intermediate

    774: .seealso: EPSIsGeneralized(), EPSIsPositive()
    775: @*/
    776: PetscErrorCode EPSIsHermitian(EPS eps,PetscBool* is)
    777: {
    781:   *is = eps->ishermitian;
    782:   return(0);
    783: }

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

    791:    Not collective

    793:    Input Parameter:
    794: .  eps - the eigenproblem solver context

    796:    Output Parameter:
    797: .  is - the answer

    799:    Level: intermediate

    801: .seealso: EPSIsGeneralized(), EPSIsHermitian()
    802: @*/
    803: PetscErrorCode EPSIsPositive(EPS eps,PetscBool* is)
    804: {
    808:   *is = eps->ispositive;
    809:   return(0);
    810: }