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-2011, Universitat 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> /*I "slepcst.h" I*/
26: PetscClassId ST_CLASSID = 0;
27: PetscLogEvent ST_SetUp = 0,ST_Apply = 0,ST_ApplyTranspose = 0;
28: static PetscBool STPackageInitialized = PETSC_FALSE;
32: /*@C
33: STFinalizePackage - This function destroys everything in the Slepc interface
34: to the ST package. It is called from SlepcFinalize().
36: Level: developer
38: .seealso: SlepcFinalize()
39: @*/
40: PetscErrorCode STFinalizePackage(void)
41: {
43: STPackageInitialized = PETSC_FALSE;
44: STList = 0;
45: STRegisterAllCalled = PETSC_FALSE;
46: return(0);
47: }
51: /*@C
52: STInitializePackage - This function initializes everything in the ST package. It is called
53: from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to STCreate()
54: when using static libraries.
56: Input Parameter:
57: . path - The dynamic library path, or PETSC_NULL
59: Level: developer
61: .seealso: SlepcInitialize()
62: @*/
63: PetscErrorCode STInitializePackage(const char *path)
64: {
65: char logList[256];
66: char *className;
67: PetscBool opt;
71: if (STPackageInitialized) return(0);
72: STPackageInitialized = PETSC_TRUE;
73: /* Register Classes */
74: PetscClassIdRegister("Spectral Transform",&ST_CLASSID);
75: /* Register Constructors */
76: STRegisterAll(path);
77: /* Register Events */
78: PetscLogEventRegister("STSetUp",ST_CLASSID,&ST_SetUp);
79: PetscLogEventRegister("STApply",ST_CLASSID,&ST_Apply);
80: PetscLogEventRegister("STApplyTranspose",ST_CLASSID,&ST_ApplyTranspose);
81: /* Process info exclusions */
82: PetscOptionsGetString(PETSC_NULL,"-info_exclude",logList,256,&opt);
83: if (opt) {
84: PetscStrstr(logList,"st",&className);
85: if (className) {
86: PetscInfoDeactivateClass(ST_CLASSID);
87: }
88: }
89: /* Process summary exclusions */
90: PetscOptionsGetString(PETSC_NULL,"-log_summary_exclude",logList,256,&opt);
91: if (opt) {
92: PetscStrstr(logList,"st",&className);
93: if (className) {
94: PetscLogEventDeactivateClass(ST_CLASSID);
95: }
96: }
97: PetscRegisterFinalize(STFinalizePackage);
98: return(0);
99: }
103: /*@
104: STReset - Resets the ST context and removes any allocated objects.
106: Collective on ST
108: Input Parameter:
109: . st - the spectral transformation context
111: Level: advanced
113: .seealso: STDestroy()
114: @*/
115: PetscErrorCode STReset(ST st)
116: {
121: if (st->ops->reset) { (*st->ops->reset)(st); }
122: if (st->ksp) { KSPReset(st->ksp); }
123: MatDestroy(&st->A);
124: MatDestroy(&st->B);
125: VecDestroy(&st->w);
126: VecDestroy(&st->D);
127: VecDestroy(&st->wb);
128: if (st->shift_matrix != ST_MATMODE_INPLACE) {
129: MatDestroy(&st->mat);
130: }
131: STResetOperationCounters(st);
132: st->setupcalled = 0;
133: return(0);
134: }
138: /*@C
139: STDestroy - Destroys ST context that was created with STCreate().
141: Collective on ST
143: Input Parameter:
144: . st - the spectral transformation context
146: Level: beginner
148: .seealso: STCreate(), STSetUp()
149: @*/
150: PetscErrorCode STDestroy(ST *st)
151: {
155: if (!*st) return(0);
157: if (--((PetscObject)(*st))->refct > 0) { *st = 0; return(0); }
158: STReset(*st);
159: PetscObjectDepublish(*st);
160: if ((*st)->ops->destroy) { (*(*st)->ops->destroy)(*st); }
161: KSPDestroy(&(*st)->ksp);
162: PetscHeaderDestroy(st);
163: return(0);
164: }
168: /*@C
169: STCreate - Creates a spectral transformation context.
171: Collective on MPI_Comm
173: Input Parameter:
174: . comm - MPI communicator
176: Output Parameter:
177: . st - location to put the spectral transformation context
179: Level: beginner
181: .seealso: STSetUp(), STApply(), STDestroy(), ST
182: @*/
183: PetscErrorCode STCreate(MPI_Comm comm,ST *newst)
184: {
186: ST st;
190: *newst = 0;
191: PetscHeaderCreate(st,_p_ST,struct _STOps,ST_CLASSID,-1,"ST","Spectral Transformation","ST",comm,STDestroy,STView);
192: st->A = 0;
193: st->B = 0;
194: st->sigma = 0.0;
195: st->sigma_set = PETSC_FALSE;
196: st->defsigma = 0.0;
197: st->data = 0;
198: st->setupcalled = 0;
199: st->w = 0;
200: st->D = 0;
201: st->wb = 0;
202: st->mat = 0;
203: st->shift_matrix = ST_MATMODE_COPY;
204: st->str = DIFFERENT_NONZERO_PATTERN;
205: *newst = st;
206: return(0);
207: }
211: /*@
212: STSetOperators - Sets the matrices associated with the eigenvalue problem.
214: Collective on ST and Mat
216: Input Parameters:
217: + st - the spectral transformation context
218: . A - the matrix associated with the eigensystem
219: - B - the second matrix in the case of generalized eigenproblems
221: Notes:
222: To specify a standard eigenproblem, use PETSC_NULL for B.
224: It must be called after STSetUp(). If it is called again after STSetUp() then
225: the ST object is reset.
227: Level: intermediate
229: .seealso: STGetOperators(), STSetUp(), STReset()
230: @*/
231: PetscErrorCode STSetOperators(ST st,Mat A,Mat B)
232: {
241: if (st->setupcalled) { STReset(st); }
242: MatDestroy(&st->A);
243: PetscObjectReference((PetscObject)A);
244: st->A = A;
245: MatDestroy(&st->B);
246: if (B) { PetscObjectReference((PetscObject)B); }
247: st->B = B;
248: return(0);
249: }
253: /*@C
254: STGetOperators - Gets the matrices associated with the eigensystem.
256: Not collective, though parallel Mats are returned if the ST is parallel
258: Input Parameter:
259: . st - the spectral transformation context
261: Output Parameters:
262: . A - the matrix associated with the eigensystem
263: - B - the second matrix in the case of generalized eigenproblems
265: Level: intermediate
267: .seealso: STSetOperators()
268: @*/
269: PetscErrorCode STGetOperators(ST st,Mat *A,Mat *B)
270: {
273: if (A) *A = st->A;
274: if (B) *B = st->B;
275: return(0);
276: }
280: /*@
281: STSetShift - Sets the shift associated with the spectral transformation.
283: Logically Collective on ST
285: Input Parameters:
286: + st - the spectral transformation context
287: - shift - the value of the shift
289: Note:
290: In some spectral transformations, changing the shift may have associated
291: a lot of work, for example recomputing a factorization.
292:
293: Level: beginner
295: @*/
296: PetscErrorCode STSetShift(ST st,PetscScalar shift)
297: {
303: if (st->sigma != shift) {
304: if (st->ops->setshift) {
305: (*st->ops->setshift)(st,shift);
306: }
307: }
308: st->sigma = shift;
309: st->sigma_set = PETSC_TRUE;
310: return(0);
311: }
315: /*@
316: STGetShift - Gets the shift associated with the spectral transformation.
318: Not Collective
320: Input Parameter:
321: . st - the spectral transformation context
323: Output Parameter:
324: . shift - the value of the shift
326: Level: beginner
328: @*/
329: PetscErrorCode STGetShift(ST st,PetscScalar* shift)
330: {
334: *shift = st->sigma;
335: return(0);
336: }
340: /*@
341: STSetDefaultShift - Sets the value of the shift that should be employed if
342: the user did not specify one.
344: Logically Collective on ST
346: Input Parameters:
347: + st - the spectral transformation context
348: - defaultshift - the default value of the shift
350: Level: developer
352: @*/
353: PetscErrorCode STSetDefaultShift(ST st,PetscScalar defaultshift)
354: {
358: st->defsigma = defaultshift;
359: return(0);
360: }
364: /*@
365: STSetBalanceMatrix - Sets the diagonal matrix to be used for balancing.
367: Collective on ST and Vec
369: Input Parameters:
370: + st - the spectral transformation context
371: - D - the diagonal matrix (represented as a vector)
373: Notes:
374: If this matrix is set, STApply will effectively apply D*OP*D^{-1}.
376: Balancing is usually set via EPSSetBalance, but the advanced user may use
377: this function to bypass the usual balancing methods.
378:
379: Level: developer
381: .seealso: EPSSetBalance(), STApply(), STGetBalanceMatrix()
382: @*/
383: PetscErrorCode STSetBalanceMatrix(ST st,Vec D)
384: {
391: PetscObjectReference((PetscObject)D);
392: VecDestroy(&st->D);
393: st->D = D;
394: st->setupcalled = 0;
395: return(0);
396: }
400: /*@
401: STGetBalanceMatrix - Gets the balance matrix used by the spectral transformation.
403: Not collective, but vector is shared by all processors that share the ST
405: Input Parameter:
406: . st - the spectral transformation context
408: Output Parameter:
409: . D - the diagonal matrix (represented as a vector)
411: Note:
412: If the matrix was not set, a null pointer will be returned.
414: Level: developer
416: .seealso: STSetBalanceMatrix()
417: @*/
418: PetscErrorCode STGetBalanceMatrix(ST st,Vec *D)
419: {
423: *D = st->D;
424: return(0);
425: }
429: /*@C
430: STSetOptionsPrefix - Sets the prefix used for searching for all
431: ST options in the database.
433: Logically Collective on ST
435: Input Parameters:
436: + st - the spectral transformation context
437: - prefix - the prefix string to prepend to all ST option requests
439: Notes:
440: A hyphen (-) must NOT be given at the beginning of the prefix name.
441: The first character of all runtime options is AUTOMATICALLY the
442: hyphen.
444: Level: advanced
446: .seealso: STAppendOptionsPrefix(), STGetOptionsPrefix()
447: @*/
448: PetscErrorCode STSetOptionsPrefix(ST st,const char *prefix)
449: {
454: if (!st->ksp) { STGetKSP(st,&st->ksp); }
455: KSPSetOptionsPrefix(st->ksp,prefix);
456: KSPAppendOptionsPrefix(st->ksp,"st_");
457: PetscObjectSetOptionsPrefix((PetscObject)st,prefix);
458: return(0);
459: }
463: /*@C
464: STAppendOptionsPrefix - Appends to the prefix used for searching for all
465: ST options in the database.
467: Logically Collective on ST
469: Input Parameters:
470: + st - the spectral transformation context
471: - prefix - the prefix string to prepend to all ST option requests
473: Notes:
474: A hyphen (-) must NOT be given at the beginning of the prefix name.
475: The first character of all runtime options is AUTOMATICALLY the
476: hyphen.
478: Level: advanced
480: .seealso: STSetOptionsPrefix(), STGetOptionsPrefix()
481: @*/
482: PetscErrorCode STAppendOptionsPrefix(ST st,const char *prefix)
483: {
488: PetscObjectAppendOptionsPrefix((PetscObject)st,prefix);
489: if (!st->ksp) { STGetKSP(st,&st->ksp); }
490: KSPSetOptionsPrefix(st->ksp,((PetscObject)st)->prefix);
491: KSPAppendOptionsPrefix(st->ksp,"st_");
492: return(0);
493: }
497: /*@C
498: STGetOptionsPrefix - Gets the prefix used for searching for all
499: ST options in the database.
501: Not Collective
503: Input Parameters:
504: . st - the spectral transformation context
506: Output Parameters:
507: . prefix - pointer to the prefix string used, is returned
509: Notes: On the Fortran side, the user should pass in a string 'prefix' of
510: sufficient length to hold the prefix.
512: Level: advanced
514: .seealso: STSetOptionsPrefix(), STAppendOptionsPrefix()
515: @*/
516: PetscErrorCode STGetOptionsPrefix(ST st,const char *prefix[])
517: {
523: PetscObjectGetOptionsPrefix((PetscObject)st,prefix);
524: return(0);
525: }
529: /*@C
530: STView - Prints the ST data structure.
532: Collective on ST
534: Input Parameters:
535: + st - the ST context
536: - viewer - optional visualization context
538: Note:
539: The available visualization contexts include
540: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
541: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
542: output where only the first processor opens
543: the file. All other processors send their
544: data to the first processor to print.
546: The user can open an alternative visualization contexts with
547: PetscViewerASCIIOpen() (output to a specified file).
549: Level: beginner
551: .seealso: EPSView(), PetscViewerASCIIOpen()
552: @*/
553: PetscErrorCode STView(ST st,PetscViewer viewer)
554: {
555: PetscErrorCode ierr;
556: const STType cstr;
557: const char* str;
558: PetscBool isascii,isstring,flg;
559: PC pc;
563: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(((PetscObject)st)->comm);
567: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
568: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
569: if (isascii) {
570: PetscObjectPrintClassNamePrefixType((PetscObject)st,viewer,"ST Object");
571: if (st->ops->view) {
572: PetscViewerASCIIPushTab(viewer);
573: (*st->ops->view)(st,viewer);
574: PetscViewerASCIIPopTab(viewer);
575: }
576: #if !defined(PETSC_USE_COMPLEX)
577: PetscViewerASCIIPrintf(viewer," shift: %G\n",st->sigma);
578: #else
579: PetscViewerASCIIPrintf(viewer," shift: %G+%G i\n",PetscRealPart(st->sigma),PetscImaginaryPart(st->sigma));
580: #endif
581: switch (st->shift_matrix) {
582: case ST_MATMODE_COPY:
583: break;
584: case ST_MATMODE_INPLACE:
585: PetscViewerASCIIPrintf(viewer," shifting the matrix and unshifting at exit\n");
586: break;
587: case ST_MATMODE_SHELL:
588: PetscViewerASCIIPrintf(viewer," using a shell matrix\n");
589: break;
590: }
591: if (st->B && st->shift_matrix != ST_MATMODE_SHELL) {
592: switch (st->str) {
593: case SAME_NONZERO_PATTERN: str = "same nonzero pattern";break;
594: case DIFFERENT_NONZERO_PATTERN: str = "different nonzero pattern";break;
595: case SUBSET_NONZERO_PATTERN: str = "subset nonzero pattern";break;
596: default: SETERRQ(((PetscObject)st)->comm,1,"Wrong structure flag");
597: }
598: PetscViewerASCIIPrintf(viewer," matrices A and B have %s\n",str);
599: }
600: } else if (isstring) {
601: STGetType(st,&cstr);
602: PetscViewerStringSPrintf(viewer," %-7.7s",cstr);
603: if (st->ops->view) {(*st->ops->view)(st,viewer);}
604: } else {
605: SETERRQ1(((PetscObject)st)->comm,1,"Viewer type %s not supported by ST",((PetscObject)viewer)->type_name);
606: }
607: PetscTypeCompareAny((PetscObject)st,&flg,STSHIFT,STFOLD,"");
608: if (st->B || !flg) {
609: if (!st->ksp) { STGetKSP(st,&st->ksp); }
610: /* Trick for PCView when an unused PC is showed */
611: KSPGetPC(st->ksp,&pc);
612: PetscTypeCompare((PetscObject)pc,PCNONE,&flg);
613: if (flg) {
614: PCSetOperators(pc,PETSC_NULL,PETSC_NULL,DIFFERENT_NONZERO_PATTERN);
615: }
616: PetscViewerASCIIPushTab(viewer);
617: KSPView(st->ksp,viewer);
618: PetscViewerASCIIPopTab(viewer);
619: }
620: return(0);
621: }
625: /*@C
626: STRegister - See STRegisterDynamic()
628: Level: advanced
629: @*/
630: PetscErrorCode STRegister(const char *sname,const char *path,const char *name,PetscErrorCode (*function)(ST))
631: {
633: char fullname[PETSC_MAX_PATH_LEN];
636: PetscFListConcat(path,name,fullname);
637: PetscFListAdd(&STList,sname,fullname,(void (*)(void))function);
638: return(0);
639: }
643: /*@
644: STRegisterDestroy - Frees the list of ST methods that were
645: registered by STRegisterDynamic().
647: Not Collective
649: Level: advanced
651: .seealso: STRegisterDynamic(), STRegisterAll()
652: @*/
653: PetscErrorCode STRegisterDestroy(void)
654: {
658: PetscFListDestroy(&STList);
659: STRegisterAllCalled = PETSC_FALSE;
660: return(0);
661: }