Actual source code: basic.c
1: /*
2: The basic EPS routines, Create, View, etc. are here.
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/eps/epsimpl.h
15: PetscFList EPSList = 0;
16: PetscCookie EPS_COOKIE = 0;
17: PetscEvent EPS_SetUp = 0, EPS_Solve = 0, EPS_Dense = 0;
21: /*@C
22: EPSInitializePackage - This function initializes everything in the EPS package. It is called
23: from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to EPSCreate()
24: when using static libraries.
26: Input Parameter:
27: path - The dynamic library path, or PETSC_NULL
29: Level: developer
31: .seealso: SlepcInitialize()
32: @*/
33: PetscErrorCode EPSInitializePackage(char *path) {
34: static PetscTruth initialized = PETSC_FALSE;
35: char logList[256];
36: char *className;
37: PetscTruth opt;
41: if (initialized) return(0);
42: initialized = PETSC_TRUE;
43: /* Register Classes */
44: PetscLogClassRegister(&EPS_COOKIE,"Eigenproblem Solver");
45: /* Register Constructors */
46: EPSRegisterAll(path);
47: /* Register Events */
48: PetscLogEventRegister(&EPS_SetUp,"EPSSetUp",EPS_COOKIE);
49: PetscLogEventRegister(&EPS_Solve,"EPSSolve",EPS_COOKIE);
50: PetscLogEventRegister(&EPS_Dense,"EPSDense",EPS_COOKIE);
51: /* Process info exclusions */
52: PetscOptionsGetString(PETSC_NULL, "-log_info_exclude", logList, 256, &opt);
53: if (opt) {
54: PetscStrstr(logList, "eps", &className);
55: if (className) {
56: PetscInfoDeactivateClass(EPS_COOKIE);
57: }
58: }
59: /* Process summary exclusions */
60: PetscOptionsGetString(PETSC_NULL, "-log_summary_exclude", logList, 256, &opt);
61: if (opt) {
62: PetscStrstr(logList, "eps", &className);
63: if (className) {
64: PetscLogEventDeactivateClass(EPS_COOKIE);
65: }
66: }
67: return(0);
68: }
72: /*@C
73: EPSView - Prints the EPS data structure.
75: Collective on EPS
77: Input Parameters:
78: + eps - the eigenproblem solver context
79: - viewer - optional visualization context
81: Options Database Key:
82: . -eps_view - Calls EPSView() at end of EPSSolve()
84: Note:
85: The available visualization contexts include
86: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
87: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
88: output where only the first processor opens
89: the file. All other processors send their
90: data to the first processor to print.
92: The user can open an alternative visualization context with
93: PetscViewerASCIIOpen() - output to a specified file.
95: Level: beginner
97: .seealso: STView(), PetscViewerASCIIOpen()
98: @*/
99: PetscErrorCode EPSView(EPS eps,PetscViewer viewer)
100: {
102: const char *type, *which;
103: PetscTruth isascii;
107: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(eps->comm);
111: #if defined(PETSC_USE_COMPLEX)
112: #define HERM "hermitian"
113: #else
114: #define HERM "symmetric"
115: #endif
116: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
117: if (isascii) {
118: PetscViewerASCIIPrintf(viewer,"EPS Object:\n");
119: switch (eps->problem_type) {
120: case EPS_HEP: type = HERM " eigenvalue problem"; break;
121: case EPS_GHEP: type = "generalized " HERM " eigenvalue problem"; break;
122: case EPS_NHEP: type = "non-" HERM " eigenvalue problem"; break;
123: case EPS_GNHEP: type = "generalized non-" HERM " eigenvalue problem"; break;
124: case 0: type = "not yet set"; break;
125: default: SETERRQ(1,"Wrong value of eps->problem_type");
126: }
127: PetscViewerASCIIPrintf(viewer," problem type: %s\n",type);
128: EPSGetType(eps,&type);
129: if (type) {
130: PetscViewerASCIIPrintf(viewer," method: %s",type);
131: switch (eps->solverclass) {
132: case EPS_ONE_SIDE:
133: PetscViewerASCIIPrintf(viewer,"\n",type); break;
134: case EPS_TWO_SIDE:
135: PetscViewerASCIIPrintf(viewer," (two-sided)\n",type); break;
136: default: SETERRQ(1,"Wrong value of eps->solverclass");
137: }
138: } else {
139: PetscViewerASCIIPrintf(viewer," method: not yet set\n");
140: }
141: if (eps->ops->view) {
142: PetscViewerASCIIPushTab(viewer);
143: (*eps->ops->view)(eps,viewer);
144: PetscViewerASCIIPopTab(viewer);
145: }
146: switch (eps->which) {
147: case EPS_LARGEST_MAGNITUDE: which = "largest eigenvalues in magnitude"; break;
148: case EPS_SMALLEST_MAGNITUDE: which = "smallest eigenvalues in magnitude"; break;
149: case EPS_LARGEST_REAL: which = "largest real parts"; break;
150: case EPS_SMALLEST_REAL: which = "smallest real parts"; break;
151: case EPS_LARGEST_IMAGINARY: which = "largest imaginary parts"; break;
152: case EPS_SMALLEST_IMAGINARY: which = "smallest imaginary parts"; break;
153: default: SETERRQ(1,"Wrong value of eps->which");
154: }
155: PetscViewerASCIIPrintf(viewer," selected portion of the spectrum: %s\n",which);
156: PetscViewerASCIIPrintf(viewer," number of eigenvalues (nev): %d\n",eps->nev);
157: PetscViewerASCIIPrintf(viewer," number of column vectors (ncv): %d\n",eps->ncv);
158: PetscViewerASCIIPrintf(viewer," maximum number of iterations: %d\n", eps->max_it);
159: PetscViewerASCIIPrintf(viewer," tolerance: %g\n",eps->tol);
160: PetscViewerASCIIPrintf(viewer," dimension of user-provided deflation space: %d\n",eps->nds);
161: PetscViewerASCIIPushTab(viewer);
162: IPView(eps->ip,viewer);
163: STView(eps->OP,viewer);
164: PetscViewerASCIIPopTab(viewer);
165: } else {
166: if (eps->ops->view) {
167: (*eps->ops->view)(eps,viewer);
168: }
169: STView(eps->OP,viewer);
170: }
171: return(0);
172: }
176: static PetscErrorCode EPSPublish_Petsc(PetscObject object)
177: {
179: return(0);
180: }
184: /*@C
185: EPSCreate - Creates the default EPS context.
187: Collective on MPI_Comm
189: Input Parameter:
190: . comm - MPI communicator
192: Output Parameter:
193: . eps - location to put the EPS context
195: Note:
196: The default EPS type is EPSKRYLOVSCHUR
198: Level: beginner
200: .seealso: EPSSetUp(), EPSSolve(), EPSDestroy(), EPS
201: @*/
202: PetscErrorCode EPSCreate(MPI_Comm comm,EPS *outeps)
203: {
205: EPS eps;
209: *outeps = 0;
211: PetscHeaderCreate(eps,_p_EPS,struct _EPSOps,EPS_COOKIE,-1,"EPS",comm,EPSDestroy,EPSView);
212: *outeps = eps;
214: eps->bops->publish = EPSPublish_Petsc;
215: PetscMemzero(eps->ops,sizeof(struct _EPSOps));
217: eps->type = -1;
218: eps->max_it = 0;
219: eps->nev = 1;
220: eps->ncv = 0;
221: eps->allocated_ncv = 0;
222: eps->nds = 0;
223: eps->tol = 1e-7;
224: eps->which = EPS_LARGEST_MAGNITUDE;
225: eps->evecsavailable = PETSC_FALSE;
226: eps->problem_type = (EPSProblemType)0;
227: eps->solverclass = (EPSClass)0;
229: eps->vec_initial = 0;
230: eps->vec_initial_left= 0;
231: eps->V = 0;
232: eps->AV = 0;
233: eps->W = 0;
234: eps->AW = 0;
235: eps->T = 0;
236: eps->DS = 0;
237: eps->ds_ortho = PETSC_TRUE;
238: eps->eigr = 0;
239: eps->eigi = 0;
240: eps->errest = 0;
241: eps->errest_left = 0;
242: eps->OP = 0;
243: eps->ip = 0;
244: eps->data = 0;
245: eps->nconv = 0;
246: eps->its = 0;
247: eps->perm = PETSC_NULL;
249: eps->nwork = 0;
250: eps->work = 0;
251: eps->isgeneralized = PETSC_FALSE;
252: eps->ishermitian = PETSC_FALSE;
253: eps->ispositive = PETSC_FALSE;
254: eps->setupcalled = 0;
255: eps->reason = EPS_CONVERGED_ITERATING;
257: eps->numbermonitors = 0;
259: STCreate(comm,&eps->OP);
260: PetscLogObjectParent(eps,eps->OP);
261: IPCreate(comm,&eps->ip);
262: IPSetOptionsPrefix(eps->ip,eps->prefix);
263: IPAppendOptionsPrefix(eps->ip,"eps_");
264: PetscLogObjectParent(eps,eps->ip);
265: PetscPublishAll(eps);
266: return(0);
267: }
268:
271: /*@C
272: EPSSetType - Selects the particular solver to be used in the EPS object.
274: Collective on EPS
276: Input Parameters:
277: + eps - the eigensolver context
278: - type - a known method
280: Options Database Key:
281: . -eps_type <method> - Sets the method; use -help for a list
282: of available methods
283:
284: Notes:
285: See "slepc/include/slepceps.h" for available methods. The default
286: is EPSKRYLOVSCHUR.
288: Normally, it is best to use the EPSSetFromOptions() command and
289: then set the EPS type from the options database rather than by using
290: this routine. Using the options database provides the user with
291: maximum flexibility in evaluating the different available methods.
292: The EPSSetType() routine is provided for those situations where it
293: is necessary to set the iterative solver independently of the command
294: line or options database.
296: Level: intermediate
298: .seealso: STSetType(), EPSType
299: @*/
300: PetscErrorCode EPSSetType(EPS eps,EPSType type)
301: {
302: PetscErrorCode ierr,(*r)(EPS);
303: PetscTruth match;
309: PetscTypeCompare((PetscObject)eps,type,&match);
310: if (match) return(0);
312: if (eps->data) {
313: /* destroy the old private EPS context */
314: (*eps->ops->destroy)(eps);
315: eps->data = 0;
316: }
318: PetscFListFind(EPSList,eps->comm,type,(void (**)(void)) &r);
320: if (!r) SETERRQ1(1,"Unknown EPS type given: %s",type);
322: eps->setupcalled = 0;
323: PetscMemzero(eps->ops,sizeof(struct _EPSOps));
324: (*r)(eps);
326: PetscObjectChangeTypeName((PetscObject)eps,type);
327: return(0);
328: }
332: /*@C
333: EPSGetType - Gets the EPS type as a string from the EPS object.
335: Not Collective
337: Input Parameter:
338: . eps - the eigensolver context
340: Output Parameter:
341: . name - name of EPS method
343: Level: intermediate
345: .seealso: EPSSetType()
346: @*/
347: PetscErrorCode EPSGetType(EPS eps,EPSType *type)
348: {
351: *type = eps->type_name;
352: return(0);
353: }
355: /*MC
356: EPSRegisterDynamic - Adds a method to the eigenproblem solver package.
358: Synopsis:
359: EPSRegisterDynamic(char *name_solver,char *path,char *name_create,int (*routine_create)(EPS))
361: Not Collective
363: Input Parameters:
364: + name_solver - name of a new user-defined solver
365: . path - path (either absolute or relative) the library containing this solver
366: . name_create - name of routine to create the solver context
367: - routine_create - routine to create the solver context
369: Notes:
370: EPSRegisterDynamic() may be called multiple times to add several user-defined solvers.
372: If dynamic libraries are used, then the fourth input argument (routine_create)
373: is ignored.
375: Sample usage:
376: .vb
377: EPSRegisterDynamic("my_solver",/home/username/my_lib/lib/libO/solaris/mylib.a,
378: "MySolverCreate",MySolverCreate);
379: .ve
381: Then, your solver can be chosen with the procedural interface via
382: $ EPSSetType(eps,"my_solver")
383: or at runtime via the option
384: $ -eps_type my_solver
386: Level: advanced
388: Environmental variables such as ${PETSC_ARCH}, ${PETSC_DIR}, ${PETSC_LIB_DIR},
389: and others of the form ${any_environmental_variable} occuring in pathname will be
390: replaced with appropriate values.
392: .seealso: EPSRegisterDestroy(), EPSRegisterAll()
394: M*/
398: /*@C
399: EPSRegister - See EPSRegisterDynamic()
401: Level: advanced
402: @*/
403: PetscErrorCode EPSRegister(const char *sname,const char *path,const char *name,int (*function)(EPS))
404: {
406: char fullname[256];
409: PetscFListConcat(path,name,fullname);
410: PetscFListAdd(&EPSList,sname,fullname,(void (*)(void))function);
411: return(0);
412: }
416: /*@
417: EPSRegisterDestroy - Frees the list of EPS methods that were
418: registered by EPSRegisterDynamic().
420: Not Collective
422: Level: advanced
424: .seealso: EPSRegisterDynamic(), EPSRegisterAll()
425: @*/
426: PetscErrorCode EPSRegisterDestroy(void)
427: {
431: PetscFListDestroy(&EPSList);
432: EPSRegisterAll(PETSC_NULL);
433: return(0);
434: }
438: /*@
439: EPSDestroy - Destroys the EPS context.
441: Collective on EPS
443: Input Parameter:
444: . eps - eigensolver context obtained from EPSCreate()
446: Level: beginner
448: .seealso: EPSCreate(), EPSSetUp(), EPSSolve()
449: @*/
450: PetscErrorCode EPSDestroy(EPS eps)
451: {
456: if (--eps->refct > 0) return(0);
458: /* if memory was published with AMS then destroy it */
459: PetscObjectDepublish(eps);
461: STDestroy(eps->OP);
462: IPDestroy(eps->ip);
464: if (eps->ops->destroy) {
465: (*eps->ops->destroy)(eps);
466: }
467:
468: PetscFree(eps->T);
469: PetscFree(eps->Tl);
470: PetscFree(eps->perm);
472: if (eps->vec_initial) {
473: VecDestroy(eps->vec_initial);
474: }
476: if (eps->vec_initial_left) {
477: VecDestroy(eps->vec_initial_left);
478: }
480: if (eps->nds > 0) {
481: VecDestroyVecs(eps->DS, eps->nds);
482: }
483:
484: PetscFree(eps->DSV);
486: EPSMonitorCancel(eps);
488: PetscHeaderDestroy(eps);
489: return(0);
490: }
494: /*@
495: EPSSetST - Associates a spectral transformation object to the
496: eigensolver.
498: Collective on EPS
500: Input Parameters:
501: + eps - eigensolver context obtained from EPSCreate()
502: - st - the spectral transformation object
504: Note:
505: Use EPSGetST() to retrieve the spectral transformation context (for example,
506: to free it at the end of the computations).
508: Level: advanced
510: .seealso: EPSGetST()
511: @*/
512: PetscErrorCode EPSSetST(EPS eps,ST st)
513: {
520: PetscObjectReference((PetscObject)st);
521: STDestroy(eps->OP);
522: eps->OP = st;
523: return(0);
524: }
528: /*@C
529: EPSGetST - Obtain the spectral transformation (ST) object associated
530: to the eigensolver object.
532: Not Collective
534: Input Parameters:
535: . eps - eigensolver context obtained from EPSCreate()
537: Output Parameter:
538: . st - spectral transformation context
540: Level: beginner
542: .seealso: EPSSetST()
543: @*/
544: PetscErrorCode EPSGetST(EPS eps, ST *st)
545: {
549: *st = eps->OP;
550: return(0);
551: }
555: /*@
556: EPSSetIP - Associates an inner product object to the
557: eigensolver.
559: Collective on EPS
561: Input Parameters:
562: + eps - eigensolver context obtained from EPSCreate()
563: - ip - the inner product object
565: Note:
566: Use EPSGetIP() to retrieve the inner product context (for example,
567: to free it at the end of the computations).
569: Level: advanced
571: .seealso: EPSGetIP()
572: @*/
573: PetscErrorCode EPSSetIP(EPS eps,IP ip)
574: {
581: PetscObjectReference((PetscObject)ip);
582: IPDestroy(eps->ip);
583: eps->ip = ip;
584: return(0);
585: }
589: /*@C
590: EPSGetIP - Obtain the inner product object associated
591: to the eigensolver object.
593: Not Collective
595: Input Parameters:
596: . eps - eigensolver context obtained from EPSCreate()
598: Output Parameter:
599: . ip - inner product context
601: Level: advanced
603: .seealso: EPSSetIP()
604: @*/
605: PetscErrorCode EPSGetIP(EPS eps,IP *ip)
606: {
610: *ip = eps->ip;
611: return(0);
612: }
616: /*@
617: EPSIsGeneralized - Ask if the EPS object corresponds to a generalized
618: eigenvalue problem.
620: Not collective
622: Input Parameter:
623: . eps - the eigenproblem solver context
625: Output Parameter:
626: . is - the answer
628: Level: intermediate
630: @*/
631: PetscErrorCode EPSIsGeneralized(EPS eps,PetscTruth* is)
632: {
634: Mat B;
638: STGetOperators(eps->OP,PETSC_NULL,&B);
639: if( B ) *is = PETSC_TRUE;
640: else *is = PETSC_FALSE;
641: if( eps->setupcalled ) {
642: if( eps->isgeneralized != *is ) {
643: SETERRQ(0,"Warning: Inconsistent EPS state");
644: }
645: }
646: return(0);
647: }
651: /*@
652: EPSIsHermitian - Ask if the EPS object corresponds to a Hermitian
653: eigenvalue problem.
655: Not collective
657: Input Parameter:
658: . eps - the eigenproblem solver context
660: Output Parameter:
661: . is - the answer
663: Level: intermediate
665: @*/
666: PetscErrorCode EPSIsHermitian(EPS eps,PetscTruth* is)
667: {
670: if( eps->ishermitian ) *is = PETSC_TRUE;
671: else *is = PETSC_FALSE;
672: return(0);
673: }