Date: 2013-09-02T10:04:29+00:00

Actual source code: gd.c

      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", submitted, 2013.

     21:    Last update: Jul 2012

     23:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     24:    SLEPc - Scalable Library for Eigenvalue Problem Computations
     25:    Copyright (c) 2002-2013, Universitat Politecnica de Valencia, Spain

     27:    This file is part of SLEPc.

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

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

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

     43: #include <slepc-private/epsimpl.h>                /*I "slepceps.h" I*/
     44: #include <../src/eps/impls/davidson/common/davidson.h>

     48: PetscErrorCode EPSSetFromOptions_GD(EPS eps)
     49: {
     51:   PetscBool      flg,op;
     52:   PetscInt       opi,opi0;
     53:   KSP            ksp;
     54:   EPSOrthType    orth;
     55:   const char     *orth_list[3] = {"I","B","B_opt"};

     58:   PetscOptionsHead("EPS Generalized Davidson (GD) Options");

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

     64:   EPSGDGetBOrth(eps,&orth);
     65:   PetscOptionsEList("-eps_gd_borth","orthogonalization used in the search subspace","EPSGDSetBOrth",orth_list,3,orth_list[orth-1],&opi,&flg);
     66:   if (flg) { EPSGDSetBOrth(eps,(EPSOrthType)(opi+1)); }

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

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

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

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

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

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

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

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

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

    110: PetscErrorCode EPSSetUp_GD(EPS eps)
    111: {
    113:   PetscBool      t;
    114:   KSP            ksp;

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

    123:   /* Setup common for all davidson solvers */
    124:   EPSSetUp_XD(eps);

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

    134: PetscErrorCode EPSDestroy_GD(EPS eps)
    135: {
    136:   PetscErrorCode  ierr;

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

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

    163:    Logically Collective on EPS

    165:    Input Parameters:
    166: +  eps - the eigenproblem solver context
    167: -  krylovstart - boolean flag

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

    173:    Level: advanced

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

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

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

    194:    Not Collective

    196:    Input Parameter:
    197: .  eps - the eigenproblem solver context

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

    203:    Level: advanced

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

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

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

    224:    Logically Collective on EPS

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

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

    233:    Level: advanced

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

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

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

    254:    Not Collective

    256:    Input Parameter:
    257: .  eps - the eigenproblem solver context

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

    262:    Level: advanced

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

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

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

    283:    Not Collective

    285:    Input Parameter:
    286: .  eps - the eigenproblem solver context

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

    292:    Level: advanced

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

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

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

    312:    Logically Collective on EPS

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

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

    323:    Level: advanced

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

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

    341: /*@
    342:    EPSGDGetInitialSize - Returns the initial size of the searching space.

    344:    Not Collective

    346:    Input Parameter:
    347: .  eps - the eigenproblem solver context

    349:    Output Parameter:
    350: .  initialsize - number of vectors of the initial searching subspace

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

    360:    Level: advanced

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

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

    377: /*@
    378:    EPSGDSetInitialSize - Sets the initial size of the searching space.

    380:    Logically Collective on EPS

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

    386:    Options Database Key:
    387: .  -eps_gd_initial_size - number of vectors of the initial searching subspace

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

    397:    Level: advanced

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

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

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

    418:    Logically Collective on EPS

    420:    Input Parameters:
    421: +  eps   - the eigenproblem solver context
    422: -  borth - the kind of orthogonalization

    424:    Possible values:
    425:    The parameter 'borth' can have one of these values

    427: +   EPS_ORTH_I - orthogonalization of the search subspace
    428: .   EPS_ORTH_B - B-orthogonalization of the search subspace
    429: -   EPS_ORTH_BOPT - B-orthogonalization of the search subspace with an alternative method

    431:    Options Database Key:
    432: .  -eps_gd_borth - Set the orthogonalization used in the search subspace

    434:    Notes:
    435:    If borth is EPS_ORTH_B, the solver uses a variant of Gram-Schmidt (selected in
    436:    IP associated to the EPS) with the inner product defined by the matrix problem B.
    437:    If borth is EPS_ORTH_BOPT, it uses another variant of Gram-Schmidt that only performs
    438:    one matrix-vector product although more than one reorthogonalization would be done.

    440:    Level: advanced

    442: .seealso: EPSGDGetBOrth()
    443: @*/
    444: PetscErrorCode EPSGDSetBOrth(EPS eps,EPSOrthType borth)
    445: {

    451:   PetscTryMethod(eps,"EPSGDSetBOrth_C",(EPS,EPSOrthType),(eps,borth));
    452:   return(0);
    453: }

    457: /*@
    458:    EPSGDGetBOrth - Returns the orthogonalization used in the search
    459:    subspace in case of generalized Hermitian problems.

    461:    Not Collective

    463:    Input Parameter:
    464: .  eps - the eigenproblem solver context

    466:    Output Parameters:
    467: .  borth - the kind of orthogonalization

    469:    Notes:
    470:    See EPSGDSetBOrth() for possible values of 'borth'.

    472:    Level: advanced

    474: .seealso: EPSGDSetBOrth(), EPSOrthType
    475: @*/
    476: PetscErrorCode EPSGDGetBOrth(EPS eps,EPSOrthType *borth)
    477: {

    483:   PetscTryMethod(eps,"EPSGDGetBOrth_C",(EPS,EPSOrthType*),(eps,borth));
    484:   return(0);
    485: }

    489: /*@
    490:    EPSGDGetWindowSizes - Gets the number of converged vectors in the projected
    491:    problem (or Rayleigh quotient) and in the projector employed in the correction
    492:    equation.

    494:    Not Collective

    496:    Input Parameter:
    497: .  eps - the eigenproblem solver context

    499:    Output Parameter:
    500: +  pwindow - number of converged vectors in the projector
    501: -  qwindow - number of converged vectors in the projected problem

    503:    Level: advanced

    505: .seealso: EPSGDSetWindowSizes()
    506: @*/
    507: PetscErrorCode EPSGDGetWindowSizes(EPS eps,PetscInt *pwindow,PetscInt *qwindow)
    508: {

    513:   PetscTryMethod(eps,"EPSGDGetWindowSizes_C",(EPS,PetscInt*,PetscInt*),(eps,pwindow,qwindow));
    514:   return(0);
    515: }

    519: /*@
    520:    EPSGDSetWindowSizes - Sets the number of converged vectors in the projected
    521:    problem (or Rayleigh quotient) and in the projector employed in the correction
    522:    equation.

    524:    Logically Collective on EPS

    526:    Input Parameters:
    527: +  eps - the eigenproblem solver context
    528: .  pwindow - number of converged vectors in the projector
    529: -  qwindow - number of converged vectors in the projected problem

    531:    Options Database Keys:
    532: +  -eps_gd_pwindow - set the number of converged vectors in the projector
    533: -  -eps_gd_qwindow - set the number of converged vectors in the projected problem

    535:    Level: advanced

    537: .seealso: EPSGDGetWindowSizes()
    538: @*/
    539: PetscErrorCode EPSGDSetWindowSizes(EPS eps,PetscInt pwindow,PetscInt qwindow)
    540: {

    547:   PetscTryMethod(eps,"EPSGDSetWindowSizes_C",(EPS,PetscInt,PetscInt),(eps,pwindow,qwindow));
    548:   return(0);
    549: }

    553: static PetscErrorCode EPSGDSetDoubleExpansion_GD(EPS eps,PetscBool use_gd2)
    554: {

    558:   EPSXDSetMethod(eps,use_gd2?DVD_METH_GD2:DVD_METH_GD);
    559:   return(0);
    560: }

    564: static PetscErrorCode EPSGDGetDoubleExpansion_GD(EPS eps,PetscBool *flg)
    565: {
    566:   Method_t       meth;

    570:   EPSXDGetMethod_XD(eps,&meth);
    571:   if (meth==DVD_METH_GD2) *flg = PETSC_TRUE;
    572:   else *flg = PETSC_FALSE;
    573:   return(0);
    574: }

    578: /*@
    579:    EPSGDGetDoubleExpansion - Gets a flag indicating whether the double
    580:    expansion variant has been activated or not.

    582:    Not Collective

    584:    Input Parameter:
    585: .  eps - the eigenproblem solver context

    587:    Output Parameter:
    588: .  flg - the flag

    590:    Level: advanced

    592: .seealso: EPSGDSetDoubleExpansion()
    593: @*/
    594: PetscErrorCode EPSGDGetDoubleExpansion(EPS eps,PetscBool *flg)
    595: {

    601:   PetscTryMethod(eps,"EPSGDGetDoubleExpansion_C",(EPS,PetscBool*),(eps,flg));
    602:   return(0);
    603: }

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

    613:    Logically Collective on EPS

    615:    Input Parameters:
    616: +  eps - the eigenproblem solver context
    617: -  use_gd2 - the boolean flag

    619:    Options Database Keys:
    620: .  -eps_gd_double_expansion - activate the double-expansion variant of GD

    622:    Level: advanced
    623: @*/
    624: PetscErrorCode EPSGDSetDoubleExpansion(EPS eps,PetscBool use_gd2)
    625: {

    631:   PetscTryMethod(eps,"EPSGDSetDoubleExpansion_C",(EPS,PetscBool),(eps,use_gd2));
    632:   return(0);
    633: }

    637: PETSC_EXTERN PetscErrorCode EPSCreate_GD(EPS eps)
    638: {
    639:   PetscErrorCode  ierr;

    642:   /* Load the Davidson solver */
    643:   EPSCreate_XD(eps);
    644:   EPSJDSetFix_JD(eps,0.0);
    645:   EPSXDSetMethod(eps,DVD_METH_GD);

    647:   /* Overload the GD properties */
    648:   eps->ops->setfromoptions       = EPSSetFromOptions_GD;
    649:   eps->ops->setup                = EPSSetUp_GD;
    650:   eps->ops->destroy              = EPSDestroy_GD;

    652:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetKrylovStart_C",EPSXDSetKrylovStart_XD);
    653:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetKrylovStart_C",EPSXDGetKrylovStart_XD);
    654:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetBOrth_C",EPSXDSetBOrth_XD);
    655:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetBOrth_C",EPSXDGetBOrth_XD);
    656:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetBlockSize_C",EPSXDSetBlockSize_XD);
    657:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetBlockSize_C",EPSXDGetBlockSize_XD);
    658:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetRestart_C",EPSXDSetRestart_XD);
    659:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetRestart_C",EPSXDGetRestart_XD);
    660:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetInitialSize_C",EPSXDSetInitialSize_XD);
    661:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetInitialSize_C",EPSXDGetInitialSize_XD);
    662:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetWindowSizes_C",EPSXDSetWindowSizes_XD);
    663:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetWindowSizes_C",EPSXDGetWindowSizes_XD);
    664:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetDoubleExpansion_C",EPSGDSetDoubleExpansion_GD);
    665:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetDoubleExpansion_C",EPSGDGetDoubleExpansion_GD);
    666:   return(0);
    667: }