Date: 2022-03-31T15:28:49+00:00

Actual source code: dsbasic.c
slepc-3.17.0 2022-03-31
Report Typos and Errors

      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:    Basic DS routines
     12: */

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

     16: PetscFunctionList DSList = 0;
     17: PetscBool         DSRegisterAllCalled = PETSC_FALSE;
     18: PetscClassId      DS_CLASSID = 0;
     19: PetscLogEvent     DS_Solve = 0,DS_Vectors = 0,DS_Synchronize = 0,DS_Other = 0;
     20: static PetscBool  DSPackageInitialized = PETSC_FALSE;

     22: const char *DSStateTypes[] = {"RAW","INTERMEDIATE","CONDENSED","TRUNCATED","DSStateType","DS_STATE_",0};
     23: const char *DSParallelTypes[] = {"REDUNDANT","SYNCHRONIZED","DISTRIBUTED","DSParallelType","DS_PARALLEL_",0};
     24: const char *DSMatName[DS_NUM_MAT] = {"A","B","C","T","D","Q","Z","X","Y","U","V","W","E0","E1","E2","E3","E4","E5","E6","E7","E8","E9"};
     25: DSMatType  DSMatExtra[DS_NUM_EXTRA] = {DS_MAT_E0,DS_MAT_E1,DS_MAT_E2,DS_MAT_E3,DS_MAT_E4,DS_MAT_E5,DS_MAT_E6,DS_MAT_E7,DS_MAT_E8,DS_MAT_E9};

     27: /*@C
     28:    DSFinalizePackage - This function destroys everything in the SLEPc interface
     29:    to the DS package. It is called from SlepcFinalize().

     31:    Level: developer

     33: .seealso: SlepcFinalize()
     34: @*/
     35: PetscErrorCode DSFinalizePackage(void)
     36: {
     37:   PetscFunctionListDestroy(&DSList);
     38:   DSPackageInitialized = PETSC_FALSE;
     39:   DSRegisterAllCalled  = PETSC_FALSE;
     40:   PetscFunctionReturn(0);
     41: }

     43: /*@C
     44:   DSInitializePackage - This function initializes everything in the DS package.
     45:   It is called from PetscDLLibraryRegister() when using dynamic libraries, and
     46:   on the first call to DSCreate() when using static libraries.

     48:   Level: developer

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

     58:   if (DSPackageInitialized) PetscFunctionReturn(0);
     59:   DSPackageInitialized = PETSC_TRUE;
     60:   /* Register Classes */
     61:   PetscClassIdRegister("Direct Solver",&DS_CLASSID);
     62:   /* Register Constructors */
     63:   DSRegisterAll();
     64:   /* Register Events */
     65:   PetscLogEventRegister("DSSolve",DS_CLASSID,&DS_Solve);
     66:   PetscLogEventRegister("DSVectors",DS_CLASSID,&DS_Vectors);
     67:   PetscLogEventRegister("DSSynchronize",DS_CLASSID,&DS_Synchronize);
     68:   PetscLogEventRegister("DSOther",DS_CLASSID,&DS_Other);
     69:   /* Process Info */
     70:   classids[0] = DS_CLASSID;
     71:   PetscInfoProcessClass("ds",1,&classids[0]);
     72:   /* Process summary exclusions */
     73:   PetscOptionsGetString(NULL,NULL,"-log_exclude",logList,sizeof(logList),&opt);
     74:   if (opt) {
     75:     PetscStrInList("ds",logList,',',&pkg);
     76:     if (pkg) PetscLogEventDeactivateClass(DS_CLASSID);
     77:   }
     78:   /* Register package finalizer */
     79:   PetscRegisterFinalize(DSFinalizePackage);
     80:   PetscFunctionReturn(0);
     81: }

     83: /*@
     84:    DSCreate - Creates a DS context.

     86:    Collective

     88:    Input Parameter:
     89: .  comm - MPI communicator

     91:    Output Parameter:
     92: .  newds - location to put the DS context

     94:    Level: beginner

     96:    Note:
     97:    DS objects are not intended for normal users but only for
     98:    advanced user that for instance implement their own solvers.

    100: .seealso: DSDestroy(), DS
    101: @*/
    102: PetscErrorCode DSCreate(MPI_Comm comm,DS *newds)
    103: {
    104:   DS             ds;
    105:   PetscInt       i;

    108:   *newds = 0;
    109:   DSInitializePackage();
    110:   SlepcHeaderCreate(ds,DS_CLASSID,"DS","Direct Solver (or Dense System)","DS",comm,DSDestroy,DSView);

    112:   ds->state         = DS_STATE_RAW;
    113:   ds->method        = 0;
    114:   ds->compact       = PETSC_FALSE;
    115:   ds->refined       = PETSC_FALSE;
    116:   ds->extrarow      = PETSC_FALSE;
    117:   ds->ld            = 0;
    118:   ds->l             = 0;
    119:   ds->n             = 0;
    120:   ds->k             = 0;
    121:   ds->t             = 0;
    122:   ds->bs            = 1;
    123:   ds->sc            = NULL;
    124:   ds->pmode         = DS_PARALLEL_REDUNDANT;

    126:   for (i=0;i<DS_NUM_MAT;i++) {
    127:     ds->mat[i]      = NULL;
    128:     ds->rmat[i]     = NULL;
    129:     ds->omat[i]     = NULL;
    130:   }
    131:   ds->perm          = NULL;
    132:   ds->data          = NULL;
    133:   ds->scset         = PETSC_FALSE;
    134:   ds->work          = NULL;
    135:   ds->rwork         = NULL;
    136:   ds->iwork         = NULL;
    137:   ds->lwork         = 0;
    138:   ds->lrwork        = 0;
    139:   ds->liwork        = 0;

    141:   *newds = ds;
    142:   PetscFunctionReturn(0);
    143: }

    145: /*@C
    146:    DSSetOptionsPrefix - Sets the prefix used for searching for all
    147:    DS options in the database.

    149:    Logically Collective on ds

    151:    Input Parameters:
    152: +  ds - the direct solver context
    153: -  prefix - the prefix string to prepend to all DS option requests

    155:    Notes:
    156:    A hyphen (-) must NOT be given at the beginning of the prefix name.
    157:    The first character of all runtime options is AUTOMATICALLY the
    158:    hyphen.

    160:    Level: advanced

    162: .seealso: DSAppendOptionsPrefix()
    163: @*/
    164: PetscErrorCode DSSetOptionsPrefix(DS ds,const char *prefix)
    165: {
    167:   PetscObjectSetOptionsPrefix((PetscObject)ds,prefix);
    168:   PetscFunctionReturn(0);
    169: }

    171: /*@C
    172:    DSAppendOptionsPrefix - Appends to the prefix used for searching for all
    173:    DS options in the database.

    175:    Logically Collective on ds

    177:    Input Parameters:
    178: +  ds - the direct solver context
    179: -  prefix - the prefix string to prepend to all DS option requests

    181:    Notes:
    182:    A hyphen (-) must NOT be given at the beginning of the prefix name.
    183:    The first character of all runtime options is AUTOMATICALLY the hyphen.

    185:    Level: advanced

    187: .seealso: DSSetOptionsPrefix()
    188: @*/
    189: PetscErrorCode DSAppendOptionsPrefix(DS ds,const char *prefix)
    190: {
    192:   PetscObjectAppendOptionsPrefix((PetscObject)ds,prefix);
    193:   PetscFunctionReturn(0);
    194: }

    196: /*@C
    197:    DSGetOptionsPrefix - Gets the prefix used for searching for all
    198:    DS options in the database.

    200:    Not Collective

    202:    Input Parameters:
    203: .  ds - the direct solver context

    205:    Output Parameters:
    206: .  prefix - pointer to the prefix string used is returned

    208:    Note:
    209:    On the Fortran side, the user should pass in a string 'prefix' of
    210:    sufficient length to hold the prefix.

    212:    Level: advanced

    214: .seealso: DSSetOptionsPrefix(), DSAppendOptionsPrefix()
    215: @*/
    216: PetscErrorCode DSGetOptionsPrefix(DS ds,const char *prefix[])
    217: {
    220:   PetscObjectGetOptionsPrefix((PetscObject)ds,prefix);
    221:   PetscFunctionReturn(0);
    222: }

    224: /*@C
    225:    DSSetType - Selects the type for the DS object.

    227:    Logically Collective on ds

    229:    Input Parameters:
    230: +  ds   - the direct solver context
    231: -  type - a known type

    233:    Level: intermediate

    235: .seealso: DSGetType()
    236: @*/
    237: PetscErrorCode DSSetType(DS ds,DSType type)
    238: {
    239:   PetscErrorCode (*r)(DS);
    240:   PetscBool      match;

    245:   PetscObjectTypeCompare((PetscObject)ds,type,&match);
    246:   if (match) PetscFunctionReturn(0);

    248:   PetscFunctionListFind(DSList,type,&r);

    251:   PetscMemzero(ds->ops,sizeof(struct _DSOps));

    253:   PetscObjectChangeTypeName((PetscObject)ds,type);
    254:   (*r)(ds);
    255:   PetscFunctionReturn(0);
    256: }

    258: /*@C
    259:    DSGetType - Gets the DS type name (as a string) from the DS context.

    261:    Not Collective

    263:    Input Parameter:
    264: .  ds - the direct solver context

    266:    Output Parameter:
    267: .  type - name of the direct solver

    269:    Level: intermediate

    271: .seealso: DSSetType()
    272: @*/
    273: PetscErrorCode DSGetType(DS ds,DSType *type)
    274: {
    277:   *type = ((PetscObject)ds)->type_name;
    278:   PetscFunctionReturn(0);
    279: }

    281: /*@
    282:    DSDuplicate - Creates a new direct solver object with the same options as
    283:    an existing one.

    285:    Collective on ds

    287:    Input Parameter:
    288: .  ds - direct solver context

    290:    Output Parameter:
    291: .  dsnew - location to put the new DS

    293:    Notes:
    294:    DSDuplicate() DOES NOT COPY the matrices, and the new DS does not even have
    295:    internal arrays allocated. Use DSAllocate() to use the new DS.

    297:    The sorting criterion options are not copied, see DSSetSlepcSC().

    299:    Level: intermediate

    301: .seealso: DSCreate(), DSAllocate(), DSSetSlepcSC()
    302: @*/
    303: PetscErrorCode DSDuplicate(DS ds,DS *dsnew)
    304: {
    307:   DSCreate(PetscObjectComm((PetscObject)ds),dsnew);
    308:   if (((PetscObject)ds)->type_name) DSSetType(*dsnew,((PetscObject)ds)->type_name);
    309:   (*dsnew)->method   = ds->method;
    310:   (*dsnew)->compact  = ds->compact;
    311:   (*dsnew)->refined  = ds->refined;
    312:   (*dsnew)->extrarow = ds->extrarow;
    313:   (*dsnew)->bs       = ds->bs;
    314:   (*dsnew)->pmode    = ds->pmode;
    315:   PetscFunctionReturn(0);
    316: }

    318: /*@
    319:    DSSetMethod - Selects the method to be used to solve the problem.

    321:    Logically Collective on ds

    323:    Input Parameters:
    324: +  ds   - the direct solver context
    325: -  meth - an index identifying the method

    327:    Options Database Key:
    328: .  -ds_method <meth> - Sets the method

    330:    Level: intermediate

    332: .seealso: DSGetMethod()
    333: @*/
    334: PetscErrorCode DSSetMethod(DS ds,PetscInt meth)
    335: {
    340:   ds->method = meth;
    341:   PetscFunctionReturn(0);
    342: }

    344: /*@
    345:    DSGetMethod - Gets the method currently used in the DS.

    347:    Not Collective

    349:    Input Parameter:
    350: .  ds - the direct solver context

    352:    Output Parameter:
    353: .  meth - identifier of the method

    355:    Level: intermediate

    357: .seealso: DSSetMethod()
    358: @*/
    359: PetscErrorCode DSGetMethod(DS ds,PetscInt *meth)
    360: {
    363:   *meth = ds->method;
    364:   PetscFunctionReturn(0);
    365: }

    367: /*@
    368:    DSSetParallel - Selects the mode of operation in parallel runs.

    370:    Logically Collective on ds

    372:    Input Parameters:
    373: +  ds    - the direct solver context
    374: -  pmode - the parallel mode

    376:    Options Database Key:
    377: .  -ds_parallel <mode> - Sets the parallel mode, 'redundant', 'synchronized'
    378:    or 'distributed'

    380:    Notes:
    381:    In the 'redundant' parallel mode, all processes will make the computation
    382:    redundantly, starting from the same data, and producing the same result.
    383:    This result may be slightly different in the different processes if using a
    384:    multithreaded BLAS library, which may cause issues in ill-conditioned problems.

    386:    In the 'synchronized' parallel mode, only the first MPI process performs the
    387:    computation and then the computed quantities are broadcast to the other
    388:    processes in the communicator. This communication is not done automatically,
    389:    an explicit call to DSSynchronize() is required.

    391:    The 'distributed' parallel mode can be used in some DS types only, such
    392:    as the contour integral method of DSNEP. In this case, every MPI process
    393:    will be in charge of part of the computation.

    395:    Level: advanced

    397: .seealso: DSSynchronize(), DSGetParallel()
    398: @*/
    399: PetscErrorCode DSSetParallel(DS ds,DSParallelType pmode)
    400: {
    403:   ds->pmode = pmode;
    404:   PetscFunctionReturn(0);
    405: }

    407: /*@
    408:    DSGetParallel - Gets the mode of operation in parallel runs.

    410:    Not Collective

    412:    Input Parameter:
    413: .  ds - the direct solver context

    415:    Output Parameter:
    416: .  pmode - the parallel mode

    418:    Level: advanced

    420: .seealso: DSSetParallel()
    421: @*/
    422: PetscErrorCode DSGetParallel(DS ds,DSParallelType *pmode)
    423: {
    426:   *pmode = ds->pmode;
    427:   PetscFunctionReturn(0);
    428: }

    430: /*@
    431:    DSSetCompact - Switch to compact storage of matrices.

    433:    Logically Collective on ds

    435:    Input Parameters:
    436: +  ds   - the direct solver context
    437: -  comp - a boolean flag

    439:    Notes:
    440:    Compact storage is used in some DS types such as DSHEP when the matrix
    441:    is tridiagonal. This flag can be used to indicate whether the user
    442:    provides the matrix entries via the compact form (the tridiagonal DS_MAT_T)
    443:    or the non-compact one (DS_MAT_A).

    445:    The default is PETSC_FALSE.

    447:    Level: advanced

    449: .seealso: DSGetCompact()
    450: @*/
    451: PetscErrorCode DSSetCompact(DS ds,PetscBool comp)
    452: {
    455:   ds->compact = comp;
    456:   PetscFunctionReturn(0);
    457: }

    459: /*@
    460:    DSGetCompact - Gets the compact storage flag.

    462:    Not Collective

    464:    Input Parameter:
    465: .  ds - the direct solver context

    467:    Output Parameter:
    468: .  comp - the flag

    470:    Level: advanced

    472: .seealso: DSSetCompact()
    473: @*/
    474: PetscErrorCode DSGetCompact(DS ds,PetscBool *comp)
    475: {
    478:   *comp = ds->compact;
    479:   PetscFunctionReturn(0);
    480: }

    482: /*@
    483:    DSSetExtraRow - Sets a flag to indicate that the matrix has one extra
    484:    row.

    486:    Logically Collective on ds

    488:    Input Parameters:
    489: +  ds  - the direct solver context
    490: -  ext - a boolean flag

    492:    Notes:
    493:    In Krylov methods it is useful that the matrix representing the direct solver
    494:    has one extra row, i.e., has dimension (n+1) x n. If this flag is activated, all
    495:    transformations applied to the right of the matrix also affect this additional
    496:    row. In that case, (n+1) must be less or equal than the leading dimension.

    498:    The default is PETSC_FALSE.

    500:    Level: advanced

    502: .seealso: DSSolve(), DSAllocate(), DSGetExtraRow()
    503: @*/
    504: PetscErrorCode DSSetExtraRow(DS ds,PetscBool ext)
    505: {
    509:   ds->extrarow = ext;
    510:   PetscFunctionReturn(0);
    511: }

    513: /*@
    514:    DSGetExtraRow - Gets the extra row flag.

    516:    Not Collective

    518:    Input Parameter:
    519: .  ds - the direct solver context

    521:    Output Parameter:
    522: .  ext - the flag

    524:    Level: advanced

    526: .seealso: DSSetExtraRow()
    527: @*/
    528: PetscErrorCode DSGetExtraRow(DS ds,PetscBool *ext)
    529: {
    532:   *ext = ds->extrarow;
    533:   PetscFunctionReturn(0);
    534: }

    536: /*@
    537:    DSSetRefined - Sets a flag to indicate that refined vectors must be
    538:    computed.

    540:    Logically Collective on ds

    542:    Input Parameters:
    543: +  ds  - the direct solver context
    544: -  ref - a boolean flag

    546:    Notes:
    547:    Normally the vectors returned in DS_MAT_X are eigenvectors of the
    548:    projected matrix. With this flag activated, DSVectors() will return
    549:    the right singular vector of the smallest singular value of matrix
    550:    \tilde{A}-theta*I, where \tilde{A} is the extended (n+1)xn matrix
    551:    and theta is the Ritz value. This is used in the refined Ritz
    552:    approximation.

    554:    The default is PETSC_FALSE.

    556:    Level: advanced

    558: .seealso: DSVectors(), DSGetRefined()
    559: @*/
    560: PetscErrorCode DSSetRefined(DS ds,PetscBool ref)
    561: {
    564:   ds->refined = ref;
    565:   PetscFunctionReturn(0);
    566: }

    568: /*@
    569:    DSGetRefined - Gets the refined vectors flag.

    571:    Not Collective

    573:    Input Parameter:
    574: .  ds - the direct solver context

    576:    Output Parameter:
    577: .  ref - the flag

    579:    Level: advanced

    581: .seealso: DSSetRefined()
    582: @*/
    583: PetscErrorCode DSGetRefined(DS ds,PetscBool *ref)
    584: {
    587:   *ref = ds->refined;
    588:   PetscFunctionReturn(0);
    589: }

    591: /*@
    592:    DSSetBlockSize - Sets the block size.

    594:    Logically Collective on ds

    596:    Input Parameters:
    597: +  ds - the direct solver context
    598: -  bs - the block size

    600:    Options Database Key:
    601: .  -ds_block_size <bs> - Sets the block size

    603:    Level: intermediate

    605: .seealso: DSGetBlockSize()
    606: @*/
    607: PetscErrorCode DSSetBlockSize(DS ds,PetscInt bs)
    608: {
    612:   ds->bs = bs;
    613:   PetscFunctionReturn(0);
    614: }

    616: /*@
    617:    DSGetBlockSize - Gets the block size.

    619:    Not Collective

    621:    Input Parameter:
    622: .  ds - the direct solver context

    624:    Output Parameter:
    625: .  bs - block size

    627:    Level: intermediate

    629: .seealso: DSSetBlockSize()
    630: @*/
    631: PetscErrorCode DSGetBlockSize(DS ds,PetscInt *bs)
    632: {
    635:   *bs = ds->bs;
    636:   PetscFunctionReturn(0);
    637: }

    639: /*@C
    640:    DSSetSlepcSC - Sets the sorting criterion context.

    642:    Not Collective

    644:    Input Parameters:
    645: +  ds - the direct solver context
    646: -  sc - a pointer to the sorting criterion context

    648:    Level: developer

    650: .seealso: DSGetSlepcSC(), DSSort()
    651: @*/
    652: PetscErrorCode DSSetSlepcSC(DS ds,SlepcSC sc)
    653: {
    656:   if (ds->sc && !ds->scset) PetscFree(ds->sc);
    657:   ds->sc    = sc;
    658:   ds->scset = PETSC_TRUE;
    659:   PetscFunctionReturn(0);
    660: }

    662: /*@C
    663:    DSGetSlepcSC - Gets the sorting criterion context.

    665:    Not Collective

    667:    Input Parameter:
    668: .  ds - the direct solver context

    670:    Output Parameters:
    671: .  sc - a pointer to the sorting criterion context

    673:    Level: developer

    675: .seealso: DSSetSlepcSC(), DSSort()
    676: @*/
    677: PetscErrorCode DSGetSlepcSC(DS ds,SlepcSC *sc)
    678: {
    681:   if (!ds->sc) PetscNewLog(ds,&ds->sc);
    682:   *sc = ds->sc;
    683:   PetscFunctionReturn(0);
    684: }

    686: /*@
    687:    DSSetFromOptions - Sets DS options from the options database.

    689:    Collective on ds

    691:    Input Parameters:
    692: .  ds - the direct solver context

    694:    Notes:
    695:    To see all options, run your program with the -help option.

    697:    Level: beginner

    699: .seealso: DSSetOptionsPrefix()
    700: @*/
    701: PetscErrorCode DSSetFromOptions(DS ds)
    702: {
    704:   PetscInt       bs,meth;
    705:   PetscBool      flag;
    706:   DSParallelType pmode;

    709:   DSRegisterAll();
    710:   /* Set default type (we do not allow changing it with -ds_type) */
    711:   if (!((PetscObject)ds)->type_name) DSSetType(ds,DSNHEP);
    712:   ierr = PetscObjectOptionsBegin((PetscObject)ds);

    714:     PetscOptionsInt("-ds_block_size","Block size for the dense system solver","DSSetBlockSize",ds->bs,&bs,&flag);
    715:     if (flag) DSSetBlockSize(ds,bs);

    717:     PetscOptionsInt("-ds_method","Method to be used for the dense system","DSSetMethod",ds->method,&meth,&flag);
    718:     if (flag) DSSetMethod(ds,meth);

    720:     PetscOptionsEnum("-ds_parallel","Operation mode in parallel runs","DSSetParallel",DSParallelTypes,(PetscEnum)ds->pmode,(PetscEnum*)&pmode,&flag);
    721:     if (flag) DSSetParallel(ds,pmode);

    723:     if (ds->ops->setfromoptions) (*ds->ops->setfromoptions)(PetscOptionsObject,ds);
    724:     PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)ds);
    725:   ierr = PetscOptionsEnd();
    726:   PetscFunctionReturn(0);
    727: }

    729: /*@C
    730:    DSView - Prints the DS data structure.

    732:    Collective on ds

    734:    Input Parameters:
    735: +  ds - the direct solver context
    736: -  viewer - optional visualization context

    738:    Note:
    739:    The available visualization contexts include
    740: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
    741: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
    742:          output where only the first processor opens
    743:          the file.  All other processors send their
    744:          data to the first processor to print.

    746:    The user can open an alternative visualization context with
    747:    PetscViewerASCIIOpen() - output to a specified file.

    749:    Level: beginner

    751: .seealso: DSViewMat()
    752: @*/
    753: PetscErrorCode DSView(DS ds,PetscViewer viewer)
    754: {
    755:   PetscBool         isascii;
    756:   PetscViewerFormat format;
    757:   PetscMPIInt       size;

    760:   if (!viewer) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ds),&viewer);
    763:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    764:   if (isascii) {
    765:     PetscViewerGetFormat(viewer,&format);
    766:     PetscObjectPrintClassNamePrefixType((PetscObject)ds,viewer);
    767:     MPI_Comm_size(PetscObjectComm((PetscObject)ds),&size);
    768:     if (size>1) PetscViewerASCIIPrintf(viewer,"  parallel operation mode: %s\n",DSParallelTypes[ds->pmode]);
    769:     if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
    770:       PetscViewerASCIIPrintf(viewer,"  current state: %s\n",DSStateTypes[ds->state]);
    771:       PetscViewerASCIIPrintf(viewer,"  dimensions: ld=%" PetscInt_FMT ", n=%" PetscInt_FMT ", l=%" PetscInt_FMT ", k=%" PetscInt_FMT,ds->ld,ds->n,ds->l,ds->k);
    772:       if (ds->state==DS_STATE_TRUNCATED) PetscViewerASCIIPrintf(viewer,", t=%" PetscInt_FMT "\n",ds->t);
    773:       else PetscViewerASCIIPrintf(viewer,"\n");
    774:       PetscViewerASCIIPrintf(viewer,"  flags:%s%s%s\n",ds->compact?" compact":"",ds->extrarow?" extrarow":"",ds->refined?" refined":"");
    775:     }
    776:     if (ds->ops->view) {
    777:       PetscViewerASCIIPushTab(viewer);
    778:       (*ds->ops->view)(ds,viewer);
    779:       PetscViewerASCIIPopTab(viewer);
    780:     }
    781:   }
    782:   PetscFunctionReturn(0);
    783: }

    785: /*@C
    786:    DSViewFromOptions - View from options

    788:    Collective on DS

    790:    Input Parameters:
    791: +  ds   - the direct solver context
    792: .  obj  - optional object
    793: -  name - command line option

    795:    Level: intermediate

    797: .seealso: DSView(), DSCreate()
    798: @*/
    799: PetscErrorCode DSViewFromOptions(DS ds,PetscObject obj,const char name[])
    800: {
    802:   PetscObjectViewFromOptions((PetscObject)ds,obj,name);
    803:   PetscFunctionReturn(0);
    804: }

    806: /*@
    807:    DSAllocate - Allocates memory for internal storage or matrices in DS.

    809:    Logically Collective on ds

    811:    Input Parameters:
    812: +  ds - the direct solver context
    813: -  ld - leading dimension (maximum allowed dimension for the matrices, including
    814:         the extra row if present)

    816:    Note:
    817:    If the leading dimension is different from a previously set value, then
    818:    all matrices are destroyed with DSReset().

    820:    Level: intermediate

    822: .seealso: DSGetLeadingDimension(), DSSetDimensions(), DSSetExtraRow(), DSReset()
    823: @*/
    824: PetscErrorCode DSAllocate(DS ds,PetscInt ld)
    825: {
    830:   if (ld!=ds->ld) {
    831:     PetscInfo(ds,"Allocating memory with leading dimension=%" PetscInt_FMT "\n",ld);
    832:     DSReset(ds);
    833:     ds->ld = ld;
    834:     (*ds->ops->allocate)(ds,ld);
    835:   }
    836:   PetscFunctionReturn(0);
    837: }

    839: /*@
    840:    DSReset - Resets the DS context to the initial state.

    842:    Collective on ds

    844:    Input Parameter:
    845: .  ds - the direct solver context

    847:    Note:
    848:    All data structures with size depending on the leading dimension
    849:    of DSAllocate() are released.

    851:    Level: advanced

    853: .seealso: DSDestroy(), DSAllocate()
    854: @*/
    855: PetscErrorCode DSReset(DS ds)
    856: {
    857:   PetscInt       i;

    860:   if (!ds) PetscFunctionReturn(0);
    861:   ds->state    = DS_STATE_RAW;
    862:   ds->ld       = 0;
    863:   ds->l        = 0;
    864:   ds->n        = 0;
    865:   ds->k        = 0;
    866:   for (i=0;i<DS_NUM_MAT;i++) {
    867:     PetscFree(ds->mat[i]);
    868:     PetscFree(ds->rmat[i]);
    869:     MatDestroy(&ds->omat[i]);
    870:   }
    871:   PetscFree(ds->perm);
    872:   PetscFunctionReturn(0);
    873: }

    875: /*@C
    876:    DSDestroy - Destroys DS context that was created with DSCreate().

    878:    Collective on ds

    880:    Input Parameter:
    881: .  ds - the direct solver context

    883:    Level: beginner

    885: .seealso: DSCreate()
    886: @*/
    887: PetscErrorCode DSDestroy(DS *ds)
    888: {
    889:   if (!*ds) PetscFunctionReturn(0);
    891:   if (--((PetscObject)(*ds))->refct > 0) { *ds = 0; PetscFunctionReturn(0); }
    892:   DSReset(*ds);
    893:   if ((*ds)->ops->destroy) (*(*ds)->ops->destroy)(*ds);
    894:   PetscFree((*ds)->work);
    895:   PetscFree((*ds)->rwork);
    896:   PetscFree((*ds)->iwork);
    897:   if (!(*ds)->scset) PetscFree((*ds)->sc);
    898:   PetscHeaderDestroy(ds);
    899:   PetscFunctionReturn(0);
    900: }

    902: /*@C
    903:    DSRegister - Adds a direct solver to the DS package.

    905:    Not collective

    907:    Input Parameters:
    908: +  name - name of a new user-defined DS
    909: -  function - routine to create context

    911:    Notes:
    912:    DSRegister() may be called multiple times to add several user-defined
    913:    direct solvers.

    915:    Level: advanced

    917: .seealso: DSRegisterAll()
    918: @*/
    919: PetscErrorCode DSRegister(const char *name,PetscErrorCode (*function)(DS))
    920: {
    921:   DSInitializePackage();
    922:   PetscFunctionListAdd(&DSList,name,function);
    923:   PetscFunctionReturn(0);
    924: }

    926: SLEPC_EXTERN PetscErrorCode DSCreate_HEP(DS);
    927: SLEPC_EXTERN PetscErrorCode DSCreate_NHEP(DS);
    928: SLEPC_EXTERN PetscErrorCode DSCreate_GHEP(DS);
    929: SLEPC_EXTERN PetscErrorCode DSCreate_GHIEP(DS);
    930: SLEPC_EXTERN PetscErrorCode DSCreate_GNHEP(DS);
    931: SLEPC_EXTERN PetscErrorCode DSCreate_NHEPTS(DS);
    932: SLEPC_EXTERN PetscErrorCode DSCreate_SVD(DS);
    933: SLEPC_EXTERN PetscErrorCode DSCreate_GSVD(DS);
    934: SLEPC_EXTERN PetscErrorCode DSCreate_PEP(DS);
    935: SLEPC_EXTERN PetscErrorCode DSCreate_NEP(DS);

    937: /*@C
    938:    DSRegisterAll - Registers all of the direct solvers in the DS package.

    940:    Not Collective

    942:    Level: advanced

    944: .seealso: DSRegister()
    945: @*/
    946: PetscErrorCode DSRegisterAll(void)
    947: {
    948:   if (DSRegisterAllCalled) PetscFunctionReturn(0);
    949:   DSRegisterAllCalled = PETSC_TRUE;
    950:   DSRegister(DSHEP,DSCreate_HEP);
    951:   DSRegister(DSNHEP,DSCreate_NHEP);
    952:   DSRegister(DSGHEP,DSCreate_GHEP);
    953:   DSRegister(DSGHIEP,DSCreate_GHIEP);
    954:   DSRegister(DSGNHEP,DSCreate_GNHEP);
    955:   DSRegister(DSNHEPTS,DSCreate_NHEPTS);
    956:   DSRegister(DSSVD,DSCreate_SVD);
    957:   DSRegister(DSGSVD,DSCreate_GSVD);
    958:   DSRegister(DSPEP,DSCreate_PEP);
    959:   DSRegister(DSNEP,DSCreate_NEP);
    960:   PetscFunctionReturn(0);
    961: }