Actual source code: nepmon.c
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: NEP routines related to monitors
12: */
14: #include <slepc/private/nepimpl.h>
15: #include <petscdraw.h>
17: /*
18: Runs the user provided monitor routines, if any.
19: */
20: PetscErrorCode NEPMonitor(NEP nep,PetscInt it,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest)
21: {
22: PetscInt i,n = nep->numbermonitors;
24: PetscFunctionBegin;
25: for (i=0;i<n;i++) PetscCall((*nep->monitor[i])(nep,it,nconv,eigr,eigi,errest,nest,nep->monitorcontext[i]));
26: PetscFunctionReturn(PETSC_SUCCESS);
27: }
29: /*@C
30: NEPMonitorSet - Sets an ADDITIONAL function to be called at every
31: iteration to monitor the error estimates for each requested eigenpair.
33: Logically Collective
35: Input Parameters:
36: + nep - the nonlinear eigensolver context
37: . monitor - pointer to function (if this is `NULL`, it turns off monitoring),
38: see `NEPMonitorFn`
39: . mctx - [optional] context for private data for the monitor routine
40: (use `NULL` if no context is desired)
41: - monitordestroy - [optional] routine that frees monitor context (may be `NULL`),
42: see `PetscCtxDestroyFn` for the calling sequence
44: Options Database Keys:
45: + -nep_monitor - print only the first error estimate
46: . -nep_monitor_all - print error estimates at each iteration
47: . -nep_monitor_conv - print the eigenvalue approximations only when
48: convergence has been reached
49: . -nep_monitor draw::draw_lg - sets line graph monitor for the first unconverged
50: approximate eigenvalue
51: . -nep_monitor_all draw::draw_lg - sets line graph monitor for all unconverged
52: approximate eigenvalues
53: . -nep_monitor_conv draw::draw_lg - sets line graph monitor for convergence history
54: - -nep_monitor_cancel - cancels all monitors that have been hardwired into
55: a code by calls to `NEPMonitorSet()`, but does not cancel
56: those set via the options database.
58: Notes:
59: The options database option `-nep_monitor` and related options are the easiest way
60: to turn on `NEP` iteration monitoring.
62: `NEPMonitorRegister()` provides a way to associate an options database key with `NEP`
63: monitor function.
65: Several different monitoring routines may be set by calling `NEPMonitorSet()` multiple
66: times; all will be called in the order in which they were set.
68: Fortran Note:
69: Only a single monitor function can be set for each `NEP` object.
71: Level: intermediate
73: .seealso: [](ch:nep), `NEPMonitorFirst()`, `NEPMonitorAll()`, `NEPMonitorConverged()`, `NEPMonitorFirstDrawLG()`, `NEPMonitorAllDrawLG()`, `NEPMonitorConvergedDrawLG()`, `NEPMonitorCancel()`
74: @*/
75: PetscErrorCode NEPMonitorSet(NEP nep,NEPMonitorFn *monitor,void *mctx,PetscCtxDestroyFn *monitordestroy)
76: {
77: PetscInt i;
78: PetscBool identical;
80: PetscFunctionBegin;
82: for (i=0;i<nep->numbermonitors;i++) {
83: PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))(PetscVoidFn*)monitor,mctx,monitordestroy,(PetscErrorCode (*)(void))(PetscVoidFn*)nep->monitor[i],nep->monitorcontext[i],nep->monitordestroy[i],&identical));
84: if (identical) PetscFunctionReturn(PETSC_SUCCESS);
85: }
86: PetscCheck(nep->numbermonitors<MAXNEPMONITORS,PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_OUTOFRANGE,"Too many NEP monitors set");
87: nep->monitor[nep->numbermonitors] = monitor;
88: nep->monitorcontext[nep->numbermonitors] = mctx;
89: nep->monitordestroy[nep->numbermonitors++] = monitordestroy;
90: PetscFunctionReturn(PETSC_SUCCESS);
91: }
93: /*@
94: NEPMonitorCancel - Clears all monitors for a `NEP` object.
96: Logically Collective
98: Input Parameter:
99: . nep - the nonlinear eigensolver context
101: Options Database Key:
102: . -nep_monitor_cancel - cancels all monitors that have been hardwired into a code by calls to
103: `NEPMonitorSet()`, but does not cancel those set via the options database.
105: Level: intermediate
107: .seealso: [](ch:nep), `NEPMonitorSet()`
108: @*/
109: PetscErrorCode NEPMonitorCancel(NEP nep)
110: {
111: PetscInt i;
113: PetscFunctionBegin;
115: for (i=0; i<nep->numbermonitors; i++) {
116: if (nep->monitordestroy[i]) PetscCall((*nep->monitordestroy[i])(&nep->monitorcontext[i]));
117: }
118: nep->numbermonitors = 0;
119: PetscFunctionReturn(PETSC_SUCCESS);
120: }
122: /*@C
123: NEPGetMonitorContext - Gets the monitor context, as set by
124: `NEPMonitorSet()` for the FIRST monitor only.
126: Not Collective
128: Input Parameter:
129: . nep - the nonlinear eigensolver context
131: Output Parameter:
132: . ctx - monitor context
134: Level: intermediate
136: .seealso: [](ch:nep), `NEPMonitorSet()`
137: @*/
138: PetscErrorCode NEPGetMonitorContext(NEP nep,void *ctx)
139: {
140: PetscFunctionBegin;
142: *(void**)ctx = nep->monitorcontext[0];
143: PetscFunctionReturn(PETSC_SUCCESS);
144: }
146: /*@C
147: NEPMonitorFirst - Print the first unconverged approximate value and
148: error estimate at each iteration of the nonlinear eigensolver.
150: Collective
152: Input Parameters:
153: + nep - the nonlinear eigensolver context
154: . its - iteration number
155: . nconv - number of converged eigenpairs so far
156: . eigr - real part of the eigenvalues
157: . eigi - imaginary part of the eigenvalues
158: . errest - error estimates
159: . nest - number of error estimates to display
160: - vf - viewer and format for monitoring
162: Options Database Key:
163: . -nep_monitor - activates `NEPMonitorFirst()`
165: Note:
166: This is not called directly by users, rather one calls `NEPMonitorSet()`, with this
167: function as an argument, to cause the monitor to be used during the `NEP` solve.
169: Level: intermediate
171: .seealso: [](ch:nep), `NEPMonitorSet()`, `NEPMonitorAll()`, `NEPMonitorConverged()`
172: @*/
173: PetscErrorCode NEPMonitorFirst(NEP nep,PetscInt its,PetscInt nconv,PetscScalar eigr[],PetscScalar eigi[],PetscReal errest[],PetscInt nest,PetscViewerAndFormat *vf)
174: {
175: PetscViewer viewer = vf->viewer;
177: PetscFunctionBegin;
180: if (its==1 && ((PetscObject)nep)->prefix) PetscCall(PetscViewerASCIIPrintf(viewer," Eigenvalue approximations and residual norms for %s solve.\n",((PetscObject)nep)->prefix));
181: if (nconv<nest) {
182: PetscCall(PetscViewerPushFormat(viewer,vf->format));
183: PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)nep)->tablevel));
184: PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " NEP nconv=%" PetscInt_FMT " first unconverged value (error)",its,nconv));
185: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
186: #if defined(PETSC_USE_COMPLEX)
187: PetscCall(PetscViewerASCIIPrintf(viewer," %g%+gi",(double)PetscRealPart(eigr[nconv]),(double)PetscImaginaryPart(eigr[nconv])));
188: #else
189: PetscCall(PetscViewerASCIIPrintf(viewer," %g",(double)eigr[nconv]));
190: if (eigi[nconv]!=0.0) PetscCall(PetscViewerASCIIPrintf(viewer,"%+gi",(double)eigi[nconv]));
191: #endif
192: PetscCall(PetscViewerASCIIPrintf(viewer," (%10.8e)\n",(double)errest[nconv]));
193: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
194: PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)nep)->tablevel));
195: PetscCall(PetscViewerPopFormat(viewer));
196: }
197: PetscFunctionReturn(PETSC_SUCCESS);
198: }
200: /*@C
201: NEPMonitorAll - Print the current approximate values and
202: error estimates at each iteration of the nonlinear eigensolver.
204: Collective
206: Input Parameters:
207: + nep - the nonlinear eigensolver context
208: . its - iteration number
209: . nconv - number of converged eigenpairs so far
210: . eigr - real part of the eigenvalues
211: . eigi - imaginary part of the eigenvalues
212: . errest - error estimates
213: . nest - number of error estimates to display
214: - vf - viewer and format for monitoring
216: Options Database Key:
217: . -nep_monitor_all - activates `NEPMonitorAll()`
219: Note:
220: This is not called directly by users, rather one calls `NEPMonitorSet()`, with this
221: function as an argument, to cause the monitor to be used during the `NEP` solve.
223: Level: intermediate
225: .seealso: [](ch:nep), `NEPMonitorSet()`, `NEPMonitorFirst()`, `NEPMonitorConverged()`
226: @*/
227: PetscErrorCode NEPMonitorAll(NEP nep,PetscInt its,PetscInt nconv,PetscScalar eigr[],PetscScalar eigi[],PetscReal errest[],PetscInt nest,PetscViewerAndFormat *vf)
228: {
229: PetscInt i;
230: PetscViewer viewer = vf->viewer;
232: PetscFunctionBegin;
235: PetscCall(PetscViewerPushFormat(viewer,vf->format));
236: PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)nep)->tablevel));
237: if (its==1 && ((PetscObject)nep)->prefix) PetscCall(PetscViewerASCIIPrintf(viewer," Eigenvalue approximations and residual norms for %s solve.\n",((PetscObject)nep)->prefix));
238: PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " NEP nconv=%" PetscInt_FMT " Values (Errors)",its,nconv));
239: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
240: for (i=0;i<nest;i++) {
241: #if defined(PETSC_USE_COMPLEX)
242: PetscCall(PetscViewerASCIIPrintf(viewer," %g%+gi",(double)PetscRealPart(eigr[i]),(double)PetscImaginaryPart(eigr[i])));
243: #else
244: PetscCall(PetscViewerASCIIPrintf(viewer," %g",(double)eigr[i]));
245: if (eigi[i]!=0.0) PetscCall(PetscViewerASCIIPrintf(viewer,"%+gi",(double)eigi[i]));
246: #endif
247: PetscCall(PetscViewerASCIIPrintf(viewer," (%10.8e)",(double)errest[i]));
248: }
249: PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
250: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
251: PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)nep)->tablevel));
252: PetscCall(PetscViewerPopFormat(viewer));
253: PetscFunctionReturn(PETSC_SUCCESS);
254: }
256: /*@C
257: NEPMonitorConverged - Print the approximate values and
258: error estimates as they converge.
260: Collective
262: Input Parameters:
263: + nep - the nonlinear eigensolver context
264: . its - iteration number
265: . nconv - number of converged eigenpairs so far
266: . eigr - real part of the eigenvalues
267: . eigi - imaginary part of the eigenvalues
268: . errest - error estimates
269: . nest - number of error estimates to display
270: - vf - viewer and format for monitoring
272: Options Database Key:
273: . -nep_monitor_conv - activates `NEPMonitorConverged()`
275: Note:
276: This is not called directly by users, rather one calls `NEPMonitorSet()`, with this
277: function as an argument, to cause the monitor to be used during the `NEP` solve.
279: Level: intermediate
281: .seealso: [](ch:nep), `NEPMonitorSet()`, `NEPMonitorFirst()`, `NEPMonitorAll()`
282: @*/
283: PetscErrorCode NEPMonitorConverged(NEP nep,PetscInt its,PetscInt nconv,PetscScalar eigr[],PetscScalar eigi[],PetscReal errest[],PetscInt nest,PetscViewerAndFormat *vf)
284: {
285: PetscInt i;
286: PetscViewer viewer = vf->viewer;
287: SlepcConvMon ctx;
289: PetscFunctionBegin;
292: ctx = (SlepcConvMon)vf->data;
293: if (its==1 && ((PetscObject)nep)->prefix) PetscCall(PetscViewerASCIIPrintf(viewer," Convergence history for %s solve.\n",((PetscObject)nep)->prefix));
294: if (its==1) ctx->oldnconv = 0;
295: if (ctx->oldnconv!=nconv) {
296: PetscCall(PetscViewerPushFormat(viewer,vf->format));
297: PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)nep)->tablevel));
298: for (i=ctx->oldnconv;i<nconv;i++) {
299: PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " NEP converged value (error) #%" PetscInt_FMT,its,i));
300: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
301: #if defined(PETSC_USE_COMPLEX)
302: PetscCall(PetscViewerASCIIPrintf(viewer," %g%+gi",(double)PetscRealPart(eigr[i]),(double)PetscImaginaryPart(eigr[i])));
303: #else
304: PetscCall(PetscViewerASCIIPrintf(viewer," %g",(double)eigr[i]));
305: if (eigi[i]!=0.0) PetscCall(PetscViewerASCIIPrintf(viewer,"%+gi",(double)eigi[i]));
306: #endif
307: PetscCall(PetscViewerASCIIPrintf(viewer," (%10.8e)\n",(double)errest[i]));
308: PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
309: }
310: PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)nep)->tablevel));
311: PetscCall(PetscViewerPopFormat(viewer));
312: ctx->oldnconv = nconv;
313: }
314: PetscFunctionReturn(PETSC_SUCCESS);
315: }
317: PetscErrorCode NEPMonitorConvergedCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
318: {
319: SlepcConvMon mctx;
321: PetscFunctionBegin;
322: PetscCall(PetscViewerAndFormatCreate(viewer,format,vf));
323: PetscCall(PetscNew(&mctx));
324: mctx->ctx = ctx;
325: (*vf)->data = (void*)mctx;
326: PetscFunctionReturn(PETSC_SUCCESS);
327: }
329: PetscErrorCode NEPMonitorConvergedDestroy(PetscViewerAndFormat **vf)
330: {
331: PetscFunctionBegin;
332: if (!*vf) PetscFunctionReturn(PETSC_SUCCESS);
333: PetscCall(PetscFree((*vf)->data));
334: PetscCall(PetscViewerDestroy(&(*vf)->viewer));
335: PetscCall(PetscFree(*vf));
336: PetscFunctionReturn(PETSC_SUCCESS);
337: }
339: /*@C
340: NEPMonitorFirstDrawLG - Plots the error estimate of the first unconverged
341: approximation at each iteration of the nonlinear eigensolver.
343: Collective
345: Input Parameters:
346: + nep - the nonlinear eigensolver context
347: . its - iteration number
348: . nconv - number of converged eigenpairs so far
349: . eigr - real part of the eigenvalues
350: . eigi - imaginary part of the eigenvalues
351: . errest - error estimates
352: . nest - number of error estimates to display
353: - vf - viewer and format for monitoring
355: Options Database Key:
356: . -nep_monitor draw::draw_lg - activates `NEPMonitorFirstDrawLG()`
358: Notes:
359: This is not called directly by users, rather one calls `NEPMonitorSet()`, with this
360: function as an argument, to cause the monitor to be used during the `NEP` solve.
362: Call `NEPMonitorFirstDrawLGCreate()` to create the context used with this monitor.
364: Level: intermediate
366: .seealso: [](ch:nep), `NEPMonitorSet()`, `NEPMonitorFirstDrawLGCreate()`
367: @*/
368: PetscErrorCode NEPMonitorFirstDrawLG(NEP nep,PetscInt its,PetscInt nconv,PetscScalar eigr[],PetscScalar eigi[],PetscReal errest[],PetscInt nest,PetscViewerAndFormat *vf)
369: {
370: PetscViewer viewer = vf->viewer;
371: PetscDrawLG lg;
372: PetscReal x,y;
374: PetscFunctionBegin;
377: PetscCall(PetscViewerPushFormat(viewer,vf->format));
378: PetscCall(PetscViewerDrawGetDrawLG(viewer,0,&lg));
379: if (its==1) {
380: PetscCall(PetscDrawLGReset(lg));
381: PetscCall(PetscDrawLGSetDimension(lg,1));
382: PetscCall(PetscDrawLGSetLimits(lg,1,1,PetscLog10Real(nep->tol)-2,0.0));
383: }
384: if (nconv<nest) {
385: x = (PetscReal)its;
386: if (errest[nconv] > 0.0) y = PetscLog10Real(errest[nconv]);
387: else y = 0.0;
388: PetscCall(PetscDrawLGAddPoint(lg,&x,&y));
389: if (its <= 20 || !(its % 5) || nep->reason) {
390: PetscCall(PetscDrawLGDraw(lg));
391: PetscCall(PetscDrawLGSave(lg));
392: }
393: }
394: PetscCall(PetscViewerPopFormat(viewer));
395: PetscFunctionReturn(PETSC_SUCCESS);
396: }
398: /*@C
399: NEPMonitorFirstDrawLGCreate - Creates the plotter for the first error estimate.
401: Collective
403: Input Parameters:
404: + viewer - the viewer
405: . format - the viewer format
406: - ctx - an optional user context
408: Output Parameter:
409: . vf - the viewer and format context
411: Level: intermediate
413: .seealso: [](ch:nep), `NEPMonitorSet()`
414: @*/
415: PetscErrorCode NEPMonitorFirstDrawLGCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
416: {
417: PetscFunctionBegin;
418: PetscCall(PetscViewerAndFormatCreate(viewer,format,vf));
419: (*vf)->data = ctx;
420: PetscCall(PetscViewerMonitorLGSetUp(viewer,NULL,"First Error Estimate","Log Error Estimate",1,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300));
421: PetscFunctionReturn(PETSC_SUCCESS);
422: }
424: /*@C
425: NEPMonitorAllDrawLG - Plots the error estimate of all unconverged
426: approximations at each iteration of the nonlinear eigensolver.
428: Collective
430: Input Parameters:
431: + nep - the nonlinear eigensolver context
432: . its - iteration number
433: . nconv - number of converged eigenpairs so far
434: . eigr - real part of the eigenvalues
435: . eigi - imaginary part of the eigenvalues
436: . errest - error estimates
437: . nest - number of error estimates to display
438: - vf - viewer and format for monitoring
440: Options Database Key:
441: . -nep_monitor_all draw::draw_lg - activates `NEPMonitorAllDrawLG()`
443: Notes:
444: This is not called directly by users, rather one calls `NEPMonitorSet()`, with this
445: function as an argument, to cause the monitor to be used during the `NEP` solve.
447: Call `NEPMonitorAllDrawLGCreate()` to create the context used with this monitor.
449: Level: intermediate
451: .seealso: [](ch:nep), `NEPMonitorSet()`, `NEPMonitorAllDrawLGCreate()`
452: @*/
453: PetscErrorCode NEPMonitorAllDrawLG(NEP nep,PetscInt its,PetscInt nconv,PetscScalar eigr[],PetscScalar eigi[],PetscReal errest[],PetscInt nest,PetscViewerAndFormat *vf)
454: {
455: PetscViewer viewer = vf->viewer;
456: PetscDrawLG lg;
457: PetscInt i,n = PetscMin(nep->nev,255);
458: PetscReal *x,*y;
460: PetscFunctionBegin;
463: PetscCall(PetscViewerPushFormat(viewer,vf->format));
464: PetscCall(PetscViewerDrawGetDrawLG(viewer,0,&lg));
465: if (its==1) {
466: PetscCall(PetscDrawLGReset(lg));
467: PetscCall(PetscDrawLGSetDimension(lg,n));
468: PetscCall(PetscDrawLGSetLimits(lg,1,1,PetscLog10Real(nep->tol)-2,0.0));
469: }
470: PetscCall(PetscMalloc2(n,&x,n,&y));
471: for (i=0;i<n;i++) {
472: x[i] = (PetscReal)its;
473: if (i < nest && errest[i] > 0.0) y[i] = PetscLog10Real(errest[i]);
474: else y[i] = 0.0;
475: }
476: PetscCall(PetscDrawLGAddPoint(lg,x,y));
477: if (its <= 20 || !(its % 5) || nep->reason) {
478: PetscCall(PetscDrawLGDraw(lg));
479: PetscCall(PetscDrawLGSave(lg));
480: }
481: PetscCall(PetscFree2(x,y));
482: PetscCall(PetscViewerPopFormat(viewer));
483: PetscFunctionReturn(PETSC_SUCCESS);
484: }
486: /*@C
487: NEPMonitorAllDrawLGCreate - Creates the plotter for all the error estimates.
489: Collective
491: Input Parameters:
492: + viewer - the viewer
493: . format - the viewer format
494: - ctx - an optional user context
496: Output Parameter:
497: . vf - the viewer and format context
499: Level: intermediate
501: .seealso: [](ch:nep), `NEPMonitorSet()`
502: @*/
503: PetscErrorCode NEPMonitorAllDrawLGCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
504: {
505: PetscFunctionBegin;
506: PetscCall(PetscViewerAndFormatCreate(viewer,format,vf));
507: (*vf)->data = ctx;
508: PetscCall(PetscViewerMonitorLGSetUp(viewer,NULL,"All Error Estimates","Log Error Estimate",1,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300));
509: PetscFunctionReturn(PETSC_SUCCESS);
510: }
512: /*@C
513: NEPMonitorConvergedDrawLG - Plots the number of converged eigenvalues
514: at each iteration of the nonlinear eigensolver.
516: Collective
518: Input Parameters:
519: + nep - the nonlinear eigensolver context
520: . its - iteration number
521: . nconv - number of converged eigenpairs so far
522: . eigr - real part of the eigenvalues
523: . eigi - imaginary part of the eigenvalues
524: . errest - error estimates
525: . nest - number of error estimates to display
526: - vf - viewer and format for monitoring
528: Options Database Key:
529: . -nep_monitor_conv draw::draw_lg - activates `NEPMonitorConvergedDrawLG()`
531: Notes:
532: This is not called directly by users, rather one calls `NEPMonitorSet()`, with this
533: function as an argument, to cause the monitor to be used during the `NEP` solve.
535: Call `NEPMonitorConvergedDrawLGCreate()` to create the context used with this monitor.
537: Level: intermediate
539: .seealso: [](ch:nep), `NEPMonitorSet()`, `NEPMonitorConvergedDrawLGCreate()`
540: @*/
541: PetscErrorCode NEPMonitorConvergedDrawLG(NEP nep,PetscInt its,PetscInt nconv,PetscScalar eigr[],PetscScalar eigi[],PetscReal errest[],PetscInt nest,PetscViewerAndFormat *vf)
542: {
543: PetscViewer viewer = vf->viewer;
544: PetscDrawLG lg;
545: PetscReal x,y;
547: PetscFunctionBegin;
550: PetscCall(PetscViewerPushFormat(viewer,vf->format));
551: PetscCall(PetscViewerDrawGetDrawLG(viewer,0,&lg));
552: if (its==1) {
553: PetscCall(PetscDrawLGReset(lg));
554: PetscCall(PetscDrawLGSetDimension(lg,1));
555: PetscCall(PetscDrawLGSetLimits(lg,1,1,0,nep->nev));
556: }
557: x = (PetscReal)its;
558: y = (PetscReal)nep->nconv;
559: PetscCall(PetscDrawLGAddPoint(lg,&x,&y));
560: if (its <= 20 || !(its % 5) || nep->reason) {
561: PetscCall(PetscDrawLGDraw(lg));
562: PetscCall(PetscDrawLGSave(lg));
563: }
564: PetscCall(PetscViewerPopFormat(viewer));
565: PetscFunctionReturn(PETSC_SUCCESS);
566: }
568: /*@C
569: NEPMonitorConvergedDrawLGCreate - Creates the plotter for the convergence history.
571: Collective
573: Input Parameters:
574: + viewer - the viewer
575: . format - the viewer format
576: - ctx - an optional user context
578: Output Parameter:
579: . vf - the viewer and format context
581: Level: intermediate
583: .seealso: [](ch:nep), `NEPMonitorSet()`
584: @*/
585: PetscErrorCode NEPMonitorConvergedDrawLGCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
586: {
587: SlepcConvMon mctx;
589: PetscFunctionBegin;
590: PetscCall(PetscViewerAndFormatCreate(viewer,format,vf));
591: PetscCall(PetscNew(&mctx));
592: mctx->ctx = ctx;
593: (*vf)->data = (void*)mctx;
594: PetscCall(PetscViewerMonitorLGSetUp(viewer,NULL,"Convergence History","Number Converged",1,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300));
595: PetscFunctionReturn(PETSC_SUCCESS);
596: }