Actual source code: epsview.c
slepc-3.20.1 2023-11-27
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: EPS routines related to various viewers
12: */
14: #include <slepc/private/epsimpl.h>
15: #include <slepc/private/bvimpl.h>
16: #include <petscdraw.h>
18: /*@C
19: EPSView - Prints the EPS data structure.
21: Collective
23: Input Parameters:
24: + eps - the eigenproblem solver context
25: - viewer - optional visualization context
27: Options Database Key:
28: . -eps_view - Calls EPSView() at end of EPSSolve()
30: Note:
31: The available visualization contexts include
32: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
33: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
34: output where only the first processor opens
35: the file. All other processors send their
36: data to the first processor to print.
38: The user can open an alternative visualization context with
39: PetscViewerASCIIOpen() - output to a specified file.
41: Level: beginner
43: .seealso: STView()
44: @*/
45: PetscErrorCode EPSView(EPS eps,PetscViewer viewer)
46: {
47: const char *type=NULL,*extr=NULL,*bal=NULL;
48: char str[50];
49: PetscBool isascii,isexternal,istrivial;
51: PetscFunctionBegin;
53: if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)eps),&viewer));
55: PetscCheckSameComm(eps,1,viewer,2);
57: PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
58: if (isascii) {
59: PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)eps,viewer));
60: PetscCall(PetscViewerASCIIPushTab(viewer));
61: PetscTryTypeMethod(eps,view,viewer);
62: PetscCall(PetscViewerASCIIPopTab(viewer));
63: if (eps->problem_type) {
64: switch (eps->problem_type) {
65: case EPS_HEP: type = SLEPC_STRING_HERMITIAN " eigenvalue problem"; break;
66: case EPS_GHEP: type = "generalized " SLEPC_STRING_HERMITIAN " eigenvalue problem"; break;
67: case EPS_NHEP: type = "non-" SLEPC_STRING_HERMITIAN " eigenvalue problem"; break;
68: case EPS_GNHEP: type = "generalized non-" SLEPC_STRING_HERMITIAN " eigenvalue problem"; break;
69: case EPS_PGNHEP: type = "generalized non-" SLEPC_STRING_HERMITIAN " eigenvalue problem with " SLEPC_STRING_HERMITIAN " positive definite B"; break;
70: case EPS_GHIEP: type = "generalized " SLEPC_STRING_HERMITIAN "-indefinite eigenvalue problem"; break;
71: }
72: } else type = "not yet set";
73: PetscCall(PetscViewerASCIIPrintf(viewer," problem type: %s\n",type));
74: if (eps->extraction) {
75: switch (eps->extraction) {
76: case EPS_RITZ: extr = "Rayleigh-Ritz"; break;
77: case EPS_HARMONIC: extr = "harmonic Ritz"; break;
78: case EPS_HARMONIC_RELATIVE: extr = "relative harmonic Ritz"; break;
79: case EPS_HARMONIC_RIGHT: extr = "right harmonic Ritz"; break;
80: case EPS_HARMONIC_LARGEST: extr = "largest harmonic Ritz"; break;
81: case EPS_REFINED: extr = "refined Ritz"; break;
82: case EPS_REFINED_HARMONIC: extr = "refined harmonic Ritz"; break;
83: }
84: PetscCall(PetscViewerASCIIPrintf(viewer," extraction type: %s\n",extr));
85: }
86: if (!eps->ishermitian && eps->balance!=EPS_BALANCE_NONE) {
87: switch (eps->balance) {
88: case EPS_BALANCE_NONE: break;
89: case EPS_BALANCE_ONESIDE: bal = "one-sided Krylov"; break;
90: case EPS_BALANCE_TWOSIDE: bal = "two-sided Krylov"; break;
91: case EPS_BALANCE_USER: bal = "user-defined matrix"; break;
92: }
93: PetscCall(PetscViewerASCIIPrintf(viewer," balancing enabled: %s",bal));
94: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
95: if (eps->balance==EPS_BALANCE_ONESIDE || eps->balance==EPS_BALANCE_TWOSIDE) PetscCall(PetscViewerASCIIPrintf(viewer,", with its=%" PetscInt_FMT,eps->balance_its));
96: if (eps->balance==EPS_BALANCE_TWOSIDE && eps->balance_cutoff!=0.0) PetscCall(PetscViewerASCIIPrintf(viewer," and cutoff=%g",(double)eps->balance_cutoff));
97: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
98: PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
99: }
100: PetscCall(PetscViewerASCIIPrintf(viewer," selected portion of the spectrum: "));
101: PetscCall(SlepcSNPrintfScalar(str,sizeof(str),eps->target,PETSC_FALSE));
102: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
103: if (!eps->which) PetscCall(PetscViewerASCIIPrintf(viewer,"not yet set\n"));
104: else switch (eps->which) {
105: case EPS_WHICH_USER:
106: PetscCall(PetscViewerASCIIPrintf(viewer,"user defined\n"));
107: break;
108: case EPS_TARGET_MAGNITUDE:
109: PetscCall(PetscViewerASCIIPrintf(viewer,"closest to target: %s (in magnitude)\n",str));
110: break;
111: case EPS_TARGET_REAL:
112: PetscCall(PetscViewerASCIIPrintf(viewer,"closest to target: %s (along the real axis)\n",str));
113: break;
114: case EPS_TARGET_IMAGINARY:
115: PetscCall(PetscViewerASCIIPrintf(viewer,"closest to target: %s (along the imaginary axis)\n",str));
116: break;
117: case EPS_LARGEST_MAGNITUDE:
118: PetscCall(PetscViewerASCIIPrintf(viewer,"largest eigenvalues in magnitude\n"));
119: break;
120: case EPS_SMALLEST_MAGNITUDE:
121: PetscCall(PetscViewerASCIIPrintf(viewer,"smallest eigenvalues in magnitude\n"));
122: break;
123: case EPS_LARGEST_REAL:
124: PetscCall(PetscViewerASCIIPrintf(viewer,"largest real parts\n"));
125: break;
126: case EPS_SMALLEST_REAL:
127: PetscCall(PetscViewerASCIIPrintf(viewer,"smallest real parts\n"));
128: break;
129: case EPS_LARGEST_IMAGINARY:
130: PetscCall(PetscViewerASCIIPrintf(viewer,"largest imaginary parts\n"));
131: break;
132: case EPS_SMALLEST_IMAGINARY:
133: PetscCall(PetscViewerASCIIPrintf(viewer,"smallest imaginary parts\n"));
134: break;
135: case EPS_ALL:
136: if (eps->inta || eps->intb) PetscCall(PetscViewerASCIIPrintf(viewer,"all eigenvalues in interval [%g,%g]\n",(double)eps->inta,(double)eps->intb));
137: else PetscCall(PetscViewerASCIIPrintf(viewer,"all eigenvalues in the region\n"));
138: break;
139: }
140: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
141: if (eps->twosided && eps->problem_type!=EPS_HEP && eps->problem_type!=EPS_GHEP) PetscCall(PetscViewerASCIIPrintf(viewer," using two-sided variant (for left eigenvectors)\n"));
142: if (eps->purify) PetscCall(PetscViewerASCIIPrintf(viewer," postprocessing eigenvectors with purification\n"));
143: if (eps->trueres) PetscCall(PetscViewerASCIIPrintf(viewer," computing true residuals explicitly\n"));
144: if (eps->trackall) PetscCall(PetscViewerASCIIPrintf(viewer," computing all residuals (for tracking convergence)\n"));
145: PetscCall(PetscViewerASCIIPrintf(viewer," number of eigenvalues (nev): %" PetscInt_FMT "\n",eps->nev));
146: PetscCall(PetscViewerASCIIPrintf(viewer," number of column vectors (ncv): %" PetscInt_FMT "\n",eps->ncv));
147: PetscCall(PetscViewerASCIIPrintf(viewer," maximum dimension of projected problem (mpd): %" PetscInt_FMT "\n",eps->mpd));
148: PetscCall(PetscViewerASCIIPrintf(viewer," maximum number of iterations: %" PetscInt_FMT "\n",eps->max_it));
149: PetscCall(PetscViewerASCIIPrintf(viewer," tolerance: %g\n",(double)eps->tol));
150: PetscCall(PetscViewerASCIIPrintf(viewer," convergence test: "));
151: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
152: switch (eps->conv) {
153: case EPS_CONV_ABS:
154: PetscCall(PetscViewerASCIIPrintf(viewer,"absolute\n"));break;
155: case EPS_CONV_REL:
156: PetscCall(PetscViewerASCIIPrintf(viewer,"relative to the eigenvalue\n"));break;
157: case EPS_CONV_NORM:
158: PetscCall(PetscViewerASCIIPrintf(viewer,"relative to the eigenvalue and matrix norms\n"));
159: PetscCall(PetscViewerASCIIPrintf(viewer," computed matrix norms: norm(A)=%g",(double)eps->nrma));
160: if (eps->isgeneralized) PetscCall(PetscViewerASCIIPrintf(viewer,", norm(B)=%g",(double)eps->nrmb));
161: PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
162: break;
163: case EPS_CONV_USER:
164: PetscCall(PetscViewerASCIIPrintf(viewer,"user-defined\n"));break;
165: }
166: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
167: if (eps->nini) PetscCall(PetscViewerASCIIPrintf(viewer," dimension of user-provided initial space: %" PetscInt_FMT "\n",PetscAbs(eps->nini)));
168: if (eps->ninil) PetscCall(PetscViewerASCIIPrintf(viewer," dimension of user-provided left initial space: %" PetscInt_FMT "\n",PetscAbs(eps->ninil)));
169: if (eps->nds) PetscCall(PetscViewerASCIIPrintf(viewer," dimension of user-provided deflation space: %" PetscInt_FMT "\n",PetscAbs(eps->nds)));
170: } else PetscTryTypeMethod(eps,view,viewer);
171: PetscCall(PetscObjectTypeCompareAny((PetscObject)eps,&isexternal,EPSARPACK,EPSBLOPEX,EPSELEMENTAL,EPSFEAST,EPSPRIMME,EPSSCALAPACK,EPSELPA,EPSEVSL,EPSTRLAN,""));
172: if (!isexternal) {
173: PetscCall(PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO));
174: if (!eps->V) PetscCall(EPSGetBV(eps,&eps->V));
175: PetscCall(BVView(eps->V,viewer));
176: if (eps->rg) {
177: PetscCall(RGIsTrivial(eps->rg,&istrivial));
178: if (!istrivial) PetscCall(RGView(eps->rg,viewer));
179: }
180: if (eps->useds) {
181: if (!eps->ds) PetscCall(EPSGetDS(eps,&eps->ds));
182: PetscCall(DSView(eps->ds,viewer));
183: }
184: PetscCall(PetscViewerPopFormat(viewer));
185: }
186: if (!eps->st) PetscCall(EPSGetST(eps,&eps->st));
187: PetscCall(STView(eps->st,viewer));
188: PetscFunctionReturn(PETSC_SUCCESS);
189: }
191: /*@C
192: EPSViewFromOptions - View from options
194: Collective
196: Input Parameters:
197: + eps - the eigensolver context
198: . obj - optional object
199: - name - command line option
201: Level: intermediate
203: .seealso: EPSView(), EPSCreate()
204: @*/
205: PetscErrorCode EPSViewFromOptions(EPS eps,PetscObject obj,const char name[])
206: {
207: PetscFunctionBegin;
209: PetscCall(PetscObjectViewFromOptions((PetscObject)eps,obj,name));
210: PetscFunctionReturn(PETSC_SUCCESS);
211: }
213: /*@C
214: EPSConvergedReasonView - Displays the reason an EPS solve converged or diverged.
216: Collective
218: Input Parameters:
219: + eps - the eigensolver context
220: - viewer - the viewer to display the reason
222: Options Database Keys:
223: . -eps_converged_reason - print reason for convergence, and number of iterations
225: Note:
226: To change the format of the output call PetscViewerPushFormat(viewer,format) before
227: this call. Use PETSC_VIEWER_DEFAULT for the default, use PETSC_VIEWER_FAILED to only
228: display a reason if it fails. The latter can be set in the command line with
229: -eps_converged_reason ::failed
231: Level: intermediate
233: .seealso: EPSSetConvergenceTest(), EPSSetTolerances(), EPSGetIterationNumber(), EPSConvergedReasonViewFromOptions()
234: @*/
235: PetscErrorCode EPSConvergedReasonView(EPS eps,PetscViewer viewer)
236: {
237: PetscBool isAscii;
238: PetscViewerFormat format;
240: PetscFunctionBegin;
241: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)eps));
242: PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii));
243: if (isAscii) {
244: PetscCall(PetscViewerGetFormat(viewer,&format));
245: PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)eps)->tablevel));
246: if (eps->reason > 0 && format != PETSC_VIEWER_FAILED) PetscCall(PetscViewerASCIIPrintf(viewer,"%s Linear eigensolve converged (%" PetscInt_FMT " eigenpair%s) due to %s; iterations %" PetscInt_FMT "\n",((PetscObject)eps)->prefix?((PetscObject)eps)->prefix:"",eps->nconv,(eps->nconv>1)?"s":"",EPSConvergedReasons[eps->reason],eps->its));
247: else if (eps->reason <= 0) PetscCall(PetscViewerASCIIPrintf(viewer,"%s Linear eigensolve did not converge due to %s; iterations %" PetscInt_FMT "\n",((PetscObject)eps)->prefix?((PetscObject)eps)->prefix:"",EPSConvergedReasons[eps->reason],eps->its));
248: PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)eps)->tablevel));
249: }
250: PetscFunctionReturn(PETSC_SUCCESS);
251: }
253: /*@
254: EPSConvergedReasonViewFromOptions - Processes command line options to determine if/how
255: the EPS converged reason is to be viewed.
257: Collective
259: Input Parameter:
260: . eps - the eigensolver context
262: Level: developer
264: .seealso: EPSConvergedReasonView()
265: @*/
266: PetscErrorCode EPSConvergedReasonViewFromOptions(EPS eps)
267: {
268: PetscViewer viewer;
269: PetscBool flg;
270: static PetscBool incall = PETSC_FALSE;
271: PetscViewerFormat format;
273: PetscFunctionBegin;
274: if (incall) PetscFunctionReturn(PETSC_SUCCESS);
275: incall = PETSC_TRUE;
276: PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)eps),((PetscObject)eps)->options,((PetscObject)eps)->prefix,"-eps_converged_reason",&viewer,&format,&flg));
277: if (flg) {
278: PetscCall(PetscViewerPushFormat(viewer,format));
279: PetscCall(EPSConvergedReasonView(eps,viewer));
280: PetscCall(PetscViewerPopFormat(viewer));
281: PetscCall(PetscViewerDestroy(&viewer));
282: }
283: incall = PETSC_FALSE;
284: PetscFunctionReturn(PETSC_SUCCESS);
285: }
287: static PetscErrorCode EPSErrorView_ASCII(EPS eps,EPSErrorType etype,PetscViewer viewer)
288: {
289: PetscReal error;
290: PetscInt i,j,k,nvals;
292: PetscFunctionBegin;
293: nvals = (eps->which==EPS_ALL)? eps->nconv: eps->nev;
294: if (eps->which!=EPS_ALL && eps->nconv<nvals) {
295: PetscCall(PetscViewerASCIIPrintf(viewer," Problem: less than %" PetscInt_FMT " eigenvalues converged\n\n",eps->nev));
296: PetscFunctionReturn(PETSC_SUCCESS);
297: }
298: if (eps->which==EPS_ALL && !nvals) {
299: PetscCall(PetscViewerASCIIPrintf(viewer," No eigenvalues have been found\n\n"));
300: PetscFunctionReturn(PETSC_SUCCESS);
301: }
302: for (i=0;i<nvals;i++) {
303: PetscCall(EPSComputeError(eps,i,etype,&error));
304: if (error>=5.0*eps->tol) {
305: PetscCall(PetscViewerASCIIPrintf(viewer," Problem: some of the first %" PetscInt_FMT " relative errors are higher than the tolerance\n\n",nvals));
306: PetscFunctionReturn(PETSC_SUCCESS);
307: }
308: }
309: if (eps->which==EPS_ALL) PetscCall(PetscViewerASCIIPrintf(viewer," Found %" PetscInt_FMT " eigenvalues, all of them computed up to the required tolerance:",nvals));
310: else PetscCall(PetscViewerASCIIPrintf(viewer," All requested eigenvalues computed up to the required tolerance:"));
311: for (i=0;i<=(nvals-1)/8;i++) {
312: PetscCall(PetscViewerASCIIPrintf(viewer,"\n "));
313: for (j=0;j<PetscMin(8,nvals-8*i);j++) {
314: k = eps->perm[8*i+j];
315: PetscCall(SlepcPrintEigenvalueASCII(viewer,eps->eigr[k],eps->eigi[k]));
316: if (8*i+j+1<nvals) PetscCall(PetscViewerASCIIPrintf(viewer,", "));
317: }
318: }
319: PetscCall(PetscViewerASCIIPrintf(viewer,"\n\n"));
320: PetscFunctionReturn(PETSC_SUCCESS);
321: }
323: static PetscErrorCode EPSErrorView_DETAIL(EPS eps,EPSErrorType etype,PetscViewer viewer)
324: {
325: PetscReal error,re,im;
326: PetscScalar kr,ki;
327: PetscInt i;
328: char ex[30],sep[]=" ---------------------- --------------------\n";
330: PetscFunctionBegin;
331: if (!eps->nconv) PetscFunctionReturn(PETSC_SUCCESS);
332: switch (etype) {
333: case EPS_ERROR_ABSOLUTE:
334: PetscCall(PetscSNPrintf(ex,sizeof(ex)," ||Ax-k%sx||",eps->isgeneralized?"B":""));
335: break;
336: case EPS_ERROR_RELATIVE:
337: PetscCall(PetscSNPrintf(ex,sizeof(ex),"||Ax-k%sx||/||kx||",eps->isgeneralized?"B":""));
338: break;
339: case EPS_ERROR_BACKWARD:
340: PetscCall(PetscSNPrintf(ex,sizeof(ex)," eta(x,k)"));
341: break;
342: }
343: PetscCall(PetscViewerASCIIPrintf(viewer,"%s k %s\n%s",sep,ex,sep));
344: for (i=0;i<eps->nconv;i++) {
345: PetscCall(EPSGetEigenpair(eps,i,&kr,&ki,NULL,NULL));
346: PetscCall(EPSComputeError(eps,i,etype,&error));
347: #if defined(PETSC_USE_COMPLEX)
348: re = PetscRealPart(kr);
349: im = PetscImaginaryPart(kr);
350: #else
351: re = kr;
352: im = ki;
353: #endif
354: if (im!=0.0) PetscCall(PetscViewerASCIIPrintf(viewer," % 9f%+9fi %12g\n",(double)re,(double)im,(double)error));
355: else PetscCall(PetscViewerASCIIPrintf(viewer," % 12f %12g\n",(double)re,(double)error));
356: }
357: PetscCall(PetscViewerASCIIPrintf(viewer,"%s",sep));
358: PetscFunctionReturn(PETSC_SUCCESS);
359: }
361: static PetscErrorCode EPSErrorView_MATLAB(EPS eps,EPSErrorType etype,PetscViewer viewer)
362: {
363: PetscReal error;
364: PetscInt i;
365: const char *name;
367: PetscFunctionBegin;
368: PetscCall(PetscObjectGetName((PetscObject)eps,&name));
369: PetscCall(PetscViewerASCIIPrintf(viewer,"Error_%s = [\n",name));
370: for (i=0;i<eps->nconv;i++) {
371: PetscCall(EPSComputeError(eps,i,etype,&error));
372: PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double)error));
373: }
374: PetscCall(PetscViewerASCIIPrintf(viewer,"];\n"));
375: PetscFunctionReturn(PETSC_SUCCESS);
376: }
378: /*@C
379: EPSErrorView - Displays the errors associated with the computed solution
380: (as well as the eigenvalues).
382: Collective
384: Input Parameters:
385: + eps - the eigensolver context
386: . etype - error type
387: - viewer - optional visualization context
389: Options Database Keys:
390: + -eps_error_absolute - print absolute errors of each eigenpair
391: . -eps_error_relative - print relative errors of each eigenpair
392: - -eps_error_backward - print backward errors of each eigenpair
394: Notes:
395: By default, this function checks the error of all eigenpairs and prints
396: the eigenvalues if all of them are below the requested tolerance.
397: If the viewer has format=PETSC_VIEWER_ASCII_INFO_DETAIL then a table with
398: eigenvalues and corresponding errors is printed.
400: Level: intermediate
402: .seealso: EPSSolve(), EPSValuesView(), EPSVectorsView()
403: @*/
404: PetscErrorCode EPSErrorView(EPS eps,EPSErrorType etype,PetscViewer viewer)
405: {
406: PetscBool isascii;
407: PetscViewerFormat format;
409: PetscFunctionBegin;
411: if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)eps),&viewer));
413: PetscCheckSameComm(eps,1,viewer,3);
414: EPSCheckSolved(eps,1);
415: PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
416: if (!isascii) PetscFunctionReturn(PETSC_SUCCESS);
418: PetscCall(PetscViewerGetFormat(viewer,&format));
419: switch (format) {
420: case PETSC_VIEWER_DEFAULT:
421: case PETSC_VIEWER_ASCII_INFO:
422: PetscCall(EPSErrorView_ASCII(eps,etype,viewer));
423: break;
424: case PETSC_VIEWER_ASCII_INFO_DETAIL:
425: PetscCall(EPSErrorView_DETAIL(eps,etype,viewer));
426: break;
427: case PETSC_VIEWER_ASCII_MATLAB:
428: PetscCall(EPSErrorView_MATLAB(eps,etype,viewer));
429: break;
430: default:
431: PetscCall(PetscInfo(eps,"Unsupported viewer format %s\n",PetscViewerFormats[format]));
432: }
433: PetscFunctionReturn(PETSC_SUCCESS);
434: }
436: /*@
437: EPSErrorViewFromOptions - Processes command line options to determine if/how
438: the errors of the computed solution are to be viewed.
440: Collective
442: Input Parameter:
443: . eps - the eigensolver context
445: Level: developer
447: .seealso: EPSErrorView()
448: @*/
449: PetscErrorCode EPSErrorViewFromOptions(EPS eps)
450: {
451: PetscViewer viewer;
452: PetscBool flg;
453: static PetscBool incall = PETSC_FALSE;
454: PetscViewerFormat format;
456: PetscFunctionBegin;
457: if (incall) PetscFunctionReturn(PETSC_SUCCESS);
458: incall = PETSC_TRUE;
459: PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)eps),((PetscObject)eps)->options,((PetscObject)eps)->prefix,"-eps_error_absolute",&viewer,&format,&flg));
460: if (flg) {
461: PetscCall(PetscViewerPushFormat(viewer,format));
462: PetscCall(EPSErrorView(eps,EPS_ERROR_ABSOLUTE,viewer));
463: PetscCall(PetscViewerPopFormat(viewer));
464: PetscCall(PetscViewerDestroy(&viewer));
465: }
466: PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)eps),((PetscObject)eps)->options,((PetscObject)eps)->prefix,"-eps_error_relative",&viewer,&format,&flg));
467: if (flg) {
468: PetscCall(PetscViewerPushFormat(viewer,format));
469: PetscCall(EPSErrorView(eps,EPS_ERROR_RELATIVE,viewer));
470: PetscCall(PetscViewerPopFormat(viewer));
471: PetscCall(PetscViewerDestroy(&viewer));
472: }
473: PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)eps),((PetscObject)eps)->options,((PetscObject)eps)->prefix,"-eps_error_backward",&viewer,&format,&flg));
474: if (flg) {
475: PetscCall(PetscViewerPushFormat(viewer,format));
476: PetscCall(EPSErrorView(eps,EPS_ERROR_BACKWARD,viewer));
477: PetscCall(PetscViewerPopFormat(viewer));
478: PetscCall(PetscViewerDestroy(&viewer));
479: }
480: incall = PETSC_FALSE;
481: PetscFunctionReturn(PETSC_SUCCESS);
482: }
484: static PetscErrorCode EPSValuesView_DRAW(EPS eps,PetscViewer viewer)
485: {
486: PetscDraw draw;
487: PetscDrawSP drawsp;
488: PetscReal re,im;
489: PetscInt i,k;
491: PetscFunctionBegin;
492: if (!eps->nconv) PetscFunctionReturn(PETSC_SUCCESS);
493: PetscCall(PetscViewerDrawGetDraw(viewer,0,&draw));
494: PetscCall(PetscDrawSetTitle(draw,"Computed Eigenvalues"));
495: PetscCall(PetscDrawSPCreate(draw,1,&drawsp));
496: for (i=0;i<eps->nconv;i++) {
497: k = eps->perm[i];
498: #if defined(PETSC_USE_COMPLEX)
499: re = PetscRealPart(eps->eigr[k]);
500: im = PetscImaginaryPart(eps->eigr[k]);
501: #else
502: re = eps->eigr[k];
503: im = eps->eigi[k];
504: #endif
505: PetscCall(PetscDrawSPAddPoint(drawsp,&re,&im));
506: }
507: PetscCall(PetscDrawSPDraw(drawsp,PETSC_TRUE));
508: PetscCall(PetscDrawSPSave(drawsp));
509: PetscCall(PetscDrawSPDestroy(&drawsp));
510: PetscFunctionReturn(PETSC_SUCCESS);
511: }
513: static PetscErrorCode EPSValuesView_BINARY(EPS eps,PetscViewer viewer)
514: {
515: #if defined(PETSC_HAVE_COMPLEX)
516: PetscInt i,k;
517: PetscComplex *ev;
518: #endif
520: PetscFunctionBegin;
521: #if defined(PETSC_HAVE_COMPLEX)
522: PetscCall(PetscMalloc1(eps->nconv,&ev));
523: for (i=0;i<eps->nconv;i++) {
524: k = eps->perm[i];
525: #if defined(PETSC_USE_COMPLEX)
526: ev[i] = eps->eigr[k];
527: #else
528: ev[i] = PetscCMPLX(eps->eigr[k],eps->eigi[k]);
529: #endif
530: }
531: PetscCall(PetscViewerBinaryWrite(viewer,ev,eps->nconv,PETSC_COMPLEX));
532: PetscCall(PetscFree(ev));
533: #endif
534: PetscFunctionReturn(PETSC_SUCCESS);
535: }
537: #if defined(PETSC_HAVE_HDF5)
538: static PetscErrorCode EPSValuesView_HDF5(EPS eps,PetscViewer viewer)
539: {
540: PetscInt i,k,n,N;
541: PetscMPIInt rank;
542: Vec v;
543: char vname[30];
544: const char *ename;
546: PetscFunctionBegin;
547: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)eps),&rank));
548: N = eps->nconv;
549: n = rank? 0: N;
550: /* create a vector containing the eigenvalues */
551: PetscCall(VecCreateMPI(PetscObjectComm((PetscObject)eps),n,N,&v));
552: PetscCall(PetscObjectGetName((PetscObject)eps,&ename));
553: PetscCall(PetscSNPrintf(vname,sizeof(vname),"eigr_%s",ename));
554: PetscCall(PetscObjectSetName((PetscObject)v,vname));
555: if (!rank) {
556: for (i=0;i<eps->nconv;i++) {
557: k = eps->perm[i];
558: PetscCall(VecSetValue(v,i,eps->eigr[k],INSERT_VALUES));
559: }
560: }
561: PetscCall(VecAssemblyBegin(v));
562: PetscCall(VecAssemblyEnd(v));
563: PetscCall(VecView(v,viewer));
564: #if !defined(PETSC_USE_COMPLEX)
565: /* in real scalars write the imaginary part as a separate vector */
566: PetscCall(PetscSNPrintf(vname,sizeof(vname),"eigi_%s",ename));
567: PetscCall(PetscObjectSetName((PetscObject)v,vname));
568: if (!rank) {
569: for (i=0;i<eps->nconv;i++) {
570: k = eps->perm[i];
571: PetscCall(VecSetValue(v,i,eps->eigi[k],INSERT_VALUES));
572: }
573: }
574: PetscCall(VecAssemblyBegin(v));
575: PetscCall(VecAssemblyEnd(v));
576: PetscCall(VecView(v,viewer));
577: #endif
578: PetscCall(VecDestroy(&v));
579: PetscFunctionReturn(PETSC_SUCCESS);
580: }
581: #endif
583: static PetscErrorCode EPSValuesView_ASCII(EPS eps,PetscViewer viewer)
584: {
585: PetscInt i,k;
587: PetscFunctionBegin;
588: PetscCall(PetscViewerASCIIPrintf(viewer,"Eigenvalues = \n"));
589: for (i=0;i<eps->nconv;i++) {
590: k = eps->perm[i];
591: PetscCall(PetscViewerASCIIPrintf(viewer," "));
592: PetscCall(SlepcPrintEigenvalueASCII(viewer,eps->eigr[k],eps->eigi[k]));
593: PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
594: }
595: PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
596: PetscFunctionReturn(PETSC_SUCCESS);
597: }
599: static PetscErrorCode EPSValuesView_MATLAB(EPS eps,PetscViewer viewer)
600: {
601: PetscInt i,k;
602: PetscReal re,im;
603: const char *name;
605: PetscFunctionBegin;
606: PetscCall(PetscObjectGetName((PetscObject)eps,&name));
607: PetscCall(PetscViewerASCIIPrintf(viewer,"Lambda_%s = [\n",name));
608: for (i=0;i<eps->nconv;i++) {
609: k = eps->perm[i];
610: #if defined(PETSC_USE_COMPLEX)
611: re = PetscRealPart(eps->eigr[k]);
612: im = PetscImaginaryPart(eps->eigr[k]);
613: #else
614: re = eps->eigr[k];
615: im = eps->eigi[k];
616: #endif
617: if (im!=0.0) PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e%+18.16ei\n",(double)re,(double)im));
618: else PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double)re));
619: }
620: PetscCall(PetscViewerASCIIPrintf(viewer,"];\n"));
621: PetscFunctionReturn(PETSC_SUCCESS);
622: }
624: /*@C
625: EPSValuesView - Displays the computed eigenvalues in a viewer.
627: Collective
629: Input Parameters:
630: + eps - the eigensolver context
631: - viewer - the viewer
633: Options Database Key:
634: . -eps_view_values - print computed eigenvalues
636: Level: intermediate
638: .seealso: EPSSolve(), EPSVectorsView(), EPSErrorView()
639: @*/
640: PetscErrorCode EPSValuesView(EPS eps,PetscViewer viewer)
641: {
642: PetscBool isascii,isdraw,isbinary;
643: PetscViewerFormat format;
644: #if defined(PETSC_HAVE_HDF5)
645: PetscBool ishdf5;
646: #endif
648: PetscFunctionBegin;
650: if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)eps),&viewer));
652: PetscCheckSameComm(eps,1,viewer,2);
653: EPSCheckSolved(eps,1);
654: PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw));
655: PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
656: #if defined(PETSC_HAVE_HDF5)
657: PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5));
658: #endif
659: PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
660: if (isdraw) PetscCall(EPSValuesView_DRAW(eps,viewer));
661: else if (isbinary) PetscCall(EPSValuesView_BINARY(eps,viewer));
662: #if defined(PETSC_HAVE_HDF5)
663: else if (ishdf5) PetscCall(EPSValuesView_HDF5(eps,viewer));
664: #endif
665: else if (isascii) {
666: PetscCall(PetscViewerGetFormat(viewer,&format));
667: switch (format) {
668: case PETSC_VIEWER_DEFAULT:
669: case PETSC_VIEWER_ASCII_INFO:
670: case PETSC_VIEWER_ASCII_INFO_DETAIL:
671: PetscCall(EPSValuesView_ASCII(eps,viewer));
672: break;
673: case PETSC_VIEWER_ASCII_MATLAB:
674: PetscCall(EPSValuesView_MATLAB(eps,viewer));
675: break;
676: default:
677: PetscCall(PetscInfo(eps,"Unsupported viewer format %s\n",PetscViewerFormats[format]));
678: }
679: }
680: PetscFunctionReturn(PETSC_SUCCESS);
681: }
683: /*@
684: EPSValuesViewFromOptions - Processes command line options to determine if/how
685: the computed eigenvalues are to be viewed.
687: Collective
689: Input Parameters:
690: . eps - the eigensolver context
692: Level: developer
694: .seealso: EPSValuesView()
695: @*/
696: PetscErrorCode EPSValuesViewFromOptions(EPS eps)
697: {
698: PetscViewer viewer;
699: PetscBool flg;
700: static PetscBool incall = PETSC_FALSE;
701: PetscViewerFormat format;
703: PetscFunctionBegin;
704: if (incall) PetscFunctionReturn(PETSC_SUCCESS);
705: incall = PETSC_TRUE;
706: PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)eps),((PetscObject)eps)->options,((PetscObject)eps)->prefix,"-eps_view_values",&viewer,&format,&flg));
707: if (flg) {
708: PetscCall(PetscViewerPushFormat(viewer,format));
709: PetscCall(EPSValuesView(eps,viewer));
710: PetscCall(PetscViewerPopFormat(viewer));
711: PetscCall(PetscViewerDestroy(&viewer));
712: }
713: incall = PETSC_FALSE;
714: PetscFunctionReturn(PETSC_SUCCESS);
715: }
717: /*@C
718: EPSVectorsView - Outputs computed eigenvectors to a viewer.
720: Collective
722: Input Parameters:
723: + eps - the eigensolver context
724: - viewer - the viewer
726: Options Database Key:
727: . -eps_view_vectors - output eigenvectors.
729: Notes:
730: If PETSc was configured with real scalars, complex conjugate eigenvectors
731: will be viewed as two separate real vectors, one containing the real part
732: and another one containing the imaginary part.
734: If left eigenvectors were computed with a two-sided eigensolver, the right
735: and left eigenvectors are interleaved, that is, the vectors are output in
736: the following order X0, Y0, X1, Y1, X2, Y2, ...
738: Level: intermediate
740: .seealso: EPSSolve(), EPSValuesView(), EPSErrorView()
741: @*/
742: PetscErrorCode EPSVectorsView(EPS eps,PetscViewer viewer)
743: {
744: PetscInt i,k;
745: Vec xr,xi=NULL;
747: PetscFunctionBegin;
749: if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)eps),&viewer));
751: PetscCheckSameComm(eps,1,viewer,2);
752: EPSCheckSolved(eps,1);
753: if (eps->nconv) {
754: PetscCall(EPSComputeVectors(eps));
755: PetscCall(BVCreateVec(eps->V,&xr));
756: #if !defined(PETSC_USE_COMPLEX)
757: PetscCall(BVCreateVec(eps->V,&xi));
758: #endif
759: for (i=0;i<eps->nconv;i++) {
760: k = eps->perm[i];
761: PetscCall(BV_GetEigenvector(eps->V,k,eps->eigi[k],xr,xi));
762: PetscCall(SlepcViewEigenvector(viewer,xr,xi,"X",i,(PetscObject)eps));
763: if (eps->twosided) {
764: PetscCall(BV_GetEigenvector(eps->W,k,eps->eigi[k],xr,xi));
765: PetscCall(SlepcViewEigenvector(viewer,xr,xi,"Y",i,(PetscObject)eps));
766: }
767: }
768: PetscCall(VecDestroy(&xr));
769: #if !defined(PETSC_USE_COMPLEX)
770: PetscCall(VecDestroy(&xi));
771: #endif
772: }
773: PetscFunctionReturn(PETSC_SUCCESS);
774: }
776: /*@
777: EPSVectorsViewFromOptions - Processes command line options to determine if/how
778: the computed eigenvectors are to be viewed.
780: Collective
782: Input Parameter:
783: . eps - the eigensolver context
785: Level: developer
787: .seealso: EPSVectorsView()
788: @*/
789: PetscErrorCode EPSVectorsViewFromOptions(EPS eps)
790: {
791: PetscViewer viewer;
792: PetscBool flg = PETSC_FALSE;
793: static PetscBool incall = PETSC_FALSE;
794: PetscViewerFormat format;
796: PetscFunctionBegin;
797: if (incall) PetscFunctionReturn(PETSC_SUCCESS);
798: incall = PETSC_TRUE;
799: PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)eps),((PetscObject)eps)->options,((PetscObject)eps)->prefix,"-eps_view_vectors",&viewer,&format,&flg));
800: if (flg) {
801: PetscCall(PetscViewerPushFormat(viewer,format));
802: PetscCall(EPSVectorsView(eps,viewer));
803: PetscCall(PetscViewerPopFormat(viewer));
804: PetscCall(PetscViewerDestroy(&viewer));
805: }
806: incall = PETSC_FALSE;
807: PetscFunctionReturn(PETSC_SUCCESS);
808: }