Actual source code: stfunc.c
1: /*
2: The ST (spectral transformation) interface routines, callable by users.
4: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5: SLEPc - Scalable Library for Eigenvalue Problem Computations
6: Copyright (c) 2002-2007, Universidad Politecnica de Valencia, Spain
8: This file is part of SLEPc. See the README file for conditions of use
9: and additional information.
10: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
11: */
13: #include src/st/stimpl.h
15: PetscCookie ST_COOKIE = 0;
16: PetscEvent ST_SetUp = 0, ST_Apply = 0, ST_ApplyTranspose = 0;
20: /*@C
21: STInitializePackage - This function initializes everything in the ST package. It is called
22: from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to STCreate()
23: when using static libraries.
25: Input Parameter:
26: path - The dynamic library path, or PETSC_NULL
28: Level: developer
30: .seealso: SlepcInitialize()
31: @*/
32: PetscErrorCode STInitializePackage(char *path) {
33: static PetscTruth initialized = PETSC_FALSE;
34: char logList[256];
35: char *className;
36: PetscTruth opt;
40: if (initialized) return(0);
41: initialized = PETSC_TRUE;
42: /* Register Classes */
43: PetscLogClassRegister(&ST_COOKIE,"Spectral Transform");
44: /* Register Constructors */
45: STRegisterAll(path);
46: /* Register Events */
47: PetscLogEventRegister(&ST_SetUp,"STSetUp",ST_COOKIE);
48: PetscLogEventRegister(&ST_Apply,"STApply",ST_COOKIE);
49: PetscLogEventRegister(&ST_ApplyTranspose,"STApplyTranspose",ST_COOKIE);
50: /* Process info exclusions */
51: PetscOptionsGetString(PETSC_NULL, "-log_info_exclude", logList, 256, &opt);
52: if (opt) {
53: PetscStrstr(logList, "st", &className);
54: if (className) {
55: PetscInfoDeactivateClass(ST_COOKIE);
56: }
57: }
58: /* Process summary exclusions */
59: PetscOptionsGetString(PETSC_NULL, "-log_summary_exclude", logList, 256, &opt);
60: if (opt) {
61: PetscStrstr(logList, "st", &className);
62: if (className) {
63: PetscLogEventDeactivateClass(ST_COOKIE);
64: }
65: }
66: return(0);
67: }
71: /*@
72: STDestroy - Destroys ST context that was created with STCreate().
74: Collective on ST
76: Input Parameter:
77: . st - the spectral transformation context
79: Level: beginner
81: .seealso: STCreate(), STSetUp()
82: @*/
83: PetscErrorCode STDestroy(ST st)
84: {
89: if (--st->refct > 0) return(0);
91: /* if memory was published with AMS then destroy it */
92: PetscObjectDepublish(st);
94: if (st->ops->destroy) { (*st->ops->destroy)(st); }
95: if (st->ksp) { KSPDestroy(st->ksp); }
96: if (st->w) { VecDestroy(st->w); }
97: if (st->shift_matrix != STMATMODE_INPLACE && st->mat) {
98: MatDestroy(st->mat);
99: }
101: PetscHeaderDestroy(st);
102: return(0);
103: }
107: static PetscErrorCode STPublish_Petsc(PetscObject object)
108: {
110: return(0);
111: }
115: /*@C
116: STCreate - Creates a spectral transformation context.
118: Collective on MPI_Comm
120: Input Parameter:
121: . comm - MPI communicator
123: Output Parameter:
124: . st - location to put the spectral transformation context
126: Level: beginner
128: .seealso: STSetUp(), STApply(), STDestroy(), ST
129: @*/
130: PetscErrorCode STCreate(MPI_Comm comm,ST *newst)
131: {
133: ST st;
134: const char *prefix;
138: *newst = 0;
140: PetscHeaderCreate(st,_p_ST,struct _STOps,ST_COOKIE,-1,"ST",comm,STDestroy,STView);
141: st->bops->publish = STPublish_Petsc;
142: PetscMemzero(st->ops,sizeof(struct _STOps));
144: st->A = 0;
145: st->B = 0;
146: st->sigma = 0.0;
147: st->data = 0;
148: st->setupcalled = 0;
149: st->w = 0;
150: st->shift_matrix = STMATMODE_COPY;
151: st->str = DIFFERENT_NONZERO_PATTERN;
152:
153: KSPCreate(st->comm,&st->ksp);
154: STGetOptionsPrefix(st,&prefix);
155: KSPSetOptionsPrefix(st->ksp,prefix);
156: KSPAppendOptionsPrefix(st->ksp,"st_");
157:
158: *newst = st;
159: PetscPublishAll(st);
160: return(0);
162: }
166: /*@
167: STSetOperators - Sets the matrices associated with the eigenvalue problem.
169: Collective on ST and Mat
171: Input Parameters:
172: + st - the spectral transformation context
173: . A - the matrix associated with the eigensystem
174: - B - the second matrix in the case of generalized eigenproblems
176: Notes:
177: To specify a standard eigenproblem, use PETSC_NULL for B.
179: Level: intermediate
181: .seealso: STGetOperators()
182: @*/
183: PetscErrorCode STSetOperators(ST st,Mat A,Mat B)
184: {
191: st->A = A;
192: st->B = B;
193: st->setupcalled = 0;
194: return(0);
195: }
199: /*@C
200: STGetOperators - Gets the matrices associated with the eigensystem.
202: Not collective, though parallel Mats are returned if the ST is parallel
204: Input Parameter:
205: . st - the spectral transformation context
207: Output Parameters:
208: . A - the matrix associated with the eigensystem
209: - B - the second matrix in the case of generalized eigenproblems
211: Level: intermediate
213: .seealso: STSetOperators()
214: @*/
215: PetscErrorCode STGetOperators(ST st,Mat *A,Mat *B)
216: {
219: if (A) *A = st->A;
220: if (B) *B = st->B;
221: return(0);
222: }
226: /*@
227: STSetShift - Sets the shift associated with the spectral transformation
229: Not collective
231: Input Parameters:
232: + st - the spectral transformation context
233: - shift - the value of the shift
235: Note:
236: In some spectral transformations, changing the shift may have associated
237: a lot of work, for example recomputing a factorization.
238:
239: Level: beginner
241: @*/
242: PetscErrorCode STSetShift(ST st,PetscScalar shift)
243: {
248: if (st->sigma != shift) {
249: if (st->ops->setshift) {
250: (*st->ops->setshift)(st,shift);
251: }
252: }
253: st->sigma = shift;
254: return(0);
255: }
259: /*@
260: STGetShift - Gets the shift associated with the spectral transformation.
262: Not collective
264: Input Parameter:
265: . st - the spectral transformation context
267: Output Parameter:
268: . shift - the value of the shift
270: Level: beginner
272: @*/
273: PetscErrorCode STGetShift(ST st,PetscScalar* shift)
274: {
277: if (shift) *shift = st->sigma;
278: return(0);
279: }
283: /*@C
284: STSetOptionsPrefix - Sets the prefix used for searching for all
285: ST options in the database.
287: Collective on ST
289: Input Parameters:
290: + st - the spectral transformation context
291: - prefix - the prefix string to prepend to all ST option requests
293: Notes:
294: A hyphen (-) must NOT be given at the beginning of the prefix name.
295: The first character of all runtime options is AUTOMATICALLY the
296: hyphen.
298: Level: advanced
300: .seealso: STAppendOptionsPrefix(), STGetOptionsPrefix()
301: @*/
302: PetscErrorCode STSetOptionsPrefix(ST st,const char *prefix)
303: {
308: PetscObjectSetOptionsPrefix((PetscObject)st,prefix);
309: KSPSetOptionsPrefix(st->ksp,prefix);
310: KSPAppendOptionsPrefix(st->ksp,"st_");
311: return(0);
312: }
316: /*@C
317: STAppendOptionsPrefix - Appends to the prefix used for searching for all
318: ST options in the database.
320: Collective on ST
322: Input Parameters:
323: + st - the spectral transformation context
324: - prefix - the prefix string to prepend to all ST option requests
326: Notes:
327: A hyphen (-) must NOT be given at the beginning of the prefix name.
328: The first character of all runtime options is AUTOMATICALLY the
329: hyphen.
331: Level: advanced
333: .seealso: STSetOptionsPrefix(), STGetOptionsPrefix()
334: @*/
335: PetscErrorCode STAppendOptionsPrefix(ST st,const char *prefix)
336: {
341: PetscObjectAppendOptionsPrefix((PetscObject)st,prefix);
342: KSPSetOptionsPrefix(st->ksp,st->prefix);
343: KSPAppendOptionsPrefix(st->ksp,"st_");
344: return(0);
345: }
349: /*@C
350: STGetOptionsPrefix - Gets the prefix used for searching for all
351: ST options in the database.
353: Not Collective
355: Input Parameters:
356: . st - the spectral transformation context
358: Output Parameters:
359: . prefix - pointer to the prefix string used, is returned
361: Notes: On the Fortran side, the user should pass in a string 'prefix' of
362: sufficient length to hold the prefix.
364: Level: advanced
366: .seealso: STSetOptionsPrefix(), STAppendOptionsPrefix()
367: @*/
368: PetscErrorCode STGetOptionsPrefix(ST st,const char *prefix[])
369: {
374: PetscObjectGetOptionsPrefix((PetscObject)st, prefix);
375: return(0);
376: }
380: /*@C
381: STView - Prints the ST data structure.
383: Collective on ST
385: Input Parameters:
386: + ST - the ST context
387: - viewer - optional visualization context
389: Note:
390: The available visualization contexts include
391: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
392: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
393: output where only the first processor opens
394: the file. All other processors send their
395: data to the first processor to print.
397: The user can open an alternative visualization contexts with
398: PetscViewerASCIIOpen() (output to a specified file).
400: Level: beginner
402: .seealso: EPSView(), PetscViewerASCIIOpen()
403: @*/
404: PetscErrorCode STView(ST st,PetscViewer viewer)
405: {
406: PetscErrorCode ierr;
407: STType cstr;
408: const char* str;
409: PetscTruth isascii,isstring;
410: PetscViewerFormat format;
414: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(st->comm);
418: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
419: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
420: if (isascii) {
421: PetscViewerGetFormat(viewer,&format);
422: PetscViewerASCIIPrintf(viewer,"ST Object:\n");
423: STGetType(st,&cstr);
424: if (cstr) {
425: PetscViewerASCIIPrintf(viewer," type: %s\n",cstr);
426: } else {
427: PetscViewerASCIIPrintf(viewer," type: not yet set\n");
428: }
429: #if !defined(PETSC_USE_COMPLEX)
430: PetscViewerASCIIPrintf(viewer," shift: %g\n",st->sigma);
431: #else
432: PetscViewerASCIIPrintf(viewer," shift: %g+%g i\n",PetscRealPart(st->sigma),PetscImaginaryPart(st->sigma));
433: #endif
434: switch (st->shift_matrix) {
435: case STMATMODE_COPY:
436: break;
437: case STMATMODE_INPLACE:
438: PetscViewerASCIIPrintf(viewer,"Shifting the matrix and unshifting at exit\n");
439: break;
440: case STMATMODE_SHELL:
441: PetscViewerASCIIPrintf(viewer,"Using a shell matrix\n");
442: break;
443: }
444: if (st->B && st->shift_matrix != STMATMODE_SHELL) {
445: switch (st->str) {
446: case SAME_NONZERO_PATTERN: str = "same nonzero pattern";break;
447: case DIFFERENT_NONZERO_PATTERN: str = "different nonzero pattern";break;
448: case SUBSET_NONZERO_PATTERN: str = "subset nonzero pattern";break;
449: default: SETERRQ(1,"Wrong structure flag");
450: }
451: PetscViewerASCIIPrintf(viewer,"Matrices A and B have %s\n",str);
452: }
453: if (st->ops->view) {
454: PetscViewerASCIIPushTab(viewer);
455: (*st->ops->view)(st,viewer);
456: PetscViewerASCIIPopTab(viewer);
457: }
458: } else if (isstring) {
459: STGetType(st,&cstr);
460: PetscViewerStringSPrintf(viewer," %-7.7s",cstr);
461: if (st->ops->view) {(*st->ops->view)(st,viewer);}
462: } else {
463: SETERRQ1(1,"Viewer type %s not supported by ST",((PetscObject)viewer)->type_name);
464: }
465: return(0);
466: }
470: PetscErrorCode STView_Default(ST st,PetscViewer viewer)
471: {
473: PetscTruth isascii,isstring;
476: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
477: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
478: if (isascii) {
479: PetscViewerASCIIPushTab(viewer);
480: PetscViewerASCIIPrintf(viewer,"Associated KSP object\n");
481: PetscViewerASCIIPrintf(viewer,"------------------------------\n");
482: KSPView(st->ksp,viewer);
483: PetscViewerASCIIPrintf(viewer,"------------------------------\n");
484: PetscViewerASCIIPopTab(viewer);
485: } else if (isstring) {
486: KSPView(st->ksp,viewer);
487: }
488: return(0);
489: }
491: /*MC
492: STRegisterDynamic - Adds a method to the spectral transformation package.
494: Synopsis:
495: STRegisterDynamic(char *name_solver,char *path,char *name_create,int (*routine_create)(ST))
497: Not collective
499: Input Parameters:
500: + name_solver - name of a new user-defined solver
501: . path - path (either absolute or relative) the library containing this solver
502: . name_create - name of routine to create method context
503: - routine_create - routine to create method context
505: Notes:
506: STRegisterDynamic() may be called multiple times to add several user-defined spectral transformations.
508: If dynamic libraries are used, then the fourth input argument (routine_create)
509: is ignored.
511: Sample usage:
512: .vb
513: STRegisterDynamic("my_solver","/home/username/my_lib/lib/libO/solaris/mylib.a",
514: "MySolverCreate",MySolverCreate);
515: .ve
517: Then, your solver can be chosen with the procedural interface via
518: $ STSetType(st,"my_solver")
519: or at runtime via the option
520: $ -st_type my_solver
522: Level: advanced
524: $PETSC_DIR, $PETSC_ARCH and $PETSC_LIB_DIR occuring in pathname will be replaced with appropriate values.
526: .seealso: STRegisterDestroy(), STRegisterAll()
527: M*/
531: /*@C
532: STRegister - See STRegisterDynamic()
534: Level: advanced
535: @*/
536: PetscErrorCode STRegister(const char *sname,const char *path,const char *name,int (*function)(ST))
537: {
539: char fullname[256];
542: PetscFListConcat(path,name,fullname);
543: PetscFListAdd(&STList,sname,fullname,(void (*)(void))function);
544: return(0);
545: }
549: /*@
550: STRegisterDestroy - Frees the list of ST methods that were
551: registered by STRegisterDynamic().
553: Not Collective
555: Level: advanced
557: .seealso: STRegisterDynamic(), STRegisterAll()
558: @*/
559: PetscErrorCode STRegisterDestroy(void)
560: {
564: PetscFListDestroy(&STList);
565: STRegisterAll(PETSC_NULL);
566: return(0);
567: }