Actual source code: dsbasic.c
slepc-3.18.2 2023-01-26
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: PetscFunctionListDestroy(&DSList);
38: DSPackageInitialized = PETSC_FALSE;
39: DSRegisterAllCalled = PETSC_FALSE;
40: return 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(void)
53: {
54: char logList[256];
55: PetscBool opt,pkg;
56: PetscClassId classids[1];
58: if (DSPackageInitialized) return 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: return 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 = NULL;
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++) ds->omat[i] = NULL;
127: ds->perm = NULL;
128: ds->data = NULL;
129: ds->scset = PETSC_FALSE;
130: ds->work = NULL;
131: ds->rwork = NULL;
132: ds->iwork = NULL;
133: ds->lwork = 0;
134: ds->lrwork = 0;
135: ds->liwork = 0;
137: *newds = ds;
138: return 0;
139: }
141: /*@C
142: DSSetOptionsPrefix - Sets the prefix used for searching for all
143: DS options in the database.
145: Logically Collective on ds
147: Input Parameters:
148: + ds - the direct solver context
149: - prefix - the prefix string to prepend to all DS option requests
151: Notes:
152: A hyphen (-) must NOT be given at the beginning of the prefix name.
153: The first character of all runtime options is AUTOMATICALLY the
154: hyphen.
156: Level: advanced
158: .seealso: DSAppendOptionsPrefix()
159: @*/
160: PetscErrorCode DSSetOptionsPrefix(DS ds,const char *prefix)
161: {
163: PetscObjectSetOptionsPrefix((PetscObject)ds,prefix);
164: return 0;
165: }
167: /*@C
168: DSAppendOptionsPrefix - Appends to the prefix used for searching for all
169: DS options in the database.
171: Logically Collective on ds
173: Input Parameters:
174: + ds - the direct solver context
175: - prefix - the prefix string to prepend to all DS option requests
177: Notes:
178: A hyphen (-) must NOT be given at the beginning of the prefix name.
179: The first character of all runtime options is AUTOMATICALLY the hyphen.
181: Level: advanced
183: .seealso: DSSetOptionsPrefix()
184: @*/
185: PetscErrorCode DSAppendOptionsPrefix(DS ds,const char *prefix)
186: {
188: PetscObjectAppendOptionsPrefix((PetscObject)ds,prefix);
189: return 0;
190: }
192: /*@C
193: DSGetOptionsPrefix - Gets the prefix used for searching for all
194: DS options in the database.
196: Not Collective
198: Input Parameters:
199: . ds - the direct solver context
201: Output Parameters:
202: . prefix - pointer to the prefix string used is returned
204: Note:
205: On the Fortran side, the user should pass in a string 'prefix' of
206: sufficient length to hold the prefix.
208: Level: advanced
210: .seealso: DSSetOptionsPrefix(), DSAppendOptionsPrefix()
211: @*/
212: PetscErrorCode DSGetOptionsPrefix(DS ds,const char *prefix[])
213: {
216: PetscObjectGetOptionsPrefix((PetscObject)ds,prefix);
217: return 0;
218: }
220: /*@C
221: DSSetType - Selects the type for the DS object.
223: Logically Collective on ds
225: Input Parameters:
226: + ds - the direct solver context
227: - type - a known type
229: Level: intermediate
231: .seealso: DSGetType()
232: @*/
233: PetscErrorCode DSSetType(DS ds,DSType type)
234: {
235: PetscErrorCode (*r)(DS);
236: PetscBool match;
241: PetscObjectTypeCompare((PetscObject)ds,type,&match);
242: if (match) return 0;
244: PetscFunctionListFind(DSList,type,&r);
247: PetscMemzero(ds->ops,sizeof(struct _DSOps));
249: PetscObjectChangeTypeName((PetscObject)ds,type);
250: (*r)(ds);
251: return 0;
252: }
254: /*@C
255: DSGetType - Gets the DS type name (as a string) from the DS context.
257: Not Collective
259: Input Parameter:
260: . ds - the direct solver context
262: Output Parameter:
263: . type - name of the direct solver
265: Level: intermediate
267: .seealso: DSSetType()
268: @*/
269: PetscErrorCode DSGetType(DS ds,DSType *type)
270: {
273: *type = ((PetscObject)ds)->type_name;
274: return 0;
275: }
277: /*@
278: DSDuplicate - Creates a new direct solver object with the same options as
279: an existing one.
281: Collective on ds
283: Input Parameter:
284: . ds - direct solver context
286: Output Parameter:
287: . dsnew - location to put the new DS
289: Notes:
290: DSDuplicate() DOES NOT COPY the matrices, and the new DS does not even have
291: internal arrays allocated. Use DSAllocate() to use the new DS.
293: The sorting criterion options are not copied, see DSSetSlepcSC().
295: Level: intermediate
297: .seealso: DSCreate(), DSAllocate(), DSSetSlepcSC()
298: @*/
299: PetscErrorCode DSDuplicate(DS ds,DS *dsnew)
300: {
303: DSCreate(PetscObjectComm((PetscObject)ds),dsnew);
304: if (((PetscObject)ds)->type_name) DSSetType(*dsnew,((PetscObject)ds)->type_name);
305: (*dsnew)->method = ds->method;
306: (*dsnew)->compact = ds->compact;
307: (*dsnew)->refined = ds->refined;
308: (*dsnew)->extrarow = ds->extrarow;
309: (*dsnew)->bs = ds->bs;
310: (*dsnew)->pmode = ds->pmode;
311: return 0;
312: }
314: /*@
315: DSSetMethod - Selects the method to be used to solve the problem.
317: Logically Collective on ds
319: Input Parameters:
320: + ds - the direct solver context
321: - meth - an index identifying the method
323: Options Database Key:
324: . -ds_method <meth> - Sets the method
326: Level: intermediate
328: .seealso: DSGetMethod()
329: @*/
330: PetscErrorCode DSSetMethod(DS ds,PetscInt meth)
331: {
336: ds->method = meth;
337: return 0;
338: }
340: /*@
341: DSGetMethod - Gets the method currently used in the DS.
343: Not Collective
345: Input Parameter:
346: . ds - the direct solver context
348: Output Parameter:
349: . meth - identifier of the method
351: Level: intermediate
353: .seealso: DSSetMethod()
354: @*/
355: PetscErrorCode DSGetMethod(DS ds,PetscInt *meth)
356: {
359: *meth = ds->method;
360: return 0;
361: }
363: /*@
364: DSSetParallel - Selects the mode of operation in parallel runs.
366: Logically Collective on ds
368: Input Parameters:
369: + ds - the direct solver context
370: - pmode - the parallel mode
372: Options Database Key:
373: . -ds_parallel <mode> - Sets the parallel mode, 'redundant', 'synchronized'
374: or 'distributed'
376: Notes:
377: In the 'redundant' parallel mode, all processes will make the computation
378: redundantly, starting from the same data, and producing the same result.
379: This result may be slightly different in the different processes if using a
380: multithreaded BLAS library, which may cause issues in ill-conditioned problems.
382: In the 'synchronized' parallel mode, only the first MPI process performs the
383: computation and then the computed quantities are broadcast to the other
384: processes in the communicator. This communication is not done automatically,
385: an explicit call to DSSynchronize() is required.
387: The 'distributed' parallel mode can be used in some DS types only, such
388: as the contour integral method of DSNEP. In this case, every MPI process
389: will be in charge of part of the computation.
391: Level: advanced
393: .seealso: DSSynchronize(), DSGetParallel()
394: @*/
395: PetscErrorCode DSSetParallel(DS ds,DSParallelType pmode)
396: {
399: ds->pmode = pmode;
400: return 0;
401: }
403: /*@
404: DSGetParallel - Gets the mode of operation in parallel runs.
406: Not Collective
408: Input Parameter:
409: . ds - the direct solver context
411: Output Parameter:
412: . pmode - the parallel mode
414: Level: advanced
416: .seealso: DSSetParallel()
417: @*/
418: PetscErrorCode DSGetParallel(DS ds,DSParallelType *pmode)
419: {
422: *pmode = ds->pmode;
423: return 0;
424: }
426: /*@
427: DSSetCompact - Switch to compact storage of matrices.
429: Logically Collective on ds
431: Input Parameters:
432: + ds - the direct solver context
433: - comp - a boolean flag
435: Notes:
436: Compact storage is used in some DS types such as DSHEP when the matrix
437: is tridiagonal. This flag can be used to indicate whether the user
438: provides the matrix entries via the compact form (the tridiagonal DS_MAT_T)
439: or the non-compact one (DS_MAT_A).
441: The default is PETSC_FALSE.
443: Level: advanced
445: .seealso: DSGetCompact()
446: @*/
447: PetscErrorCode DSSetCompact(DS ds,PetscBool comp)
448: {
451: ds->compact = comp;
452: return 0;
453: }
455: /*@
456: DSGetCompact - Gets the compact storage flag.
458: Not Collective
460: Input Parameter:
461: . ds - the direct solver context
463: Output Parameter:
464: . comp - the flag
466: Level: advanced
468: .seealso: DSSetCompact()
469: @*/
470: PetscErrorCode DSGetCompact(DS ds,PetscBool *comp)
471: {
474: *comp = ds->compact;
475: return 0;
476: }
478: /*@
479: DSSetExtraRow - Sets a flag to indicate that the matrix has one extra
480: row.
482: Logically Collective on ds
484: Input Parameters:
485: + ds - the direct solver context
486: - ext - a boolean flag
488: Notes:
489: In Krylov methods it is useful that the matrix representing the direct solver
490: has one extra row, i.e., has dimension (n+1) x n. If this flag is activated, all
491: transformations applied to the right of the matrix also affect this additional
492: row. In that case, (n+1) must be less or equal than the leading dimension.
494: The default is PETSC_FALSE.
496: Level: advanced
498: .seealso: DSSolve(), DSAllocate(), DSGetExtraRow()
499: @*/
500: PetscErrorCode DSSetExtraRow(DS ds,PetscBool ext)
501: {
505: ds->extrarow = ext;
506: return 0;
507: }
509: /*@
510: DSGetExtraRow - Gets the extra row flag.
512: Not Collective
514: Input Parameter:
515: . ds - the direct solver context
517: Output Parameter:
518: . ext - the flag
520: Level: advanced
522: .seealso: DSSetExtraRow()
523: @*/
524: PetscErrorCode DSGetExtraRow(DS ds,PetscBool *ext)
525: {
528: *ext = ds->extrarow;
529: return 0;
530: }
532: /*@
533: DSSetRefined - Sets a flag to indicate that refined vectors must be
534: computed.
536: Logically Collective on ds
538: Input Parameters:
539: + ds - the direct solver context
540: - ref - a boolean flag
542: Notes:
543: Normally the vectors returned in DS_MAT_X are eigenvectors of the
544: projected matrix. With this flag activated, DSVectors() will return
545: the right singular vector of the smallest singular value of matrix
546: \tilde{A}-theta*I, where \tilde{A} is the extended (n+1)xn matrix
547: and theta is the Ritz value. This is used in the refined Ritz
548: approximation.
550: The default is PETSC_FALSE.
552: Level: advanced
554: .seealso: DSVectors(), DSGetRefined()
555: @*/
556: PetscErrorCode DSSetRefined(DS ds,PetscBool ref)
557: {
560: ds->refined = ref;
561: return 0;
562: }
564: /*@
565: DSGetRefined - Gets the refined vectors flag.
567: Not Collective
569: Input Parameter:
570: . ds - the direct solver context
572: Output Parameter:
573: . ref - the flag
575: Level: advanced
577: .seealso: DSSetRefined()
578: @*/
579: PetscErrorCode DSGetRefined(DS ds,PetscBool *ref)
580: {
583: *ref = ds->refined;
584: return 0;
585: }
587: /*@
588: DSSetBlockSize - Sets the block size.
590: Logically Collective on ds
592: Input Parameters:
593: + ds - the direct solver context
594: - bs - the block size
596: Options Database Key:
597: . -ds_block_size <bs> - Sets the block size
599: Level: intermediate
601: .seealso: DSGetBlockSize()
602: @*/
603: PetscErrorCode DSSetBlockSize(DS ds,PetscInt bs)
604: {
608: ds->bs = bs;
609: return 0;
610: }
612: /*@
613: DSGetBlockSize - Gets the block size.
615: Not Collective
617: Input Parameter:
618: . ds - the direct solver context
620: Output Parameter:
621: . bs - block size
623: Level: intermediate
625: .seealso: DSSetBlockSize()
626: @*/
627: PetscErrorCode DSGetBlockSize(DS ds,PetscInt *bs)
628: {
631: *bs = ds->bs;
632: return 0;
633: }
635: /*@C
636: DSSetSlepcSC - Sets the sorting criterion context.
638: Not Collective
640: Input Parameters:
641: + ds - the direct solver context
642: - sc - a pointer to the sorting criterion context
644: Level: developer
646: .seealso: DSGetSlepcSC(), DSSort()
647: @*/
648: PetscErrorCode DSSetSlepcSC(DS ds,SlepcSC sc)
649: {
652: if (ds->sc && !ds->scset) PetscFree(ds->sc);
653: ds->sc = sc;
654: ds->scset = PETSC_TRUE;
655: return 0;
656: }
658: /*@C
659: DSGetSlepcSC - Gets the sorting criterion context.
661: Not Collective
663: Input Parameter:
664: . ds - the direct solver context
666: Output Parameters:
667: . sc - a pointer to the sorting criterion context
669: Level: developer
671: .seealso: DSSetSlepcSC(), DSSort()
672: @*/
673: PetscErrorCode DSGetSlepcSC(DS ds,SlepcSC *sc)
674: {
677: if (!ds->sc) PetscNew(&ds->sc);
678: *sc = ds->sc;
679: return 0;
680: }
682: /*@
683: DSSetFromOptions - Sets DS options from the options database.
685: Collective on ds
687: Input Parameters:
688: . ds - the direct solver context
690: Notes:
691: To see all options, run your program with the -help option.
693: Level: beginner
695: .seealso: DSSetOptionsPrefix()
696: @*/
697: PetscErrorCode DSSetFromOptions(DS ds)
698: {
699: PetscInt bs,meth;
700: PetscBool flag;
701: DSParallelType pmode;
704: DSRegisterAll();
705: /* Set default type (we do not allow changing it with -ds_type) */
706: if (!((PetscObject)ds)->type_name) DSSetType(ds,DSNHEP);
707: PetscObjectOptionsBegin((PetscObject)ds);
709: PetscOptionsInt("-ds_block_size","Block size for the dense system solver","DSSetBlockSize",ds->bs,&bs,&flag);
710: if (flag) DSSetBlockSize(ds,bs);
712: PetscOptionsInt("-ds_method","Method to be used for the dense system","DSSetMethod",ds->method,&meth,&flag);
713: if (flag) DSSetMethod(ds,meth);
715: PetscOptionsEnum("-ds_parallel","Operation mode in parallel runs","DSSetParallel",DSParallelTypes,(PetscEnum)ds->pmode,(PetscEnum*)&pmode,&flag);
716: if (flag) DSSetParallel(ds,pmode);
718: PetscTryTypeMethod(ds,setfromoptions,PetscOptionsObject);
719: PetscObjectProcessOptionsHandlers((PetscObject)ds,PetscOptionsObject);
720: PetscOptionsEnd();
721: return 0;
722: }
724: /*@C
725: DSView - Prints the DS data structure.
727: Collective on ds
729: Input Parameters:
730: + ds - the direct solver context
731: - viewer - optional visualization context
733: Note:
734: The available visualization contexts include
735: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
736: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
737: output where only the first processor opens
738: the file. All other processors send their
739: data to the first processor to print.
741: The user can open an alternative visualization context with
742: PetscViewerASCIIOpen() - output to a specified file.
744: Level: beginner
746: .seealso: DSViewMat()
747: @*/
748: PetscErrorCode DSView(DS ds,PetscViewer viewer)
749: {
750: PetscBool isascii;
751: PetscViewerFormat format;
752: PetscMPIInt size;
755: if (!viewer) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ds),&viewer);
758: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
759: if (isascii) {
760: PetscViewerGetFormat(viewer,&format);
761: PetscObjectPrintClassNamePrefixType((PetscObject)ds,viewer);
762: MPI_Comm_size(PetscObjectComm((PetscObject)ds),&size);
763: if (size>1) PetscViewerASCIIPrintf(viewer," parallel operation mode: %s\n",DSParallelTypes[ds->pmode]);
764: if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
765: PetscViewerASCIIPrintf(viewer," current state: %s\n",DSStateTypes[ds->state]);
766: PetscViewerASCIIPrintf(viewer," dimensions: ld=%" PetscInt_FMT ", n=%" PetscInt_FMT ", l=%" PetscInt_FMT ", k=%" PetscInt_FMT,ds->ld,ds->n,ds->l,ds->k);
767: if (ds->state==DS_STATE_TRUNCATED) PetscViewerASCIIPrintf(viewer,", t=%" PetscInt_FMT "\n",ds->t);
768: else PetscViewerASCIIPrintf(viewer,"\n");
769: PetscViewerASCIIPrintf(viewer," flags:%s%s%s\n",ds->compact?" compact":"",ds->extrarow?" extrarow":"",ds->refined?" refined":"");
770: }
771: PetscViewerASCIIPushTab(viewer);
772: PetscTryTypeMethod(ds,view,viewer);
773: PetscViewerASCIIPopTab(viewer);
774: }
775: return 0;
776: }
778: /*@C
779: DSViewFromOptions - View from options
781: Collective on DS
783: Input Parameters:
784: + ds - the direct solver context
785: . obj - optional object
786: - name - command line option
788: Level: intermediate
790: .seealso: DSView(), DSCreate()
791: @*/
792: PetscErrorCode DSViewFromOptions(DS ds,PetscObject obj,const char name[])
793: {
795: PetscObjectViewFromOptions((PetscObject)ds,obj,name);
796: return 0;
797: }
799: /*@
800: DSAllocate - Allocates memory for internal storage or matrices in DS.
802: Logically Collective on ds
804: Input Parameters:
805: + ds - the direct solver context
806: - ld - leading dimension (maximum allowed dimension for the matrices, including
807: the extra row if present)
809: Note:
810: If the leading dimension is different from a previously set value, then
811: all matrices are destroyed with DSReset().
813: Level: intermediate
815: .seealso: DSGetLeadingDimension(), DSSetDimensions(), DSSetExtraRow(), DSReset()
816: @*/
817: PetscErrorCode DSAllocate(DS ds,PetscInt ld)
818: {
823: if (ld!=ds->ld) {
824: PetscInfo(ds,"Allocating memory with leading dimension=%" PetscInt_FMT "\n",ld);
825: DSReset(ds);
826: ds->ld = ld;
827: PetscUseTypeMethod(ds,allocate,ld);
828: }
829: return 0;
830: }
832: /*@
833: DSReset - Resets the DS context to the initial state.
835: Collective on ds
837: Input Parameter:
838: . ds - the direct solver context
840: Note:
841: All data structures with size depending on the leading dimension
842: of DSAllocate() are released.
844: Level: advanced
846: .seealso: DSDestroy(), DSAllocate()
847: @*/
848: PetscErrorCode DSReset(DS ds)
849: {
850: PetscInt i;
853: if (!ds) return 0;
854: ds->state = DS_STATE_RAW;
855: ds->ld = 0;
856: ds->l = 0;
857: ds->n = 0;
858: ds->k = 0;
859: for (i=0;i<DS_NUM_MAT;i++) MatDestroy(&ds->omat[i]);
860: PetscFree(ds->perm);
861: return 0;
862: }
864: /*@C
865: DSDestroy - Destroys DS context that was created with DSCreate().
867: Collective on ds
869: Input Parameter:
870: . ds - the direct solver context
872: Level: beginner
874: .seealso: DSCreate()
875: @*/
876: PetscErrorCode DSDestroy(DS *ds)
877: {
878: if (!*ds) return 0;
880: if (--((PetscObject)(*ds))->refct > 0) { *ds = NULL; return 0; }
881: DSReset(*ds);
882: PetscTryTypeMethod(*ds,destroy);
883: PetscFree((*ds)->work);
884: PetscFree((*ds)->rwork);
885: PetscFree((*ds)->iwork);
886: if (!(*ds)->scset) PetscFree((*ds)->sc);
887: PetscHeaderDestroy(ds);
888: return 0;
889: }
891: /*@C
892: DSRegister - Adds a direct solver to the DS package.
894: Not collective
896: Input Parameters:
897: + name - name of a new user-defined DS
898: - function - routine to create context
900: Notes:
901: DSRegister() may be called multiple times to add several user-defined
902: direct solvers.
904: Level: advanced
906: .seealso: DSRegisterAll()
907: @*/
908: PetscErrorCode DSRegister(const char *name,PetscErrorCode (*function)(DS))
909: {
910: DSInitializePackage();
911: PetscFunctionListAdd(&DSList,name,function);
912: return 0;
913: }
915: SLEPC_EXTERN PetscErrorCode DSCreate_HEP(DS);
916: SLEPC_EXTERN PetscErrorCode DSCreate_NHEP(DS);
917: SLEPC_EXTERN PetscErrorCode DSCreate_GHEP(DS);
918: SLEPC_EXTERN PetscErrorCode DSCreate_GHIEP(DS);
919: SLEPC_EXTERN PetscErrorCode DSCreate_GNHEP(DS);
920: SLEPC_EXTERN PetscErrorCode DSCreate_NHEPTS(DS);
921: SLEPC_EXTERN PetscErrorCode DSCreate_SVD(DS);
922: SLEPC_EXTERN PetscErrorCode DSCreate_GSVD(DS);
923: SLEPC_EXTERN PetscErrorCode DSCreate_PEP(DS);
924: SLEPC_EXTERN PetscErrorCode DSCreate_NEP(DS);
926: /*@C
927: DSRegisterAll - Registers all of the direct solvers in the DS package.
929: Not Collective
931: Level: advanced
933: .seealso: DSRegister()
934: @*/
935: PetscErrorCode DSRegisterAll(void)
936: {
937: if (DSRegisterAllCalled) return 0;
938: DSRegisterAllCalled = PETSC_TRUE;
939: DSRegister(DSHEP,DSCreate_HEP);
940: DSRegister(DSNHEP,DSCreate_NHEP);
941: DSRegister(DSGHEP,DSCreate_GHEP);
942: DSRegister(DSGHIEP,DSCreate_GHIEP);
943: DSRegister(DSGNHEP,DSCreate_GNHEP);
944: DSRegister(DSNHEPTS,DSCreate_NHEPTS);
945: DSRegister(DSSVD,DSCreate_SVD);
946: DSRegister(DSGSVD,DSCreate_GSVD);
947: DSRegister(DSPEP,DSCreate_PEP);
948: DSRegister(DSNEP,DSCreate_NEP);
949: return 0;
950: }