Actual source code: dsbasic.c

slepc-3.17.1 2022-04-11
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: }