Date: 2024-12-02T08:58:12+00:00

Actual source code: dsbasic.c
slepc-3.22.2 2024-12-02
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 = NULL;
     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_",NULL};
     23: const char *DSParallelTypes[] = {"REDUNDANT","SYNCHRONIZED","DISTRIBUTED","DSParallelType","DS_PARALLEL_",NULL};
     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:   PetscFunctionBegin;
     38:   PetscCall(PetscFunctionListDestroy(&DSList));
     39:   DSPackageInitialized = PETSC_FALSE;
     40:   DSRegisterAllCalled  = PETSC_FALSE;
     41:   PetscFunctionReturn(PETSC_SUCCESS);
     42: }

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

     49:   Level: developer

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

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

     85: /*@
     86:    DSCreate - Creates a DS context.

     88:    Collective

     90:    Input Parameter:
     91: .  comm - MPI communicator

     93:    Output Parameter:
     94: .  newds - location to put the DS context

     96:    Level: beginner

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

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

    109:   PetscFunctionBegin;
    110:   PetscAssertPointer(newds,2);
    111:   PetscCall(DSInitializePackage());
    112:   PetscCall(SlepcHeaderCreate(ds,DS_CLASSID,"DS","Direct Solver (or Dense System)","DS",comm,DSDestroy,DSView));

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

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

    139:   *newds = ds;
    140:   PetscFunctionReturn(PETSC_SUCCESS);
    141: }

    143: /*@
    144:    DSSetOptionsPrefix - Sets the prefix used for searching for all
    145:    DS options in the database.

    147:    Logically Collective

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

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

    158:    Level: advanced

    160: .seealso: DSAppendOptionsPrefix()
    161: @*/
    162: PetscErrorCode DSSetOptionsPrefix(DS ds,const char *prefix)
    163: {
    164:   PetscFunctionBegin;
    166:   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)ds,prefix));
    167:   PetscFunctionReturn(PETSC_SUCCESS);
    168: }

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

    174:    Logically Collective

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

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

    184:    Level: advanced

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

    196: /*@
    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: {
    218:   PetscFunctionBegin;
    220:   PetscAssertPointer(prefix,2);
    221:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ds,prefix));
    222:   PetscFunctionReturn(PETSC_SUCCESS);
    223: }

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

    228:    Logically Collective

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

    234:    Level: intermediate

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

    243:   PetscFunctionBegin;
    245:   PetscAssertPointer(type,2);

    247:   PetscCall(PetscObjectTypeCompare((PetscObject)ds,type,&match));
    248:   if (match) PetscFunctionReturn(PETSC_SUCCESS);

    250:   PetscCall(PetscFunctionListFind(DSList,type,&r));
    251:   PetscCheck(r,PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested DS type %s",type);

    253:   PetscTryTypeMethod(ds,destroy);
    254:   PetscCall(DSReset(ds));
    255:   PetscCall(PetscMemzero(ds->ops,sizeof(struct _DSOps)));

    257:   PetscCall(PetscObjectChangeTypeName((PetscObject)ds,type));
    258:   PetscCall((*r)(ds));
    259:   PetscFunctionReturn(PETSC_SUCCESS);
    260: }

    262: /*@
    263:    DSGetType - Gets the DS type name (as a string) from the DS context.

    265:    Not Collective

    267:    Input Parameter:
    268: .  ds - the direct solver context

    270:    Output Parameter:
    271: .  type - name of the direct solver

    273:    Level: intermediate

    275: .seealso: DSSetType()
    276: @*/
    277: PetscErrorCode DSGetType(DS ds,DSType *type)
    278: {
    279:   PetscFunctionBegin;
    281:   PetscAssertPointer(type,2);
    282:   *type = ((PetscObject)ds)->type_name;
    283:   PetscFunctionReturn(PETSC_SUCCESS);
    284: }

    286: /*@
    287:    DSDuplicate - Creates a new direct solver object with the same options as
    288:    an existing one.

    290:    Collective

    292:    Input Parameter:
    293: .  ds - direct solver context

    295:    Output Parameter:
    296: .  dsnew - location to put the new DS

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

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

    304:    Level: intermediate

    306: .seealso: DSCreate(), DSAllocate(), DSSetSlepcSC()
    307: @*/
    308: PetscErrorCode DSDuplicate(DS ds,DS *dsnew)
    309: {
    310:   PetscFunctionBegin;
    312:   PetscAssertPointer(dsnew,2);
    313:   PetscCall(DSCreate(PetscObjectComm((PetscObject)ds),dsnew));
    314:   if (((PetscObject)ds)->type_name) PetscCall(DSSetType(*dsnew,((PetscObject)ds)->type_name));
    315:   (*dsnew)->method   = ds->method;
    316:   (*dsnew)->compact  = ds->compact;
    317:   (*dsnew)->refined  = ds->refined;
    318:   (*dsnew)->extrarow = ds->extrarow;
    319:   (*dsnew)->bs       = ds->bs;
    320:   (*dsnew)->pmode    = ds->pmode;
    321:   PetscFunctionReturn(PETSC_SUCCESS);
    322: }

    324: /*@
    325:    DSSetMethod - Selects the method to be used to solve the problem.

    327:    Logically Collective

    329:    Input Parameters:
    330: +  ds   - the direct solver context
    331: -  meth - an index identifying the method

    333:    Options Database Key:
    334: .  -ds_method <meth> - Sets the method

    336:    Level: intermediate

    338: .seealso: DSGetMethod()
    339: @*/
    340: PetscErrorCode DSSetMethod(DS ds,PetscInt meth)
    341: {
    342:   PetscFunctionBegin;
    345:   PetscCheck(meth>=0,PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_OUTOFRANGE,"The method must be a non-negative integer");
    346:   PetscCheck(meth<=DS_MAX_SOLVE,PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_OUTOFRANGE,"Too large value for the method");
    347:   ds->method = meth;
    348:   PetscFunctionReturn(PETSC_SUCCESS);
    349: }

    351: /*@
    352:    DSGetMethod - Gets the method currently used in the DS.

    354:    Not Collective

    356:    Input Parameter:
    357: .  ds - the direct solver context

    359:    Output Parameter:
    360: .  meth - identifier of the method

    362:    Level: intermediate

    364: .seealso: DSSetMethod()
    365: @*/
    366: PetscErrorCode DSGetMethod(DS ds,PetscInt *meth)
    367: {
    368:   PetscFunctionBegin;
    370:   PetscAssertPointer(meth,2);
    371:   *meth = ds->method;
    372:   PetscFunctionReturn(PETSC_SUCCESS);
    373: }

    375: /*@
    376:    DSSetParallel - Selects the mode of operation in parallel runs.

    378:    Logically Collective

    380:    Input Parameters:
    381: +  ds    - the direct solver context
    382: -  pmode - the parallel mode

    384:    Options Database Key:
    385: .  -ds_parallel <mode> - Sets the parallel mode, 'redundant', 'synchronized'
    386:    or 'distributed'

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

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

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

    403:    Level: advanced

    405: .seealso: DSSynchronize(), DSGetParallel()
    406: @*/
    407: PetscErrorCode DSSetParallel(DS ds,DSParallelType pmode)
    408: {
    409:   PetscFunctionBegin;
    412:   ds->pmode = pmode;
    413:   PetscFunctionReturn(PETSC_SUCCESS);
    414: }

    416: /*@
    417:    DSGetParallel - Gets the mode of operation in parallel runs.

    419:    Not Collective

    421:    Input Parameter:
    422: .  ds - the direct solver context

    424:    Output Parameter:
    425: .  pmode - the parallel mode

    427:    Level: advanced

    429: .seealso: DSSetParallel()
    430: @*/
    431: PetscErrorCode DSGetParallel(DS ds,DSParallelType *pmode)
    432: {
    433:   PetscFunctionBegin;
    435:   PetscAssertPointer(pmode,2);
    436:   *pmode = ds->pmode;
    437:   PetscFunctionReturn(PETSC_SUCCESS);
    438: }

    440: /*@
    441:    DSSetCompact - Switch to compact storage of matrices.

    443:    Logically Collective

    445:    Input Parameters:
    446: +  ds   - the direct solver context
    447: -  comp - a boolean flag

    449:    Notes:
    450:    Compact storage is used in some DS types such as DSHEP when the matrix
    451:    is tridiagonal. This flag can be used to indicate whether the user
    452:    provides the matrix entries via the compact form (the tridiagonal DS_MAT_T)
    453:    or the non-compact one (DS_MAT_A).

    455:    The default is PETSC_FALSE.

    457:    Level: advanced

    459: .seealso: DSGetCompact()
    460: @*/
    461: PetscErrorCode DSSetCompact(DS ds,PetscBool comp)
    462: {
    463:   PetscFunctionBegin;
    466:   if (ds->compact != comp && ds->ld) PetscTryTypeMethod(ds,setcompact,comp);
    467:   ds->compact = comp;
    468:   PetscFunctionReturn(PETSC_SUCCESS);
    469: }

    471: /*@
    472:    DSGetCompact - Gets the compact storage flag.

    474:    Not Collective

    476:    Input Parameter:
    477: .  ds - the direct solver context

    479:    Output Parameter:
    480: .  comp - the flag

    482:    Level: advanced

    484: .seealso: DSSetCompact()
    485: @*/
    486: PetscErrorCode DSGetCompact(DS ds,PetscBool *comp)
    487: {
    488:   PetscFunctionBegin;
    490:   PetscAssertPointer(comp,2);
    491:   *comp = ds->compact;
    492:   PetscFunctionReturn(PETSC_SUCCESS);
    493: }

    495: /*@
    496:    DSSetExtraRow - Sets a flag to indicate that the matrix has one extra
    497:    row.

    499:    Logically Collective

    501:    Input Parameters:
    502: +  ds  - the direct solver context
    503: -  ext - a boolean flag

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

    511:    The default is PETSC_FALSE.

    513:    Level: advanced

    515: .seealso: DSSolve(), DSAllocate(), DSGetExtraRow()
    516: @*/
    517: PetscErrorCode DSSetExtraRow(DS ds,PetscBool ext)
    518: {
    519:   PetscFunctionBegin;
    522:   PetscCheck(!ext || ds->n==0 || ds->n!=ds->ld,PetscObjectComm((PetscObject)ds),PETSC_ERR_ORDER,"Cannot set extra row after setting n=ld");
    523:   ds->extrarow = ext;
    524:   PetscFunctionReturn(PETSC_SUCCESS);
    525: }

    527: /*@
    528:    DSGetExtraRow - Gets the extra row flag.

    530:    Not Collective

    532:    Input Parameter:
    533: .  ds - the direct solver context

    535:    Output Parameter:
    536: .  ext - the flag

    538:    Level: advanced

    540: .seealso: DSSetExtraRow()
    541: @*/
    542: PetscErrorCode DSGetExtraRow(DS ds,PetscBool *ext)
    543: {
    544:   PetscFunctionBegin;
    546:   PetscAssertPointer(ext,2);
    547:   *ext = ds->extrarow;
    548:   PetscFunctionReturn(PETSC_SUCCESS);
    549: }

    551: /*@
    552:    DSSetRefined - Sets a flag to indicate that refined vectors must be
    553:    computed.

    555:    Logically Collective

    557:    Input Parameters:
    558: +  ds  - the direct solver context
    559: -  ref - a boolean flag

    561:    Notes:
    562:    Normally the vectors returned in DS_MAT_X are eigenvectors of the
    563:    projected matrix. With this flag activated, DSVectors() will return
    564:    the right singular vector of the smallest singular value of matrix
    565:    \tilde{A}-theta*I, where \tilde{A} is the extended (n+1)xn matrix
    566:    and theta is the Ritz value. This is used in the refined Ritz
    567:    approximation.

    569:    The default is PETSC_FALSE.

    571:    Level: advanced

    573: .seealso: DSVectors(), DSGetRefined()
    574: @*/
    575: PetscErrorCode DSSetRefined(DS ds,PetscBool ref)
    576: {
    577:   PetscFunctionBegin;
    580:   ds->refined = ref;
    581:   PetscFunctionReturn(PETSC_SUCCESS);
    582: }

    584: /*@
    585:    DSGetRefined - Gets the refined vectors flag.

    587:    Not Collective

    589:    Input Parameter:
    590: .  ds - the direct solver context

    592:    Output Parameter:
    593: .  ref - the flag

    595:    Level: advanced

    597: .seealso: DSSetRefined()
    598: @*/
    599: PetscErrorCode DSGetRefined(DS ds,PetscBool *ref)
    600: {
    601:   PetscFunctionBegin;
    603:   PetscAssertPointer(ref,2);
    604:   *ref = ds->refined;
    605:   PetscFunctionReturn(PETSC_SUCCESS);
    606: }

    608: /*@
    609:    DSSetBlockSize - Sets the block size.

    611:    Logically Collective

    613:    Input Parameters:
    614: +  ds - the direct solver context
    615: -  bs - the block size

    617:    Options Database Key:
    618: .  -ds_block_size <bs> - Sets the block size

    620:    Level: intermediate

    622: .seealso: DSGetBlockSize()
    623: @*/
    624: PetscErrorCode DSSetBlockSize(DS ds,PetscInt bs)
    625: {
    626:   PetscFunctionBegin;
    629:   PetscCheck(bs>0,PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_OUTOFRANGE,"The block size must be at least one");
    630:   ds->bs = bs;
    631:   PetscFunctionReturn(PETSC_SUCCESS);
    632: }

    634: /*@
    635:    DSGetBlockSize - Gets the block size.

    637:    Not Collective

    639:    Input Parameter:
    640: .  ds - the direct solver context

    642:    Output Parameter:
    643: .  bs - block size

    645:    Level: intermediate

    647: .seealso: DSSetBlockSize()
    648: @*/
    649: PetscErrorCode DSGetBlockSize(DS ds,PetscInt *bs)
    650: {
    651:   PetscFunctionBegin;
    653:   PetscAssertPointer(bs,2);
    654:   *bs = ds->bs;
    655:   PetscFunctionReturn(PETSC_SUCCESS);
    656: }

    658: /*@C
    659:    DSSetSlepcSC - Sets the sorting criterion context.

    661:    Logically Collective

    663:    Input Parameters:
    664: +  ds - the direct solver context
    665: -  sc - a pointer to the sorting criterion context

    667:    Note:
    668:    Not available in Fortran.

    670:    Level: developer

    672: .seealso: DSGetSlepcSC(), DSSort()
    673: @*/
    674: PetscErrorCode DSSetSlepcSC(DS ds,SlepcSC sc)
    675: {
    676:   PetscFunctionBegin;
    678:   PetscAssertPointer(sc,2);
    679:   if (ds->sc && !ds->scset) PetscCall(PetscFree(ds->sc));
    680:   ds->sc    = sc;
    681:   ds->scset = PETSC_TRUE;
    682:   PetscFunctionReturn(PETSC_SUCCESS);
    683: }

    685: /*@C
    686:    DSGetSlepcSC - Gets the sorting criterion context.

    688:    Not Collective

    690:    Input Parameter:
    691: .  ds - the direct solver context

    693:    Output Parameter:
    694: .  sc - a pointer to the sorting criterion context

    696:    Note:
    697:    Not available in Fortran.

    699:    Level: developer

    701: .seealso: DSSetSlepcSC(), DSSort()
    702: @*/
    703: PetscErrorCode DSGetSlepcSC(DS ds,SlepcSC *sc)
    704: {
    705:   PetscFunctionBegin;
    707:   PetscAssertPointer(sc,2);
    708:   if (!ds->sc) PetscCall(PetscNew(&ds->sc));
    709:   *sc = ds->sc;
    710:   PetscFunctionReturn(PETSC_SUCCESS);
    711: }

    713: /*@
    714:    DSSetFromOptions - Sets DS options from the options database.

    716:    Collective

    718:    Input Parameters:
    719: .  ds - the direct solver context

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

    724:    Level: beginner

    726: .seealso: DSSetOptionsPrefix()
    727: @*/
    728: PetscErrorCode DSSetFromOptions(DS ds)
    729: {
    730:   PetscInt       bs,meth;
    731:   PetscBool      flag;
    732:   DSParallelType pmode;

    734:   PetscFunctionBegin;
    736:   PetscCall(DSRegisterAll());
    737:   /* Set default type (we do not allow changing it with -ds_type) */
    738:   if (!((PetscObject)ds)->type_name) PetscCall(DSSetType(ds,DSNHEP));
    739:   PetscObjectOptionsBegin((PetscObject)ds);

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

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

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

    750:     PetscTryTypeMethod(ds,setfromoptions,PetscOptionsObject);
    751:     PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)ds,PetscOptionsObject));
    752:   PetscOptionsEnd();
    753:   PetscFunctionReturn(PETSC_SUCCESS);
    754: }

    756: /*@
    757:    DSView - Prints the DS data structure.

    759:    Collective

    761:    Input Parameters:
    762: +  ds - the direct solver context
    763: -  viewer - optional visualization context

    765:    Note:
    766:    The available visualization contexts include
    767: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
    768: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
    769:          output where only the first processor opens
    770:          the file.  All other processors send their
    771:          data to the first processor to print.

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

    776:    Level: beginner

    778: .seealso: DSViewMat()
    779: @*/
    780: PetscErrorCode DSView(DS ds,PetscViewer viewer)
    781: {
    782:   PetscBool         isascii;
    783:   PetscViewerFormat format;
    784:   PetscMPIInt       size;

    786:   PetscFunctionBegin;
    788:   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ds),&viewer));
    790:   PetscCheckSameComm(ds,1,viewer,2);
    791:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
    792:   if (isascii) {
    793:     PetscCall(PetscViewerGetFormat(viewer,&format));
    794:     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)ds,viewer));
    795:     PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)ds),&size));
    796:     if (size>1) PetscCall(PetscViewerASCIIPrintf(viewer,"  parallel operation mode: %s\n",DSParallelTypes[ds->pmode]));
    797:     if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
    798:       PetscCall(PetscViewerASCIIPrintf(viewer,"  current state: %s\n",DSStateTypes[ds->state]));
    799:       PetscCall(PetscViewerASCIIPrintf(viewer,"  dimensions: ld=%" PetscInt_FMT ", n=%" PetscInt_FMT ", l=%" PetscInt_FMT ", k=%" PetscInt_FMT,ds->ld,ds->n,ds->l,ds->k));
    800:       if (ds->state==DS_STATE_TRUNCATED) PetscCall(PetscViewerASCIIPrintf(viewer,", t=%" PetscInt_FMT "\n",ds->t));
    801:       else PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
    802:       PetscCall(PetscViewerASCIIPrintf(viewer,"  flags:%s%s%s\n",ds->compact?" compact":"",ds->extrarow?" extrarow":"",ds->refined?" refined":""));
    803:     }
    804:     PetscCall(PetscViewerASCIIPushTab(viewer));
    805:     PetscTryTypeMethod(ds,view,viewer);
    806:     PetscCall(PetscViewerASCIIPopTab(viewer));
    807:   }
    808:   PetscFunctionReturn(PETSC_SUCCESS);
    809: }

    811: /*@
    812:    DSViewFromOptions - View from options

    814:    Collective

    816:    Input Parameters:
    817: +  ds   - the direct solver context
    818: .  obj  - optional object
    819: -  name - command line option

    821:    Level: intermediate

    823: .seealso: DSView(), DSCreate()
    824: @*/
    825: PetscErrorCode DSViewFromOptions(DS ds,PetscObject obj,const char name[])
    826: {
    827:   PetscFunctionBegin;
    829:   PetscCall(PetscObjectViewFromOptions((PetscObject)ds,obj,name));
    830:   PetscFunctionReturn(PETSC_SUCCESS);
    831: }

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

    836:    Logically Collective

    838:    Input Parameters:
    839: +  ds - the direct solver context
    840: -  ld - leading dimension (maximum allowed dimension for the matrices, including
    841:         the extra row if present)

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

    847:    Level: intermediate

    849: .seealso: DSGetLeadingDimension(), DSSetDimensions(), DSSetExtraRow(), DSReset()
    850: @*/
    851: PetscErrorCode DSAllocate(DS ds,PetscInt ld)
    852: {
    853:   PetscFunctionBegin;
    857:   PetscCheck(ld>0,PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_OUTOFRANGE,"Leading dimension should be at least one");
    858:   if (ld!=ds->ld) {
    859:     PetscCall(PetscInfo(ds,"Allocating memory with leading dimension=%" PetscInt_FMT "\n",ld));
    860:     PetscCall(DSReset(ds));
    861:     ds->ld = ld;
    862:     PetscUseTypeMethod(ds,allocate,ld);
    863:   }
    864:   PetscFunctionReturn(PETSC_SUCCESS);
    865: }

    867: /*@
    868:    DSReset - Resets the DS context to the initial state.

    870:    Collective

    872:    Input Parameter:
    873: .  ds - the direct solver context

    875:    Note:
    876:    All data structures with size depending on the leading dimension
    877:    of DSAllocate() are released.

    879:    Level: advanced

    881: .seealso: DSDestroy(), DSAllocate()
    882: @*/
    883: PetscErrorCode DSReset(DS ds)
    884: {
    885:   PetscInt       i;

    887:   PetscFunctionBegin;
    889:   if (!ds) PetscFunctionReturn(PETSC_SUCCESS);
    890:   ds->state    = DS_STATE_RAW;
    891:   ds->ld       = 0;
    892:   ds->l        = 0;
    893:   ds->n        = 0;
    894:   ds->k        = 0;
    895:   for (i=0;i<DS_NUM_MAT;i++) PetscCall(MatDestroy(&ds->omat[i]));
    896:   PetscCall(PetscFree(ds->perm));
    897:   PetscFunctionReturn(PETSC_SUCCESS);
    898: }

    900: /*@
    901:    DSDestroy - Destroys DS context that was created with DSCreate().

    903:    Collective

    905:    Input Parameter:
    906: .  ds - the direct solver context

    908:    Level: beginner

    910: .seealso: DSCreate()
    911: @*/
    912: PetscErrorCode DSDestroy(DS *ds)
    913: {
    914:   PetscFunctionBegin;
    915:   if (!*ds) PetscFunctionReturn(PETSC_SUCCESS);
    917:   if (--((PetscObject)*ds)->refct > 0) { *ds = NULL; PetscFunctionReturn(PETSC_SUCCESS); }
    918:   PetscCall(DSReset(*ds));
    919:   PetscTryTypeMethod(*ds,destroy);
    920:   PetscCall(PetscFree((*ds)->work));
    921:   PetscCall(PetscFree((*ds)->rwork));
    922:   PetscCall(PetscFree((*ds)->iwork));
    923:   if (!(*ds)->scset) PetscCall(PetscFree((*ds)->sc));
    924:   PetscCall(PetscHeaderDestroy(ds));
    925:   PetscFunctionReturn(PETSC_SUCCESS);
    926: }

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

    931:    Not Collective

    933:    Input Parameters:
    934: +  name - name of a new user-defined DS
    935: -  function - routine to create context

    937:    Note:
    938:    DSRegister() may be called multiple times to add several user-defined
    939:    direct solvers.

    941:    Level: advanced

    943: .seealso: DSRegisterAll()
    944: @*/
    945: PetscErrorCode DSRegister(const char *name,PetscErrorCode (*function)(DS))
    946: {
    947:   PetscFunctionBegin;
    948:   PetscCall(DSInitializePackage());
    949:   PetscCall(PetscFunctionListAdd(&DSList,name,function));
    950:   PetscFunctionReturn(PETSC_SUCCESS);
    951: }

    953: SLEPC_EXTERN PetscErrorCode DSCreate_HEP(DS);
    954: SLEPC_EXTERN PetscErrorCode DSCreate_NHEP(DS);
    955: SLEPC_EXTERN PetscErrorCode DSCreate_GHEP(DS);
    956: SLEPC_EXTERN PetscErrorCode DSCreate_GHIEP(DS);
    957: SLEPC_EXTERN PetscErrorCode DSCreate_GNHEP(DS);
    958: SLEPC_EXTERN PetscErrorCode DSCreate_NHEPTS(DS);
    959: SLEPC_EXTERN PetscErrorCode DSCreate_SVD(DS);
    960: SLEPC_EXTERN PetscErrorCode DSCreate_HSVD(DS);
    961: SLEPC_EXTERN PetscErrorCode DSCreate_GSVD(DS);
    962: SLEPC_EXTERN PetscErrorCode DSCreate_PEP(DS);
    963: SLEPC_EXTERN PetscErrorCode DSCreate_NEP(DS);

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

    968:    Not Collective

    970:    Level: advanced

    972: .seealso: DSRegister()
    973: @*/
    974: PetscErrorCode DSRegisterAll(void)
    975: {
    976:   PetscFunctionBegin;
    977:   if (DSRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS);
    978:   DSRegisterAllCalled = PETSC_TRUE;
    979:   PetscCall(DSRegister(DSHEP,DSCreate_HEP));
    980:   PetscCall(DSRegister(DSNHEP,DSCreate_NHEP));
    981:   PetscCall(DSRegister(DSGHEP,DSCreate_GHEP));
    982:   PetscCall(DSRegister(DSGHIEP,DSCreate_GHIEP));
    983:   PetscCall(DSRegister(DSGNHEP,DSCreate_GNHEP));
    984:   PetscCall(DSRegister(DSNHEPTS,DSCreate_NHEPTS));
    985:   PetscCall(DSRegister(DSSVD,DSCreate_SVD));
    986:   PetscCall(DSRegister(DSHSVD,DSCreate_HSVD));
    987:   PetscCall(DSRegister(DSGSVD,DSCreate_GSVD));
    988:   PetscCall(DSRegister(DSPEP,DSCreate_PEP));
    989:   PetscCall(DSRegister(DSNEP,DSCreate_NEP));
    990:   PetscFunctionReturn(PETSC_SUCCESS);
    991: }