Date: 2026-05-01T10:02:20+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()`
     40: @*/
     41: PetscErrorCode STSetType(ST st,STType type)
     42: {
     43:   PetscErrorCode (*r)(ST);
     44:   PetscBool      match;

     46:   PetscFunctionBegin;
     48:   PetscAssertPointer(type,2);

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

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

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

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

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

     70:    Not Collective

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

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

     78:    Level: intermediate

     80: .seealso: [](ch:st), `STSetType()`
     81: @*/
     82: PetscErrorCode STGetType(ST st,STType *type)
     83: {
     84:   PetscFunctionBegin;
     86:   PetscAssertPointer(type,2);
     87:   *type = ((PetscObject)st)->type_name;
     88:   PetscFunctionReturn(PETSC_SUCCESS);
     89: }

     91: /*@
     92:    STSetFromOptions - Sets `ST` options from the options database.

     94:    Collective

     96:    Input Parameter:
     97: .  st - the spectral transformation context

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

    102:    Level: beginner

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

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

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

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

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

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

    134:     PetscTryTypeMethod(st,setfromoptions,PetscOptionsObject);
    135:     PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)st,PetscOptionsObject));
    136:   PetscOptionsEnd();

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

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

    149:    Logically Collective

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

    156:    Options Database Key:
    157: .  -st_matstructure (same|different|subset|unknown) - set the structure flag

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

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

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

    171:    Level: advanced

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

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

    197:    Not Collective

    199:    Input Parameter:
    200: .  st  - the spectral transformation context

    202:    Output Parameter:
    203: .  str - either `SAME_NONZERO_PATTERN`, `DIFFERENT_NONZERO_PATTERN`,
    204:          `SUBSET_NONZERO_PATTERN`, or `UNKNOWN_NONZERO_PATTERN`

    206:    Level: advanced

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

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

    223:    Logically Collective

    225:    Input Parameters:
    226: +  st - the spectral transformation context
    227: -  mode - the mode

    229:    Options Database Key:
    230: .  -st_matmode (copy|inplace|shell) - set the mode

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

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

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

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

    251:    Level: intermediate

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

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

    273:    Not Collective

    275:    Input Parameter:
    276: .  st - the spectral transformation context

    278:    Output Parameter:
    279: .  mode - the mode flag

    281:    Level: intermediate

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

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

    298:    Logically Collective

    300:    Input Parameters:
    301: +  st  - the spectral transformation context
    302: -  flg - the boolean flag

    304:    Options Database Key:
    305: .  -st_transform (true|false) - toggle the computation of matrices

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

    313:    Level: developer

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

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

    334:    Not Collective

    336:    Input Parameter:
    337: .  st - the spectral transformation context

    339:    Output Parameter:
    340: .  flg - the flag

    342:    Level: developer

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

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

    359:    Logically Collective

    361:    Input Parameters:
    362: +  st  - the spectral transformation context
    363: -  flg - the boolean flag

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

    369:    Level: developer

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

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

    390:    Not Collective

    392:    Input Parameter:
    393: .  st - the spectral transformation context

    395:    Output Parameter:
    396: .  flg - the flag

    398:    Level: developer

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