Actual source code: epsmon.c

slepc-main 2024-12-17
Report Typos and Errors
  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: }