Date: 2017-05-17T08:25:02+00:00

Actual source code: stfunc.c
slepc-3.7.4 2017-05-17
Report Typos and Errors

      1: /*
      2:     The ST (spectral transformation) interface routines, callable by users.

      4:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      5:    SLEPc - Scalable Library for Eigenvalue Problem Computations
      6:    Copyright (c) 2002-2016, Universitat Politecnica de Valencia, Spain

      8:    This file is part of SLEPc.

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

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

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

     24: #include <slepc/private/stimpl.h>            /*I "slepcst.h" I*/

     26: PetscClassId     ST_CLASSID = 0;
     27: PetscLogEvent    ST_SetUp = 0,ST_Apply = 0,ST_ApplyTranspose = 0,ST_MatSetUp = 0,ST_MatMult = 0,ST_MatMultTranspose = 0,ST_MatSolve = 0,ST_MatSolveTranspose = 0;
     28: static PetscBool STPackageInitialized = PETSC_FALSE;

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

     36:    Level: developer

     38: .seealso: SlepcFinalize()
     39: @*/
     40: PetscErrorCode STFinalizePackage(void)
     41: {

     45:   PetscFunctionListDestroy(&STList);
     46:   STPackageInitialized = PETSC_FALSE;
     47:   STRegisterAllCalled  = PETSC_FALSE;
     48:   return(0);
     49: }

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

     58:    Level: developer

     60: .seealso: SlepcInitialize()
     61: @*/
     62: PetscErrorCode STInitializePackage(void)
     63: {
     64:   char           logList[256];
     65:   char           *className;
     66:   PetscBool      opt;

     70:   if (STPackageInitialized) return(0);
     71:   STPackageInitialized = PETSC_TRUE;
     72:   /* Register Classes */
     73:   PetscClassIdRegister("Spectral Transform",&ST_CLASSID);
     74:   /* Register Constructors */
     75:   STRegisterAll();
     76:   /* Register Events */
     77:   PetscLogEventRegister("STSetUp",ST_CLASSID,&ST_SetUp);
     78:   PetscLogEventRegister("STApply",ST_CLASSID,&ST_Apply);
     79:   PetscLogEventRegister("STApplyTranspose",ST_CLASSID,&ST_ApplyTranspose);
     80:   PetscLogEventRegister("STMatSetUp",ST_CLASSID,&ST_MatSetUp);
     81:   PetscLogEventRegister("STMatMult",ST_CLASSID,&ST_MatMult);
     82:   PetscLogEventRegister("STMatMultTranspose",ST_CLASSID,&ST_MatMultTranspose);
     83:   PetscLogEventRegister("STMatSolve",ST_CLASSID,&ST_MatSolve);
     84:   PetscLogEventRegister("STMatSolveTranspose",ST_CLASSID,&ST_MatSolveTranspose);
     85:   /* Process info exclusions */
     86:   PetscOptionsGetString(NULL,NULL,"-info_exclude",logList,256,&opt);
     87:   if (opt) {
     88:     PetscStrstr(logList,"st",&className);
     89:     if (className) {
     90:       PetscInfoDeactivateClass(ST_CLASSID);
     91:     }
     92:   }
     93:   /* Process summary exclusions */
     94:   PetscOptionsGetString(NULL,NULL,"-log_exclude",logList,256,&opt);
     95:   if (opt) {
     96:     PetscStrstr(logList,"st",&className);
     97:     if (className) {
     98:       PetscLogEventDeactivateClass(ST_CLASSID);
     99:     }
    100:   }
    101:   PetscRegisterFinalize(STFinalizePackage);
    102:   return(0);
    103: }

    107: /*@
    108:    STReset - Resets the ST context and removes any allocated objects.

    110:    Collective on ST

    112:    Input Parameter:
    113: .  st - the spectral transformation context

    115:    Level: advanced

    117: .seealso: STDestroy()
    118: @*/
    119: PetscErrorCode STReset(ST st)
    120: {

    125:   if (st->ops->reset) { (*st->ops->reset)(st); }
    126:   if (st->ksp) { KSPReset(st->ksp); }
    127:   MatDestroyMatrices(PetscMax(2,st->nmat),&st->T);
    128:   VecDestroy(&st->w);
    129:   VecDestroy(&st->wb);
    130:   st->state = ST_STATE_INITIAL;
    131:   return(0);
    132: }

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

    139:    Collective on ST

    141:    Input Parameter:
    142: .  st - the spectral transformation context

    144:    Level: beginner

    146: .seealso: STCreate(), STSetUp()
    147: @*/
    148: PetscErrorCode STDestroy(ST *st)
    149: {

    153:   if (!*st) return(0);
    155:   if (--((PetscObject)(*st))->refct > 0) { *st = 0; return(0); }
    156:   STReset(*st);
    157:   MatDestroyMatrices(PetscMax(2,(*st)->nmat),&(*st)->A);
    158:   PetscFree((*st)->Astate);
    159:   if ((*st)->ops->destroy) { (*(*st)->ops->destroy)(*st); }
    160:   MatDestroy(&(*st)->P);
    161:   VecDestroy(&(*st)->D);
    162:   KSPDestroy(&(*st)->ksp);
    163:   PetscHeaderDestroy(st);
    164:   return(0);
    165: }

    169: /*@
    170:    STCreate - Creates a spectral transformation context.

    172:    Collective on MPI_Comm

    174:    Input Parameter:
    175: .  comm - MPI communicator

    177:    Output Parameter:
    178: .  st - location to put the spectral transformation context

    180:    Level: beginner

    182: .seealso: STSetUp(), STApply(), STDestroy(), ST
    183: @*/
    184: PetscErrorCode STCreate(MPI_Comm comm,ST *newst)
    185: {
    187:   ST             st;

    191:   *newst = 0;
    192:   STInitializePackage();
    193:   SlepcHeaderCreate(st,ST_CLASSID,"ST","Spectral Transformation","ST",comm,STDestroy,STView);

    195:   st->A            = NULL;
    196:   st->Astate       = NULL;
    197:   st->T            = NULL;
    198:   st->P            = NULL;
    199:   st->nmat         = 0;
    200:   st->sigma        = 0.0;
    201:   st->sigma_set    = PETSC_FALSE;
    202:   st->defsigma     = 0.0;
    203:   st->shift_matrix = ST_MATMODE_COPY;
    204:   st->str          = DIFFERENT_NONZERO_PATTERN;
    205:   st->transform    = PETSC_FALSE;

    207:   st->ksp          = NULL;
    208:   st->w            = NULL;
    209:   st->D            = NULL;
    210:   st->wb           = NULL;
    211:   st->data         = NULL;
    212:   st->state        = ST_STATE_INITIAL;

    214:   *newst = st;
    215:   return(0);
    216: }

    220: /*@
    221:    STSetOperators - Sets the matrices associated with the eigenvalue problem.

    223:    Collective on ST and Mat

    225:    Input Parameters:
    226: +  st - the spectral transformation context
    227: .  n  - number of matrices in array A
    228: -  A  - the array of matrices associated with the eigensystem

    230:    Notes:
    231:    It must be called before STSetUp(). If it is called again after STSetUp() then
    232:    the ST object is reset.

    234:    Level: intermediate

    236: .seealso: STGetOperators(), STGetNumMatrices(), STSetUp(), STReset()
    237:  @*/
    238: PetscErrorCode STSetOperators(ST st,PetscInt n,Mat A[])
    239: {
    240:   PetscInt       i;
    242:   PetscBool      same=PETSC_TRUE;

    247:   if (n <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more matrices, you have %D",n);
    250:   if (st->state) {
    251:     if (n!=st->nmat) same = PETSC_FALSE;
    252:     for (i=0;same&&i<n;i++) {
    253:       if (A[i]!=st->A[i]) same = PETSC_FALSE;
    254:     }
    255:     if (!same) { STReset(st); }
    256:   } else same = PETSC_FALSE;
    257:   if (!same) {
    258:     MatDestroyMatrices(PetscMax(2,st->nmat),&st->A);
    259:     PetscCalloc1(PetscMax(2,n),&st->A);
    260:     PetscLogObjectMemory((PetscObject)st,PetscMax(2,n)*sizeof(Mat));
    261:     PetscFree(st->Astate);
    262:     PetscMalloc1(PetscMax(2,n),&st->Astate);
    263:     PetscLogObjectMemory((PetscObject)st,PetscMax(2,n)*sizeof(PetscInt));
    264:   }
    265:   for (i=0;i<n;i++) {
    267:     PetscObjectReference((PetscObject)A[i]);
    268:     MatDestroy(&st->A[i]);
    269:     st->A[i] = A[i];
    270:     st->Astate[i] = ((PetscObject)A[i])->state;
    271:   }
    272:   if (n==1) {
    273:     st->A[1] = NULL;
    274:     st->Astate[1] = 0;
    275:   }
    276:   st->nmat = n;
    277:   if (same) st->state = ST_STATE_UPDATED;
    278:   else st->state = ST_STATE_INITIAL;
    279:   return(0);
    280: }

    284: /*@
    285:    STGetOperators - Gets the matrices associated with the original eigensystem.

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

    289:    Input Parameter:
    290: +  st - the spectral transformation context
    291: -  k  - the index of the requested matrix (starting in 0)

    293:    Output Parameters:
    294: .  A - the requested matrix

    296:    Level: intermediate

    298: .seealso: STSetOperators(), STGetNumMatrices()
    299: @*/
    300: PetscErrorCode STGetOperators(ST st,PetscInt k,Mat *A)
    301: {
    306:   STCheckMatrices(st,1);
    307:   if (k<0 || k>=st->nmat) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"k must be between 0 and %D",st->nmat-1);
    308:   if (((PetscObject)st->A[k])->state!=st->Astate[k]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot retrieve original matrices (have been modified)");
    309:   *A = st->A[k];
    310:   return(0);
    311: }

    315: /*@
    316:    STGetTOperators - Gets the matrices associated with the transformed eigensystem.

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

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

    324:    Output Parameters:
    325: .  T - the requested matrix

    327:    Level: developer

    329: .seealso: STGetOperators(), STGetNumMatrices()
    330: @*/
    331: PetscErrorCode STGetTOperators(ST st,PetscInt k,Mat *T)
    332: {
    337:   STCheckMatrices(st,1);
    338:   if (k<0 || k>=st->nmat) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"k must be between 0 and %D",st->nmat-1);
    339:   if (!st->T) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_POINTER,"There are no transformed matrices");
    340:   *T = st->T[k];
    341:   return(0);
    342: }

    346: /*@
    347:    STGetNumMatrices - Returns the number of matrices stored in the ST.

    349:    Not collective

    351:    Input Parameter:
    352: .  st - the spectral transformation context

    354:    Output Parameters:
    355: .  n - the number of matrices passed in STSetOperators()

    357:    Level: intermediate

    359: .seealso: STSetOperators()
    360: @*/
    361: PetscErrorCode STGetNumMatrices(ST st,PetscInt *n)
    362: {
    366:   *n = st->nmat;
    367:   return(0);
    368: }

    372: /*@
    373:    STSetShift - Sets the shift associated with the spectral transformation.

    375:    Logically Collective on ST

    377:    Input Parameters:
    378: +  st - the spectral transformation context
    379: -  shift - the value of the shift

    381:    Notes:
    382:    In some spectral transformations, changing the shift may have associated
    383:    a lot of work, for example recomputing a factorization.

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

    388:    Level: intermediate

    390: .seealso: EPSSetTarget(), STGetShift(), STSetDefaultShift()
    391: @*/
    392: PetscErrorCode STSetShift(ST st,PetscScalar shift)
    393: {

    399:   if (st->state==ST_STATE_SETUP && st->sigma != shift) {
    400:     if (st->ops->setshift) {
    401:       (*st->ops->setshift)(st,shift);
    402:     }
    403:   }
    404:   st->sigma = shift;
    405:   st->sigma_set = PETSC_TRUE;
    406:   return(0);
    407: }

    411: /*@
    412:    STGetShift - Gets the shift associated with the spectral transformation.

    414:    Not Collective

    416:    Input Parameter:
    417: .  st - the spectral transformation context

    419:    Output Parameter:
    420: .  shift - the value of the shift

    422:    Level: intermediate

    424: .seealso: STSetShift()
    425: @*/
    426: PetscErrorCode STGetShift(ST st,PetscScalar* shift)
    427: {
    431:   *shift = st->sigma;
    432:   return(0);
    433: }

    437: /*@
    438:    STSetDefaultShift - Sets the value of the shift that should be employed if
    439:    the user did not specify one.

    441:    Logically Collective on ST

    443:    Input Parameters:
    444: +  st - the spectral transformation context
    445: -  defaultshift - the default value of the shift

    447:    Level: developer

    449: .seealso: STSetShift()
    450: @*/
    451: PetscErrorCode STSetDefaultShift(ST st,PetscScalar defaultshift)
    452: {
    456:   st->defsigma = defaultshift;
    457:   return(0);
    458: }

    462: /*@
    463:    STScaleShift - Multiply the shift with a given factor.

    465:    Logically Collective on ST

    467:    Input Parameters:
    468: +  st     - the spectral transformation context
    469: -  factor - the scaling factor

    471:    Note:
    472:    This function does not update the transformation matrices, as opposed to
    473:    STSetShift().

    475:    Level: developer

    477: .seealso: STSetShift()
    478: @*/
    479: PetscErrorCode STScaleShift(ST st,PetscScalar factor)
    480: {
    484:   st->sigma *= factor;
    485:   return(0);
    486: }

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

    493:    Collective on ST and Vec

    495:    Input Parameters:
    496: +  st - the spectral transformation context
    497: -  D  - the diagonal matrix (represented as a vector)

    499:    Notes:
    500:    If this matrix is set, STApply will effectively apply D*OP*D^{-1}.

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

    505:    Level: developer

    507: .seealso: EPSSetBalance(), STApply(), STGetBalanceMatrix()
    508: @*/
    509: PetscErrorCode STSetBalanceMatrix(ST st,Vec D)
    510: {

    517:   PetscObjectReference((PetscObject)D);
    518:   VecDestroy(&st->D);
    519:   st->D = D;
    520:   st->state = ST_STATE_INITIAL;
    521:   return(0);
    522: }

    526: /*@
    527:    STGetBalanceMatrix - Gets the balance matrix used by the spectral transformation.

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

    531:    Input Parameter:
    532: .  st - the spectral transformation context

    534:    Output Parameter:
    535: .  D  - the diagonal matrix (represented as a vector)

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

    540:    Level: developer

    542: .seealso: STSetBalanceMatrix()
    543: @*/
    544: PetscErrorCode STGetBalanceMatrix(ST st,Vec *D)
    545: {
    549:   *D = st->D;
    550:   return(0);
    551: }

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

    558:    Collective on ST

    560:    Input Parameter:
    561: .  st - the spectral transformation context

    563:    Output Parameters:
    564: +  right - (optional) vector that the matrix can be multiplied against
    565: -  left  - (optional) vector that the matrix vector product can be stored in

    567:    Level: developer
    568: @*/
    569: PetscErrorCode STMatCreateVecs(ST st,Vec *right,Vec *left)
    570: {

    574:   STCheckMatrices(st,1);
    575:   MatCreateVecs(st->A[0],right,left);
    576:   return(0);
    577: }

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

    584:    Not Collective

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

    589:    Output Parameters:
    590: +  m - the number of global rows
    591: -  n - the number of global columns

    593:    Level: developer
    594: @*/
    595: PetscErrorCode STMatGetSize(ST st,PetscInt *m,PetscInt *n)
    596: {

    600:   STCheckMatrices(st,1);
    601:   MatGetSize(st->A[0],m,n);
    602:   return(0);
    603: }

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

    610:    Not Collective

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

    615:    Output Parameters:
    616: +  m - the number of local rows
    617: -  n - the number of local columns

    619:    Level: developer
    620: @*/
    621: PetscErrorCode STMatGetLocalSize(ST st,PetscInt *m,PetscInt *n)
    622: {

    626:   STCheckMatrices(st,1);
    627:   MatGetLocalSize(st->A[0],m,n);
    628:   return(0);
    629: }

    633: /*@C
    634:    STSetOptionsPrefix - Sets the prefix used for searching for all
    635:    ST options in the database.

    637:    Logically Collective on ST

    639:    Input Parameters:
    640: +  st     - the spectral transformation context
    641: -  prefix - the prefix string to prepend to all ST option requests

    643:    Notes:
    644:    A hyphen (-) must NOT be given at the beginning of the prefix name.
    645:    The first character of all runtime options is AUTOMATICALLY the
    646:    hyphen.

    648:    Level: advanced

    650: .seealso: STAppendOptionsPrefix(), STGetOptionsPrefix()
    651: @*/
    652: PetscErrorCode STSetOptionsPrefix(ST st,const char *prefix)
    653: {

    658:   if (!st->ksp) { STGetKSP(st,&st->ksp); }
    659:   KSPSetOptionsPrefix(st->ksp,prefix);
    660:   KSPAppendOptionsPrefix(st->ksp,"st_");
    661:   PetscObjectSetOptionsPrefix((PetscObject)st,prefix);
    662:   return(0);
    663: }

    667: /*@C
    668:    STAppendOptionsPrefix - Appends to the prefix used for searching for all
    669:    ST options in the database.

    671:    Logically Collective on ST

    673:    Input Parameters:
    674: +  st     - the spectral transformation context
    675: -  prefix - the prefix string to prepend to all ST option requests

    677:    Notes:
    678:    A hyphen (-) must NOT be given at the beginning of the prefix name.
    679:    The first character of all runtime options is AUTOMATICALLY the
    680:    hyphen.

    682:    Level: advanced

    684: .seealso: STSetOptionsPrefix(), STGetOptionsPrefix()
    685: @*/
    686: PetscErrorCode STAppendOptionsPrefix(ST st,const char *prefix)
    687: {

    692:   PetscObjectAppendOptionsPrefix((PetscObject)st,prefix);
    693:   if (!st->ksp) { STGetKSP(st,&st->ksp); }
    694:   KSPSetOptionsPrefix(st->ksp,((PetscObject)st)->prefix);
    695:   KSPAppendOptionsPrefix(st->ksp,"st_");
    696:   return(0);
    697: }

    701: /*@C
    702:    STGetOptionsPrefix - Gets the prefix used for searching for all
    703:    ST options in the database.

    705:    Not Collective

    707:    Input Parameters:
    708: .  st - the spectral transformation context

    710:    Output Parameters:
    711: .  prefix - pointer to the prefix string used, is returned

    713:    Note:
    714:    On the Fortran side, the user should pass in a string 'prefix' of
    715:    sufficient length to hold the prefix.

    717:    Level: advanced

    719: .seealso: STSetOptionsPrefix(), STAppendOptionsPrefix()
    720: @*/
    721: PetscErrorCode STGetOptionsPrefix(ST st,const char *prefix[])
    722: {

    728:   PetscObjectGetOptionsPrefix((PetscObject)st,prefix);
    729:   return(0);
    730: }

    734: /*@C
    735:    STView - Prints the ST data structure.

    737:    Collective on ST

    739:    Input Parameters:
    740: +  st - the ST context
    741: -  viewer - optional visualization context

    743:    Note:
    744:    The available visualization contexts include
    745: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
    746: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
    747:          output where only the first processor opens
    748:          the file.  All other processors send their
    749:          data to the first processor to print.

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

    754:    Level: beginner

    756: .seealso: EPSView(), PetscViewerASCIIOpen()
    757: @*/
    758: PetscErrorCode STView(ST st,PetscViewer viewer)
    759: {
    761:   STType         cstr;
    762:   const char*    pat;
    763:   char           str[50];
    764:   PetscBool      isascii,isstring,flg;

    768:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)st));

    772:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    773:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
    774:   if (isascii) {
    775:     PetscObjectPrintClassNamePrefixType((PetscObject)st,viewer);
    776:     if (st->ops->view) {
    777:       PetscViewerASCIIPushTab(viewer);
    778:       (*st->ops->view)(st,viewer);
    779:       PetscViewerASCIIPopTab(viewer);
    780:     }
    781:     SlepcSNPrintfScalar(str,50,st->sigma,PETSC_FALSE);
    782:     PetscViewerASCIIPrintf(viewer,"  shift: %s\n",str);
    783:     PetscViewerASCIIPrintf(viewer,"  number of matrices: %D\n",st->nmat);
    784:     switch (st->shift_matrix) {
    785:     case ST_MATMODE_COPY:
    786:       break;
    787:     case ST_MATMODE_INPLACE:
    788:       PetscViewerASCIIPrintf(viewer,"  shifting the matrix and unshifting at exit\n");
    789:       break;
    790:     case ST_MATMODE_SHELL:
    791:       PetscViewerASCIIPrintf(viewer,"  using a shell matrix\n");
    792:       break;
    793:     }
    794:     if (st->nmat>1 && st->shift_matrix != ST_MATMODE_SHELL) {
    795:       switch (st->str) {
    796:         case SAME_NONZERO_PATTERN:      pat = "same nonzero pattern";break;
    797:         case DIFFERENT_NONZERO_PATTERN: pat = "different nonzero pattern";break;
    798:         case SUBSET_NONZERO_PATTERN:    pat = "subset nonzero pattern";break;
    799:         default: SETERRQ(PetscObjectComm((PetscObject)st),1,"Wrong structure flag");
    800:       }
    801:       PetscViewerASCIIPrintf(viewer,"  all matrices have %s\n",pat);
    802:     }
    803:     if (st->transform && st->nmat>2) {
    804:       PetscViewerASCIIPrintf(viewer,"  computing transformed matrices\n");
    805:     }
    806:   } else if (isstring) {
    807:     STGetType(st,&cstr);
    808:     PetscViewerStringSPrintf(viewer," %-7.7s",cstr);
    809:     if (st->ops->view) { (*st->ops->view)(st,viewer); }
    810:   }
    811:   PetscObjectTypeCompare((PetscObject)st,STSHIFT,&flg);
    812:   if (st->nmat>1 || !flg) {
    813:     if (!st->ksp) { STGetKSP(st,&st->ksp); }
    814:     PetscViewerASCIIPushTab(viewer);
    815:     KSPView(st->ksp,viewer);
    816:     PetscViewerASCIIPopTab(viewer);
    817:   }
    818:   return(0);
    819: }

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

    826:    Not collective

    828:    Input Parameters:
    829: +  name - name of a new user-defined transformation
    830: -  function - routine to create method context

    832:    Notes:
    833:    STRegister() may be called multiple times to add several user-defined
    834:    spectral transformations.

    836:    Sample usage:
    837: .vb
    838:     STRegister("my_transform",MyTransformCreate);
    839: .ve

    841:    Then, your spectral transform can be chosen with the procedural interface via
    842: $     STSetType(st,"my_transform")
    843:    or at runtime via the option
    844: $     -st_type my_transform

    846:    Level: advanced

    848: .seealso: STRegisterAll()
    849: @*/
    850: PetscErrorCode STRegister(const char *name,PetscErrorCode (*function)(ST))
    851: {

    855:   PetscFunctionListAdd(&STList,name,function);
    856:   return(0);
    857: }