Actual source code: gd.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:    SLEPc eigensolver: "gd"

     13:    Method: Generalized Davidson

     15:    Algorithm:

     17:        Generalized Davidson with various subspace extraction and
     18:        restart techniques.

     20:    References:

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

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

     30: #include <slepc/private/epsimpl.h>
     31: #include <../src/eps/impls/davidson/davidson.h>

     33: static PetscErrorCode EPSSetFromOptions_GD(EPS eps,PetscOptionItems PetscOptionsObject)
     34: {
     35:   PetscBool      flg,flg2,op,orth;
     36:   PetscInt       opi,opi0;

     38:   PetscFunctionBegin;
     39:   PetscOptionsHeadBegin(PetscOptionsObject,"EPS Generalized Davidson (GD) Options");

     41:     PetscCall(EPSGDGetKrylovStart(eps,&op));
     42:     PetscCall(PetscOptionsBool("-eps_gd_krylov_start","Start the search subspace with a Krylov basis","EPSGDSetKrylovStart",op,&op,&flg));
     43:     if (flg) PetscCall(EPSGDSetKrylovStart(eps,op));

     45:     PetscCall(EPSGDGetBOrth(eps,&orth));
     46:     PetscCall(PetscOptionsBool("-eps_gd_borth","Use B-orthogonalization in the search subspace","EPSGDSetBOrth",op,&op,&flg));
     47:     if (flg) PetscCall(EPSGDSetBOrth(eps,op));

     49:     PetscCall(EPSGDGetBlockSize(eps,&opi));
     50:     PetscCall(PetscOptionsInt("-eps_gd_blocksize","Number of vectors to add to the search subspace","EPSGDSetBlockSize",opi,&opi,&flg));
     51:     if (flg) PetscCall(EPSGDSetBlockSize(eps,opi));

     53:     PetscCall(EPSGDGetRestart(eps,&opi,&opi0));
     54:     PetscCall(PetscOptionsInt("-eps_gd_minv","Size of the search subspace after restarting","EPSGDSetRestart",opi,&opi,&flg));
     55:     PetscCall(PetscOptionsInt("-eps_gd_plusk","Number of eigenvectors saved from the previous iteration when restarting","EPSGDSetRestart",opi0,&opi0,&flg2));
     56:     if (flg || flg2) PetscCall(EPSGDSetRestart(eps,opi,opi0));

     58:     PetscCall(EPSGDGetInitialSize(eps,&opi));
     59:     PetscCall(PetscOptionsInt("-eps_gd_initial_size","Initial size of the search subspace","EPSGDSetInitialSize",opi,&opi,&flg));
     60:     if (flg) PetscCall(EPSGDSetInitialSize(eps,opi));

     62:     PetscCall(PetscOptionsBool("-eps_gd_double_expansion","Use the doble-expansion variant of GD","EPSGDSetDoubleExpansion",PETSC_FALSE,&op,&flg));
     63:     if (flg) PetscCall(EPSGDSetDoubleExpansion(eps,op));

     65:   PetscOptionsHeadEnd();
     66:   PetscFunctionReturn(PETSC_SUCCESS);
     67: }

     69: static PetscErrorCode EPSSetUp_GD(EPS eps)
     70: {
     71:   PetscBool      t;
     72:   KSP            ksp;

     74:   PetscFunctionBegin;
     75:   /* Setup common for all davidson solvers */
     76:   PetscCall(EPSSetUp_XD(eps));

     78:   /* Check some constraints */
     79:   PetscCall(STGetKSP(eps->st,&ksp));
     80:   PetscCall(PetscObjectTypeCompare((PetscObject)ksp,KSPPREONLY,&t));
     81:   PetscCheck(t,PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"EPSGD only works with KSPPREONLY");
     82:   PetscFunctionReturn(PETSC_SUCCESS);
     83: }

     85: static PetscErrorCode EPSView_GD(EPS eps,PetscViewer viewer)
     86: {
     87:   PetscBool      isascii,opb;
     88:   PetscInt       opi,opi0;
     89:   PetscBool      borth;
     90:   EPS_DAVIDSON   *data = (EPS_DAVIDSON*)eps->data;

     92:   PetscFunctionBegin;
     93:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
     94:   if (isascii) {
     95:     if (data->doubleexp) PetscCall(PetscViewerASCIIPrintf(viewer,"  using double expansion variant (GD2)\n"));
     96:     PetscCall(EPSXDGetBOrth_XD(eps,&borth));
     97:     if (borth) PetscCall(PetscViewerASCIIPrintf(viewer,"  search subspace is B-orthogonalized\n"));
     98:     else PetscCall(PetscViewerASCIIPrintf(viewer,"  search subspace is orthogonalized\n"));
     99:     PetscCall(EPSXDGetBlockSize_XD(eps,&opi));
    100:     PetscCall(PetscViewerASCIIPrintf(viewer,"  block size=%" PetscInt_FMT "\n",opi));
    101:     PetscCall(EPSXDGetKrylovStart_XD(eps,&opb));
    102:     if (!opb) PetscCall(PetscViewerASCIIPrintf(viewer,"  type of the initial subspace: non-Krylov\n"));
    103:     else PetscCall(PetscViewerASCIIPrintf(viewer,"  type of the initial subspace: Krylov\n"));
    104:     PetscCall(EPSXDGetRestart_XD(eps,&opi,&opi0));
    105:     PetscCall(PetscViewerASCIIPrintf(viewer,"  size of the subspace after restarting: %" PetscInt_FMT "\n",opi));
    106:     PetscCall(PetscViewerASCIIPrintf(viewer,"  number of vectors after restarting from the previous iteration: %" PetscInt_FMT "\n",opi0));
    107:   }
    108:   PetscFunctionReturn(PETSC_SUCCESS);
    109: }

    111: static PetscErrorCode EPSDestroy_GD(EPS eps)
    112: {
    113:   PetscFunctionBegin;
    114:   PetscCall(PetscFree(eps->data));
    115:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetKrylovStart_C",NULL));
    116:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetKrylovStart_C",NULL));
    117:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetBOrth_C",NULL));
    118:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetBOrth_C",NULL));
    119:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetBlockSize_C",NULL));
    120:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetBlockSize_C",NULL));
    121:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetRestart_C",NULL));
    122:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetRestart_C",NULL));
    123:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetInitialSize_C",NULL));
    124:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetInitialSize_C",NULL));
    125:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetDoubleExpansion_C",NULL));
    126:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetDoubleExpansion_C",NULL));
    127:   PetscFunctionReturn(PETSC_SUCCESS);
    128: }

    130: /*@
    131:    EPSGDSetKrylovStart - Activates or deactivates starting the searching
    132:    subspace with a Krylov basis.

    134:    Logically Collective

    136:    Input Parameters:
    137: +  eps         - the linear eigensolver context
    138: -  krylovstart - boolean flag

    140:    Options Database Key:
    141: .  -eps_gd_krylov_start (true|false) - activate starting the searching subspace with a Krylov basis

    143:    Note:
    144:    See discussion at `EPSGDSetInitialSize()`.

    146:    Level: advanced

    148: .seealso: [](ch:eps), `EPSGD`, `EPSGDGetKrylovStart()`, `EPSGDSetInitialSize()`
    149: @*/
    150: PetscErrorCode EPSGDSetKrylovStart(EPS eps,PetscBool krylovstart)
    151: {
    152:   PetscFunctionBegin;
    155:   PetscTryMethod(eps,"EPSGDSetKrylovStart_C",(EPS,PetscBool),(eps,krylovstart));
    156:   PetscFunctionReturn(PETSC_SUCCESS);
    157: }

    159: /*@
    160:    EPSGDGetKrylovStart - Returns a flag indicating if the search subspace is started with a
    161:    Krylov basis.

    163:    Not Collective

    165:    Input Parameter:
    166: .  eps - the linear eigensolver context

    168:    Output Parameter:
    169: .  krylovstart - boolean flag indicating if the search subspace is started with a Krylov basis

    171:    Level: advanced

    173: .seealso: [](ch:eps), `EPSGD`, `EPSGDSetKrylovStart()`
    174: @*/
    175: PetscErrorCode EPSGDGetKrylovStart(EPS eps,PetscBool *krylovstart)
    176: {
    177:   PetscFunctionBegin;
    179:   PetscAssertPointer(krylovstart,2);
    180:   PetscUseMethod(eps,"EPSGDGetKrylovStart_C",(EPS,PetscBool*),(eps,krylovstart));
    181:   PetscFunctionReturn(PETSC_SUCCESS);
    182: }

    184: /*@
    185:    EPSGDSetBlockSize - Sets the number of vectors to be added to the searching space
    186:    in every iteration.

    188:    Logically Collective

    190:    Input Parameters:
    191: +  eps       - the linear eigensolver context
    192: -  blocksize - number of vectors added to the search space in every iteration

    194:    Options Database Key:
    195: .  -eps_gd_blocksize blocksize - number of vectors added to the search space in every iteration

    197:    Note:
    198:    Detailed information can be found at {cite:p}`Rom14`.

    200:    Level: advanced

    202: .seealso: [](ch:eps), `EPSGD`, `EPSGDSetKrylovStart()`
    203: @*/
    204: PetscErrorCode EPSGDSetBlockSize(EPS eps,PetscInt blocksize)
    205: {
    206:   PetscFunctionBegin;
    209:   PetscTryMethod(eps,"EPSGDSetBlockSize_C",(EPS,PetscInt),(eps,blocksize));
    210:   PetscFunctionReturn(PETSC_SUCCESS);
    211: }

    213: /*@
    214:    EPSGDGetBlockSize - Returns the number of vectors to be added to the searching space
    215:    in every iteration.

    217:    Not Collective

    219:    Input Parameter:
    220: .  eps - the linear eigensolver context

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

    225:    Level: advanced

    227: .seealso: [](ch:eps), `EPSGD`, `EPSGDSetBlockSize()`
    228: @*/
    229: PetscErrorCode EPSGDGetBlockSize(EPS eps,PetscInt *blocksize)
    230: {
    231:   PetscFunctionBegin;
    233:   PetscAssertPointer(blocksize,2);
    234:   PetscUseMethod(eps,"EPSGDGetBlockSize_C",(EPS,PetscInt*),(eps,blocksize));
    235:   PetscFunctionReturn(PETSC_SUCCESS);
    236: }

    238: /*@
    239:    EPSGDSetRestart - Sets the number of vectors of the searching space after
    240:    restarting and the number of vectors saved from the previous iteration.

    242:    Logically Collective

    244:    Input Parameters:
    245: +  eps   - the linear eigensolver context
    246: .  minv  - number of vectors of the searching subspace after restarting
    247: -  plusk - number of vectors saved from the previous iteration

    249:    Options Database Keys:
    250: +  -eps_gd_minv minv   - number of vectors of the searching subspace after restarting
    251: -  -eps_gd_plusk plusk - number of vectors saved from the previous iteration

    253:    Notes:
    254:    `PETSC_CURRENT` can be used to preserve the current value of any of the
    255:    arguments, and `PETSC_DETERMINE` to set them to a default value.

    257:    Detailed information can be found at {cite:p}`Rom14`.

    259:    Level: advanced

    261: .seealso: [](ch:eps), `EPSGD`, `EPSGDGetRestart()`
    262: @*/
    263: PetscErrorCode EPSGDSetRestart(EPS eps,PetscInt minv,PetscInt plusk)
    264: {
    265:   PetscFunctionBegin;
    269:   PetscTryMethod(eps,"EPSGDSetRestart_C",(EPS,PetscInt,PetscInt),(eps,minv,plusk));
    270:   PetscFunctionReturn(PETSC_SUCCESS);
    271: }

    273: /*@
    274:    EPSGDGetRestart - Gets the number of vectors of the searching space after
    275:    restarting and the number of vectors saved from the previous iteration.

    277:    Not Collective

    279:    Input Parameter:
    280: .  eps - the linear eigensolver context

    282:    Output Parameters:
    283: +  minv  - number of vectors of the searching subspace after restarting
    284: -  plusk - number of vectors saved from the previous iteration

    286:    Level: advanced

    288: .seealso: [](ch:eps), `EPSGD`, `EPSGDSetRestart()`
    289: @*/
    290: PetscErrorCode EPSGDGetRestart(EPS eps,PetscInt *minv,PetscInt *plusk)
    291: {
    292:   PetscFunctionBegin;
    294:   PetscUseMethod(eps,"EPSGDGetRestart_C",(EPS,PetscInt*,PetscInt*),(eps,minv,plusk));
    295:   PetscFunctionReturn(PETSC_SUCCESS);
    296: }

    298: /*@
    299:    EPSGDSetInitialSize - Sets the initial size of the searching space.

    301:    Logically Collective

    303:    Input Parameters:
    304: +  eps         - the linear eigensolver context
    305: -  initialsize - number of vectors of the initial searching subspace

    307:    Options Database Key:
    308: .  -eps_gd_initial_size initialsize - number of vectors of the initial searching subspace

    310:    Notes:
    311:    If the flag in `EPSGDSetKrylovStart()` is set to `PETSC_FALSE` and the user
    312:    provides vectors with `EPSSetInitialSpace()`, up to `initialsize` vectors will be used;
    313:    and if the provided vectors are not enough, the solver completes the subspace with
    314:    random vectors. In case the `EPSGDSetKrylovStart()` flag is `PETSC_TRUE`, the solver
    315:    gets the first vector provided by the user or, if not available, a random vector,
    316:    and expands the Krylov basis up to `initialsize` vectors.

    318:    Detailed information can be found at {cite:p}`Rom14`.

    320:    Level: advanced

    322: .seealso: [](ch:eps), `EPSGD`, `EPSGDGetInitialSize()`, `EPSGDSetKrylovStart()`
    323: @*/
    324: PetscErrorCode EPSGDSetInitialSize(EPS eps,PetscInt initialsize)
    325: {
    326:   PetscFunctionBegin;
    329:   PetscTryMethod(eps,"EPSGDSetInitialSize_C",(EPS,PetscInt),(eps,initialsize));
    330:   PetscFunctionReturn(PETSC_SUCCESS);
    331: }

    333: /*@
    334:    EPSGDGetInitialSize - Returns the initial size of the searching space.

    336:    Not Collective

    338:    Input Parameter:
    339: .  eps - the linear eigensolver context

    341:    Output Parameter:
    342: .  initialsize - number of vectors of the initial searching subspace

    344:    Level: advanced

    346: .seealso: [](ch:eps), `EPSGD`, `EPSGDSetInitialSize()`, `EPSGDGetKrylovStart()`
    347: @*/
    348: PetscErrorCode EPSGDGetInitialSize(EPS eps,PetscInt *initialsize)
    349: {
    350:   PetscFunctionBegin;
    352:   PetscAssertPointer(initialsize,2);
    353:   PetscUseMethod(eps,"EPSGDGetInitialSize_C",(EPS,PetscInt*),(eps,initialsize));
    354:   PetscFunctionReturn(PETSC_SUCCESS);
    355: }

    357: /*@
    358:    EPSGDSetBOrth - Selects the orthogonalization that will be used in the search
    359:    subspace in case of generalized Hermitian problems.

    361:    Logically Collective

    363:    Input Parameters:
    364: +  eps   - the linear eigensolver context
    365: -  borth - whether to $B$-orthogonalize the search subspace

    367:    Options Database Key:
    368: .  -eps_gd_borth (true|false) - toggle the $B$-orthogonalization

    370:    Note:
    371:    Detailed information can be found at {cite:p}`Rom14`.

    373:    Level: advanced

    375: .seealso: [](ch:eps), `EPSGD`, `EPSGDGetBOrth()`
    376: @*/
    377: PetscErrorCode EPSGDSetBOrth(EPS eps,PetscBool borth)
    378: {
    379:   PetscFunctionBegin;
    382:   PetscTryMethod(eps,"EPSGDSetBOrth_C",(EPS,PetscBool),(eps,borth));
    383:   PetscFunctionReturn(PETSC_SUCCESS);
    384: }

    386: /*@
    387:    EPSGDGetBOrth - Returns the orthogonalization used in the search
    388:    subspace in case of generalized Hermitian problems.

    390:    Not Collective

    392:    Input Parameter:
    393: .  eps - the linear eigensolver context

    395:    Output Parameter:
    396: .  borth - whether to $B$-orthogonalize the search subspace

    398:    Level: advanced

    400: .seealso: [](ch:eps), `EPSGD`, `EPSGDSetBOrth()`
    401: @*/
    402: PetscErrorCode EPSGDGetBOrth(EPS eps,PetscBool *borth)
    403: {
    404:   PetscFunctionBegin;
    406:   PetscAssertPointer(borth,2);
    407:   PetscUseMethod(eps,"EPSGDGetBOrth_C",(EPS,PetscBool*),(eps,borth));
    408:   PetscFunctionReturn(PETSC_SUCCESS);
    409: }

    411: static PetscErrorCode EPSGDSetDoubleExpansion_GD(EPS eps,PetscBool doubleexp)
    412: {
    413:   EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;

    415:   PetscFunctionBegin;
    416:   data->doubleexp = doubleexp;
    417:   PetscFunctionReturn(PETSC_SUCCESS);
    418: }

    420: /*@
    421:    EPSGDSetDoubleExpansion - Activate the double expansion variant of GD.

    423:    Logically Collective

    425:    Input Parameters:
    426: +  eps - the linear eigensolver context
    427: -  doubleexp - the boolean flag

    429:    Options Database Key:
    430: .  -eps_gd_double_expansion (true|false) - activate the double-expansion variant of GD

    432:    Note:
    433:    In the double expansion variant the search subspace is expanded with $K[Ax, Bx]$
    434:    instead of the classic $Kr$, where $K$ is the preconditioner, $x$ the selected
    435:    approximate eigenvector and $r$ its associated residual vector. More details
    436:    can be found in {cite:p}`Hoc12`.

    438:    Level: advanced

    440: .seealso: [](ch:eps), `EPSGD`, `EPSGDGetDoubleExpansion()`
    441: @*/
    442: PetscErrorCode EPSGDSetDoubleExpansion(EPS eps,PetscBool doubleexp)
    443: {
    444:   PetscFunctionBegin;
    447:   PetscTryMethod(eps,"EPSGDSetDoubleExpansion_C",(EPS,PetscBool),(eps,doubleexp));
    448:   PetscFunctionReturn(PETSC_SUCCESS);
    449: }

    451: static PetscErrorCode EPSGDGetDoubleExpansion_GD(EPS eps,PetscBool *doubleexp)
    452: {
    453:   EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;

    455:   PetscFunctionBegin;
    456:   *doubleexp = data->doubleexp;
    457:   PetscFunctionReturn(PETSC_SUCCESS);
    458: }

    460: /*@
    461:    EPSGDGetDoubleExpansion - Gets a flag indicating whether the double
    462:    expansion variant has been activated or not.

    464:    Not Collective

    466:    Input Parameter:
    467: .  eps - the linear eigensolver context

    469:    Output Parameter:
    470: .  doubleexp - the flag

    472:    Level: advanced

    474: .seealso: [](ch:eps), `EPSGD`, `EPSGDSetDoubleExpansion()`
    475: @*/
    476: PetscErrorCode EPSGDGetDoubleExpansion(EPS eps,PetscBool *doubleexp)
    477: {
    478:   PetscFunctionBegin;
    480:   PetscAssertPointer(doubleexp,2);
    481:   PetscUseMethod(eps,"EPSGDGetDoubleExpansion_C",(EPS,PetscBool*),(eps,doubleexp));
    482:   PetscFunctionReturn(PETSC_SUCCESS);
    483: }

    485: /*MC
    486:    EPSGD - EPSGD = "gd" - The generalized Davidson method.

    488:    Notes:
    489:    This is a preconditioned eigensolver, that is, it may be competitive
    490:    when computing interior eigenvalues in case the shift-and-invert spectral
    491:    transformation is too costly and a good preconditioner is available.

    493:    The implemented method is Generalized Davidson, where any `PC`
    494:    preconditioner can be used, in contrast to the original Davidson method
    495:    that used a diagonal preconditioner.

    497:    The preconditioner is specified via the internal `ST` object and its
    498:    associated `KSP`.

    500:    Details of the implementation are described in {cite:p}`Rom14`.

    502:    Level: beginner

    504: .seealso: [](ch:eps), `EPS`, `EPSType`, `EPSSetType()`, `EPSGetST()`
    505: M*/
    506: SLEPC_EXTERN PetscErrorCode EPSCreate_GD(EPS eps)
    507: {
    508:   EPS_DAVIDSON    *data;

    510:   PetscFunctionBegin;
    511:   PetscCall(PetscNew(&data));
    512:   eps->data = (void*)data;

    514:   data->blocksize   = 1;
    515:   data->initialsize = 0;
    516:   data->minv        = 0;
    517:   data->plusk       = PETSC_DETERMINE;
    518:   data->ipB         = PETSC_TRUE;
    519:   data->fix         = 0.0;
    520:   data->krylovstart = PETSC_FALSE;
    521:   data->dynamic     = PETSC_FALSE;

    523:   eps->useds = PETSC_TRUE;
    524:   eps->categ = EPS_CATEGORY_PRECOND;

    526:   eps->ops->solve          = EPSSolve_XD;
    527:   eps->ops->setup          = EPSSetUp_GD;
    528:   eps->ops->setupsort      = EPSSetUpSort_Default;
    529:   eps->ops->setfromoptions = EPSSetFromOptions_GD;
    530:   eps->ops->destroy        = EPSDestroy_GD;
    531:   eps->ops->reset          = EPSReset_XD;
    532:   eps->ops->view           = EPSView_GD;
    533:   eps->ops->backtransform  = EPSBackTransform_Default;
    534:   eps->ops->computevectors = EPSComputeVectors_XD;
    535:   eps->ops->setdefaultst   = EPSSetDefaultST_Precond;

    537:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetKrylovStart_C",EPSXDSetKrylovStart_XD));
    538:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetKrylovStart_C",EPSXDGetKrylovStart_XD));
    539:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetBOrth_C",EPSXDSetBOrth_XD));
    540:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetBOrth_C",EPSXDGetBOrth_XD));
    541:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetBlockSize_C",EPSXDSetBlockSize_XD));
    542:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetBlockSize_C",EPSXDGetBlockSize_XD));
    543:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetRestart_C",EPSXDSetRestart_XD));
    544:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetRestart_C",EPSXDGetRestart_XD));
    545:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetInitialSize_C",EPSXDSetInitialSize_XD));
    546:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetInitialSize_C",EPSXDGetInitialSize_XD));
    547:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetDoubleExpansion_C",EPSGDSetDoubleExpansion_GD));
    548:   PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetDoubleExpansion_C",EPSGDGetDoubleExpansion_GD));
    549:   PetscFunctionReturn(PETSC_SUCCESS);
    550: }