Date: 2026-03-09T09:12:16+00:00

Actual source code: stset.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:    Routines to set ST methods and options
     12: */

     14: #include <slepc/private/stimpl.h>

     16: PetscBool         STRegisterAllCalled = PETSC_FALSE;
     17: PetscFunctionList STList = NULL;

     19: /*@
     20:    STSetType - Selects the type of spectral transformation.

     22:    Logically Collective

     24:    Input Parameters:
     25: +  st   - the spectral transformation context.
     26: -  type - a known type

     28:    Options Database Key:
     29: .  -st_type \<type\> - sets the `ST` type

     31:    Notes:
     32:    Normally, it is best to call the `EPSSetFromOptions()` function and
     33:    then set the `ST` type from the options database rather than by using
     34:    this routine.  Using the options database provides the user with
     35:    maximum flexibility in evaluating the different transformations.

     37:    Level: beginner

     39: .seealso: [](ch:st), `STGetType()`, `EPSSetType()`, `EPSSetFromOptions()`

     41: @*/
     42: PetscErrorCode STSetType(ST st,STType type)
     43: {
     44:   PetscErrorCode (*r)(ST);
     45:   PetscBool      match;

     47:   PetscFunctionBegin;
     49:   PetscAssertPointer(type,2);

     51:   PetscCall(PetscObjectTypeCompare((PetscObject)st,type,&match));
     52:   if (match) PetscFunctionReturn(PETSC_SUCCESS);
     53:   STCheckNotSeized(st,1);

     55:   PetscCall(PetscFunctionListFind(STList,type,&r));
     56:   PetscCheck(r,PetscObjectComm((PetscObject)st),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested ST type %s",type);

     58:   PetscTryTypeMethod(st,destroy);
     59:   PetscCall(PetscMemzero(st->ops,sizeof(struct _STOps)));

     61:   st->state   = ST_STATE_INITIAL;
     62:   st->opready = PETSC_FALSE;
     63:   PetscCall(PetscObjectChangeTypeName((PetscObject)st,type));
     64:   PetscCall((*r)(st));
     65:   PetscFunctionReturn(PETSC_SUCCESS);
     66: }

     68: /*@
     69:    STGetType - Gets the `ST` type name (as a string) from the `ST` context.

     71:    Not Collective

     73:    Input Parameter:
     74: .  st - the spectral transformation context

     76:    Output Parameter:
     77: .  type - name of the spectral transformation

     79:    Level: intermediate

     81: .seealso: [](ch:st), `STSetType()`

     83: @*/
     84: PetscErrorCode STGetType(ST st,STType *type)
     85: {
     86:   PetscFunctionBegin;
     88:   PetscAssertPointer(type,2);
     89:   *type = ((PetscObject)st)->type_name;
     90:   PetscFunctionReturn(PETSC_SUCCESS);
     91: }

     93: /*@
     94:    STSetFromOptions - Sets `ST` options from the options database.

     96:    Collective

     98:    Input Parameter:
     99: .  st - the spectral transformation context

    101:    Note:
    102:    To see all options, run your program with the `-help` option.

    104:    Level: beginner

    106: .seealso: [](ch:st), `STSetOptionsPrefix()`
    107: @*/
    108: PetscErrorCode STSetFromOptions(ST st)
    109: {
    110:   PetscScalar    s;
    111:   char           type[256];
    112:   PetscBool      flg,bval;
    113:   STMatMode      mode;
    114:   MatStructure   mstr;

    116:   PetscFunctionBegin;
    118:   PetscCall(STRegisterAll());
    119:   PetscObjectOptionsBegin((PetscObject)st);
    120:     PetscCall(PetscOptionsFList("-st_type","Spectral transformation","STSetType",STList,(char*)(((PetscObject)st)->type_name?((PetscObject)st)->type_name:STSHIFT),type,sizeof(type),&flg));
    121:     if (flg) PetscCall(STSetType(st,type));
    122:     else if (!((PetscObject)st)->type_name) PetscCall(STSetType(st,STSHIFT));

    124:     PetscCall(PetscOptionsScalar("-st_shift","Value of the shift","STSetShift",st->sigma,&s,&flg));
    125:     if (flg) PetscCall(STSetShift(st,s));

    127:     PetscCall(PetscOptionsEnum("-st_matmode","Matrix mode for transformed matrices","STSetMatMode",STMatModes,(PetscEnum)st->matmode,(PetscEnum*)&mode,&flg));
    128:     if (flg) PetscCall(STSetMatMode(st,mode));

    130:     PetscCall(PetscOptionsEnum("-st_matstructure","Relation of the sparsity pattern of the matrices","STSetMatStructure",MatStructures,(PetscEnum)st->str,(PetscEnum*)&mstr,&flg));
    131:     if (flg) PetscCall(STSetMatStructure(st,mstr));

    133:     PetscCall(PetscOptionsBool("-st_transform","Whether transformed matrices are computed or not","STSetTransform",st->transform,&bval,&flg));
    134:     if (flg) PetscCall(STSetTransform(st,bval));

    136:     PetscTryTypeMethod(st,setfromoptions,PetscOptionsObject);
    137:     PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)st,PetscOptionsObject));
    138:   PetscOptionsEnd();

    140:   if (st->usesksp) {
    141:     PetscCall(STSetDefaultKSP(st));
    142:     PetscCall(KSPSetFromOptions(st->ksp));
    143:   }
    144:   PetscFunctionReturn(PETSC_SUCCESS);
    145: }

    147: /*@
    148:    STSetMatStructure - Sets an internal `MatStructure` attribute to
    149:    indicate which is the relation of the sparsity pattern of all `ST` matrices.

    151:    Logically Collective

    153:    Input Parameters:
    154: +  st  - the spectral transformation context
    155: -  str - either `SAME_NONZERO_PATTERN`, `DIFFERENT_NONZERO_PATTERN`,
    156:          `SUBSET_NONZERO_PATTERN`, or `UNKNOWN_NONZERO_PATTERN`

    158:    Options Database Key:
    159: .  -st_matstructure \<str\> - the structure flag, one of `same`, `different`, `subset`, `unknown`

    161:    Notes:
    162:    If the sparsity pattern of the second matrix is equal or a subset of the
    163:    pattern of the first matrix then it is recommended to set this attribute
    164:    for efficiency reasons (in particular, for internal `MatAXPY()` operations).
    165:    If not set, the default is `UNKNOWN_NONZERO_PATTERN`, in which case the patterns
    166:    will be compared to determine if they are equal.

    168:    This function has no effect in the case of standard eigenproblems.

    170:    In case of polynomial eigenproblems, the flag applies to all matrices
    171:    relative to the first one.

    173:    Level: advanced

    175: .seealso: [](ch:st), `STGetMatStructure()`, `STSetMatrices()`, `MatAXPY()`
    176: @*/
    177: PetscErrorCode STSetMatStructure(ST st,MatStructure str)
    178: {
    179:   PetscFunctionBegin;
    182:   switch (str) {
    183:     case SAME_NONZERO_PATTERN:
    184:     case DIFFERENT_NONZERO_PATTERN:
    185:     case SUBSET_NONZERO_PATTERN:
    186:     case UNKNOWN_NONZERO_PATTERN:
    187:       st->str = str;
    188:       break;
    189:     default:
    190:       SETERRQ(PetscObjectComm((PetscObject)st),PETSC_ERR_ARG_OUTOFRANGE,"Invalid matrix structure flag");
    191:   }
    192:   PetscFunctionReturn(PETSC_SUCCESS);
    193: }

    195: /*@
    196:    STGetMatStructure - Gets the internal `MatStructure` attribute to
    197:    indicate which is the relation of the sparsity pattern of the matrices.

    199:    Not Collective

    201:    Input Parameter:
    202: .  st  - the spectral transformation context

    204:    Output Parameter:
    205: .  str - either `SAME_NONZERO_PATTERN`, `DIFFERENT_NONZERO_PATTERN`,
    206:          `SUBSET_NONZERO_PATTERN`, or `UNKNOWN_NONZERO_PATTERN`

    208:    Level: advanced

    210: .seealso: [](ch:st), `STSetMatStructure()`, `STSetMatrices()`, `MatAXPY()`
    211: @*/
    212: PetscErrorCode STGetMatStructure(ST st,MatStructure *str)
    213: {
    214:   PetscFunctionBegin;
    216:   PetscAssertPointer(str,2);
    217:   *str = st->str;
    218:   PetscFunctionReturn(PETSC_SUCCESS);
    219: }

    221: /*@
    222:    STSetMatMode - Sets a flag to indicate how the transformed matrices are
    223:    being stored in the spectral transformations.

    225:    Logically Collective

    227:    Input Parameters:
    228: +  st - the spectral transformation context
    229: -  mode - the mode

    231:    Options Database Key:
    232: .  -st_matmode \<mode\> - set the mode, one of `copy`, `inplace`, `shell`

    234:    Notes:
    235:    By default (`ST_MATMODE_COPY`), a copy of matrix $A$ is made and then
    236:    this copy is modified explicitly, e.g., $A \leftarrow A - \sigma B$.

    238:    With `ST_MATMODE_INPLACE`, the original matrix $A$ is modified at `STSetUp()`
    239:    and changes are reverted at the end of the computations. With respect to
    240:    the previous one, this mode avoids a copy of matrix $A$. However, a
    241:    drawback is that the recovered matrix might be slightly different
    242:    from the original one (due to roundoff).

    244:    With `ST_MATMODE_SHELL`, the solver works with an implicit shell
    245:    matrix that represents the shifted matrix. This mode is the most efficient
    246:    in creating the transformed matrix but it places serious limitations to the
    247:    linear solves performed in each iteration of the eigensolver (typically,
    248:    only iterative solvers with Jacobi preconditioning can be used).

    250:    In the two first modes the efficiency of the computation can be controlled
    251:    with `STSetMatStructure()`.

    253:    Level: intermediate

    255: .seealso: [](ch:st), `STSetMatrices()`, `STSetMatStructure()`, `STGetMatMode()`, `STMatMode`
    256: @*/
    257: PetscErrorCode STSetMatMode(ST st,STMatMode mode)
    258: {
    259:   PetscFunctionBegin;
    262:   if (st->matmode != mode) {
    263:     STCheckNotSeized(st,1);
    264:     st->matmode = mode;
    265:     st->state   = ST_STATE_INITIAL;
    266:     st->opready = PETSC_FALSE;
    267:   }
    268:   PetscFunctionReturn(PETSC_SUCCESS);
    269: }

    271: /*@
    272:    STGetMatMode - Gets a flag that indicates how the transformed matrices
    273:    are stored in spectral transformations.

    275:    Not Collective

    277:    Input Parameter:
    278: .  st - the spectral transformation context

    280:    Output Parameter:
    281: .  mode - the mode flag

    283:    Level: intermediate

    285: .seealso: [](ch:st), `STSetMatMode()`, `STMatMode`
    286: @*/
    287: PetscErrorCode STGetMatMode(ST st,STMatMode *mode)
    288: {
    289:   PetscFunctionBegin;
    291:   PetscAssertPointer(mode,2);
    292:   *mode = st->matmode;
    293:   PetscFunctionReturn(PETSC_SUCCESS);
    294: }

    296: /*@
    297:    STSetTransform - Sets a flag to indicate whether the transformed matrices are
    298:    computed or not.

    300:    Logically Collective

    302:    Input Parameters:
    303: +  st  - the spectral transformation context
    304: -  flg - the boolean flag

    306:    Options Database Key:
    307: .  -st_transform - toggle the computation of matrices

    309:    Notes:
    310:    This flag is intended for the case of polynomial eigenproblems solved
    311:    via linearization. If this flag is off (default) the spectral transformation
    312:    is applied to the linearization (handled by the eigensolver), otherwise
    313:    it is applied to the original problem.

    315:    Level: developer

    317: .seealso: [](ch:st), `STMatSolve()`, `STMatMult()`, `STSetMatStructure()`, `STGetTransform()`
    318: @*/
    319: PetscErrorCode STSetTransform(ST st,PetscBool flg)
    320: {
    321:   PetscFunctionBegin;
    324:   if (st->transform != flg) {
    325:     st->transform = flg;
    326:     st->state     = ST_STATE_INITIAL;
    327:     st->opready   = PETSC_FALSE;
    328:   }
    329:   PetscFunctionReturn(PETSC_SUCCESS);
    330: }

    332: /*@
    333:    STGetTransform - Gets a flag that indicates whether the transformed
    334:    matrices are computed or not.

    336:    Not Collective

    338:    Input Parameter:
    339: .  st - the spectral transformation context

    341:    Output Parameter:
    342: .  flg - the flag

    344:    Level: developer

    346: .seealso: [](ch:st), `STSetTransform()`
    347: @*/
    348: PetscErrorCode STGetTransform(ST st,PetscBool *flg)
    349: {
    350:   PetscFunctionBegin;
    352:   PetscAssertPointer(flg,2);
    353:   *flg = st->transform;
    354:   PetscFunctionReturn(PETSC_SUCCESS);
    355: }

    357: /*@
    358:    STSetStructured - Sets a flag to indicate that the application of the
    359:    operator must be done taking into account its structure.

    361:    Logically Collective

    363:    Input Parameters:
    364: +  st  - the spectral transformation context
    365: -  flg - the boolean flag

    367:    Note:
    368:    This flag is intended for the case of structured eigenproblems. It is set
    369:    internally by the solver, the user should not modify its value.

    371:    Level: developer

    373: .seealso: [](ch:st), `STApply()`, `STGetStructured()`
    374: @*/
    375: PetscErrorCode STSetStructured(ST st,PetscBool flg)
    376: {
    377:   PetscFunctionBegin;
    380:   if (st->structured != flg) {
    381:     st->structured = flg;
    382:     st->state      = ST_STATE_INITIAL;
    383:     st->opready    = PETSC_FALSE;
    384:   }
    385:   PetscFunctionReturn(PETSC_SUCCESS);
    386: }

    388: /*@
    389:    STGetStructured - Gets a flag that indicates if the application of the
    390:    operator is done using its structure.

    392:    Not Collective

    394:    Input Parameter:
    395: .  st - the spectral transformation context

    397:    Output Parameter:
    398: .  flg - the flag

    400:    Level: developer

    402: .seealso: [](ch:st), `STSetStructured()`
    403: @*/
    404: PetscErrorCode STGetStructured(ST st,PetscBool *flg)
    405: {
    406:   PetscFunctionBegin;
    408:   PetscAssertPointer(flg,2);
    409:   *flg = st->structured;
    410:   PetscFunctionReturn(PETSC_SUCCESS);
    411: }