Date: 2016-03-29T14:58:46+00:00

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

      1: /*
      2:    The basic PEP 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/pepimpl.h>      /*I "slepcpep.h" I*/

     26: PetscFunctionList PEPList = 0;
     27: PetscBool         PEPRegisterAllCalled = PETSC_FALSE;
     28: PetscClassId      PEP_CLASSID = 0;
     29: PetscLogEvent     PEP_SetUp = 0,PEP_Solve = 0,PEP_Refine = 0;

     33: /*@
     34:    PEPCreate - Creates the default PEP context.

     36:    Collective on MPI_Comm

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

     41:    Output Parameter:
     42: .  pep - location to put the PEP context

     44:    Note:
     45:    The default PEP type is PEPTOAR

     47:    Level: beginner

     49: .seealso: PEPSetUp(), PEPSolve(), PEPDestroy(), PEP
     50: @*/
     51: PetscErrorCode PEPCreate(MPI_Comm comm,PEP *outpep)
     52: {
     54:   PEP            pep;

     58:   *outpep = 0;
     59:   PEPInitializePackage();
     60:   SlepcHeaderCreate(pep,PEP_CLASSID,"PEP","Polynomial Eigenvalue Problem","PEP",comm,PEPDestroy,PEPView);

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

     86:   pep->converged       = PEPConvergedEigRelative;
     87:   pep->convergeddestroy= NULL;
     88:   pep->convergedctx    = NULL;
     89:   pep->numbermonitors  = 0;

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

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

    123:   PetscNewLog(pep,&pep->sc);
    124:   PetscRandomCreate(comm,&pep->rand);
    125:   PetscRandomSetSeed(pep->rand,0x12345678);
    126:   PetscLogObjectParent((PetscObject)pep,(PetscObject)pep->rand);
    127:   *outpep = pep;
    128:   return(0);
    129: }

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

    136:    Logically Collective on PEP

    138:    Input Parameters:
    139: +  pep      - the polynomial eigensolver context
    140: -  type     - a known method

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

    146:    Notes:
    147:    See "slepc/include/slepcpep.h" for available methods. The default
    148:    is PEPTOAR.

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

    158:    Level: intermediate

    160: .seealso: PEPType
    161: @*/
    162: PetscErrorCode PEPSetType(PEP pep,PEPType type)
    163: {
    164:   PetscErrorCode ierr,(*r)(PEP);
    165:   PetscBool      match;

    171:   PetscObjectTypeCompare((PetscObject)pep,type,&match);
    172:   if (match) return(0);

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

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

    180:   pep->state = PEP_STATE_INITIAL;
    181:   PetscObjectChangeTypeName((PetscObject)pep,type);
    182:   (*r)(pep);
    183:   return(0);
    184: }

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

    191:    Not Collective

    193:    Input Parameter:
    194: .  pep - the eigensolver context

    196:    Output Parameter:
    197: .  name - name of PEP method

    199:    Level: intermediate

    201: .seealso: PEPSetType()
    202: @*/
    203: PetscErrorCode PEPGetType(PEP pep,PEPType *type)
    204: {
    208:   *type = ((PetscObject)pep)->type_name;
    209:   return(0);
    210: }

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

    217:    Not Collective

    219:    Input Parameters:
    220: +  name - name of a new user-defined solver
    221: -  function - routine to create the solver context

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

    226:    Sample usage:
    227: .vb
    228:    PEPRegister("my_solver",MySolverCreate);
    229: .ve

    231:    Then, your solver can be chosen with the procedural interface via
    232: $     PEPSetType(pep,"my_solver")
    233:    or at runtime via the option
    234: $     -pep_type my_solver

    236:    Level: advanced

    238: .seealso: PEPRegisterAll()
    239: @*/
    240: PetscErrorCode PEPRegister(const char *name,PetscErrorCode (*function)(PEP))
    241: {

    245:   PetscFunctionListAdd(&PEPList,name,function);
    246:   return(0);
    247: }

    251: /*@
    252:    PEPReset - Resets the PEP context to the initial state and removes any
    253:    allocated objects.

    255:    Collective on PEP

    257:    Input Parameter:
    258: .  pep - eigensolver context obtained from PEPCreate()

    260:    Level: advanced

    262: .seealso: PEPDestroy()
    263: @*/
    264: PetscErrorCode PEPReset(PEP pep)
    265: {
    267:   PetscInt       ncols;

    271:   if (pep->ops->reset) { (pep->ops->reset)(pep); }
    272:   if (pep->st) { STReset(pep->st); }
    273:   if (pep->ds) { DSReset(pep->ds); }
    274:   if (pep->nmat) {
    275:     MatDestroyMatrices(pep->nmat,&pep->A);
    276:     PetscFree2(pep->pbc,pep->nrma);
    277:     PetscFree(pep->solvematcoeffs);
    278:     pep->nmat = 0;
    279:   }
    280:   VecDestroy(&pep->Dl);
    281:   VecDestroy(&pep->Dr);
    282:   BVGetSizes(pep->V,NULL,NULL,&ncols);
    283:   if (ncols) {
    284:     PetscFree4(pep->eigr,pep->eigi,pep->errest,pep->perm);
    285:   }
    286:   BVDestroy(&pep->V);
    287:   VecDestroyVecs(pep->nwork,&pep->work);
    288:   KSPDestroy(&pep->refineksp);
    289:   PetscSubcommDestroy(&pep->refinesubc);
    290:   pep->nwork = 0;
    291:   pep->state = PEP_STATE_INITIAL;
    292:   return(0);
    293: }

    297: /*@
    298:    PEPDestroy - Destroys the PEP context.

    300:    Collective on PEP

    302:    Input Parameter:
    303: .  pep - eigensolver context obtained from PEPCreate()

    305:    Level: beginner

    307: .seealso: PEPCreate(), PEPSetUp(), PEPSolve()
    308: @*/
    309: PetscErrorCode PEPDestroy(PEP *pep)
    310: {

    314:   if (!*pep) return(0);
    316:   if (--((PetscObject)(*pep))->refct > 0) { *pep = 0; return(0); }
    317:   PEPReset(*pep);
    318:   if ((*pep)->ops->destroy) { (*(*pep)->ops->destroy)(*pep); }
    319:   STDestroy(&(*pep)->st);
    320:   RGDestroy(&(*pep)->rg);
    321:   DSDestroy(&(*pep)->ds);
    322:   PetscRandomDestroy(&(*pep)->rand);
    323:   PetscFree((*pep)->sc);
    324:   /* just in case the initial vectors have not been used */
    325:   SlepcBasisDestroy_Private(&(*pep)->nini,&(*pep)->IS);
    326:   if ((*pep)->convergeddestroy) {
    327:     (*(*pep)->convergeddestroy)((*pep)->convergedctx);
    328:   }
    329:   PEPMonitorCancel(*pep);
    330:   PetscHeaderDestroy(pep);
    331:   return(0);
    332: }

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

    339:    Collective on PEP

    341:    Input Parameters:
    342: +  pep - eigensolver context obtained from PEPCreate()
    343: -  bv  - the basis vectors object

    345:    Note:
    346:    Use PEPGetBV() to retrieve the basis vectors context (for example,
    347:    to free it at the end of the computations).

    349:    Level: advanced

    351: .seealso: PEPGetBV()
    352: @*/
    353: PetscErrorCode PEPSetBV(PEP pep,BV bv)
    354: {

    361:   PetscObjectReference((PetscObject)bv);
    362:   BVDestroy(&pep->V);
    363:   pep->V = bv;
    364:   PetscLogObjectParent((PetscObject)pep,(PetscObject)pep->V);
    365:   return(0);
    366: }

    370: /*@
    371:    PEPGetBV - Obtain the basis vectors object associated to the polynomial
    372:    eigensolver object.

    374:    Not Collective

    376:    Input Parameters:
    377: .  pep - eigensolver context obtained from PEPCreate()

    379:    Output Parameter:
    380: .  bv - basis vectors context

    382:    Level: advanced

    384: .seealso: PEPSetBV()
    385: @*/
    386: PetscErrorCode PEPGetBV(PEP pep,BV *bv)
    387: {

    393:   if (!pep->V) {
    394:     BVCreate(PetscObjectComm((PetscObject)pep),&pep->V);
    395:     PetscLogObjectParent((PetscObject)pep,(PetscObject)pep->V);
    396:   }
    397:   *bv = pep->V;
    398:   return(0);
    399: }

    403: /*@
    404:    PEPSetRG - Associates a region object to the polynomial eigensolver.

    406:    Collective on PEP

    408:    Input Parameters:
    409: +  pep - eigensolver context obtained from PEPCreate()
    410: -  rg  - the region object

    412:    Note:
    413:    Use PEPGetRG() to retrieve the region context (for example,
    414:    to free it at the end of the computations).

    416:    Level: advanced

    418: .seealso: PEPGetRG()
    419: @*/
    420: PetscErrorCode PEPSetRG(PEP pep,RG rg)
    421: {

    428:   PetscObjectReference((PetscObject)rg);
    429:   RGDestroy(&pep->rg);
    430:   pep->rg = rg;
    431:   PetscLogObjectParent((PetscObject)pep,(PetscObject)pep->rg);
    432:   return(0);
    433: }

    437: /*@
    438:    PEPGetRG - Obtain the region object associated to the
    439:    polynomial eigensolver object.

    441:    Not Collective

    443:    Input Parameters:
    444: .  pep - eigensolver context obtained from PEPCreate()

    446:    Output Parameter:
    447: .  rg - region context

    449:    Level: advanced

    451: .seealso: PEPSetRG()
    452: @*/
    453: PetscErrorCode PEPGetRG(PEP pep,RG *rg)
    454: {

    460:   if (!pep->rg) {
    461:     RGCreate(PetscObjectComm((PetscObject)pep),&pep->rg);
    462:     PetscLogObjectParent((PetscObject)pep,(PetscObject)pep->rg);
    463:   }
    464:   *rg = pep->rg;
    465:   return(0);
    466: }

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

    473:    Collective on PEP

    475:    Input Parameters:
    476: +  pep - eigensolver context obtained from PEPCreate()
    477: -  ds  - the direct solver object

    479:    Note:
    480:    Use PEPGetDS() to retrieve the direct solver context (for example,
    481:    to free it at the end of the computations).

    483:    Level: advanced

    485: .seealso: PEPGetDS()
    486: @*/
    487: PetscErrorCode PEPSetDS(PEP pep,DS ds)
    488: {

    495:   PetscObjectReference((PetscObject)ds);
    496:   DSDestroy(&pep->ds);
    497:   pep->ds = ds;
    498:   PetscLogObjectParent((PetscObject)pep,(PetscObject)pep->ds);
    499:   return(0);
    500: }

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

    508:    Not Collective

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

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

    516:    Level: advanced

    518: .seealso: PEPSetDS()
    519: @*/
    520: PetscErrorCode PEPGetDS(PEP pep,DS *ds)
    521: {

    527:   if (!pep->ds) {
    528:     DSCreate(PetscObjectComm((PetscObject)pep),&pep->ds);
    529:     PetscLogObjectParent((PetscObject)pep,(PetscObject)pep->ds);
    530:   }
    531:   *ds = pep->ds;
    532:   return(0);
    533: }

    537: /*@
    538:    PEPSetST - Associates a spectral transformation object to the eigensolver.

    540:    Collective on PEP

    542:    Input Parameters:
    543: +  pep - eigensolver context obtained from PEPCreate()
    544: -  st   - the spectral transformation object

    546:    Note:
    547:    Use PEPGetST() to retrieve the spectral transformation context (for example,
    548:    to free it at the end of the computations).

    550:    Level: advanced

    552: .seealso: PEPGetST()
    553: @*/
    554: PetscErrorCode PEPSetST(PEP pep,ST st)
    555: {

    562:   PetscObjectReference((PetscObject)st);
    563:   STDestroy(&pep->st);
    564:   pep->st = st;
    565:   PetscLogObjectParent((PetscObject)pep,(PetscObject)pep->st);
    566:   return(0);
    567: }

    571: /*@
    572:    PEPGetST - Obtain the spectral transformation (ST) object associated
    573:    to the eigensolver object.

    575:    Not Collective

    577:    Input Parameters:
    578: .  pep - eigensolver context obtained from PEPCreate()

    580:    Output Parameter:
    581: .  st - spectral transformation context

    583:    Level: intermediate

    585: .seealso: PEPSetST()
    586: @*/
    587: PetscErrorCode PEPGetST(PEP pep,ST *st)
    588: {

    594:   if (!pep->st) {
    595:     STCreate(PetscObjectComm((PetscObject)pep),&pep->st);
    596:     PetscLogObjectParent((PetscObject)pep,(PetscObject)pep->st);
    597:   }
    598:   *st = pep->st;
    599:   return(0);
    600: }

    604: /*@
    605:    PEPRefineGetKSP - Obtain the ksp object used by the eigensolver
    606:    object in the refinement phase.

    608:    Not Collective

    610:    Input Parameters:
    611: .  pep - eigensolver context obtained from PEPCreate()

    613:    Output Parameter:
    614: .  ksp - ksp context

    616:    Level: advanced

    618: .seealso: PEPSetRefine()
    619: @*/
    620: PetscErrorCode PEPRefineGetKSP(PEP pep,KSP *ksp)
    621: {

    627:   if (!pep->refineksp) {
    628:     if (pep->npart>1) {
    629:       /* Split in subcomunicators */
    630:       PetscSubcommCreate(PetscObjectComm((PetscObject)pep),&pep->refinesubc);
    631:       PetscSubcommSetNumber(pep->refinesubc,pep->npart);
    632:       PetscSubcommSetType(pep->refinesubc,PETSC_SUBCOMM_CONTIGUOUS);
    633:       PetscLogObjectMemory((PetscObject)pep,sizeof(PetscSubcomm));
    634:     }
    635:     KSPCreate((pep->npart==1)?PetscObjectComm((PetscObject)pep):PetscSubcommChild(pep->refinesubc),&pep->refineksp);
    636:     PetscLogObjectParent((PetscObject)pep,(PetscObject)pep->refineksp);
    637:     KSPSetOptionsPrefix(*ksp,((PetscObject)pep)->prefix);
    638:     KSPAppendOptionsPrefix(*ksp,"pep_refine_");
    639:     KSPSetErrorIfNotConverged(*ksp,PETSC_TRUE);
    640:   }
    641:   *ksp = pep->refineksp;
    642:   return(0);
    643: }

    647: /*@
    648:    PEPSetTarget - Sets the value of the target.

    650:    Logically Collective on PEP

    652:    Input Parameters:
    653: +  pep    - eigensolver context
    654: -  target - the value of the target

    656:    Options Database Key:
    657: .  -pep_target <scalar> - the value of the target

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

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

    667:    Level: intermediate

    669: .seealso: PEPGetTarget(), PEPSetWhichEigenpairs()
    670: @*/
    671: PetscErrorCode PEPSetTarget(PEP pep,PetscScalar target)
    672: {

    678:   pep->target = target;
    679:   if (!pep->st) { PEPGetST(pep,&pep->st); }
    680:   STSetDefaultShift(pep->st,target);
    681:   return(0);
    682: }

    686: /*@
    687:    PEPGetTarget - Gets the value of the target.

    689:    Not Collective

    691:    Input Parameter:
    692: .  pep - eigensolver context

    694:    Output Parameter:
    695: .  target - the value of the target

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

    700:    Level: intermediate

    702: .seealso: PEPSetTarget()
    703: @*/
    704: PetscErrorCode PEPGetTarget(PEP pep,PetscScalar* target)
    705: {
    709:   *target = pep->target;
    710:   return(0);
    711: }