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

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

      1: /*

      3:    SLEPc eigensolver: "gd"

      5:    Method: Generalized Davidson

      7:    Algorithm:

      9:        Generalized Davidson with various subspace extraction and
     10:        restart techniques.

     12:    References:

     14:        [1] E.R. Davidson, "Super-matrix methods", Comput. Phys. Commun.
     15:            53(2):49-60, 1989.

     17:        [2] E. Romero and J.E. Roman, "A parallel implementation of
     18:            Davidson methods for large-scale eigenvalue problems in
     19:            SLEPc", ACM Trans. Math. Software 40(2), Article 13, 2014.

     21:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     22:    SLEPc - Scalable Library for Eigenvalue Problem Computations
     23:    Copyright (c) 2002-2015, Universitat Politecnica de Valencia, Spain

     25:    This file is part of SLEPc.

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

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

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

     41: #include <slepc/private/epsimpl.h>                /*I "slepceps.h" I*/
     42: #include <../src/eps/impls/davidson/davidson.h>

     46: PetscErrorCode EPSSetFromOptions_GD(PetscOptions *PetscOptionsObject,EPS eps)
     47: {
     49:   PetscBool      flg,op;
     50:   PetscInt       opi,opi0;
     51:   KSP            ksp;
     52:   PetscBool      orth;
     53:   const char     *orth_list[2] = {"I","B"};

     56:   PetscOptionsHead(PetscOptionsObject,"EPS Generalized Davidson (GD) Options");

     58:   EPSGDGetKrylovStart(eps,&op);
     59:   PetscOptionsBool("-eps_gd_krylov_start","Start the searching subspace with a krylov basis","EPSGDSetKrylovStart",op,&op,&flg);
     60:   if (flg) { EPSGDSetKrylovStart(eps,op); }

     62:   EPSGDGetBOrth(eps,&orth);
     63:   PetscOptionsEList("-eps_gd_borth","orthogonalization used in the search subspace","EPSGDSetBOrth",orth_list,2,orth_list[orth?1:0],&opi,&flg);
     64:   if (flg) { EPSGDSetBOrth(eps,opi==1?PETSC_TRUE:PETSC_FALSE); }

     66:   EPSGDGetBlockSize(eps,&opi);
     67:   PetscOptionsInt("-eps_gd_blocksize","Number vectors add to the searching subspace","EPSGDSetBlockSize",opi,&opi,&flg);
     68:   if (flg) { EPSGDSetBlockSize(eps,opi); }

     70:   EPSGDGetRestart(eps,&opi,&opi0);
     71:   PetscOptionsInt("-eps_gd_minv","Set the size of the searching subspace after restarting","EPSGDSetRestart",opi,&opi,&flg);
     72:   if (flg) { EPSGDSetRestart(eps,opi,opi0); }

     74:   PetscOptionsInt("-eps_gd_plusk","Set the number of saved eigenvectors from the previous iteration when restarting","EPSGDSetRestart",opi0,&opi0,&flg);
     75:   if (flg) { EPSGDSetRestart(eps,opi,opi0); }

     77:   EPSGDGetInitialSize(eps,&opi);
     78:   PetscOptionsInt("-eps_gd_initial_size","Set the initial size of the searching subspace","EPSGDSetInitialSize",opi,&opi,&flg);
     79:   if (flg) { EPSGDSetInitialSize(eps,opi); }

     81:   EPSGDGetWindowSizes(eps,&opi,&opi0);
     82:   PetscOptionsInt("-eps_gd_pwindow","(Experimental!) Set the number of converged vectors in the projector","EPSGDSetWindowSizes",opi,&opi,&flg);
     83:   if (flg) { EPSGDSetWindowSizes(eps,opi,opi0); }

     85:   PetscOptionsInt("-eps_gd_qwindow","(Experimental!) Set the number of converged vectors in the projected problem","EPSGDSetWindowSizes",opi0,&opi0,&flg);
     86:   if (flg) { EPSGDSetWindowSizes(eps,opi,opi0); }

     88:   PetscOptionsBool("-eps_gd_double_expansion","use the doble-expansion variant of GD","EPSGDSetDoubleExpansion",PETSC_FALSE,&op,&flg);
     89:   if (flg) { EPSGDSetDoubleExpansion(eps,op); }

     91:   /* Set STPrecond as the default ST */
     92:   if (!((PetscObject)eps->st)->type_name) {
     93:     STSetType(eps->st,STPRECOND);
     94:   }
     95:   STPrecondSetKSPHasMat(eps->st,PETSC_FALSE);

     97:   /* Set the default options of the KSP */
     98:   STGetKSP(eps->st,&ksp);
     99:   if (!((PetscObject)ksp)->type_name) {
    100:     KSPSetType(ksp,KSPPREONLY);
    101:   }
    102:   PetscOptionsTail();
    103:   return(0);
    104: }

    108: PetscErrorCode EPSSetUp_GD(EPS eps)
    109: {
    111:   PetscBool      t;
    112:   KSP            ksp;

    115:   /* Set KSPPREONLY as default */
    116:   STGetKSP(eps->st,&ksp);
    117:   if (!((PetscObject)ksp)->type_name) {
    118:     KSPSetType(ksp,KSPPREONLY);
    119:   }

    121:   /* Setup common for all davidson solvers */
    122:   EPSSetUp_XD(eps);

    124:   /* Check some constraints */
    125:   PetscObjectTypeCompare((PetscObject)ksp,KSPPREONLY,&t);
    126:   if (!t) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"EPSGD only works with KSPPREONLY");
    127:   return(0);
    128: }

    132: PetscErrorCode EPSDestroy_GD(EPS eps)
    133: {
    134:   PetscErrorCode  ierr;

    137:   PetscFree(eps->data);
    138:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetKrylovStart_C",NULL);
    139:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetKrylovStart_C",NULL);
    140:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetBOrth_C",NULL);
    141:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetBOrth_C",NULL);
    142:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetBlockSize_C",NULL);
    143:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetBlockSize_C",NULL);
    144:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetRestart_C",NULL);
    145:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetRestart_C",NULL);
    146:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetInitialSize_C",NULL);
    147:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetInitialSize_C",NULL);
    148:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetWindowSizes_C",NULL);
    149:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetWindowSizes_C",NULL);
    150:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetDoubleExpansion_C",NULL);
    151:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetDoubleExpansion_C",NULL);
    152:   return(0);
    153: }

    157: /*@
    158:    EPSGDSetKrylovStart - Activates or deactivates starting the searching
    159:    subspace with a Krylov basis.

    161:    Logically Collective on EPS

    163:    Input Parameters:
    164: +  eps - the eigenproblem solver context
    165: -  krylovstart - boolean flag

    167:    Options Database Key:
    168: .  -eps_gd_krylov_start - Activates starting the searching subspace with a
    169:     Krylov basis

    171:    Level: advanced

    173: .seealso: EPSGDGetKrylovStart()
    174: @*/
    175: PetscErrorCode EPSGDSetKrylovStart(EPS eps,PetscBool krylovstart)
    176: {

    182:   PetscTryMethod(eps,"EPSGDSetKrylovStart_C",(EPS,PetscBool),(eps,krylovstart));
    183:   return(0);
    184: }

    188: /*@
    189:    EPSGDGetKrylovStart - Returns a flag indicating if the search subspace is started with a
    190:    Krylov basis.

    192:    Not Collective

    194:    Input Parameter:
    195: .  eps - the eigenproblem solver context

    197:    Output Parameters:
    198: .  krylovstart - boolean flag indicating if the search subspace is started
    199:    with a Krylov basis

    201:    Level: advanced

    203: .seealso: EPSGDGetKrylovStart()
    204: @*/
    205: PetscErrorCode EPSGDGetKrylovStart(EPS eps,PetscBool *krylovstart)
    206: {

    212:   PetscTryMethod(eps,"EPSGDGetKrylovStart_C",(EPS,PetscBool*),(eps,krylovstart));
    213:   return(0);
    214: }

    218: /*@
    219:    EPSGDSetBlockSize - Sets the number of vectors to be added to the searching space
    220:    in every iteration.

    222:    Logically Collective on EPS

    224:    Input Parameters:
    225: +  eps - the eigenproblem solver context
    226: -  blocksize - number of vectors added to the search space in every iteration

    228:    Options Database Key:
    229: .  -eps_gd_blocksize - number of vectors added to the search space in every iteration

    231:    Level: advanced

    233: .seealso: EPSGDSetKrylovStart()
    234: @*/
    235: PetscErrorCode EPSGDSetBlockSize(EPS eps,PetscInt blocksize)
    236: {

    242:   PetscTryMethod(eps,"EPSGDSetBlockSize_C",(EPS,PetscInt),(eps,blocksize));
    243:   return(0);
    244: }

    248: /*@
    249:    EPSGDGetBlockSize - Returns the number of vectors to be added to the searching space
    250:    in every iteration.

    252:    Not Collective

    254:    Input Parameter:
    255: .  eps - the eigenproblem solver context

    257:    Output Parameter:
    258: .  blocksize - number of vectors added to the search space in every iteration

    260:    Level: advanced

    262: .seealso: EPSGDSetBlockSize()
    263: @*/
    264: PetscErrorCode EPSGDGetBlockSize(EPS eps,PetscInt *blocksize)
    265: {

    271:   PetscTryMethod(eps,"EPSGDGetBlockSize_C",(EPS,PetscInt*),(eps,blocksize));
    272:   return(0);
    273: }

    277: /*@
    278:    EPSGDGetRestart - Gets the number of vectors of the searching space after
    279:    restarting and the number of vectors saved from the previous iteration.

    281:    Not Collective

    283:    Input Parameter:
    284: .  eps - the eigenproblem solver context

    286:    Output Parameter:
    287: +  minv - number of vectors of the searching subspace after restarting
    288: -  plusk - number of vectors saved from the previous iteration

    290:    Level: advanced

    292: .seealso: EPSGDSetRestart()
    293: @*/
    294: PetscErrorCode EPSGDGetRestart(EPS eps,PetscInt *minv,PetscInt *plusk)
    295: {

    300:   PetscTryMethod(eps,"EPSGDGetRestart_C",(EPS,PetscInt*,PetscInt*),(eps,minv,plusk));
    301:   return(0);
    302: }

    306: /*@
    307:    EPSGDSetRestart - Sets the number of vectors of the searching space after
    308:    restarting and the number of vectors saved from the previous iteration.

    310:    Logically Collective on EPS

    312:    Input Parameters:
    313: +  eps - the eigenproblem solver context
    314: .  minv - number of vectors of the searching subspace after restarting
    315: -  plusk - number of vectors saved from the previous iteration

    317:    Options Database Keys:
    318: +  -eps_gd_minv - number of vectors of the searching subspace after restarting
    319: -  -eps_gd_plusk - number of vectors saved from the previous iteration

    321:    Level: advanced

    323: .seealso: EPSGDSetRestart()
    324: @*/
    325: PetscErrorCode EPSGDSetRestart(EPS eps,PetscInt minv,PetscInt plusk)
    326: {

    333:   PetscTryMethod(eps,"EPSGDSetRestart_C",(EPS,PetscInt,PetscInt),(eps,minv,plusk));
    334:   return(0);
    335: }

    339: /*@
    340:    EPSGDGetInitialSize - Returns the initial size of the searching space.

    342:    Not Collective

    344:    Input Parameter:
    345: .  eps - the eigenproblem solver context

    347:    Output Parameter:
    348: .  initialsize - number of vectors of the initial searching subspace

    350:    Notes:
    351:    If EPSGDGetKrylovStart() is PETSC_FALSE and the user provides vectors with
    352:    EPSSetInitialSpace(), up to initialsize vectors will be used; and if the
    353:    provided vectors are not enough, the solver completes the subspace with
    354:    random vectors. In the case of EPSGDGetKrylovStart() being PETSC_TRUE, the solver
    355:    gets the first vector provided by the user or, if not available, a random vector,
    356:    and expands the Krylov basis up to initialsize vectors.

    358:    Level: advanced

    360: .seealso: EPSGDSetInitialSize(), EPSGDGetKrylovStart()
    361: @*/
    362: PetscErrorCode EPSGDGetInitialSize(EPS eps,PetscInt *initialsize)
    363: {

    369:   PetscTryMethod(eps,"EPSGDGetInitialSize_C",(EPS,PetscInt*),(eps,initialsize));
    370:   return(0);
    371: }

    375: /*@
    376:    EPSGDSetInitialSize - Sets the initial size of the searching space.

    378:    Logically Collective on EPS

    380:    Input Parameters:
    381: +  eps - the eigenproblem solver context
    382: -  initialsize - number of vectors of the initial searching subspace

    384:    Options Database Key:
    385: .  -eps_gd_initial_size - number of vectors of the initial searching subspace

    387:    Notes:
    388:    If EPSGDGetKrylovStart() is PETSC_FALSE and the user provides vectors with
    389:    EPSSetInitialSpace(), up to initialsize vectors will be used; and if the
    390:    provided vectors are not enough, the solver completes the subspace with
    391:    random vectors. In the case of EPSGDGetKrylovStart() being PETSC_TRUE, the solver
    392:    gets the first vector provided by the user or, if not available, a random vector,
    393:    and expands the Krylov basis up to initialsize vectors.

    395:    Level: advanced

    397: .seealso: EPSGDGetInitialSize(), EPSGDGetKrylovStart()
    398: @*/
    399: PetscErrorCode EPSGDSetInitialSize(EPS eps,PetscInt initialsize)
    400: {

    406:   PetscTryMethod(eps,"EPSGDSetInitialSize_C",(EPS,PetscInt),(eps,initialsize));
    407:   return(0);
    408: }

    412: /*@
    413:    EPSGDSetBOrth - Selects the orthogonalization that will be used in the search
    414:    subspace in case of generalized Hermitian problems.

    416:    Logically Collective on EPS

    418:    Input Parameters:
    419: +  eps   - the eigenproblem solver context
    420: -  borth - whether to B-orthogonalize the search subspace

    422:    Options Database Key:
    423: .  -eps_gd_borth - Set the orthogonalization used in the search subspace

    425:    Level: advanced

    427: .seealso: EPSGDGetBOrth()
    428: @*/
    429: PetscErrorCode EPSGDSetBOrth(EPS eps,PetscBool borth)
    430: {

    436:   PetscTryMethod(eps,"EPSGDSetBOrth_C",(EPS,PetscBool),(eps,borth));
    437:   return(0);
    438: }

    442: /*@
    443:    EPSGDGetBOrth - Returns the orthogonalization used in the search
    444:    subspace in case of generalized Hermitian problems.

    446:    Not Collective

    448:    Input Parameter:
    449: .  eps - the eigenproblem solver context

    451:    Output Parameters:
    452: .  borth - whether to B-orthogonalize the search subspace

    454:    Level: advanced

    456: .seealso: EPSGDSetBOrth()
    457: @*/
    458: PetscErrorCode EPSGDGetBOrth(EPS eps,PetscBool *borth)
    459: {

    465:   PetscTryMethod(eps,"EPSGDGetBOrth_C",(EPS,PetscBool*),(eps,borth));
    466:   return(0);
    467: }

    471: /*@
    472:    EPSGDGetWindowSizes - Gets the number of converged vectors in the projected
    473:    problem (or Rayleigh quotient) and in the projector employed in the correction
    474:    equation.

    476:    Not Collective

    478:    Input Parameter:
    479: .  eps - the eigenproblem solver context

    481:    Output Parameter:
    482: +  pwindow - number of converged vectors in the projector
    483: -  qwindow - number of converged vectors in the projected problem

    485:    Level: advanced

    487: .seealso: EPSGDSetWindowSizes()
    488: @*/
    489: PetscErrorCode EPSGDGetWindowSizes(EPS eps,PetscInt *pwindow,PetscInt *qwindow)
    490: {

    495:   PetscTryMethod(eps,"EPSGDGetWindowSizes_C",(EPS,PetscInt*,PetscInt*),(eps,pwindow,qwindow));
    496:   return(0);
    497: }

    501: /*@
    502:    EPSGDSetWindowSizes - Sets the number of converged vectors in the projected
    503:    problem (or Rayleigh quotient) and in the projector employed in the correction
    504:    equation.

    506:    Logically Collective on EPS

    508:    Input Parameters:
    509: +  eps - the eigenproblem solver context
    510: .  pwindow - number of converged vectors in the projector
    511: -  qwindow - number of converged vectors in the projected problem

    513:    Options Database Keys:
    514: +  -eps_gd_pwindow - set the number of converged vectors in the projector
    515: -  -eps_gd_qwindow - set the number of converged vectors in the projected problem

    517:    Level: advanced

    519: .seealso: EPSGDGetWindowSizes()
    520: @*/
    521: PetscErrorCode EPSGDSetWindowSizes(EPS eps,PetscInt pwindow,PetscInt qwindow)
    522: {

    529:   PetscTryMethod(eps,"EPSGDSetWindowSizes_C",(EPS,PetscInt,PetscInt),(eps,pwindow,qwindow));
    530:   return(0);
    531: }

    535: static PetscErrorCode EPSGDSetDoubleExpansion_GD(EPS eps,PetscBool use_gd2)
    536: {

    540:   EPSXDSetMethod(eps,use_gd2?DVD_METH_GD2:DVD_METH_GD);
    541:   return(0);
    542: }

    546: static PetscErrorCode EPSGDGetDoubleExpansion_GD(EPS eps,PetscBool *flg)
    547: {
    548:   Method_t       meth;

    552:   EPSXDGetMethod_XD(eps,&meth);
    553:   if (meth==DVD_METH_GD2) *flg = PETSC_TRUE;
    554:   else *flg = PETSC_FALSE;
    555:   return(0);
    556: }

    560: /*@
    561:    EPSGDGetDoubleExpansion - Gets a flag indicating whether the double
    562:    expansion variant has been activated or not.

    564:    Not Collective

    566:    Input Parameter:
    567: .  eps - the eigenproblem solver context

    569:    Output Parameter:
    570: .  flg - the flag

    572:    Level: advanced

    574: .seealso: EPSGDSetDoubleExpansion()
    575: @*/
    576: PetscErrorCode EPSGDGetDoubleExpansion(EPS eps,PetscBool *flg)
    577: {

    583:   PetscTryMethod(eps,"EPSGDGetDoubleExpansion_C",(EPS,PetscBool*),(eps,flg));
    584:   return(0);
    585: }

    589: /*@
    590:    EPSGDSetDoubleExpansion - Activate a variant where the search subspace is
    591:    expanded with K*[A*x B*x] (double expansion) instead of the classic K*r,
    592:    where K is the preconditioner, x the selected approximate eigenvector and
    593:    r its associated residual vector.

    595:    Logically Collective on EPS

    597:    Input Parameters:
    598: +  eps - the eigenproblem solver context
    599: -  use_gd2 - the boolean flag

    601:    Options Database Keys:
    602: .  -eps_gd_double_expansion - activate the double-expansion variant of GD

    604:    Level: advanced
    605: @*/
    606: PetscErrorCode EPSGDSetDoubleExpansion(EPS eps,PetscBool use_gd2)
    607: {

    613:   PetscTryMethod(eps,"EPSGDSetDoubleExpansion_C",(EPS,PetscBool),(eps,use_gd2));
    614:   return(0);
    615: }

    619: PETSC_EXTERN PetscErrorCode EPSCreate_GD(EPS eps)
    620: {
    621:   PetscErrorCode  ierr;

    624:   /* Load the Davidson solver */
    625:   EPSCreate_XD(eps);
    626:   EPSJDSetFix_JD(eps,0.0);
    627:   EPSXDSetMethod(eps,DVD_METH_GD);

    629:   /* Overload the GD properties */
    630:   eps->ops->setfromoptions       = EPSSetFromOptions_GD;
    631:   eps->ops->setup                = EPSSetUp_GD;
    632:   eps->ops->destroy              = EPSDestroy_GD;

    634:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetKrylovStart_C",EPSXDSetKrylovStart_XD);
    635:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetKrylovStart_C",EPSXDGetKrylovStart_XD);
    636:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetBOrth_C",EPSXDSetBOrth_XD);
    637:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetBOrth_C",EPSXDGetBOrth_XD);
    638:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetBlockSize_C",EPSXDSetBlockSize_XD);
    639:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetBlockSize_C",EPSXDGetBlockSize_XD);
    640:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetRestart_C",EPSXDSetRestart_XD);
    641:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetRestart_C",EPSXDGetRestart_XD);
    642:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetInitialSize_C",EPSXDSetInitialSize_XD);
    643:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetInitialSize_C",EPSXDGetInitialSize_XD);
    644:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetWindowSizes_C",EPSXDSetWindowSizes_XD);
    645:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetWindowSizes_C",EPSXDGetWindowSizes_XD);
    646:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetDoubleExpansion_C",EPSGDSetDoubleExpansion_GD);
    647:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetDoubleExpansion_C",EPSGDGetDoubleExpansion_GD);
    648:   return(0);
    649: }