Actual source code: epsmon.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: EPS routines related to monitors
12: */
14: #include <slepc/private/epsimpl.h>
15: #include <petscdraw.h>
17: PetscErrorCode EPSMonitorLGCreate(MPI_Comm comm,const char host[],const char label[],const char metric[],PetscInt l,const char *names[],int x,int y,int m,int n,PetscDrawLG *lgctx)
18: {
19: PetscDraw draw;
20: PetscDrawAxis axis;
21: PetscDrawLG lg;
23: PetscFunctionBegin;
24: PetscCall(PetscDrawCreate(comm,host,label,x,y,m,n,&draw));
25: PetscCall(PetscDrawSetFromOptions(draw));
26: PetscCall(PetscDrawLGCreate(draw,l,&lg));
27: if (names) PetscCall(PetscDrawLGSetLegend(lg,names));
28: PetscCall(PetscDrawLGSetFromOptions(lg));
29: PetscCall(PetscDrawLGGetAxis(lg,&axis));
30: PetscCall(PetscDrawAxisSetLabels(axis,"Convergence","Iteration",metric));
31: PetscCall(PetscDrawDestroy(&draw));
32: *lgctx = lg;
33: PetscFunctionReturn(PETSC_SUCCESS);
34: }
36: /*
37: Runs the user provided monitor routines, if any.
38: */
39: PetscErrorCode EPSMonitor(EPS eps,PetscInt it,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest)
40: {
41: PetscInt i,n = eps->numbermonitors;
43: PetscFunctionBegin;
44: for (i=0;i<n;i++) PetscCall((*eps->monitor[i])(eps,it,nconv,eigr,eigi,errest,nest,eps->monitorcontext[i]));
45: PetscFunctionReturn(PETSC_SUCCESS);
46: }
48: /*@C
49: EPSMonitorSet - Sets an ADDITIONAL function to be called at every
50: iteration to monitor the error estimates for each requested eigenpair.
52: Logically Collective
54: Input Parameters:
55: + eps - eigensolver context obtained from EPSCreate()
56: . monitor - pointer to function (if this is NULL, it turns off monitoring)
57: . mctx - [optional] context for private data for the
58: monitor routine (use NULL if no context is desired)
59: - monitordestroy - [optional] routine that frees monitor context (may be NULL),
60: see PetscCtxDestroyFn for the calling sequence
62: Calling sequence of monitor:
63: $ PetscErrorCode monitor(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *mctx)
64: + eps - eigensolver context obtained from EPSCreate()
65: . its - iteration number
66: . nconv - number of converged eigenpairs
67: . eigr - real part of the eigenvalues
68: . eigi - imaginary part of the eigenvalues
69: . errest - relative error estimates for each eigenpair
70: . nest - number of error estimates
71: - mctx - optional monitoring context, as set by EPSMonitorSet()
73: Options Database Keys:
74: + -eps_monitor - print only the first error estimate
75: . -eps_monitor_all - print error estimates at each iteration
76: . -eps_monitor_conv - print the eigenvalue approximations only when
77: convergence has been reached
78: . -eps_monitor draw::draw_lg - sets line graph monitor for the first unconverged
79: approximate eigenvalue
80: . -eps_monitor_all draw::draw_lg - sets line graph monitor for all unconverged
81: approximate eigenvalues
82: . -eps_monitor_conv draw::draw_lg - sets line graph monitor for convergence history
83: - -eps_monitor_cancel - cancels all monitors that have been hardwired into
84: a code by calls to EPSMonitorSet(), but does not cancel those set via
85: the options database.
87: Notes:
88: Several different monitoring routines may be set by calling
89: EPSMonitorSet() multiple times; all will be called in the
90: order in which they were set.
92: Level: intermediate
94: .seealso: EPSMonitorFirst(), EPSMonitorAll(), EPSMonitorCancel()
95: @*/
96: PetscErrorCode EPSMonitorSet(EPS eps,PetscErrorCode (*monitor)(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *mctx),void *mctx,PetscCtxDestroyFn *monitordestroy)
97: {
98: PetscFunctionBegin;
100: PetscCheck(eps->numbermonitors<MAXEPSMONITORS,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Too many EPS monitors set");
101: eps->monitor[eps->numbermonitors] = monitor;
102: eps->monitorcontext[eps->numbermonitors] = (void*)mctx;
103: eps->monitordestroy[eps->numbermonitors++] = monitordestroy;
104: PetscFunctionReturn(PETSC_SUCCESS);
105: }
107: /*@
108: EPSMonitorCancel - Clears all monitors for an EPS object.
110: Logically Collective
112: Input Parameters:
113: . eps - eigensolver context obtained from EPSCreate()
115: Options Database Key:
116: . -eps_monitor_cancel - Cancels all monitors that have been hardwired
117: into a code by calls to EPSMonitorSet(),
118: but does not cancel those set via the options database.
120: Level: intermediate
122: .seealso: EPSMonitorSet()
123: @*/
124: PetscErrorCode EPSMonitorCancel(EPS eps)
125: {
126: PetscInt i;
128: PetscFunctionBegin;
130: for (i=0; i<eps->numbermonitors; i++) {
131: if (eps->monitordestroy[i]) PetscCall((*eps->monitordestroy[i])(&eps->monitorcontext[i]));
132: }
133: eps->numbermonitors = 0;
134: PetscFunctionReturn(PETSC_SUCCESS);
135: }
137: /*@C
138: EPSGetMonitorContext - Gets the monitor context, as set by
139: EPSMonitorSet() for the FIRST monitor only.
141: Not Collective
143: Input Parameter:
144: . eps - eigensolver context obtained from EPSCreate()
146: Output Parameter:
147: . ctx - monitor context
149: Level: intermediate
151: .seealso: EPSMonitorSet()
152: @*/
153: PetscErrorCode EPSGetMonitorContext(EPS eps,void *ctx)
154: {
155: PetscFunctionBegin;
157: *(void**)ctx = eps->monitorcontext[0];
158: PetscFunctionReturn(PETSC_SUCCESS);
159: }
161: static inline PetscErrorCode EPSMonitorPrintEval(EPS eps,PetscViewer viewer,PetscScalar er,PetscScalar ei)
162: {
163: PetscFunctionBegin;
164: if (eps->problem_type==EPS_HEP || eps->problem_type==EPS_GHEP || eps->problem_type==EPS_BSE) PetscCall(PetscViewerASCIIPrintf(viewer," %g",(double)PetscRealPart(er)));
165: else {
166: #if defined(PETSC_USE_COMPLEX)
167: PetscCall(PetscViewerASCIIPrintf(viewer," %g%+gi",(double)PetscRealPart(er),(double)PetscImaginaryPart(er)));
168: #else
169: PetscCall(PetscViewerASCIIPrintf(viewer," %g",(double)er));
170: if (ei!=0.0) PetscCall(PetscViewerASCIIPrintf(viewer,"%+gi",(double)ei));
171: #endif
172: }
173: PetscFunctionReturn(PETSC_SUCCESS);
174: }
176: /*@C
177: EPSMonitorFirst - Print the first unconverged approximate value and
178: error estimate at each iteration of the eigensolver.
180: Collective
182: Input Parameters:
183: + eps - eigensolver context
184: . its - iteration number
185: . nconv - number of converged eigenpairs so far
186: . eigr - real part of the eigenvalues
187: . eigi - imaginary part of the eigenvalues
188: . errest - error estimates
189: . nest - number of error estimates to display
190: - vf - viewer and format for monitoring
192: Options Database Key:
193: . -eps_monitor - activates EPSMonitorFirst()
195: Level: intermediate
197: .seealso: EPSMonitorSet(), EPSMonitorAll(), EPSMonitorConverged()
198: @*/
199: PetscErrorCode EPSMonitorFirst(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
200: {
201: PetscScalar er,ei;
202: PetscViewer viewer = vf->viewer;
204: PetscFunctionBegin;
207: if (its==1 && ((PetscObject)eps)->prefix) PetscCall(PetscViewerASCIIPrintf(viewer," Eigenvalue approximations and residual norms for %s solve.\n",((PetscObject)eps)->prefix));
208: if (nconv<nest) {
209: PetscCall(PetscViewerPushFormat(viewer,vf->format));
210: PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)eps)->tablevel));
211: PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " EPS nconv=%" PetscInt_FMT " first unconverged value (error)",its,nconv));
212: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
213: er = eigr[nconv]; ei = eigi[nconv];
214: PetscCall(STBackTransform(eps->st,1,&er,&ei));
215: PetscCall(EPSMonitorPrintEval(eps,viewer,er,ei));
216: PetscCall(PetscViewerASCIIPrintf(viewer," (%10.8e)\n",(double)errest[nconv]));
217: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
218: PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)eps)->tablevel));
219: PetscCall(PetscViewerPopFormat(viewer));
220: }
221: PetscFunctionReturn(PETSC_SUCCESS);
222: }
224: /*@C
225: EPSMonitorAll - Print the current approximate values and
226: error estimates at each iteration of the eigensolver.
228: Collective
230: Input Parameters:
231: + eps - eigensolver context
232: . its - iteration number
233: . nconv - number of converged eigenpairs so far
234: . eigr - real part of the eigenvalues
235: . eigi - imaginary part of the eigenvalues
236: . errest - error estimates
237: . nest - number of error estimates to display
238: - vf - viewer and format for monitoring
240: Options Database Key:
241: . -eps_monitor_all - activates EPSMonitorAll()
243: Level: intermediate
245: .seealso: EPSMonitorSet(), EPSMonitorFirst(), EPSMonitorConverged()
246: @*/
247: PetscErrorCode EPSMonitorAll(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
248: {
249: PetscInt i;
250: PetscScalar er,ei;
251: PetscViewer viewer = vf->viewer;
253: PetscFunctionBegin;
256: PetscCall(PetscViewerPushFormat(viewer,vf->format));
257: PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)eps)->tablevel));
258: if (its==1 && ((PetscObject)eps)->prefix) PetscCall(PetscViewerASCIIPrintf(viewer," Eigenvalue approximations and residual norms for %s solve.\n",((PetscObject)eps)->prefix));
259: PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " EPS nconv=%" PetscInt_FMT " Values (Errors)",its,nconv));
260: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
261: for (i=0;i<nest;i++) {
262: er = eigr[i]; ei = eigi[i];
263: PetscCall(STBackTransform(eps->st,1,&er,&ei));
264: PetscCall(EPSMonitorPrintEval(eps,viewer,er,ei));
265: PetscCall(PetscViewerASCIIPrintf(viewer," (%10.8e)",(double)errest[i]));
266: }
267: PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
268: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
269: PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)eps)->tablevel));
270: PetscCall(PetscViewerPopFormat(viewer));
271: PetscFunctionReturn(PETSC_SUCCESS);
272: }
274: /*@C
275: EPSMonitorConverged - Print the approximate values and
276: error estimates as they converge.
278: Collective
280: Input Parameters:
281: + eps - eigensolver context
282: . its - iteration number
283: . nconv - number of converged eigenpairs so far
284: . eigr - real part of the eigenvalues
285: . eigi - imaginary part of the eigenvalues
286: . errest - error estimates
287: . nest - number of error estimates to display
288: - vf - viewer and format for monitoring
290: Options Database Key:
291: . -eps_monitor_conv - activates EPSMonitorConverged()
293: Level: intermediate
295: .seealso: EPSMonitorSet(), EPSMonitorFirst(), EPSMonitorAll()
296: @*/
297: PetscErrorCode EPSMonitorConverged(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
298: {
299: PetscInt i;
300: PetscScalar er,ei;
301: PetscViewer viewer = vf->viewer;
302: SlepcConvMon ctx;
304: PetscFunctionBegin;
307: ctx = (SlepcConvMon)vf->data;
308: if (its==1 && ((PetscObject)eps)->prefix) PetscCall(PetscViewerASCIIPrintf(viewer," Convergence history for %s solve.\n",((PetscObject)eps)->prefix));
309: if (its==1) ctx->oldnconv = 0;
310: if (ctx->oldnconv!=nconv) {
311: PetscCall(PetscViewerPushFormat(viewer,vf->format));
312: PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)eps)->tablevel));
313: for (i=ctx->oldnconv;i<nconv;i++) {
314: PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " EPS converged value (error) #%" PetscInt_FMT,its,i));
315: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
316: er = eigr[i]; ei = eigi[i];
317: PetscCall(STBackTransform(eps->st,1,&er,&ei));
318: PetscCall(EPSMonitorPrintEval(eps,viewer,er,ei));
319: PetscCall(PetscViewerASCIIPrintf(viewer," (%10.8e)\n",(double)errest[i]));
320: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
321: }
322: PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)eps)->tablevel));
323: PetscCall(PetscViewerPopFormat(viewer));
324: ctx->oldnconv = nconv;
325: }
326: PetscFunctionReturn(PETSC_SUCCESS);
327: }
329: PetscErrorCode EPSMonitorConvergedCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
330: {
331: SlepcConvMon mctx;
333: PetscFunctionBegin;
334: PetscCall(PetscViewerAndFormatCreate(viewer,format,vf));
335: PetscCall(PetscNew(&mctx));
336: mctx->ctx = ctx;
337: (*vf)->data = (void*)mctx;
338: PetscFunctionReturn(PETSC_SUCCESS);
339: }
341: PetscErrorCode EPSMonitorConvergedDestroy(PetscViewerAndFormat **vf)
342: {
343: PetscFunctionBegin;
344: if (!*vf) PetscFunctionReturn(PETSC_SUCCESS);
345: PetscCall(PetscFree((*vf)->data));
346: PetscCall(PetscViewerDestroy(&(*vf)->viewer));
347: PetscCall(PetscDrawLGDestroy(&(*vf)->lg));
348: PetscCall(PetscFree(*vf));
349: PetscFunctionReturn(PETSC_SUCCESS);
350: }
352: /*@C
353: EPSMonitorFirstDrawLG - Plots the error estimate of the first unconverged
354: approximation at each iteration of the eigensolver.
356: Collective
358: Input Parameters:
359: + eps - eigensolver context
360: . its - iteration number
361: . nconv - number of converged eigenpairs so far
362: . eigr - real part of the eigenvalues
363: . eigi - imaginary part of the eigenvalues
364: . errest - error estimates
365: . nest - number of error estimates to display
366: - vf - viewer and format for monitoring
368: Options Database Key:
369: . -eps_monitor draw::draw_lg - activates EPSMonitorFirstDrawLG()
371: Level: intermediate
373: .seealso: EPSMonitorSet()
374: @*/
375: PetscErrorCode EPSMonitorFirstDrawLG(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
376: {
377: PetscViewer viewer = vf->viewer;
378: PetscDrawLG lg = vf->lg;
379: PetscReal x,y;
381: PetscFunctionBegin;
385: PetscCall(PetscViewerPushFormat(viewer,vf->format));
386: if (its==1) {
387: PetscCall(PetscDrawLGReset(lg));
388: PetscCall(PetscDrawLGSetDimension(lg,1));
389: PetscCall(PetscDrawLGSetLimits(lg,1,1,PetscLog10Real(eps->tol)-2,0.0));
390: }
391: if (nconv<nest) {
392: x = (PetscReal)its;
393: if (errest[nconv] > 0.0) y = PetscLog10Real(errest[nconv]);
394: else y = 0.0;
395: PetscCall(PetscDrawLGAddPoint(lg,&x,&y));
396: if (its <= 20 || !(its % 5) || eps->reason) {
397: PetscCall(PetscDrawLGDraw(lg));
398: PetscCall(PetscDrawLGSave(lg));
399: }
400: }
401: PetscCall(PetscViewerPopFormat(viewer));
402: PetscFunctionReturn(PETSC_SUCCESS);
403: }
405: /*@C
406: EPSMonitorFirstDrawLGCreate - Creates the plotter for the first error estimate.
408: Collective
410: Input Parameters:
411: + viewer - the viewer
412: . format - the viewer format
413: - ctx - an optional user context
415: Output Parameter:
416: . vf - the viewer and format context
418: Level: intermediate
420: .seealso: EPSMonitorSet()
421: @*/
422: PetscErrorCode EPSMonitorFirstDrawLGCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
423: {
424: PetscFunctionBegin;
425: PetscCall(PetscViewerAndFormatCreate(viewer,format,vf));
426: (*vf)->data = ctx;
427: PetscCall(EPSMonitorLGCreate(PetscObjectComm((PetscObject)viewer),NULL,"First Error Estimate","Log Error Estimate",1,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&(*vf)->lg));
428: PetscFunctionReturn(PETSC_SUCCESS);
429: }
431: /*@C
432: EPSMonitorAllDrawLG - Plots the error estimate of all unconverged
433: approximations at each iteration of the eigensolver.
435: Collective
437: Input Parameters:
438: + eps - eigensolver context
439: . its - iteration number
440: . nconv - number of converged eigenpairs so far
441: . eigr - real part of the eigenvalues
442: . eigi - imaginary part of the eigenvalues
443: . errest - error estimates
444: . nest - number of error estimates to display
445: - vf - viewer and format for monitoring
447: Options Database Key:
448: . -eps_monitor_all draw::draw_lg - activates EPSMonitorAllDrawLG()
450: Level: intermediate
452: .seealso: EPSMonitorSet()
453: @*/
454: PetscErrorCode EPSMonitorAllDrawLG(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
455: {
456: PetscViewer viewer = vf->viewer;
457: PetscDrawLG lg = vf->lg;
458: PetscInt i,n = PetscMin(eps->nev,255);
459: PetscReal *x,*y;
461: PetscFunctionBegin;
465: PetscCall(PetscViewerPushFormat(viewer,vf->format));
466: if (its==1) {
467: PetscCall(PetscDrawLGReset(lg));
468: PetscCall(PetscDrawLGSetDimension(lg,n));
469: PetscCall(PetscDrawLGSetLimits(lg,1,1,PetscLog10Real(eps->tol)-2,0.0));
470: }
471: PetscCall(PetscMalloc2(n,&x,n,&y));
472: for (i=0;i<n;i++) {
473: x[i] = (PetscReal)its;
474: if (i < nest && errest[i] > 0.0) y[i] = PetscLog10Real(errest[i]);
475: else y[i] = 0.0;
476: }
477: PetscCall(PetscDrawLGAddPoint(lg,x,y));
478: if (its <= 20 || !(its % 5) || eps->reason) {
479: PetscCall(PetscDrawLGDraw(lg));
480: PetscCall(PetscDrawLGSave(lg));
481: }
482: PetscCall(PetscFree2(x,y));
483: PetscCall(PetscViewerPopFormat(viewer));
484: PetscFunctionReturn(PETSC_SUCCESS);
485: }
487: /*@C
488: EPSMonitorAllDrawLGCreate - Creates the plotter for all the error estimates.
490: Collective
492: Input Parameters:
493: + viewer - the viewer
494: . format - the viewer format
495: - ctx - an optional user context
497: Output Parameter:
498: . vf - the viewer and format context
500: Level: intermediate
502: .seealso: EPSMonitorSet()
503: @*/
504: PetscErrorCode EPSMonitorAllDrawLGCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
505: {
506: PetscFunctionBegin;
507: PetscCall(PetscViewerAndFormatCreate(viewer,format,vf));
508: (*vf)->data = ctx;
509: PetscCall(EPSMonitorLGCreate(PetscObjectComm((PetscObject)viewer),NULL,"All Error Estimates","Log Error Estimate",1,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&(*vf)->lg));
510: PetscFunctionReturn(PETSC_SUCCESS);
511: }
513: /*@C
514: EPSMonitorConvergedDrawLG - Plots the number of converged eigenvalues
515: at each iteration of the eigensolver.
517: Collective
519: Input Parameters:
520: + eps - eigensolver context
521: . its - iteration number
522: . nconv - number of converged eigenpairs so far
523: . eigr - real part of the eigenvalues
524: . eigi - imaginary part of the eigenvalues
525: . errest - error estimates
526: . nest - number of error estimates to display
527: - vf - viewer and format for monitoring
529: Options Database Key:
530: . -eps_monitor_conv draw::draw_lg - activates EPSMonitorConvergedDrawLG()
532: Level: intermediate
534: .seealso: EPSMonitorSet()
535: @*/
536: PetscErrorCode EPSMonitorConvergedDrawLG(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
537: {
538: PetscViewer viewer = vf->viewer;
539: PetscDrawLG lg = vf->lg;
540: PetscReal x,y;
542: PetscFunctionBegin;
546: PetscCall(PetscViewerPushFormat(viewer,vf->format));
547: if (its==1) {
548: PetscCall(PetscDrawLGReset(lg));
549: PetscCall(PetscDrawLGSetDimension(lg,1));
550: PetscCall(PetscDrawLGSetLimits(lg,1,1,0,eps->nev));
551: }
552: x = (PetscReal)its;
553: y = (PetscReal)eps->nconv;
554: PetscCall(PetscDrawLGAddPoint(lg,&x,&y));
555: if (its <= 20 || !(its % 5) || eps->reason) {
556: PetscCall(PetscDrawLGDraw(lg));
557: PetscCall(PetscDrawLGSave(lg));
558: }
559: PetscCall(PetscViewerPopFormat(viewer));
560: PetscFunctionReturn(PETSC_SUCCESS);
561: }
563: /*@C
564: EPSMonitorConvergedDrawLGCreate - Creates the plotter for the convergence history.
566: Collective
568: Input Parameters:
569: + viewer - the viewer
570: . format - the viewer format
571: - ctx - an optional user context
573: Output Parameter:
574: . vf - the viewer and format context
576: Level: intermediate
578: .seealso: EPSMonitorSet()
579: @*/
580: PetscErrorCode EPSMonitorConvergedDrawLGCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
581: {
582: SlepcConvMon mctx;
584: PetscFunctionBegin;
585: PetscCall(PetscViewerAndFormatCreate(viewer,format,vf));
586: PetscCall(PetscNew(&mctx));
587: mctx->ctx = ctx;
588: (*vf)->data = (void*)mctx;
589: PetscCall(EPSMonitorLGCreate(PetscObjectComm((PetscObject)viewer),NULL,"Convergence History","Number Converged",1,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&(*vf)->lg));
590: PetscFunctionReturn(PETSC_SUCCESS);
591: }