Actual source code: pepview.c
slepc-main 2024-12-17
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: The PEP routines related to various viewers
12: */
14: #include <slepc/private/pepimpl.h>
15: #include <slepc/private/bvimpl.h>
16: #include <petscdraw.h>
18: /*@
19: PEPView - Prints the PEP data structure.
21: Collective
23: Input Parameters:
24: + pep - the polynomial eigenproblem solver context
25: - viewer - optional visualization context
27: Options Database Key:
28: . -pep_view - Calls PEPView() at end of PEPSolve()
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 PEPView(PEP pep,PetscViewer viewer)
46: {
47: const char *type=NULL;
48: char str[50];
49: PetscBool isascii,islinear,istrivial;
50: PetscInt i;
51: PetscViewer sviewer;
52: MPI_Comm child;
54: PetscFunctionBegin;
56: if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pep),&viewer));
58: PetscCheckSameComm(pep,1,viewer,2);
60: PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
61: if (isascii) {
62: PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)pep,viewer));
63: PetscCall(PetscViewerASCIIPushTab(viewer));
64: PetscTryTypeMethod(pep,view,viewer);
65: PetscCall(PetscViewerASCIIPopTab(viewer));
66: if (pep->problem_type) {
67: switch (pep->problem_type) {
68: case PEP_GENERAL: type = "general polynomial eigenvalue problem"; break;
69: case PEP_HERMITIAN: type = SLEPC_STRING_HERMITIAN " polynomial eigenvalue problem"; break;
70: case PEP_HYPERBOLIC: type = "hyperbolic polynomial eigenvalue problem"; break;
71: case PEP_GYROSCOPIC: type = "gyroscopic polynomial eigenvalue problem"; break;
72: }
73: } else type = "not yet set";
74: PetscCall(PetscViewerASCIIPrintf(viewer," problem type: %s\n",type));
75: PetscCall(PetscViewerASCIIPrintf(viewer," polynomial represented in %s basis\n",PEPBasisTypes[pep->basis]));
76: switch (pep->scale) {
77: case PEP_SCALE_NONE:
78: break;
79: case PEP_SCALE_SCALAR:
80: PetscCall(PetscViewerASCIIPrintf(viewer," parameter scaling enabled, with scaling factor=%g\n",(double)pep->sfactor));
81: break;
82: case PEP_SCALE_DIAGONAL:
83: PetscCall(PetscViewerASCIIPrintf(viewer," diagonal balancing enabled, with its=%" PetscInt_FMT " and lambda=%g\n",pep->sits,(double)pep->slambda));
84: break;
85: case PEP_SCALE_BOTH:
86: PetscCall(PetscViewerASCIIPrintf(viewer," parameter scaling & diagonal balancing enabled, with scaling factor=%g, its=%" PetscInt_FMT " and lambda=%g\n",(double)pep->sfactor,pep->sits,(double)pep->slambda));
87: break;
88: }
89: PetscCall(PetscViewerASCIIPrintf(viewer," selected portion of the spectrum: "));
90: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
91: PetscCall(SlepcSNPrintfScalar(str,sizeof(str),pep->target,PETSC_FALSE));
92: if (!pep->which) PetscCall(PetscViewerASCIIPrintf(viewer,"not yet set\n"));
93: else switch (pep->which) {
94: case PEP_WHICH_USER:
95: PetscCall(PetscViewerASCIIPrintf(viewer,"user defined\n"));
96: break;
97: case PEP_TARGET_MAGNITUDE:
98: PetscCall(PetscViewerASCIIPrintf(viewer,"closest to target: %s (in magnitude)\n",str));
99: break;
100: case PEP_TARGET_REAL:
101: PetscCall(PetscViewerASCIIPrintf(viewer,"closest to target: %s (along the real axis)\n",str));
102: break;
103: case PEP_TARGET_IMAGINARY:
104: PetscCall(PetscViewerASCIIPrintf(viewer,"closest to target: %s (along the imaginary axis)\n",str));
105: break;
106: case PEP_LARGEST_MAGNITUDE:
107: PetscCall(PetscViewerASCIIPrintf(viewer,"largest eigenvalues in magnitude\n"));
108: break;
109: case PEP_SMALLEST_MAGNITUDE:
110: PetscCall(PetscViewerASCIIPrintf(viewer,"smallest eigenvalues in magnitude\n"));
111: break;
112: case PEP_LARGEST_REAL:
113: PetscCall(PetscViewerASCIIPrintf(viewer,"largest real parts\n"));
114: break;
115: case PEP_SMALLEST_REAL:
116: PetscCall(PetscViewerASCIIPrintf(viewer,"smallest real parts\n"));
117: break;
118: case PEP_LARGEST_IMAGINARY:
119: PetscCall(PetscViewerASCIIPrintf(viewer,"largest imaginary parts\n"));
120: break;
121: case PEP_SMALLEST_IMAGINARY:
122: PetscCall(PetscViewerASCIIPrintf(viewer,"smallest imaginary parts\n"));
123: break;
124: case PEP_ALL:
125: if (pep->inta || pep->intb) PetscCall(PetscViewerASCIIPrintf(viewer,"all eigenvalues in interval [%g,%g]\n",(double)pep->inta,(double)pep->intb));
126: else PetscCall(PetscViewerASCIIPrintf(viewer,"all eigenvalues in the region\n"));
127: break;
128: }
129: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
130: PetscCall(PetscViewerASCIIPrintf(viewer," number of eigenvalues (nev): %" PetscInt_FMT "\n",pep->nev));
131: PetscCall(PetscViewerASCIIPrintf(viewer," number of column vectors (ncv): %" PetscInt_FMT "\n",pep->ncv));
132: PetscCall(PetscViewerASCIIPrintf(viewer," maximum dimension of projected problem (mpd): %" PetscInt_FMT "\n",pep->mpd));
133: PetscCall(PetscViewerASCIIPrintf(viewer," maximum number of iterations: %" PetscInt_FMT "\n",pep->max_it));
134: PetscCall(PetscViewerASCIIPrintf(viewer," tolerance: %g\n",(double)pep->tol));
135: PetscCall(PetscViewerASCIIPrintf(viewer," convergence test: "));
136: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
137: switch (pep->conv) {
138: case PEP_CONV_ABS:
139: PetscCall(PetscViewerASCIIPrintf(viewer,"absolute\n"));break;
140: case PEP_CONV_REL:
141: PetscCall(PetscViewerASCIIPrintf(viewer,"relative to the eigenvalue\n"));break;
142: case PEP_CONV_NORM:
143: PetscCall(PetscViewerASCIIPrintf(viewer,"relative to the matrix norms\n"));
144: if (pep->nrma) {
145: PetscCall(PetscViewerASCIIPrintf(viewer," computed matrix norms: %g",(double)pep->nrma[0]));
146: for (i=1;i<pep->nmat;i++) PetscCall(PetscViewerASCIIPrintf(viewer,", %g",(double)pep->nrma[i]));
147: PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
148: }
149: break;
150: case PEP_CONV_USER:
151: PetscCall(PetscViewerASCIIPrintf(viewer,"user-defined\n"));break;
152: }
153: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
154: PetscCall(PetscViewerASCIIPrintf(viewer," extraction type: %s\n",PEPExtractTypes[pep->extract]));
155: if (pep->refine) {
156: PetscCall(PetscViewerASCIIPrintf(viewer," iterative refinement: %s, with %s scheme\n",PEPRefineTypes[pep->refine],PEPRefineSchemes[pep->scheme]));
157: PetscCall(PetscViewerASCIIPrintf(viewer," refinement stopping criterion: tol=%g, its=%" PetscInt_FMT "\n",(double)pep->rtol,pep->rits));
158: if (pep->npart>1) PetscCall(PetscViewerASCIIPrintf(viewer," splitting communicator in %" PetscInt_FMT " partitions for refinement\n",pep->npart));
159: }
160: if (pep->nini) PetscCall(PetscViewerASCIIPrintf(viewer," dimension of user-provided initial space: %" PetscInt_FMT "\n",PetscAbs(pep->nini)));
161: } else PetscTryTypeMethod(pep,view,viewer);
162: PetscCall(PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO));
163: if (!pep->V) PetscCall(PEPGetBV(pep,&pep->V));
164: PetscCall(BVView(pep->V,viewer));
165: if (!pep->rg) PetscCall(PEPGetRG(pep,&pep->rg));
166: PetscCall(RGIsTrivial(pep->rg,&istrivial));
167: if (!istrivial) PetscCall(RGView(pep->rg,viewer));
168: PetscCall(PetscObjectTypeCompare((PetscObject)pep,PEPLINEAR,&islinear));
169: if (!islinear) {
170: if (!pep->ds) PetscCall(PEPGetDS(pep,&pep->ds));
171: PetscCall(DSView(pep->ds,viewer));
172: }
173: PetscCall(PetscViewerPopFormat(viewer));
174: if (!pep->st) PetscCall(PEPGetST(pep,&pep->st));
175: PetscCall(STView(pep->st,viewer));
176: if (pep->refine!=PEP_REFINE_NONE) {
177: PetscCall(PetscViewerASCIIPushTab(viewer));
178: if (pep->npart>1) {
179: if (pep->refinesubc->color==0) {
180: PetscCall(PetscSubcommGetChild(pep->refinesubc,&child));
181: PetscCall(PetscViewerASCIIGetStdout(child,&sviewer));
182: PetscCall(KSPView(pep->refineksp,sviewer));
183: }
184: } else PetscCall(KSPView(pep->refineksp,viewer));
185: PetscCall(PetscViewerASCIIPopTab(viewer));
186: }
187: PetscFunctionReturn(PETSC_SUCCESS);
188: }
190: /*@
191: PEPViewFromOptions - View from options
193: Collective
195: Input Parameters:
196: + pep - the eigensolver context
197: . obj - optional object
198: - name - command line option
200: Level: intermediate
202: .seealso: PEPView(), PEPCreate()
203: @*/
204: PetscErrorCode PEPViewFromOptions(PEP pep,PetscObject obj,const char name[])
205: {
206: PetscFunctionBegin;
208: PetscCall(PetscObjectViewFromOptions((PetscObject)pep,obj,name));
209: PetscFunctionReturn(PETSC_SUCCESS);
210: }
212: /*@
213: PEPConvergedReasonView - Displays the reason a PEP solve converged or diverged.
215: Collective
217: Input Parameters:
218: + pep - the eigensolver context
219: - viewer - the viewer to display the reason
221: Options Database Keys:
222: . -pep_converged_reason - print reason for convergence, and number of iterations
224: Note:
225: To change the format of the output call PetscViewerPushFormat(viewer,format) before
226: this call. Use PETSC_VIEWER_DEFAULT for the default, use PETSC_VIEWER_FAILED to only
227: display a reason if it fails. The latter can be set in the command line with
228: -pep_converged_reason ::failed
230: Level: intermediate
232: .seealso: PEPSetConvergenceTest(), PEPSetTolerances(), PEPGetIterationNumber(), PEPConvergedReasonViewFromOptions()
233: @*/
234: PetscErrorCode PEPConvergedReasonView(PEP pep,PetscViewer viewer)
235: {
236: PetscBool isAscii;
237: PetscViewerFormat format;
239: PetscFunctionBegin;
240: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pep));
241: PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii));
242: if (isAscii) {
243: PetscCall(PetscViewerGetFormat(viewer,&format));
244: PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)pep)->tablevel));
245: if (pep->reason > 0 && format != PETSC_VIEWER_FAILED) PetscCall(PetscViewerASCIIPrintf(viewer,"%s Polynomial eigensolve converged (%" PetscInt_FMT " eigenpair%s) due to %s; iterations %" PetscInt_FMT "\n",((PetscObject)pep)->prefix?((PetscObject)pep)->prefix:"",pep->nconv,(pep->nconv>1)?"s":"",PEPConvergedReasons[pep->reason],pep->its));
246: else if (pep->reason <= 0) PetscCall(PetscViewerASCIIPrintf(viewer,"%s Polynomial eigensolve did not converge due to %s; iterations %" PetscInt_FMT "\n",((PetscObject)pep)->prefix?((PetscObject)pep)->prefix:"",PEPConvergedReasons[pep->reason],pep->its));
247: PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)pep)->tablevel));
248: }
249: PetscFunctionReturn(PETSC_SUCCESS);
250: }
252: /*@
253: PEPConvergedReasonViewFromOptions - Processes command line options to determine if/how
254: the PEP converged reason is to be viewed.
256: Collective
258: Input Parameter:
259: . pep - the eigensolver context
261: Level: developer
263: .seealso: PEPConvergedReasonView()
264: @*/
265: PetscErrorCode PEPConvergedReasonViewFromOptions(PEP pep)
266: {
267: PetscViewer viewer;
268: PetscBool flg;
269: static PetscBool incall = PETSC_FALSE;
270: PetscViewerFormat format;
272: PetscFunctionBegin;
273: if (incall) PetscFunctionReturn(PETSC_SUCCESS);
274: incall = PETSC_TRUE;
275: PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)pep),((PetscObject)pep)->options,((PetscObject)pep)->prefix,"-pep_converged_reason",&viewer,&format,&flg));
276: if (flg) {
277: PetscCall(PetscViewerPushFormat(viewer,format));
278: PetscCall(PEPConvergedReasonView(pep,viewer));
279: PetscCall(PetscViewerPopFormat(viewer));
280: PetscCall(PetscViewerDestroy(&viewer));
281: }
282: incall = PETSC_FALSE;
283: PetscFunctionReturn(PETSC_SUCCESS);
284: }
286: static PetscErrorCode PEPErrorView_ASCII(PEP pep,PEPErrorType etype,PetscViewer viewer)
287: {
288: PetscReal error;
289: PetscInt i,j,k,nvals;
291: PetscFunctionBegin;
292: nvals = (pep->which==PEP_ALL)? pep->nconv: pep->nev;
293: if (pep->which!=PEP_ALL && pep->nconv<pep->nev) {
294: PetscCall(PetscViewerASCIIPrintf(viewer," Problem: less than %" PetscInt_FMT " eigenvalues converged\n\n",pep->nev));
295: PetscFunctionReturn(PETSC_SUCCESS);
296: }
297: if (pep->which==PEP_ALL && !nvals) {
298: PetscCall(PetscViewerASCIIPrintf(viewer," No eigenvalues have been found\n\n"));
299: PetscFunctionReturn(PETSC_SUCCESS);
300: }
301: for (i=0;i<nvals;i++) {
302: PetscCall(PEPComputeError(pep,i,etype,&error));
303: if (error>=5.0*pep->tol) {
304: PetscCall(PetscViewerASCIIPrintf(viewer," Problem: some of the first %" PetscInt_FMT " relative errors are higher than the tolerance\n\n",nvals));
305: PetscFunctionReturn(PETSC_SUCCESS);
306: }
307: }
308: if (pep->which==PEP_ALL) PetscCall(PetscViewerASCIIPrintf(viewer," Found %" PetscInt_FMT " eigenvalues, all of them computed up to the required tolerance:",nvals));
309: else PetscCall(PetscViewerASCIIPrintf(viewer," All requested eigenvalues computed up to the required tolerance:"));
310: for (i=0;i<=(nvals-1)/8;i++) {
311: PetscCall(PetscViewerASCIIPrintf(viewer,"\n "));
312: for (j=0;j<PetscMin(8,nvals-8*i);j++) {
313: k = pep->perm[8*i+j];
314: PetscCall(SlepcPrintEigenvalueASCII(viewer,pep->eigr[k],pep->eigi[k]));
315: if (8*i+j+1<nvals) PetscCall(PetscViewerASCIIPrintf(viewer,", "));
316: }
317: }
318: PetscCall(PetscViewerASCIIPrintf(viewer,"\n\n"));
319: PetscFunctionReturn(PETSC_SUCCESS);
320: }
322: static PetscErrorCode PEPErrorView_DETAIL(PEP pep,PEPErrorType etype,PetscViewer viewer)
323: {
324: PetscReal error,re,im;
325: PetscScalar kr,ki;
326: PetscInt i;
327: char ex[30],sep[]=" ---------------------- --------------------\n";
329: PetscFunctionBegin;
330: if (!pep->nconv) PetscFunctionReturn(PETSC_SUCCESS);
331: switch (etype) {
332: case PEP_ERROR_ABSOLUTE:
333: PetscCall(PetscSNPrintf(ex,sizeof(ex)," ||P(k)x||"));
334: break;
335: case PEP_ERROR_RELATIVE:
336: PetscCall(PetscSNPrintf(ex,sizeof(ex),"||P(k)x||/||kx||"));
337: break;
338: case PEP_ERROR_BACKWARD:
339: PetscCall(PetscSNPrintf(ex,sizeof(ex)," eta(x,k)"));
340: break;
341: }
342: PetscCall(PetscViewerASCIIPrintf(viewer,"%s k %s\n%s",sep,ex,sep));
343: for (i=0;i<pep->nconv;i++) {
344: PetscCall(PEPGetEigenpair(pep,i,&kr,&ki,NULL,NULL));
345: PetscCall(PEPComputeError(pep,i,etype,&error));
346: #if defined(PETSC_USE_COMPLEX)
347: re = PetscRealPart(kr);
348: im = PetscImaginaryPart(kr);
349: #else
350: re = kr;
351: im = ki;
352: #endif
353: if (im!=0.0) PetscCall(PetscViewerASCIIPrintf(viewer," % 9f%+9fi %12g\n",(double)re,(double)im,(double)error));
354: else PetscCall(PetscViewerASCIIPrintf(viewer," % 12f %12g\n",(double)re,(double)error));
355: }
356: PetscCall(PetscViewerASCIIPrintf(viewer,"%s",sep));
357: PetscFunctionReturn(PETSC_SUCCESS);
358: }
360: static PetscErrorCode PEPErrorView_MATLAB(PEP pep,PEPErrorType etype,PetscViewer viewer)
361: {
362: PetscReal error;
363: PetscInt i;
364: const char *name;
366: PetscFunctionBegin;
367: PetscCall(PetscObjectGetName((PetscObject)pep,&name));
368: PetscCall(PetscViewerASCIIPrintf(viewer,"Error_%s = [\n",name));
369: for (i=0;i<pep->nconv;i++) {
370: PetscCall(PEPComputeError(pep,i,etype,&error));
371: PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double)error));
372: }
373: PetscCall(PetscViewerASCIIPrintf(viewer,"];\n"));
374: PetscFunctionReturn(PETSC_SUCCESS);
375: }
377: /*@
378: PEPErrorView - Displays the errors associated with the computed solution
379: (as well as the eigenvalues).
381: Collective
383: Input Parameters:
384: + pep - the eigensolver context
385: . etype - error type
386: - viewer - optional visualization context
388: Options Database Keys:
389: + -pep_error_absolute - print absolute errors of each eigenpair
390: . -pep_error_relative - print relative errors of each eigenpair
391: - -pep_error_backward - print backward errors of each eigenpair
393: Notes:
394: By default, this function checks the error of all eigenpairs and prints
395: the eigenvalues if all of them are below the requested tolerance.
396: If the viewer has format=PETSC_VIEWER_ASCII_INFO_DETAIL then a table with
397: eigenvalues and corresponding errors is printed.
399: Level: intermediate
401: .seealso: PEPSolve(), PEPValuesView(), PEPVectorsView()
402: @*/
403: PetscErrorCode PEPErrorView(PEP pep,PEPErrorType etype,PetscViewer viewer)
404: {
405: PetscBool isascii;
406: PetscViewerFormat format;
408: PetscFunctionBegin;
410: if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pep),&viewer));
412: PetscCheckSameComm(pep,1,viewer,3);
413: PEPCheckSolved(pep,1);
414: PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
415: if (!isascii) PetscFunctionReturn(PETSC_SUCCESS);
417: PetscCall(PetscViewerGetFormat(viewer,&format));
418: switch (format) {
419: case PETSC_VIEWER_DEFAULT:
420: case PETSC_VIEWER_ASCII_INFO:
421: PetscCall(PEPErrorView_ASCII(pep,etype,viewer));
422: break;
423: case PETSC_VIEWER_ASCII_INFO_DETAIL:
424: PetscCall(PEPErrorView_DETAIL(pep,etype,viewer));
425: break;
426: case PETSC_VIEWER_ASCII_MATLAB:
427: PetscCall(PEPErrorView_MATLAB(pep,etype,viewer));
428: break;
429: default:
430: PetscCall(PetscInfo(pep,"Unsupported viewer format %s\n",PetscViewerFormats[format]));
431: }
432: PetscFunctionReturn(PETSC_SUCCESS);
433: }
435: /*@
436: PEPErrorViewFromOptions - Processes command line options to determine if/how
437: the errors of the computed solution are to be viewed.
439: Collective
441: Input Parameter:
442: . pep - the eigensolver context
444: Level: developer
446: .seealso: PEPErrorView()
447: @*/
448: PetscErrorCode PEPErrorViewFromOptions(PEP pep)
449: {
450: PetscViewer viewer;
451: PetscBool flg;
452: static PetscBool incall = PETSC_FALSE;
453: PetscViewerFormat format;
455: PetscFunctionBegin;
456: if (incall) PetscFunctionReturn(PETSC_SUCCESS);
457: incall = PETSC_TRUE;
458: PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)pep),((PetscObject)pep)->options,((PetscObject)pep)->prefix,"-pep_error_absolute",&viewer,&format,&flg));
459: if (flg) {
460: PetscCall(PetscViewerPushFormat(viewer,format));
461: PetscCall(PEPErrorView(pep,PEP_ERROR_ABSOLUTE,viewer));
462: PetscCall(PetscViewerPopFormat(viewer));
463: PetscCall(PetscViewerDestroy(&viewer));
464: }
465: PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)pep),((PetscObject)pep)->options,((PetscObject)pep)->prefix,"-pep_error_relative",&viewer,&format,&flg));
466: if (flg) {
467: PetscCall(PetscViewerPushFormat(viewer,format));
468: PetscCall(PEPErrorView(pep,PEP_ERROR_RELATIVE,viewer));
469: PetscCall(PetscViewerPopFormat(viewer));
470: PetscCall(PetscViewerDestroy(&viewer));
471: }
472: PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)pep),((PetscObject)pep)->options,((PetscObject)pep)->prefix,"-pep_error_backward",&viewer,&format,&flg));
473: if (flg) {
474: PetscCall(PetscViewerPushFormat(viewer,format));
475: PetscCall(PEPErrorView(pep,PEP_ERROR_BACKWARD,viewer));
476: PetscCall(PetscViewerPopFormat(viewer));
477: PetscCall(PetscViewerDestroy(&viewer));
478: }
479: incall = PETSC_FALSE;
480: PetscFunctionReturn(PETSC_SUCCESS);
481: }
483: static PetscErrorCode PEPValuesView_DRAW(PEP pep,PetscViewer viewer)
484: {
485: PetscDraw draw;
486: PetscDrawSP drawsp;
487: PetscReal re,im;
488: PetscInt i,k;
490: PetscFunctionBegin;
491: if (!pep->nconv) PetscFunctionReturn(PETSC_SUCCESS);
492: PetscCall(PetscViewerDrawGetDraw(viewer,0,&draw));
493: PetscCall(PetscDrawSetTitle(draw,"Computed Eigenvalues"));
494: PetscCall(PetscDrawSPCreate(draw,1,&drawsp));
495: for (i=0;i<pep->nconv;i++) {
496: k = pep->perm[i];
497: #if defined(PETSC_USE_COMPLEX)
498: re = PetscRealPart(pep->eigr[k]);
499: im = PetscImaginaryPart(pep->eigr[k]);
500: #else
501: re = pep->eigr[k];
502: im = pep->eigi[k];
503: #endif
504: PetscCall(PetscDrawSPAddPoint(drawsp,&re,&im));
505: }
506: PetscCall(PetscDrawSPDraw(drawsp,PETSC_TRUE));
507: PetscCall(PetscDrawSPSave(drawsp));
508: PetscCall(PetscDrawSPDestroy(&drawsp));
509: PetscFunctionReturn(PETSC_SUCCESS);
510: }
512: static PetscErrorCode PEPValuesView_BINARY(PEP pep,PetscViewer viewer)
513: {
514: #if defined(PETSC_HAVE_COMPLEX)
515: PetscInt i,k;
516: PetscComplex *ev;
517: #endif
519: PetscFunctionBegin;
520: #if defined(PETSC_HAVE_COMPLEX)
521: PetscCall(PetscMalloc1(pep->nconv,&ev));
522: for (i=0;i<pep->nconv;i++) {
523: k = pep->perm[i];
524: #if defined(PETSC_USE_COMPLEX)
525: ev[i] = pep->eigr[k];
526: #else
527: ev[i] = PetscCMPLX(pep->eigr[k],pep->eigi[k]);
528: #endif
529: }
530: PetscCall(PetscViewerBinaryWrite(viewer,ev,pep->nconv,PETSC_COMPLEX));
531: PetscCall(PetscFree(ev));
532: #endif
533: PetscFunctionReturn(PETSC_SUCCESS);
534: }
536: #if defined(PETSC_HAVE_HDF5)
537: static PetscErrorCode PEPValuesView_HDF5(PEP pep,PetscViewer viewer)
538: {
539: PetscInt i,k,n,N;
540: PetscMPIInt rank;
541: Vec v;
542: char vname[30];
543: const char *ename;
545: PetscFunctionBegin;
546: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)pep),&rank));
547: N = pep->nconv;
548: n = rank? 0: N;
549: /* create a vector containing the eigenvalues */
550: PetscCall(VecCreateMPI(PetscObjectComm((PetscObject)pep),n,N,&v));
551: PetscCall(PetscObjectGetName((PetscObject)pep,&ename));
552: PetscCall(PetscSNPrintf(vname,sizeof(vname),"eigr_%s",ename));
553: PetscCall(PetscObjectSetName((PetscObject)v,vname));
554: if (!rank) {
555: for (i=0;i<pep->nconv;i++) {
556: k = pep->perm[i];
557: PetscCall(VecSetValue(v,i,pep->eigr[k],INSERT_VALUES));
558: }
559: }
560: PetscCall(VecAssemblyBegin(v));
561: PetscCall(VecAssemblyEnd(v));
562: PetscCall(VecView(v,viewer));
563: #if !defined(PETSC_USE_COMPLEX)
564: /* in real scalars write the imaginary part as a separate vector */
565: PetscCall(PetscSNPrintf(vname,sizeof(vname),"eigi_%s",ename));
566: PetscCall(PetscObjectSetName((PetscObject)v,vname));
567: if (!rank) {
568: for (i=0;i<pep->nconv;i++) {
569: k = pep->perm[i];
570: PetscCall(VecSetValue(v,i,pep->eigi[k],INSERT_VALUES));
571: }
572: }
573: PetscCall(VecAssemblyBegin(v));
574: PetscCall(VecAssemblyEnd(v));
575: PetscCall(VecView(v,viewer));
576: #endif
577: PetscCall(VecDestroy(&v));
578: PetscFunctionReturn(PETSC_SUCCESS);
579: }
580: #endif
582: static PetscErrorCode PEPValuesView_ASCII(PEP pep,PetscViewer viewer)
583: {
584: PetscInt i,k;
586: PetscFunctionBegin;
587: PetscCall(PetscViewerASCIIPrintf(viewer,"Eigenvalues = \n"));
588: for (i=0;i<pep->nconv;i++) {
589: k = pep->perm[i];
590: PetscCall(PetscViewerASCIIPrintf(viewer," "));
591: PetscCall(SlepcPrintEigenvalueASCII(viewer,pep->eigr[k],pep->eigi[k]));
592: PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
593: }
594: PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
595: PetscFunctionReturn(PETSC_SUCCESS);
596: }
598: static PetscErrorCode PEPValuesView_MATLAB(PEP pep,PetscViewer viewer)
599: {
600: PetscInt i,k;
601: PetscReal re,im;
602: const char *name;
604: PetscFunctionBegin;
605: PetscCall(PetscObjectGetName((PetscObject)pep,&name));
606: PetscCall(PetscViewerASCIIPrintf(viewer,"Lambda_%s = [\n",name));
607: for (i=0;i<pep->nconv;i++) {
608: k = pep->perm[i];
609: #if defined(PETSC_USE_COMPLEX)
610: re = PetscRealPart(pep->eigr[k]);
611: im = PetscImaginaryPart(pep->eigr[k]);
612: #else
613: re = pep->eigr[k];
614: im = pep->eigi[k];
615: #endif
616: if (im!=0.0) PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e%+18.16ei\n",(double)re,(double)im));
617: else PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double)re));
618: }
619: PetscCall(PetscViewerASCIIPrintf(viewer,"];\n"));
620: PetscFunctionReturn(PETSC_SUCCESS);
621: }
623: /*@
624: PEPValuesView - Displays the computed eigenvalues in a viewer.
626: Collective
628: Input Parameters:
629: + pep - the eigensolver context
630: - viewer - the viewer
632: Options Database Key:
633: . -pep_view_values - print computed eigenvalues
635: Level: intermediate
637: .seealso: PEPSolve(), PEPVectorsView(), PEPErrorView()
638: @*/
639: PetscErrorCode PEPValuesView(PEP pep,PetscViewer viewer)
640: {
641: PetscBool isascii,isdraw,isbinary;
642: PetscViewerFormat format;
643: #if defined(PETSC_HAVE_HDF5)
644: PetscBool ishdf5;
645: #endif
647: PetscFunctionBegin;
649: if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pep),&viewer));
651: PetscCheckSameComm(pep,1,viewer,2);
652: PEPCheckSolved(pep,1);
653: PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw));
654: PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
655: #if defined(PETSC_HAVE_HDF5)
656: PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5));
657: #endif
658: PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
659: if (isdraw) PetscCall(PEPValuesView_DRAW(pep,viewer));
660: else if (isbinary) PetscCall(PEPValuesView_BINARY(pep,viewer));
661: #if defined(PETSC_HAVE_HDF5)
662: else if (ishdf5) PetscCall(PEPValuesView_HDF5(pep,viewer));
663: #endif
664: else if (isascii) {
665: PetscCall(PetscViewerGetFormat(viewer,&format));
666: switch (format) {
667: case PETSC_VIEWER_DEFAULT:
668: case PETSC_VIEWER_ASCII_INFO:
669: case PETSC_VIEWER_ASCII_INFO_DETAIL:
670: PetscCall(PEPValuesView_ASCII(pep,viewer));
671: break;
672: case PETSC_VIEWER_ASCII_MATLAB:
673: PetscCall(PEPValuesView_MATLAB(pep,viewer));
674: break;
675: default:
676: PetscCall(PetscInfo(pep,"Unsupported viewer format %s\n",PetscViewerFormats[format]));
677: }
678: }
679: PetscFunctionReturn(PETSC_SUCCESS);
680: }
682: /*@
683: PEPValuesViewFromOptions - Processes command line options to determine if/how
684: the computed eigenvalues are to be viewed.
686: Collective
688: Input Parameter:
689: . pep - the eigensolver context
691: Level: developer
693: .seealso: PEPValuesView()
694: @*/
695: PetscErrorCode PEPValuesViewFromOptions(PEP pep)
696: {
697: PetscViewer viewer;
698: PetscBool flg;
699: static PetscBool incall = PETSC_FALSE;
700: PetscViewerFormat format;
702: PetscFunctionBegin;
703: if (incall) PetscFunctionReturn(PETSC_SUCCESS);
704: incall = PETSC_TRUE;
705: PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)pep),((PetscObject)pep)->options,((PetscObject)pep)->prefix,"-pep_view_values",&viewer,&format,&flg));
706: if (flg) {
707: PetscCall(PetscViewerPushFormat(viewer,format));
708: PetscCall(PEPValuesView(pep,viewer));
709: PetscCall(PetscViewerPopFormat(viewer));
710: PetscCall(PetscViewerDestroy(&viewer));
711: }
712: incall = PETSC_FALSE;
713: PetscFunctionReturn(PETSC_SUCCESS);
714: }
716: /*@
717: PEPVectorsView - Outputs computed eigenvectors to a viewer.
719: Collective
721: Input Parameters:
722: + pep - the eigensolver context
723: - viewer - the viewer
725: Options Database Key:
726: . -pep_view_vectors - output eigenvectors.
728: Note:
729: If PETSc was configured with real scalars, complex conjugate eigenvectors
730: will be viewed as two separate real vectors, one containing the real part
731: and another one containing the imaginary part.
733: Level: intermediate
735: .seealso: PEPSolve(), PEPValuesView(), PEPErrorView()
736: @*/
737: PetscErrorCode PEPVectorsView(PEP pep,PetscViewer viewer)
738: {
739: PetscInt i,k;
740: Vec xr,xi=NULL;
742: PetscFunctionBegin;
744: if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pep),&viewer));
746: PetscCheckSameComm(pep,1,viewer,2);
747: PEPCheckSolved(pep,1);
748: if (pep->nconv) {
749: PetscCall(PEPComputeVectors(pep));
750: PetscCall(BVCreateVec(pep->V,&xr));
751: #if !defined(PETSC_USE_COMPLEX)
752: PetscCall(BVCreateVec(pep->V,&xi));
753: #endif
754: for (i=0;i<pep->nconv;i++) {
755: k = pep->perm[i];
756: PetscCall(BV_GetEigenvector(pep->V,k,pep->eigi[k],xr,xi));
757: PetscCall(SlepcViewEigenvector(viewer,xr,xi,"X",i,(PetscObject)pep));
758: }
759: PetscCall(VecDestroy(&xr));
760: #if !defined(PETSC_USE_COMPLEX)
761: PetscCall(VecDestroy(&xi));
762: #endif
763: }
764: PetscFunctionReturn(PETSC_SUCCESS);
765: }
767: /*@
768: PEPVectorsViewFromOptions - Processes command line options to determine if/how
769: the computed eigenvectors are to be viewed.
771: Collective
773: Input Parameter:
774: . pep - the eigensolver context
776: Level: developer
778: .seealso: PEPVectorsView()
779: @*/
780: PetscErrorCode PEPVectorsViewFromOptions(PEP pep)
781: {
782: PetscViewer viewer;
783: PetscBool flg = PETSC_FALSE;
784: static PetscBool incall = PETSC_FALSE;
785: PetscViewerFormat format;
787: PetscFunctionBegin;
788: if (incall) PetscFunctionReturn(PETSC_SUCCESS);
789: incall = PETSC_TRUE;
790: PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)pep),((PetscObject)pep)->options,((PetscObject)pep)->prefix,"-pep_view_vectors",&viewer,&format,&flg));
791: if (flg) {
792: PetscCall(PetscViewerPushFormat(viewer,format));
793: PetscCall(PEPVectorsView(pep,viewer));
794: PetscCall(PetscViewerPopFormat(viewer));
795: PetscCall(PetscViewerDestroy(&viewer));
796: }
797: incall = PETSC_FALSE;
798: PetscFunctionReturn(PETSC_SUCCESS);
799: }