1: /*
2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3: SLEPc - Scalable Library for Eigenvalue Problem Computations
4: Copyright (c) 2002-2017, 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> /*I "slepcds.h" I*/
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","DSParallelType","DS_PARALLEL_",0};
24: const char *DSMatName[DS_NUM_MAT] = {"A","B","C","T","D","Q","Z","X","Y","U","VT","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: {
40: PetscFunctionListDestroy(&DSList);
41: DSPackageInitialized = PETSC_FALSE;
42: DSRegisterAllCalled = PETSC_FALSE;
43: return(0);
44: }
46: /*@C
47: DSInitializePackage - This function initializes everything in the DS package.
48: It is called from PetscDLLibraryRegister() when using dynamic libraries, and
49: on the first call to DSCreate() when using static libraries.
51: Level: developer
53: .seealso: SlepcInitialize()
54: @*/
55: PetscErrorCode DSInitializePackage() 56: {
57: char logList[256];
58: char *className;
59: PetscBool opt;
60: PetscErrorCode ierr;
63: if (DSPackageInitialized) return(0);
64: DSPackageInitialized = PETSC_TRUE;
65: /* Register Classes */
66: PetscClassIdRegister("Direct Solver",&DS_CLASSID);
67: /* Register Constructors */
68: DSRegisterAll();
69: /* Register Events */
70: PetscLogEventRegister("DSSolve",DS_CLASSID,&DS_Solve);
71: PetscLogEventRegister("DSVectors",DS_CLASSID,&DS_Vectors);
72: PetscLogEventRegister("DSSynchronize",DS_CLASSID,&DS_Synchronize);
73: PetscLogEventRegister("DSOther",DS_CLASSID,&DS_Other);
74: /* Process info exclusions */
75: PetscOptionsGetString(NULL,NULL,"-info_exclude",logList,256,&opt);
76: if (opt) {
77: PetscStrstr(logList,"ds",&className);
78: if (className) {
79: PetscInfoDeactivateClass(DS_CLASSID);
80: }
81: }
82: /* Process summary exclusions */
83: PetscOptionsGetString(NULL,NULL,"-log_exclude",logList,256,&opt);
84: if (opt) {
85: PetscStrstr(logList,"ds",&className);
86: if (className) {
87: PetscLogEventDeactivateClass(DS_CLASSID);
88: }
89: }
90: PetscRegisterFinalize(DSFinalizePackage);
91: return(0);
92: }
94: /*@
95: DSCreate - Creates a DS context.
97: Collective on MPI_Comm
99: Input Parameter:
100: . comm - MPI communicator
102: Output Parameter:
103: . newds - location to put the DS context
105: Level: beginner
107: Note:
108: DS objects are not intended for normal users but only for
109: advanced user that for instance implement their own solvers.
111: .seealso: DSDestroy(), DS112: @*/
113: PetscErrorCode DSCreate(MPI_Comm comm,DS *newds)114: {
115: DS ds;
116: PetscInt i;
121: *newds = 0;
122: DSInitializePackage();
123: SlepcHeaderCreate(ds,DS_CLASSID,"DS","Direct Solver (or Dense System)","DS",comm,DSDestroy,DSView);
125: ds->state = DS_STATE_RAW;
126: ds->method = 0;
127: ds->compact = PETSC_FALSE;
128: ds->refined = PETSC_FALSE;
129: ds->extrarow = PETSC_FALSE;
130: ds->ld = 0;
131: ds->l = 0;
132: ds->n = 0;
133: ds->m = 0;
134: ds->k = 0;
135: ds->t = 0;
136: ds->bs = 1;
137: ds->sc = NULL;
138: ds->pmode = DS_PARALLEL_REDUNDANT;
140: for (i=0;i<DS_NUM_MAT;i++) {
141: ds->mat[i] = NULL;
142: ds->rmat[i] = NULL;
143: ds->omat[i] = NULL;
144: }
145: ds->perm = NULL;
146: ds->data = NULL;
147: ds->work = NULL;
148: ds->rwork = NULL;
149: ds->iwork = NULL;
150: ds->lwork = 0;
151: ds->lrwork = 0;
152: ds->liwork = 0;
154: *newds = ds;
155: return(0);
156: }
158: /*@C
159: DSSetOptionsPrefix - Sets the prefix used for searching for all
160: DS options in the database.
162: Logically Collective on DS164: Input Parameters:
165: + ds - the direct solver context
166: - prefix - the prefix string to prepend to all DS option requests
168: Notes:
169: A hyphen (-) must NOT be given at the beginning of the prefix name.
170: The first character of all runtime options is AUTOMATICALLY the
171: hyphen.
173: Level: advanced
175: .seealso: DSAppendOptionsPrefix()
176: @*/
177: PetscErrorCode DSSetOptionsPrefix(DS ds,const char *prefix)178: {
183: PetscObjectSetOptionsPrefix((PetscObject)ds,prefix);
184: return(0);
185: }
187: /*@C
188: DSAppendOptionsPrefix - Appends to the prefix used for searching for all
189: DS options in the database.
191: Logically Collective on DS193: Input Parameters:
194: + ds - the direct solver context
195: - prefix - the prefix string to prepend to all DS option requests
197: Notes:
198: A hyphen (-) must NOT be given at the beginning of the prefix name.
199: The first character of all runtime options is AUTOMATICALLY the hyphen.
201: Level: advanced
203: .seealso: DSSetOptionsPrefix()
204: @*/
205: PetscErrorCode DSAppendOptionsPrefix(DS ds,const char *prefix)206: {
211: PetscObjectAppendOptionsPrefix((PetscObject)ds,prefix);
212: return(0);
213: }
215: /*@C
216: DSGetOptionsPrefix - Gets the prefix used for searching for all
217: DS options in the database.
219: Not Collective
221: Input Parameters:
222: . ds - the direct solver context
224: Output Parameters:
225: . prefix - pointer to the prefix string used is returned
227: Note:
228: On the Fortran side, the user should pass in a string 'prefix' of
229: sufficient length to hold the prefix.
231: Level: advanced
233: .seealso: DSSetOptionsPrefix(), DSAppendOptionsPrefix()
234: @*/
235: PetscErrorCode DSGetOptionsPrefix(DS ds,const char *prefix[])236: {
242: PetscObjectGetOptionsPrefix((PetscObject)ds,prefix);
243: return(0);
244: }
246: /*@C
247: DSSetType - Selects the type for the DS object.
249: Logically Collective on DS251: Input Parameter:
252: + ds - the direct solver context
253: - type - a known type
255: Level: intermediate
257: .seealso: DSGetType()
258: @*/
259: PetscErrorCode DSSetType(DS ds,DSType type)260: {
261: PetscErrorCode ierr,(*r)(DS);
262: PetscBool match;
268: PetscObjectTypeCompare((PetscObject)ds,type,&match);
269: if (match) return(0);
271: PetscFunctionListFind(DSList,type,&r);
272: if (!r) SETERRQ1(PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested DS type %s",type);
274: PetscMemzero(ds->ops,sizeof(struct _DSOps));
276: PetscObjectChangeTypeName((PetscObject)ds,type);
277: (*r)(ds);
278: return(0);
279: }
281: /*@C
282: DSGetType - Gets the DS type name (as a string) from the DS context.
284: Not Collective
286: Input Parameter:
287: . ds - the direct solver context
289: Output Parameter:
290: . name - name of the direct solver
292: Level: intermediate
294: .seealso: DSSetType()
295: @*/
296: PetscErrorCode DSGetType(DS ds,DSType *type)297: {
301: *type = ((PetscObject)ds)->type_name;
302: return(0);
303: }
305: /*@
306: DSSetMethod - Selects the method to be used to solve the problem.
308: Logically Collective on DS310: Input Parameter:
311: + ds - the direct solver context
312: - meth - an index indentifying the method
314: Options Database Key:
315: . -ds_method <meth> - Sets the method
317: Level: intermediate
319: .seealso: DSGetMethod()
320: @*/
321: PetscErrorCode DSSetMethod(DS ds,PetscInt meth)322: {
326: if (meth<0) SETERRQ(PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_OUTOFRANGE,"The method must be a non-negative integer");
327: if (meth>DS_MAX_SOLVE) SETERRQ(PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_OUTOFRANGE,"Too large value for the method");
328: ds->method = meth;
329: return(0);
330: }
332: /*@
333: DSGetMethod - Gets the method currently used in the DS.
335: Not Collective
337: Input Parameter:
338: . ds - the direct solver context
340: Output Parameter:
341: . meth - identifier of the method
343: Level: intermediate
345: .seealso: DSSetMethod()
346: @*/
347: PetscErrorCode DSGetMethod(DS ds,PetscInt *meth)348: {
352: *meth = ds->method;
353: return(0);
354: }
356: /*@
357: DSSetParallel - Selects the mode of operation in parallel runs.
359: Logically Collective on DS361: Input Parameter:
362: + ds - the direct solver context
363: - pmode - the parallel mode
365: Options Database Key:
366: . -ds_parallel <mode> - Sets the parallel mode, either 'redundant' or 'synchronized'
368: Notes:
369: In the 'redundant' parallel mode, all processes will make the computation
370: redundantly, starting from the same data, and producing the same result.
371: This result may be slightly different in the different processes if using a
372: multithreaded BLAS library, which may cause issues in ill-conditioned problems.
374: In the 'synchronized' parallel mode, only the first MPI process performs the
375: computation and then the computed quantities are broadcast to the other
376: processes in the communicator. This communication is not done automatically,
377: an explicit call to DSSynchronize() is required.
379: Level: advanced
381: .seealso: DSSynchronize(), DSGetParallel()
382: @*/
383: PetscErrorCode DSSetParallel(DS ds,DSParallelType pmode)384: {
388: ds->pmode = pmode;
389: return(0);
390: }
392: /*@
393: DSGetParallel - Gets the mode of operation in parallel runs.
395: Not Collective
397: Input Parameter:
398: . ds - the direct solver context
400: Output Parameter:
401: . pmode - the parallel mode
403: Level: advanced
405: .seealso: DSSetParallel()
406: @*/
407: PetscErrorCode DSGetParallel(DS ds,DSParallelType *pmode)408: {
412: *pmode = ds->pmode;
413: return(0);
414: }
416: /*@
417: DSSetCompact - Switch to compact storage of matrices.
419: Logically Collective on DS421: Input Parameter:
422: + ds - the direct solver context
423: - comp - a boolean flag
425: Notes:
426: Compact storage is used in some DS types such as DSHEP when the matrix
427: is tridiagonal. This flag can be used to indicate whether the user
428: provides the matrix entries via the compact form (the tridiagonal DS_MAT_T)
429: or the non-compact one (DS_MAT_A).
431: The default is PETSC_FALSE.
433: Level: advanced
435: .seealso: DSGetCompact()
436: @*/
437: PetscErrorCode DSSetCompact(DS ds,PetscBool comp)438: {
442: ds->compact = comp;
443: return(0);
444: }
446: /*@
447: DSGetCompact - Gets the compact storage flag.
449: Not Collective
451: Input Parameter:
452: . ds - the direct solver context
454: Output Parameter:
455: . comp - the flag
457: Level: advanced
459: .seealso: DSSetCompact()
460: @*/
461: PetscErrorCode DSGetCompact(DS ds,PetscBool *comp)462: {
466: *comp = ds->compact;
467: return(0);
468: }
470: /*@
471: DSSetExtraRow - Sets a flag to indicate that the matrix has one extra
472: row.
474: Logically Collective on DS476: Input Parameter:
477: + ds - the direct solver context
478: - ext - a boolean flag
480: Notes:
481: In Krylov methods it is useful that the matrix representing the direct solver
482: has one extra row, i.e., has dimension (n+1) x n. If this flag is activated, all
483: transformations applied to the right of the matrix also affect this additional
484: row. In that case, (n+1) must be less or equal than the leading dimension.
486: The default is PETSC_FALSE.
488: Level: advanced
490: .seealso: DSSolve(), DSAllocate(), DSGetExtraRow()
491: @*/
492: PetscErrorCode DSSetExtraRow(DS ds,PetscBool ext)493: {
497: if (ds->n>0 && ds->n==ds->ld) SETERRQ(PetscObjectComm((PetscObject)ds),PETSC_ERR_ORDER,"Cannot set extra row after setting n=ld");
498: ds->extrarow = ext;
499: return(0);
500: }
502: /*@
503: DSGetExtraRow - Gets the extra row flag.
505: Not Collective
507: Input Parameter:
508: . ds - the direct solver context
510: Output Parameter:
511: . ext - the flag
513: Level: advanced
515: .seealso: DSSetExtraRow()
516: @*/
517: PetscErrorCode DSGetExtraRow(DS ds,PetscBool *ext)518: {
522: *ext = ds->extrarow;
523: return(0);
524: }
526: /*@
527: DSSetRefined - Sets a flag to indicate that refined vectors must be
528: computed.
530: Logically Collective on DS532: Input Parameter:
533: + ds - the direct solver context
534: - ref - a boolean flag
536: Notes:
537: Normally the vectors returned in DS_MAT_X are eigenvectors of the
538: projected matrix. With this flag activated, DSVectors() will return
539: the right singular vector of the smallest singular value of matrix
540: \tilde{A}-theta*I, where \tilde{A} is the extended (n+1)xn matrix
541: and theta is the Ritz value. This is used in the refined Ritz
542: approximation.
544: The default is PETSC_FALSE.
546: Level: advanced
548: .seealso: DSVectors(), DSGetRefined()
549: @*/
550: PetscErrorCode DSSetRefined(DS ds,PetscBool ref)551: {
555: ds->refined = ref;
556: return(0);
557: }
559: /*@
560: DSGetRefined - Gets the refined vectors flag.
562: Not Collective
564: Input Parameter:
565: . ds - the direct solver context
567: Output Parameter:
568: . ref - the flag
570: Level: advanced
572: .seealso: DSSetRefined()
573: @*/
574: PetscErrorCode DSGetRefined(DS ds,PetscBool *ref)575: {
579: *ref = ds->refined;
580: return(0);
581: }
583: /*@
584: DSSetBlockSize - Sets the block size.
586: Logically Collective on DS588: Input Parameter:
589: + ds - the direct solver context
590: - bs - the block size
592: Options Database Key:
593: . -ds_block_size <bs> - Sets the block size
595: Level: intermediate
597: .seealso: DSGetBlockSize()
598: @*/
599: PetscErrorCode DSSetBlockSize(DS ds,PetscInt bs)600: {
604: if (bs<1) SETERRQ(PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_OUTOFRANGE,"The block size must be at least one");
605: ds->bs = bs;
606: return(0);
607: }
609: /*@
610: DSGetBlockSize - Gets the block size.
612: Not Collective
614: Input Parameter:
615: . ds - the direct solver context
617: Output Parameter:
618: . bs - block size
620: Level: intermediate
622: .seealso: DSSetBlockSize()
623: @*/
624: PetscErrorCode DSGetBlockSize(DS ds,PetscInt *bs)625: {
629: *bs = ds->bs;
630: return(0);
631: }
633: /*@C
634: DSSetSlepcSC - Sets the sorting criterion context.
636: Not Collective
638: Input Parameters:
639: + ds - the direct solver context
640: - sc - a pointer to the sorting criterion context
642: Level: developer
644: .seealso: DSGetSlepcSC(), DSSort()
645: @*/
646: PetscErrorCode DSSetSlepcSC(DS ds,SlepcSC sc)647: {
653: if (ds->sc) {
654: PetscFree(ds->sc);
655: }
656: ds->sc = sc;
657: return(0);
658: }
660: /*@C
661: DSGetSlepcSC - Gets the sorting criterion context.
663: Not Collective
665: Input Parameter:
666: . ds - the direct solver context
668: Output Parameters:
669: . sc - a pointer to the sorting criterion context
671: Level: developer
673: .seealso: DSSetSlepcSC(), DSSort()
674: @*/
675: PetscErrorCode DSGetSlepcSC(DS ds,SlepcSC *sc)676: {
682: if (!ds->sc) {
683: PetscNewLog(ds,&ds->sc);
684: }
685: *sc = ds->sc;
686: return(0);
687: }
689: /*@
690: DSSetFromOptions - Sets DS options from the options database.
692: Collective on DS694: Input Parameters:
695: . ds - the direct solver context
697: Notes:
698: To see all options, run your program with the -help option.
700: Level: beginner
701: @*/
702: PetscErrorCode DSSetFromOptions(DS ds)703: {
705: PetscInt bs,meth;
706: PetscBool flag;
707: DSParallelType pmode;
711: DSRegisterAll();
712: /* Set default type (we do not allow changing it with -ds_type) */
713: if (!((PetscObject)ds)->type_name) {
714: DSSetType(ds,DSNHEP);
715: }
716: PetscObjectOptionsBegin((PetscObject)ds);
718: PetscOptionsInt("-ds_block_size","Block size for the dense system solver","DSSetBlockSize",ds->bs,&bs,&flag);
719: if (flag) { DSSetBlockSize(ds,bs); }
721: PetscOptionsInt("-ds_method","Method to be used for the dense system","DSSetMethod",ds->method,&meth,&flag);
722: if (flag) { DSSetMethod(ds,meth); }
724: PetscOptionsEnum("-ds_parallel","Operation mode in parallel runs","DSSetParallel",DSParallelTypes,(PetscEnum)ds->pmode,(PetscEnum*)&pmode,&flag);
725: if (flag) { DSSetParallel(ds,pmode); }
727: PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)ds);
728: PetscOptionsEnd();
729: return(0);
730: }
732: /*@C
733: DSView - Prints the DS data structure.
735: Collective on DS737: Input Parameters:
738: + ds - the direct solver context
739: - viewer - optional visualization context
741: Note:
742: The available visualization contexts include
743: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
744: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
745: output where only the first processor opens
746: the file. All other processors send their
747: data to the first processor to print.
749: The user can open an alternative visualization context with
750: PetscViewerASCIIOpen() - output to a specified file.
752: Level: beginner
754: .seealso: DSViewMat()
755: @*/
756: PetscErrorCode DSView(DS ds,PetscViewer viewer)757: {
758: PetscBool isascii,issvd;
759: PetscViewerFormat format;
760: PetscErrorCode ierr;
761: PetscMPIInt size;
765: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)ds));
768: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
769: if (isascii) {
770: PetscViewerGetFormat(viewer,&format);
771: PetscObjectPrintClassNamePrefixType((PetscObject)ds,viewer);
772: MPI_Comm_size(PetscObjectComm((PetscObject)ds),&size);
773: if (size>1) {
774: PetscViewerASCIIPrintf(viewer," parallel operation mode: %s\n",DSParallelTypes[ds->pmode]);
775: }
776: if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
777: PetscViewerASCIIPrintf(viewer," current state: %s\n",DSStateTypes[ds->state]);
778: PetscObjectTypeCompare((PetscObject)ds,DSSVD,&issvd);
779: if (issvd) {
780: PetscViewerASCIIPrintf(viewer," dimensions: ld=%D, n=%D, m=%D, l=%D, k=%D",ds->ld,ds->n,ds->m,ds->l,ds->k);
781: } else {
782: PetscViewerASCIIPrintf(viewer," dimensions: ld=%D, n=%D, l=%D, k=%D",ds->ld,ds->n,ds->l,ds->k);
783: }
784: if (ds->state==DS_STATE_TRUNCATED) {
785: PetscViewerASCIIPrintf(viewer,", t=%D\n",ds->t);
786: } else {
787: PetscViewerASCIIPrintf(viewer,"\n");
788: }
789: PetscViewerASCIIPrintf(viewer," flags:%s%s%s\n",ds->compact?" compact":"",ds->extrarow?" extrarow":"",ds->refined?" refined":"");
790: }
791: if (ds->ops->view) {
792: PetscViewerASCIIPushTab(viewer);
793: (*ds->ops->view)(ds,viewer);
794: PetscViewerASCIIPopTab(viewer);
795: }
796: }
797: return(0);
798: }
800: /*@
801: DSAllocate - Allocates memory for internal storage or matrices in DS.
803: Logically Collective on DS805: Input Parameters:
806: + ds - the direct solver context
807: - ld - leading dimension (maximum allowed dimension for the matrices, including
808: the extra row if present)
810: Note:
811: If the leading dimension is different from a previously set value, then
812: all matrices are destroyed with DSReset().
814: Level: intermediate
816: .seealso: DSGetLeadingDimension(), DSSetDimensions(), DSSetExtraRow(), DSReset()
817: @*/
818: PetscErrorCode DSAllocate(DS ds,PetscInt ld)819: {
826: if (ld<1) SETERRQ(PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_OUTOFRANGE,"Leading dimension should be at least one");
827: if (ld!=ds->ld) {
828: DSReset(ds);
829: ds->ld = ld;
830: (*ds->ops->allocate)(ds,ld);
831: }
832: return(0);
833: }
835: /*@
836: DSReset - Resets the DS context to the initial state.
838: Collective on DS840: Input Parameter:
841: . ds - the direct solver context
843: Note:
844: All data structures with size depending on the leading dimension
845: of DSAllocate() are released.
847: Level: advanced
849: .seealso: DSDestroy(), DSAllocate()
850: @*/
851: PetscErrorCode DSReset(DS ds)852: {
853: PetscInt i;
858: if (!ds) return(0);
859: ds->state = DS_STATE_RAW;
860: ds->ld = 0;
861: ds->l = 0;
862: ds->n = 0;
863: ds->m = 0;
864: ds->k = 0;
865: for (i=0;i<DS_NUM_MAT;i++) {
866: PetscFree(ds->mat[i]);
867: PetscFree(ds->rmat[i]);
868: MatDestroy(&ds->omat[i]);
869: }
870: PetscFree(ds->perm);
871: return(0);
872: }
874: /*@
875: DSDestroy - Destroys DS context that was created with DSCreate().
877: Collective on DS879: Input Parameter:
880: . ds - the direct solver context
882: Level: beginner
884: .seealso: DSCreate()
885: @*/
886: PetscErrorCode DSDestroy(DS *ds)887: {
891: if (!*ds) return(0);
893: if (--((PetscObject)(*ds))->refct > 0) { *ds = 0; return(0); }
894: DSReset(*ds);
895: if ((*ds)->ops->destroy) { (*(*ds)->ops->destroy)(*ds); }
896: PetscFree((*ds)->work);
897: PetscFree((*ds)->rwork);
898: PetscFree((*ds)->iwork);
899: PetscFree((*ds)->sc);
900: PetscHeaderDestroy(ds);
901: return(0);
902: }
904: /*@C
905: DSRegister - Adds a direct solver to the DS package.
907: Not collective
909: Input Parameters:
910: + name - name of a new user-defined DS911: - routine_create - routine to create context
913: Notes:
914: DSRegister() may be called multiple times to add several user-defined
915: direct solvers.
917: Level: advanced
919: .seealso: DSRegisterAll()
920: @*/
921: PetscErrorCode DSRegister(const char *name,PetscErrorCode (*function)(DS))922: {
926: PetscFunctionListAdd(&DSList,name,function);
927: return(0);
928: }
930: PETSC_EXTERN PetscErrorCode DSCreate_HEP(DS);
931: PETSC_EXTERN PetscErrorCode DSCreate_NHEP(DS);
932: PETSC_EXTERN PetscErrorCode DSCreate_GHEP(DS);
933: PETSC_EXTERN PetscErrorCode DSCreate_GHIEP(DS);
934: PETSC_EXTERN PetscErrorCode DSCreate_GNHEP(DS);
935: PETSC_EXTERN PetscErrorCode DSCreate_SVD(DS);
936: PETSC_EXTERN PetscErrorCode DSCreate_PEP(DS);
937: PETSC_EXTERN PetscErrorCode DSCreate_NEP(DS);
939: /*@C
940: DSRegisterAll - Registers all of the direct solvers in the DS package.
942: Not Collective
944: Level: advanced
945: @*/
946: PetscErrorCode DSRegisterAll(void)947: {
951: if (DSRegisterAllCalled) return(0);
952: DSRegisterAllCalled = PETSC_TRUE;
953: DSRegister(DSHEP,DSCreate_HEP);
954: DSRegister(DSNHEP,DSCreate_NHEP);
955: DSRegister(DSGHEP,DSCreate_GHEP);
956: DSRegister(DSGHIEP,DSCreate_GHIEP);
957: DSRegister(DSGNHEP,DSCreate_GNHEP);
958: DSRegister(DSSVD,DSCreate_SVD);
959: DSRegister(DSPEP,DSCreate_PEP);
960: DSRegister(DSNEP,DSCreate_NEP);
961: return(0);
962: }