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-2010, Universidad Politecnica de Valencia, Spain
8: This file is part of SLEPc.
9:
10: SLEPc is free software: you can redistribute it and/or modify it under the
11: terms of version 3 of the GNU Lesser General Public License as published by
12: the Free Software Foundation.
14: SLEPc is distributed in the hope that it will be useful, but WITHOUT ANY
15: WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16: FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
17: more details.
19: You should have received a copy of the GNU Lesser General Public License
20: along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
21: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
22: */
24: #include private/stimpl.h
26: PetscCookie ST_COOKIE = 0;
27: PetscLogEvent ST_SetUp = 0, ST_Apply = 0, ST_ApplyTranspose = 0;
28: static PetscTruth STPackageInitialized = PETSC_FALSE;
32: /*@C
33: STFinalizePackage - This function destroys everything in the Slepc interface to the ST package. It is
34: called from SlepcFinalize().
36: Level: developer
38: .seealso: SlepcFinalize()
39: @*/
40: PetscErrorCode STFinalizePackage(void)
41: {
43: STPackageInitialized = PETSC_FALSE;
44: STList = 0;
45: return(0);
46: }
50: /*@C
51: STInitializePackage - This function initializes everything in the ST package. It is called
52: from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to STCreate()
53: when using static libraries.
55: Input Parameter:
56: path - The dynamic library path, or PETSC_NULL
58: Level: developer
60: .seealso: SlepcInitialize()
61: @*/
62: PetscErrorCode STInitializePackage(char *path) {
63: char logList[256];
64: char *className;
65: PetscTruth opt;
69: if (STPackageInitialized) return(0);
70: STPackageInitialized = PETSC_TRUE;
71: /* Register Classes */
72: PetscCookieRegister("Spectral Transform",&ST_COOKIE);
73: /* Register Constructors */
74: STRegisterAll(path);
75: /* Register Events */
76: PetscLogEventRegister("STSetUp",ST_COOKIE,&ST_SetUp);
77: PetscLogEventRegister("STApply",ST_COOKIE,&ST_Apply);
78: PetscLogEventRegister("STApplyTranspose",ST_COOKIE,&ST_ApplyTranspose);
79: /* Process info exclusions */
80: PetscOptionsGetString(PETSC_NULL, "-log_info_exclude", logList, 256, &opt);
81: if (opt) {
82: PetscStrstr(logList, "st", &className);
83: if (className) {
84: PetscInfoDeactivateClass(ST_COOKIE);
85: }
86: }
87: /* Process summary exclusions */
88: PetscOptionsGetString(PETSC_NULL, "-log_summary_exclude", logList, 256, &opt);
89: if (opt) {
90: PetscStrstr(logList, "st", &className);
91: if (className) {
92: PetscLogEventDeactivateClass(ST_COOKIE);
93: }
94: }
95: PetscRegisterFinalize(STFinalizePackage);
96: return(0);
97: }
101: /*@
102: STDestroy - Destroys ST context that was created with STCreate().
104: Collective on ST
106: Input Parameter:
107: . st - the spectral transformation context
109: Level: beginner
111: .seealso: STCreate(), STSetUp()
112: @*/
113: PetscErrorCode STDestroy(ST st)
114: {
119: if (--((PetscObject)st)->refct > 0) return(0);
121: /* if memory was published with AMS then destroy it */
122: PetscObjectDepublish(st);
124: if (st->ops->destroy) { (*st->ops->destroy)(st); }
125: if (st->A) { MatDestroy(st->A); }
126: if (st->B) { MatDestroy(st->B); }
127: if (st->ksp) { KSPDestroy(st->ksp); }
128: if (st->w) { VecDestroy(st->w); }
129: if (st->D) { VecDestroy(st->D); }
130: if (st->wb){ VecDestroy(st->wb); }
131: if (st->shift_matrix != ST_MATMODE_INPLACE && st->mat) {
132: MatDestroy(st->mat);
133: }
135: PetscHeaderDestroy(st);
136: return(0);
137: }
141: /*@C
142: STCreate - Creates a spectral transformation context.
144: Collective on MPI_Comm
146: Input Parameter:
147: . comm - MPI communicator
149: Output Parameter:
150: . st - location to put the spectral transformation context
152: Level: beginner
154: .seealso: STSetUp(), STApply(), STDestroy(), ST
155: @*/
156: PetscErrorCode STCreate(MPI_Comm comm,ST *newst)
157: {
159: ST st;
160: const char *prefix;
164: *newst = 0;
166: PetscHeaderCreate(st,_p_ST,struct _STOps,ST_COOKIE,-1,"ST",comm,STDestroy,STView);
167: PetscMemzero(st->ops,sizeof(struct _STOps));
169: st->A = 0;
170: st->B = 0;
171: st->sigma = 0.0;
172: st->sigma_set = PETSC_FALSE;
173: st->defsigma = 0.0;
174: st->data = 0;
175: st->setupcalled = 0;
176: st->w = 0;
177: st->D = 0;
178: st->wb = 0;
179: st->shift_matrix = ST_MATMODE_COPY;
180: st->str = DIFFERENT_NONZERO_PATTERN;
181:
182: KSPCreate(((PetscObject)st)->comm,&st->ksp);
183: STGetOptionsPrefix(st,&prefix);
184: KSPSetOptionsPrefix(st->ksp,prefix);
185: KSPAppendOptionsPrefix(st->ksp,"st_");
186: PetscObjectIncrementTabLevel((PetscObject)st->ksp,(PetscObject)st,1);
187:
188: *newst = st;
189: PetscPublishAll(st);
190: return(0);
192: }
196: /*@
197: STSetOperators - Sets the matrices associated with the eigenvalue problem.
199: Collective on ST and Mat
201: Input Parameters:
202: + st - the spectral transformation context
203: . A - the matrix associated with the eigensystem
204: - B - the second matrix in the case of generalized eigenproblems
206: Notes:
207: To specify a standard eigenproblem, use PETSC_NULL for B.
209: Level: intermediate
211: .seealso: STGetOperators()
212: @*/
213: PetscErrorCode STSetOperators(ST st,Mat A,Mat B)
214: {
222: PetscObjectReference((PetscObject)A);
223: if (st->A) { MatDestroy(st->A); }
224: st->A = A;
225: if (B) { PetscObjectReference((PetscObject)B); }
226: if (st->B) { MatDestroy(st->B); }
227: st->B = B;
228: st->setupcalled = 0;
229: return(0);
230: }
234: /*@C
235: STGetOperators - Gets the matrices associated with the eigensystem.
237: Not collective, though parallel Mats are returned if the ST is parallel
239: Input Parameter:
240: . st - the spectral transformation context
242: Output Parameters:
243: . A - the matrix associated with the eigensystem
244: - B - the second matrix in the case of generalized eigenproblems
246: Level: intermediate
248: .seealso: STSetOperators()
249: @*/
250: PetscErrorCode STGetOperators(ST st,Mat *A,Mat *B)
251: {
254: if (A) *A = st->A;
255: if (B) *B = st->B;
256: return(0);
257: }
261: /*@
262: STSetShift - Sets the shift associated with the spectral transformation.
264: Collective on ST
266: Input Parameters:
267: + st - the spectral transformation context
268: - shift - the value of the shift
270: Note:
271: In some spectral transformations, changing the shift may have associated
272: a lot of work, for example recomputing a factorization.
273:
274: Level: beginner
276: @*/
277: PetscErrorCode STSetShift(ST st,PetscScalar shift)
278: {
283: if (st->sigma != shift) {
284: if (st->ops->setshift) {
285: (*st->ops->setshift)(st,shift);
286: }
287: }
288: st->sigma = shift;
289: st->sigma_set = PETSC_TRUE;
290: return(0);
291: }
295: /*@
296: STGetShift - Gets the shift associated with the spectral transformation.
298: Not collective
300: Input Parameter:
301: . st - the spectral transformation context
303: Output Parameter:
304: . shift - the value of the shift
306: Level: beginner
308: @*/
309: PetscErrorCode STGetShift(ST st,PetscScalar* shift)
310: {
313: if (shift) *shift = st->sigma;
314: return(0);
315: }
319: /*@
320: STSetDefaultShift - Sets the value of the shift that should be employed if
321: the user did not specify one.
323: Collective on ST
325: Input Parameters:
326: + st - the spectral transformation context
327: - defaultshift - the default value of the shift
329: Level: developer
331: @*/
332: PetscErrorCode STSetDefaultShift(ST st,PetscScalar defaultshift)
333: {
336: st->defsigma = defaultshift;
337: return(0);
338: }
342: /*@
343: STSetBalanceMatrix - Sets the diagonal matrix to be used for balancing.
345: Collective on ST and Vec
347: Input Parameters:
348: + st - the spectral transformation context
349: - D - the diagonal matrix (represented as a vector)
351: Notes:
352: If this matrix is set, STApply will effectively apply D*OP*D^{-1}.
354: Balancing is usually set via EPSSetBalance, but the advanced user may use
355: this function to bypass the usual balancing methods.
356:
357: Level: developer
359: .seealso: EPSSetBalance(), STApply(), STGetBalanceMatrix()
360: @*/
361: PetscErrorCode STSetBalanceMatrix(ST st,Vec D)
362: {
369: PetscObjectReference((PetscObject)D);
370: if (st->D) {
371: VecDestroy(st->D);
372: }
373: st->D = D;
374: if (!st->wb) {
375: VecDuplicate(st->D,&st->wb);
376: }
377: return(0);
378: }
382: /*@
383: STGetBalanceMatrix - Gets the balance matrix used by the spectral transformation.
385: Not collective, but vector is shared by all processors that share the ST
387: Input Parameter:
388: . st - the spectral transformation context
390: Output Parameter:
391: . D - the diagonal matrix (represented as a vector)
393: Note:
394: If the matrix was not set, a null pointer will be returned.
396: Level: developer
398: .seealso: STSetBalanceMatrix()
399: @*/
400: PetscErrorCode STGetBalanceMatrix(ST st,Vec *D)
401: {
405: *D = st->D;
406: return(0);
407: }
411: /*@C
412: STSetOptionsPrefix - Sets the prefix used for searching for all
413: ST options in the database.
415: Collective on ST
417: Input Parameters:
418: + st - the spectral transformation context
419: - prefix - the prefix string to prepend to all ST option requests
421: Notes:
422: A hyphen (-) must NOT be given at the beginning of the prefix name.
423: The first character of all runtime options is AUTOMATICALLY the
424: hyphen.
426: Level: advanced
428: .seealso: STAppendOptionsPrefix(), STGetOptionsPrefix()
429: @*/
430: PetscErrorCode STSetOptionsPrefix(ST st,const char *prefix)
431: {
436: PetscObjectSetOptionsPrefix((PetscObject)st,prefix);
437: KSPSetOptionsPrefix(st->ksp,prefix);
438: KSPAppendOptionsPrefix(st->ksp,"st_");
439: return(0);
440: }
444: /*@C
445: STAppendOptionsPrefix - Appends to the prefix used for searching for all
446: ST options in the database.
448: Collective on ST
450: Input Parameters:
451: + st - the spectral transformation context
452: - prefix - the prefix string to prepend to all ST option requests
454: Notes:
455: A hyphen (-) must NOT be given at the beginning of the prefix name.
456: The first character of all runtime options is AUTOMATICALLY the
457: hyphen.
459: Level: advanced
461: .seealso: STSetOptionsPrefix(), STGetOptionsPrefix()
462: @*/
463: PetscErrorCode STAppendOptionsPrefix(ST st,const char *prefix)
464: {
469: PetscObjectAppendOptionsPrefix((PetscObject)st,prefix);
470: KSPSetOptionsPrefix(st->ksp,((PetscObject)st)->prefix);
471: KSPAppendOptionsPrefix(st->ksp,"st_");
472: return(0);
473: }
477: /*@C
478: STGetOptionsPrefix - Gets the prefix used for searching for all
479: ST options in the database.
481: Not Collective
483: Input Parameters:
484: . st - the spectral transformation context
486: Output Parameters:
487: . prefix - pointer to the prefix string used, is returned
489: Notes: On the Fortran side, the user should pass in a string 'prefix' of
490: sufficient length to hold the prefix.
492: Level: advanced
494: .seealso: STSetOptionsPrefix(), STAppendOptionsPrefix()
495: @*/
496: PetscErrorCode STGetOptionsPrefix(ST st,const char *prefix[])
497: {
502: PetscObjectGetOptionsPrefix((PetscObject)st, prefix);
503: return(0);
504: }
508: /*@C
509: STView - Prints the ST data structure.
511: Collective on ST
513: Input Parameters:
514: + ST - the ST context
515: - viewer - optional visualization context
517: Note:
518: The available visualization contexts include
519: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
520: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
521: output where only the first processor opens
522: the file. All other processors send their
523: data to the first processor to print.
525: The user can open an alternative visualization contexts with
526: PetscViewerASCIIOpen() (output to a specified file).
528: Level: beginner
530: .seealso: EPSView(), PetscViewerASCIIOpen()
531: @*/
532: PetscErrorCode STView(ST st,PetscViewer viewer)
533: {
534: PetscErrorCode ierr;
535: const STType cstr;
536: const char* str;
537: PetscTruth isascii,isstring;
538: PetscViewerFormat format;
542: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(((PetscObject)st)->comm);
546: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
547: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
548: if (isascii) {
549: PetscViewerGetFormat(viewer,&format);
550: PetscViewerASCIIPrintf(viewer,"ST Object:\n");
551: STGetType(st,&cstr);
552: if (cstr) {
553: PetscViewerASCIIPrintf(viewer," type: %s\n",cstr);
554: } else {
555: PetscViewerASCIIPrintf(viewer," type: not yet set\n");
556: }
557: #if !defined(PETSC_USE_COMPLEX)
558: PetscViewerASCIIPrintf(viewer," shift: %g\n",st->sigma);
559: #else
560: PetscViewerASCIIPrintf(viewer," shift: %g+%g i\n",PetscRealPart(st->sigma),PetscImaginaryPart(st->sigma));
561: #endif
562: switch (st->shift_matrix) {
563: case ST_MATMODE_COPY:
564: break;
565: case ST_MATMODE_INPLACE:
566: PetscViewerASCIIPrintf(viewer,"Shifting the matrix and unshifting at exit\n");
567: break;
568: case ST_MATMODE_SHELL:
569: PetscViewerASCIIPrintf(viewer,"Using a shell matrix\n");
570: break;
571: }
572: if (st->B && st->shift_matrix != ST_MATMODE_SHELL) {
573: switch (st->str) {
574: case SAME_NONZERO_PATTERN: str = "same nonzero pattern";break;
575: case DIFFERENT_NONZERO_PATTERN: str = "different nonzero pattern";break;
576: case SUBSET_NONZERO_PATTERN: str = "subset nonzero pattern";break;
577: default: SETERRQ(1,"Wrong structure flag");
578: }
579: PetscViewerASCIIPrintf(viewer,"Matrices A and B have %s\n",str);
580: }
581: if (st->ops->view) {
582: PetscViewerASCIIPushTab(viewer);
583: (*st->ops->view)(st,viewer);
584: PetscViewerASCIIPopTab(viewer);
585: }
586: } else if (isstring) {
587: STGetType(st,&cstr);
588: PetscViewerStringSPrintf(viewer," %-7.7s",cstr);
589: if (st->ops->view) {(*st->ops->view)(st,viewer);}
590: } else {
591: SETERRQ1(1,"Viewer type %s not supported by ST",((PetscObject)viewer)->type_name);
592: }
593: return(0);
594: }
598: PetscErrorCode STView_Default(ST st,PetscViewer viewer)
599: {
601: PetscTruth isascii,isstring;
604: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
605: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
606: if (isascii) {
607: PetscViewerASCIIPushTab(viewer);
608: PetscViewerASCIIPrintf(viewer,"Associated KSP object\n");
609: PetscViewerASCIIPrintf(viewer,"------------------------------\n");
610: KSPView(st->ksp,viewer);
611: PetscViewerASCIIPrintf(viewer,"------------------------------\n");
612: PetscViewerASCIIPopTab(viewer);
613: } else if (isstring) {
614: KSPView(st->ksp,viewer);
615: }
616: return(0);
617: }
619: /*MC
620: STRegisterDynamic - Adds a method to the spectral transformation package.
622: Synopsis:
623: STRegisterDynamic(char *name_solver,char *path,char *name_create,PetscErrorCode (*routine_create)(ST))
625: Not collective
627: Input Parameters:
628: + name_solver - name of a new user-defined solver
629: . path - path (either absolute or relative) the library containing this solver
630: . name_create - name of routine to create method context
631: - routine_create - routine to create method context
633: Notes:
634: STRegisterDynamic() may be called multiple times to add several user-defined spectral transformations.
636: If dynamic libraries are used, then the fourth input argument (routine_create)
637: is ignored.
639: Sample usage:
640: .vb
641: STRegisterDynamic("my_solver","/home/username/my_lib/lib/libO/solaris/mylib.a",
642: "MySolverCreate",MySolverCreate);
643: .ve
645: Then, your solver can be chosen with the procedural interface via
646: $ STSetType(st,"my_solver")
647: or at runtime via the option
648: $ -st_type my_solver
650: Level: advanced
652: $PETSC_DIR, $PETSC_ARCH and $PETSC_LIB_DIR occuring in pathname will be replaced with appropriate values.
654: .seealso: STRegisterDestroy(), STRegisterAll()
655: M*/
659: /*@C
660: STRegister - See STRegisterDynamic()
662: Level: advanced
663: @*/
664: PetscErrorCode STRegister(const char *sname,const char *path,const char *name,PetscErrorCode (*function)(ST))
665: {
667: char fullname[256];
670: PetscFListConcat(path,name,fullname);
671: PetscFListAdd(&STList,sname,fullname,(void (*)(void))function);
672: return(0);
673: }
677: /*@
678: STRegisterDestroy - Frees the list of ST methods that were
679: registered by STRegisterDynamic().
681: Not Collective
683: Level: advanced
685: .seealso: STRegisterDynamic(), STRegisterAll()
686: @*/
687: PetscErrorCode STRegisterDestroy(void)
688: {
692: PetscFListDestroy(&STList);
693: STRegisterAll(PETSC_NULL);
694: return(0);
695: }