Date: 2021-02-01T14:41:50+00:00

Actual source code: stfunc.c
slepc-3.14.2 2021-02-01
Report Typos and Errors

      1: /*
      2:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      3:    SLEPc - Scalable Library for Eigenvalue Problem Computations
      4:    Copyright (c) 2002-2020, 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:    The ST interface routines, callable by users
     12: */

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

     16: PetscClassId     ST_CLASSID = 0;
     17: PetscLogEvent    ST_SetUp = 0,ST_ComputeOperator = 0,ST_Apply = 0,ST_ApplyTranspose = 0,ST_MatSetUp = 0,ST_MatMult = 0,ST_MatMultTranspose = 0,ST_MatSolve = 0,ST_MatSolveTranspose = 0;
     18: static PetscBool STPackageInitialized = PETSC_FALSE;

     20: const char *STMatModes[] = {"COPY","INPLACE","SHELL","STMatMode","ST_MATMODE_",0};

     22: /*@C
     23:    STFinalizePackage - This function destroys everything in the Slepc interface
     24:    to the ST package. It is called from SlepcFinalize().

     26:    Level: developer

     28: .seealso: SlepcFinalize()
     29: @*/
     30: PetscErrorCode STFinalizePackage(void)
     31: {

     35:   PetscFunctionListDestroy(&STList);
     36:   STPackageInitialized = PETSC_FALSE;
     37:   STRegisterAllCalled  = PETSC_FALSE;
     38:   return(0);
     39: }

     41: /*@C
     42:    STInitializePackage - This function initializes everything in the ST package.
     43:    It is called from PetscDLLibraryRegister() when using dynamic libraries, and
     44:    on the first call to STCreate() when using static libraries.

     46:    Level: developer

     48: .seealso: SlepcInitialize()
     49: @*/
     50: PetscErrorCode STInitializePackage(void)
     51: {
     52:   char           logList[256];
     53:   PetscBool      opt,pkg;
     54:   PetscClassId   classids[1];

     58:   if (STPackageInitialized) return(0);
     59:   STPackageInitialized = PETSC_TRUE;
     60:   /* Register Classes */
     61:   PetscClassIdRegister("Spectral Transform",&ST_CLASSID);
     62:   /* Register Constructors */
     63:   STRegisterAll();
     64:   /* Register Events */
     65:   PetscLogEventRegister("STSetUp",ST_CLASSID,&ST_SetUp);
     66:   PetscLogEventRegister("STComputeOperatr",ST_CLASSID,&ST_ComputeOperator);
     67:   PetscLogEventRegister("STApply",ST_CLASSID,&ST_Apply);
     68:   PetscLogEventRegister("STApplyTranspose",ST_CLASSID,&ST_ApplyTranspose);
     69:   PetscLogEventRegister("STMatSetUp",ST_CLASSID,&ST_MatSetUp);
     70:   PetscLogEventRegister("STMatMult",ST_CLASSID,&ST_MatMult);
     71:   PetscLogEventRegister("STMatMultTranspose",ST_CLASSID,&ST_MatMultTranspose);
     72:   PetscLogEventRegister("STMatSolve",ST_CLASSID,&ST_MatSolve);
     73:   PetscLogEventRegister("STMatSolveTranspose",ST_CLASSID,&ST_MatSolveTranspose);
     74:   /* Process Info */
     75:   classids[0] = ST_CLASSID;
     76:   PetscInfoProcessClass("st",1,&classids[0]);
     77:   /* Process summary exclusions */
     78:   PetscOptionsGetString(NULL,NULL,"-log_exclude",logList,sizeof(logList),&opt);
     79:   if (opt) {
     80:     PetscStrInList("st",logList,',',&pkg);
     81:     if (pkg) { PetscLogEventDeactivateClass(ST_CLASSID); }
     82:   }
     83:   /* Register package finalizer */
     84:   PetscRegisterFinalize(STFinalizePackage);
     85:   return(0);
     86: }

     88: /*@
     89:    STReset - Resets the ST context to the initial state (prior to setup)
     90:    and destroys any allocated Vecs and Mats.

     92:    Collective on st

     94:    Input Parameter:
     95: .  st - the spectral transformation context

     97:    Level: advanced

     99: .seealso: STDestroy()
    100: @*/
    101: PetscErrorCode STReset(ST st)
    102: {

    107:   if (!st) return(0);
    108:   STCheckNotSeized(st,1);
    109:   if (st->ops->reset) { (*st->ops->reset)(st); }
    110:   if (st->ksp) { KSPReset(st->ksp); }
    111:   MatDestroyMatrices(PetscMax(2,st->nmat),&st->T);
    112:   MatDestroyMatrices(PetscMax(2,st->nmat),&st->A);
    113:   PetscFree(st->Astate);
    114:   MatDestroy(&st->Op);
    115:   MatDestroy(&st->P);
    116:   VecDestroyVecs(st->nwork,&st->work);
    117:   st->nwork = 0;
    118:   VecDestroy(&st->wb);
    119:   VecDestroy(&st->wht);
    120:   VecDestroy(&st->D);
    121:   st->state   = ST_STATE_INITIAL;
    122:   st->opready = PETSC_FALSE;
    123:   return(0);
    124: }

    126: /*@
    127:    STDestroy - Destroys ST context that was created with STCreate().

    129:    Collective on st

    131:    Input Parameter:
    132: .  st - the spectral transformation context

    134:    Level: beginner

    136: .seealso: STCreate(), STSetUp()
    137: @*/
    138: PetscErrorCode STDestroy(ST *st)
    139: {

    143:   if (!*st) return(0);
    145:   if (--((PetscObject)(*st))->refct > 0) { *st = 0; return(0); }
    146:   STReset(*st);
    147:   if ((*st)->ops->destroy) { (*(*st)->ops->destroy)(*st); }
    148:   KSPDestroy(&(*st)->ksp);
    149:   PetscHeaderDestroy(st);
    150:   return(0);
    151: }

    153: /*@
    154:    STCreate - Creates a spectral transformation context.

    156:    Collective

    158:    Input Parameter:
    159: .  comm - MPI communicator

    161:    Output Parameter:
    162: .  st - location to put the spectral transformation context

    164:    Level: beginner

    166: .seealso: STSetUp(), STApply(), STDestroy(), ST
    167: @*/
    168: PetscErrorCode STCreate(MPI_Comm comm,ST *newst)
    169: {
    171:   ST             st;

    175:   *newst = 0;
    176:   STInitializePackage();
    177:   SlepcHeaderCreate(st,ST_CLASSID,"ST","Spectral Transformation","ST",comm,STDestroy,STView);

    179:   st->A            = NULL;
    180:   st->nmat         = 0;
    181:   st->sigma        = 0.0;
    182:   st->defsigma     = 0.0;
    183:   st->matmode      = ST_MATMODE_COPY;
    184:   st->str          = DIFFERENT_NONZERO_PATTERN;
    185:   st->transform    = PETSC_FALSE;
    186:   st->D            = NULL;

    188:   st->ksp          = NULL;
    189:   st->usesksp      = PETSC_FALSE;
    190:   st->nwork        = 0;
    191:   st->work         = NULL;
    192:   st->wb           = NULL;
    193:   st->wht          = NULL;
    194:   st->state        = ST_STATE_INITIAL;
    195:   st->Astate       = NULL;
    196:   st->T            = NULL;
    197:   st->Op           = NULL;
    198:   st->opseized     = PETSC_FALSE;
    199:   st->opready      = PETSC_FALSE;
    200:   st->P            = NULL;
    201:   st->M            = NULL;
    202:   st->sigma_set    = PETSC_FALSE;
    203:   st->asymm        = PETSC_FALSE;
    204:   st->aherm        = PETSC_FALSE;
    205:   st->data         = NULL;

    207:   *newst = st;
    208:   return(0);
    209: }

    211: /*
    212:    Checks whether the ST matrices are all symmetric or hermitian.
    213: */
    214: PETSC_STATIC_INLINE PetscErrorCode STMatIsSymmetricKnown(ST st,PetscBool *symm,PetscBool *herm)
    215: {
    217:   PetscInt       i;
    218:   PetscBool      sbaij=PETSC_FALSE,set,flg=PETSC_FALSE;

    221:   /* check if problem matrices are all sbaij */
    222:   for (i=0;i<st->nmat;i++) {
    223:     PetscObjectTypeCompareAny((PetscObject)st->A[i],&sbaij,MATSEQSBAIJ,MATMPISBAIJ,"");
    224:     if (!sbaij) break;
    225:   }
    226:   /* check if user has set the symmetric flag */
    227:   *symm = PETSC_TRUE;
    228:   for (i=0;i<st->nmat;i++) {
    229:     MatIsSymmetricKnown(st->A[i],&set,&flg);
    230:     if (!set || !flg) { *symm = PETSC_FALSE; break; }
    231:   }
    232:   if (sbaij) *symm = PETSC_TRUE;
    233: #if defined(PETSC_USE_COMPLEX)
    234:   /* check if user has set the hermitian flag */
    235:   *herm = PETSC_TRUE;
    236:   for (i=0;i<st->nmat;i++) {
    237:     MatIsHermitianKnown(st->A[i],&set,&flg);
    238:     if (!set || !flg) { *herm = PETSC_FALSE; break; }
    239:   }
    240: #else
    241:   *herm = *symm;
    242: #endif
    243:   return(0);
    244: }

    246: /*@
    247:    STSetMatrices - Sets the matrices associated with the eigenvalue problem.

    249:    Collective on st

    251:    Input Parameters:
    252: +  st - the spectral transformation context
    253: .  n  - number of matrices in array A
    254: -  A  - the array of matrices associated with the eigensystem

    256:    Notes:
    257:    It must be called before STSetUp(). If it is called again after STSetUp() then
    258:    the ST object is reset.

    260:    Level: intermediate

    262: .seealso: STGetMatrix(), STGetNumMatrices(), STSetUp(), STReset()
    263:  @*/
    264: PetscErrorCode STSetMatrices(ST st,PetscInt n,Mat A[])
    265: {
    266:   PetscInt       i;
    268:   PetscBool      same=PETSC_TRUE;

    273:   if (n <= 0) SETERRQ1(PetscObjectComm((PetscObject)st),PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more matrices, you have %D",n);
    276:   STCheckNotSeized(st,1);

    278:   if (st->state) {
    279:     if (n!=st->nmat) same = PETSC_FALSE;
    280:     for (i=0;same&&i<n;i++) {
    281:       if (A[i]!=st->A[i]) same = PETSC_FALSE;
    282:     }
    283:     if (!same) { STReset(st); }
    284:   } else same = PETSC_FALSE;
    285:   if (!same) {
    286:     MatDestroyMatrices(PetscMax(2,st->nmat),&st->A);
    287:     PetscCalloc1(PetscMax(2,n),&st->A);
    288:     PetscLogObjectMemory((PetscObject)st,PetscMax(2,n)*sizeof(Mat));
    289:     PetscFree(st->Astate);
    290:     PetscMalloc1(PetscMax(2,n),&st->Astate);
    291:     PetscLogObjectMemory((PetscObject)st,PetscMax(2,n)*sizeof(PetscInt));
    292:   }
    293:   for (i=0;i<n;i++) {
    295:     PetscObjectReference((PetscObject)A[i]);
    296:     MatDestroy(&st->A[i]);
    297:     st->A[i] = A[i];
    298:     st->Astate[i] = ((PetscObject)A[i])->state;
    299:   }
    300:   if (n==1) {
    301:     st->A[1] = NULL;
    302:     st->Astate[1] = 0;
    303:   }
    304:   st->nmat = n;
    305:   if (same) st->state = ST_STATE_UPDATED;
    306:   else st->state = ST_STATE_INITIAL;
    307:   st->opready = PETSC_FALSE;
    308:   if (!same) {
    309:     STMatIsSymmetricKnown(st,&st->asymm,&st->aherm);
    310:   }
    311:   return(0);
    312: }

    314: /*@
    315:    STGetMatrix - Gets the matrices associated with the original eigensystem.

    317:    Not collective, though parallel Mats are returned if the ST is parallel

    319:    Input Parameter:
    320: +  st - the spectral transformation context
    321: -  k  - the index of the requested matrix (starting in 0)

    323:    Output Parameters:
    324: .  A - the requested matrix

    326:    Level: intermediate

    328: .seealso: STSetMatrices(), STGetNumMatrices()
    329: @*/
    330: PetscErrorCode STGetMatrix(ST st,PetscInt k,Mat *A)
    331: {
    336:   STCheckMatrices(st,1);
    337:   if (k<0 || k>=st->nmat) SETERRQ1(PetscObjectComm((PetscObject)st),PETSC_ERR_ARG_OUTOFRANGE,"k must be between 0 and %D",st->nmat-1);
    338:   if (((PetscObject)st->A[k])->state!=st->Astate[k]) SETERRQ(PetscObjectComm((PetscObject)st),PETSC_ERR_SUP,"Cannot retrieve original matrices (have been modified)");
    339:   *A = st->A[k];
    340:   return(0);
    341: }

    343: /*@
    344:    STGetMatrixTransformed - Gets the matrices associated with the transformed eigensystem.

    346:    Not collective, though parallel Mats are returned if the ST is parallel

    348:    Input Parameter:
    349: +  st - the spectral transformation context
    350: -  k  - the index of the requested matrix (starting in 0)

    352:    Output Parameters:
    353: .  T - the requested matrix

    355:    Level: developer

    357: .seealso: STGetMatrix(), STGetNumMatrices()
    358: @*/
    359: PetscErrorCode STGetMatrixTransformed(ST st,PetscInt k,Mat *T)
    360: {
    365:   STCheckMatrices(st,1);
    366:   if (k<0 || k>=st->nmat) SETERRQ1(PetscObjectComm((PetscObject)st),PETSC_ERR_ARG_OUTOFRANGE,"k must be between 0 and %D",st->nmat-1);
    367:   if (!st->T) SETERRQ(PetscObjectComm((PetscObject)st),PETSC_ERR_POINTER,"There are no transformed matrices");
    368:   *T = st->T[k];
    369:   return(0);
    370: }

    372: /*@
    373:    STGetNumMatrices - Returns the number of matrices stored in the ST.

    375:    Not collective

    377:    Input Parameter:
    378: .  st - the spectral transformation context

    380:    Output Parameters:
    381: .  n - the number of matrices passed in STSetMatrices()

    383:    Level: intermediate

    385: .seealso: STSetMatrices()
    386: @*/
    387: PetscErrorCode STGetNumMatrices(ST st,PetscInt *n)
    388: {
    392:   *n = st->nmat;
    393:   return(0);
    394: }

    396: /*@
    397:    STResetMatrixState - Resets the stored state of the matrices in the ST.

    399:    Logically Collective on st

    401:    Input Parameter:
    402: .  st - the spectral transformation context

    404:    Note:
    405:    This is useful in solvers where the user matrices are modified during
    406:    the computation, as in nonlinear inverse iteration. The effect is that
    407:    STGetMatrix() will retrieve the modified matrices as if they were
    408:    the matrices originally provided by the user.

    410:    Level: developer

    412: .seealso: STGetMatrix(), EPSPowerSetNonlinear()
    413: @*/
    414: PetscErrorCode STResetMatrixState(ST st)
    415: {
    416:   PetscInt i;

    420:   for (i=0;i<st->nmat;i++) st->Astate[i] = ((PetscObject)st->A[i])->state;
    421:   return(0);
    422: }

    424: /*@
    425:    STSetShift - Sets the shift associated with the spectral transformation.

    427:    Logically Collective on st

    429:    Input Parameters:
    430: +  st - the spectral transformation context
    431: -  shift - the value of the shift

    433:    Notes:
    434:    In some spectral transformations, changing the shift may have associated
    435:    a lot of work, for example recomputing a factorization.

    437:    This function is normally not directly called by users, since the shift is
    438:    indirectly set by EPSSetTarget().

    440:    Level: intermediate

    442: .seealso: EPSSetTarget(), STGetShift(), STSetDefaultShift()
    443: @*/
    444: PetscErrorCode STSetShift(ST st,PetscScalar shift)
    445: {

    452:   if (st->sigma != shift) {
    453:     STCheckNotSeized(st,1);
    454:     if (st->state==ST_STATE_SETUP && st->ops->setshift) {
    455:       (*st->ops->setshift)(st,shift);
    456:     }
    457:     st->sigma = shift;
    458:   }
    459:   st->sigma_set = PETSC_TRUE;
    460:   return(0);
    461: }

    463: /*@
    464:    STGetShift - Gets the shift associated with the spectral transformation.

    466:    Not Collective

    468:    Input Parameter:
    469: .  st - the spectral transformation context

    471:    Output Parameter:
    472: .  shift - the value of the shift

    474:    Level: intermediate

    476: .seealso: STSetShift()
    477: @*/
    478: PetscErrorCode STGetShift(ST st,PetscScalar* shift)
    479: {
    483:   *shift = st->sigma;
    484:   return(0);
    485: }

    487: /*@
    488:    STSetDefaultShift - Sets the value of the shift that should be employed if
    489:    the user did not specify one.

    491:    Logically Collective on st

    493:    Input Parameters:
    494: +  st - the spectral transformation context
    495: -  defaultshift - the default value of the shift

    497:    Level: developer

    499: .seealso: STSetShift()
    500: @*/
    501: PetscErrorCode STSetDefaultShift(ST st,PetscScalar defaultshift)
    502: {
    506:   if (st->defsigma != defaultshift) {
    507:     st->defsigma = defaultshift;
    508:     st->state    = ST_STATE_INITIAL;
    509:     st->opready  = PETSC_FALSE;
    510:   }
    511:   return(0);
    512: }

    514: /*@
    515:    STScaleShift - Multiply the shift with a given factor.

    517:    Logically Collective on st

    519:    Input Parameters:
    520: +  st     - the spectral transformation context
    521: -  factor - the scaling factor

    523:    Note:
    524:    This function does not update the transformation matrices, as opposed to
    525:    STSetShift().

    527:    Level: developer

    529: .seealso: STSetShift()
    530: @*/
    531: PetscErrorCode STScaleShift(ST st,PetscScalar factor)
    532: {
    536:   st->sigma *= factor;
    537:   return(0);
    538: }

    540: /*@
    541:    STSetBalanceMatrix - Sets the diagonal matrix to be used for balancing.

    543:    Collective on st

    545:    Input Parameters:
    546: +  st - the spectral transformation context
    547: -  D  - the diagonal matrix (represented as a vector)

    549:    Notes:
    550:    If this matrix is set, STApply will effectively apply D*OP*D^{-1}. Use NULL
    551:    to reset a previously passed D.

    553:    Balancing is usually set via EPSSetBalance, but the advanced user may use
    554:    this function to bypass the usual balancing methods.

    556:    Level: developer

    558: .seealso: EPSSetBalance(), STApply(), STGetBalanceMatrix()
    559: @*/
    560: PetscErrorCode STSetBalanceMatrix(ST st,Vec D)
    561: {

    566:   if (st->D == D) return(0);
    567:   STCheckNotSeized(st,1);
    568:   if (D) {
    571:     PetscObjectReference((PetscObject)D);
    572:   }
    573:   VecDestroy(&st->D);
    574:   st->D = D;
    575:   st->state   = ST_STATE_INITIAL;
    576:   st->opready = PETSC_FALSE;
    577:   return(0);
    578: }

    580: /*@
    581:    STGetBalanceMatrix - Gets the balance matrix used by the spectral transformation.

    583:    Not collective, but vector is shared by all processors that share the ST

    585:    Input Parameter:
    586: .  st - the spectral transformation context

    588:    Output Parameter:
    589: .  D  - the diagonal matrix (represented as a vector)

    591:    Note:
    592:    If the matrix was not set, a null pointer will be returned.

    594:    Level: developer

    596: .seealso: STSetBalanceMatrix()
    597: @*/
    598: PetscErrorCode STGetBalanceMatrix(ST st,Vec *D)
    599: {
    603:   *D = st->D;
    604:   return(0);
    605: }

    607: /*@C
    608:    STMatCreateVecs - Get vector(s) compatible with the ST matrices.

    610:    Collective on st

    612:    Input Parameter:
    613: .  st - the spectral transformation context

    615:    Output Parameters:
    616: +  right - (optional) vector that the matrix can be multiplied against
    617: -  left  - (optional) vector that the matrix vector product can be stored in

    619:    Level: developer
    620: @*/
    621: PetscErrorCode STMatCreateVecs(ST st,Vec *right,Vec *left)
    622: {

    626:   STCheckMatrices(st,1);
    627:   MatCreateVecs(st->A[0],right,left);
    628:   return(0);
    629: }

    631: /*@C
    632:    STMatCreateVecsEmpty - Get vector(s) compatible with the ST matrices, i.e. with the same
    633:    parallel layout, but without internal array.

    635:    Collective on st

    637:    Input Parameter:
    638: .  st - the spectral transformation context

    640:    Output Parameters:
    641: +  right - (optional) vector that the matrix can be multiplied against
    642: -  left  - (optional) vector that the matrix vector product can be stored in

    644:    Level: developer

    646: .seealso: MatCreateVecsEmpty()
    647: @*/
    648: PetscErrorCode STMatCreateVecsEmpty(ST st,Vec *right,Vec *left)
    649: {

    653:   STCheckMatrices(st,1);
    654:   MatCreateVecsEmpty(st->A[0],right,left);
    655:   return(0);
    656: }

    658: /*@
    659:    STMatGetSize - Returns the number of rows and columns of the ST matrices.

    661:    Not Collective

    663:    Input Parameter:
    664: .  st - the spectral transformation context

    666:    Output Parameters:
    667: +  m - the number of global rows
    668: -  n - the number of global columns

    670:    Level: developer
    671: @*/
    672: PetscErrorCode STMatGetSize(ST st,PetscInt *m,PetscInt *n)
    673: {

    677:   STCheckMatrices(st,1);
    678:   MatGetSize(st->A[0],m,n);
    679:   return(0);
    680: }

    682: /*@
    683:    STMatGetLocalSize - Returns the number of local rows and columns of the ST matrices.

    685:    Not Collective

    687:    Input Parameter:
    688: .  st - the spectral transformation context

    690:    Output Parameters:
    691: +  m - the number of local rows
    692: -  n - the number of local columns

    694:    Level: developer
    695: @*/
    696: PetscErrorCode STMatGetLocalSize(ST st,PetscInt *m,PetscInt *n)
    697: {

    701:   STCheckMatrices(st,1);
    702:   MatGetLocalSize(st->A[0],m,n);
    703:   return(0);
    704: }

    706: /*@C
    707:    STSetOptionsPrefix - Sets the prefix used for searching for all
    708:    ST options in the database.

    710:    Logically Collective on st

    712:    Input Parameters:
    713: +  st     - the spectral transformation context
    714: -  prefix - the prefix string to prepend to all ST option requests

    716:    Notes:
    717:    A hyphen (-) must NOT be given at the beginning of the prefix name.
    718:    The first character of all runtime options is AUTOMATICALLY the
    719:    hyphen.

    721:    Level: advanced

    723: .seealso: STAppendOptionsPrefix(), STGetOptionsPrefix()
    724: @*/
    725: PetscErrorCode STSetOptionsPrefix(ST st,const char *prefix)
    726: {

    731:   if (!st->ksp) { STGetKSP(st,&st->ksp); }
    732:   KSPSetOptionsPrefix(st->ksp,prefix);
    733:   KSPAppendOptionsPrefix(st->ksp,"st_");
    734:   PetscObjectSetOptionsPrefix((PetscObject)st,prefix);
    735:   return(0);
    736: }

    738: /*@C
    739:    STAppendOptionsPrefix - Appends to the prefix used for searching for all
    740:    ST options in the database.

    742:    Logically Collective on st

    744:    Input Parameters:
    745: +  st     - the spectral transformation context
    746: -  prefix - the prefix string to prepend to all ST option requests

    748:    Notes:
    749:    A hyphen (-) must NOT be given at the beginning of the prefix name.
    750:    The first character of all runtime options is AUTOMATICALLY the
    751:    hyphen.

    753:    Level: advanced

    755: .seealso: STSetOptionsPrefix(), STGetOptionsPrefix()
    756: @*/
    757: PetscErrorCode STAppendOptionsPrefix(ST st,const char *prefix)
    758: {

    763:   PetscObjectAppendOptionsPrefix((PetscObject)st,prefix);
    764:   if (!st->ksp) { STGetKSP(st,&st->ksp); }
    765:   KSPSetOptionsPrefix(st->ksp,((PetscObject)st)->prefix);
    766:   KSPAppendOptionsPrefix(st->ksp,"st_");
    767:   return(0);
    768: }

    770: /*@C
    771:    STGetOptionsPrefix - Gets the prefix used for searching for all
    772:    ST options in the database.

    774:    Not Collective

    776:    Input Parameters:
    777: .  st - the spectral transformation context

    779:    Output Parameters:
    780: .  prefix - pointer to the prefix string used, is returned

    782:    Note:
    783:    On the Fortran side, the user should pass in a string 'prefix' of
    784:    sufficient length to hold the prefix.

    786:    Level: advanced

    788: .seealso: STSetOptionsPrefix(), STAppendOptionsPrefix()
    789: @*/
    790: PetscErrorCode STGetOptionsPrefix(ST st,const char *prefix[])
    791: {

    797:   PetscObjectGetOptionsPrefix((PetscObject)st,prefix);
    798:   return(0);
    799: }

    801: /*@C
    802:    STView - Prints the ST data structure.

    804:    Collective on st

    806:    Input Parameters:
    807: +  st - the ST context
    808: -  viewer - optional visualization context

    810:    Note:
    811:    The available visualization contexts include
    812: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
    813: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
    814:          output where only the first processor opens
    815:          the file.  All other processors send their
    816:          data to the first processor to print.

    818:    The user can open an alternative visualization contexts with
    819:    PetscViewerASCIIOpen() (output to a specified file).

    821:    Level: beginner

    823: .seealso: EPSView()
    824: @*/
    825: PetscErrorCode STView(ST st,PetscViewer viewer)
    826: {
    828:   STType         cstr;
    829:   const char*    pat=NULL;
    830:   char           str[50];
    831:   PetscBool      isascii,isstring;

    835:   if (!viewer) {
    836:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)st),&viewer);
    837:   }

    841:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    842:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
    843:   if (isascii) {
    844:     PetscObjectPrintClassNamePrefixType((PetscObject)st,viewer);
    845:     if (st->ops->view) {
    846:       PetscViewerASCIIPushTab(viewer);
    847:       (*st->ops->view)(st,viewer);
    848:       PetscViewerASCIIPopTab(viewer);
    849:     }
    850:     SlepcSNPrintfScalar(str,sizeof(str),st->sigma,PETSC_FALSE);
    851:     PetscViewerASCIIPrintf(viewer,"  shift: %s\n",str);
    852:     PetscViewerASCIIPrintf(viewer,"  number of matrices: %D\n",st->nmat);
    853:     switch (st->matmode) {
    854:     case ST_MATMODE_COPY:
    855:       break;
    856:     case ST_MATMODE_INPLACE:
    857:       PetscViewerASCIIPrintf(viewer,"  shifting the matrix and unshifting at exit\n");
    858:       break;
    859:     case ST_MATMODE_SHELL:
    860:       PetscViewerASCIIPrintf(viewer,"  using a shell matrix\n");
    861:       break;
    862:     }
    863:     if (st->nmat>1 && st->matmode != ST_MATMODE_SHELL) {
    864:       switch (st->str) {
    865:         case SAME_NONZERO_PATTERN:      pat = "same nonzero pattern";break;
    866:         case DIFFERENT_NONZERO_PATTERN: pat = "different nonzero pattern";break;
    867:         case SUBSET_NONZERO_PATTERN:    pat = "subset nonzero pattern";break;
    868:       }
    869:       PetscViewerASCIIPrintf(viewer,"  all matrices have %s\n",pat);
    870:     }
    871:     if (st->transform && st->nmat>2) {
    872:       PetscViewerASCIIPrintf(viewer,"  computing transformed matrices\n");
    873:     }
    874:   } else if (isstring) {
    875:     STGetType(st,&cstr);
    876:     PetscViewerStringSPrintf(viewer," %-7.7s",cstr);
    877:     if (st->ops->view) { (*st->ops->view)(st,viewer); }
    878:   }
    879:   if (st->usesksp) {
    880:     if (!st->ksp) { STGetKSP(st,&st->ksp); }
    881:     PetscViewerASCIIPushTab(viewer);
    882:     KSPView(st->ksp,viewer);
    883:     PetscViewerASCIIPopTab(viewer);
    884:   }
    885:   return(0);
    886: }

    888: /*@C
    889:    STViewFromOptions - View from options

    891:    Collective on ST

    893:    Input Parameters:
    894: +  st   - the spectral transformation context
    895: .  obj  - optional object
    896: -  name - command line option

    898:    Level: intermediate

    900: .seealso: STView(), STCreate()
    901: @*/
    902: PetscErrorCode STViewFromOptions(ST st,PetscObject obj,const char name[])
    903: {

    908:   PetscObjectViewFromOptions((PetscObject)st,obj,name);
    909:   return(0);
    910: }

    912: /*@C
    913:    STRegister - Adds a method to the spectral transformation package.

    915:    Not collective

    917:    Input Parameters:
    918: +  name - name of a new user-defined transformation
    919: -  function - routine to create method context

    921:    Notes:
    922:    STRegister() may be called multiple times to add several user-defined
    923:    spectral transformations.

    925:    Sample usage:
    926: .vb
    927:     STRegister("my_transform",MyTransformCreate);
    928: .ve

    930:    Then, your spectral transform can be chosen with the procedural interface via
    931: $     STSetType(st,"my_transform")
    932:    or at runtime via the option
    933: $     -st_type my_transform

    935:    Level: advanced

    937: .seealso: STRegisterAll()
    938: @*/
    939: PetscErrorCode STRegister(const char *name,PetscErrorCode (*function)(ST))
    940: {

    944:   STInitializePackage();
    945:   PetscFunctionListAdd(&STList,name,function);
    946:   return(0);
    947: }