Date: 2022-10-01T06:40:33+00:00

Actual source code: nepmon.c
slepc-3.18.0 2022-10-01
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:    NEP routines related to monitors
     12: */

     14: #include <slepc/private/nepimpl.h>
     15: #include <petscdraw.h>

     17: PetscErrorCode NEPMonitorLGCreate(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:   PetscDrawCreate(comm,host,label,x,y,m,n,&draw);
     24:   PetscDrawSetFromOptions(draw);
     25:   PetscDrawLGCreate(draw,l,&lg);
     26:   if (names) PetscDrawLGSetLegend(lg,names);
     27:   PetscDrawLGSetFromOptions(lg);
     28:   PetscDrawLGGetAxis(lg,&axis);
     29:   PetscDrawAxisSetLabels(axis,"Convergence","Iteration",metric);
     30:   PetscDrawDestroy(&draw);
     31:   *lgctx = lg;
     32:   return 0;
     33: }

     35: /*
     36:    Runs the user provided monitor routines, if any.
     37: */
     38: PetscErrorCode NEPMonitor(NEP nep,PetscInt it,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest)
     39: {
     40:   PetscInt       i,n = nep->numbermonitors;

     42:   for (i=0;i<n;i++) (*nep->monitor[i])(nep,it,nconv,eigr,eigi,errest,nest,nep->monitorcontext[i]);
     43:   return 0;
     44: }

     46: /*@C
     47:    NEPMonitorSet - Sets an ADDITIONAL function to be called at every
     48:    iteration to monitor the error estimates for each requested eigenpair.

     50:    Logically Collective on nep

     52:    Input Parameters:
     53: +  nep     - eigensolver context obtained from NEPCreate()
     54: .  monitor - pointer to function (if this is NULL, it turns off monitoring)
     55: .  mctx    - [optional] context for private data for the
     56:              monitor routine (use NULL if no context is desired)
     57: -  monitordestroy - [optional] routine that frees monitor context (may be NULL)

     59:    Calling Sequence of monitor:
     60: $   monitor(NEP nep,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal* errest,PetscInt nest,void *mctx)

     62: +  nep    - nonlinear eigensolver context obtained from NEPCreate()
     63: .  its    - iteration number
     64: .  nconv  - number of converged eigenpairs
     65: .  eigr   - real part of the eigenvalues
     66: .  eigi   - imaginary part of the eigenvalues
     67: .  errest - error estimates for each eigenpair
     68: .  nest   - number of error estimates
     69: -  mctx   - optional monitoring context, as set by NEPMonitorSet()

     71:    Options Database Keys:
     72: +    -nep_monitor        - print only the first error estimate
     73: .    -nep_monitor_all    - print error estimates at each iteration
     74: .    -nep_monitor_conv   - print the eigenvalue approximations only when
     75:       convergence has been reached
     76: .    -nep_monitor draw::draw_lg - sets line graph monitor for the first unconverged
     77:       approximate eigenvalue
     78: .    -nep_monitor_all draw::draw_lg - sets line graph monitor for all unconverged
     79:       approximate eigenvalues
     80: .    -nep_monitor_conv draw::draw_lg - sets line graph monitor for convergence history
     81: -    -nep_monitor_cancel - cancels all monitors that have been hardwired into
     82:       a code by calls to NEPMonitorSet(), but does not cancel those set via
     83:       the options database.

     85:    Notes:
     86:    Several different monitoring routines may be set by calling
     87:    NEPMonitorSet() multiple times; all will be called in the
     88:    order in which they were set.

     90:    Level: intermediate

     92: .seealso: NEPMonitorFirst(), NEPMonitorAll(), NEPMonitorCancel()
     93: @*/
     94: PetscErrorCode NEPMonitorSet(NEP nep,PetscErrorCode (*monitor)(NEP,PetscInt,PetscInt,PetscScalar*,PetscScalar*,PetscReal*,PetscInt,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
     95: {
     98:   nep->monitor[nep->numbermonitors]           = monitor;
     99:   nep->monitorcontext[nep->numbermonitors]    = (void*)mctx;
    100:   nep->monitordestroy[nep->numbermonitors++]  = monitordestroy;
    101:   return 0;
    102: }

    104: /*@
    105:    NEPMonitorCancel - Clears all monitors for a NEP object.

    107:    Logically Collective on nep

    109:    Input Parameters:
    110: .  nep - eigensolver context obtained from NEPCreate()

    112:    Options Database Key:
    113: .    -nep_monitor_cancel - Cancels all monitors that have been hardwired
    114:       into a code by calls to NEPMonitorSet(),
    115:       but does not cancel those set via the options database.

    117:    Level: intermediate

    119: .seealso: NEPMonitorSet()
    120: @*/
    121: PetscErrorCode NEPMonitorCancel(NEP nep)
    122: {
    123:   PetscInt       i;

    126:   for (i=0; i<nep->numbermonitors; i++) {
    127:     if (nep->monitordestroy[i]) (*nep->monitordestroy[i])(&nep->monitorcontext[i]);
    128:   }
    129:   nep->numbermonitors = 0;
    130:   return 0;
    131: }

    133: /*@C
    134:    NEPGetMonitorContext - Gets the monitor context, as set by
    135:    NEPMonitorSet() for the FIRST monitor only.

    137:    Not Collective

    139:    Input Parameter:
    140: .  nep - eigensolver context obtained from NEPCreate()

    142:    Output Parameter:
    143: .  ctx - monitor context

    145:    Level: intermediate

    147: .seealso: NEPMonitorSet(), NEPDefaultMonitor()
    148: @*/
    149: PetscErrorCode NEPGetMonitorContext(NEP nep,void *ctx)
    150: {
    152:   *(void**)ctx = nep->monitorcontext[0];
    153:   return 0;
    154: }

    156: /*@C
    157:    NEPMonitorFirst - Print the first unconverged approximate value and
    158:    error estimate at each iteration of the nonlinear eigensolver.

    160:    Collective on nep

    162:    Input Parameters:
    163: +  nep    - nonlinear eigensolver context
    164: .  its    - iteration number
    165: .  nconv  - number of converged eigenpairs so far
    166: .  eigr   - real part of the eigenvalues
    167: .  eigi   - imaginary part of the eigenvalues
    168: .  errest - error estimates
    169: .  nest   - number of error estimates to display
    170: -  vf     - viewer and format for monitoring

    172:    Options Database Key:
    173: .  -nep_monitor - activates NEPMonitorFirst()

    175:    Level: intermediate

    177: .seealso: NEPMonitorSet(), NEPMonitorAll(), NEPMonitorConverged()
    178: @*/
    179: PetscErrorCode NEPMonitorFirst(NEP nep,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
    180: {
    181:   PetscViewer    viewer = vf->viewer;

    185:   if (its==1 && ((PetscObject)nep)->prefix) PetscViewerASCIIPrintf(viewer,"  Eigenvalue approximations and residual norms for %s solve.\n",((PetscObject)nep)->prefix);
    186:   if (nconv<nest) {
    187:     PetscViewerPushFormat(viewer,vf->format);
    188:     PetscViewerASCIIAddTab(viewer,((PetscObject)nep)->tablevel);
    189:     PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " NEP nconv=%" PetscInt_FMT " first unconverged value (error)",its,nconv);
    190:     PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);
    191: #if defined(PETSC_USE_COMPLEX)
    192:     PetscViewerASCIIPrintf(viewer," %g%+gi",(double)PetscRealPart(eigr[nconv]),(double)PetscImaginaryPart(eigr[nconv]));
    193: #else
    194:     PetscViewerASCIIPrintf(viewer," %g",(double)eigr[nconv]);
    195:     if (eigi[nconv]!=0.0) PetscViewerASCIIPrintf(viewer,"%+gi",(double)eigi[nconv]);
    196: #endif
    197:     PetscViewerASCIIPrintf(viewer," (%10.8e)\n",(double)errest[nconv]);
    198:     PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);
    199:     PetscViewerASCIISubtractTab(viewer,((PetscObject)nep)->tablevel);
    200:     PetscViewerPopFormat(viewer);
    201:   }
    202:   return 0;
    203: }

    205: /*@C
    206:    NEPMonitorAll - Print the current approximate values and
    207:    error estimates at each iteration of the nonlinear eigensolver.

    209:    Collective on nep

    211:    Input Parameters:
    212: +  nep    - nonlinear eigensolver context
    213: .  its    - iteration number
    214: .  nconv  - number of converged eigenpairs so far
    215: .  eigr   - real part of the eigenvalues
    216: .  eigi   - imaginary part of the eigenvalues
    217: .  errest - error estimates
    218: .  nest   - number of error estimates to display
    219: -  vf     - viewer and format for monitoring

    221:    Options Database Key:
    222: .  -nep_monitor_all - activates NEPMonitorAll()

    224:    Level: intermediate

    226: .seealso: NEPMonitorSet(), NEPMonitorFirst(), NEPMonitorConverged()
    227: @*/
    228: PetscErrorCode NEPMonitorAll(NEP nep,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
    229: {
    230:   PetscInt       i;
    231:   PetscViewer    viewer = vf->viewer;

    235:   PetscViewerPushFormat(viewer,vf->format);
    236:   PetscViewerASCIIAddTab(viewer,((PetscObject)nep)->tablevel);
    237:   if (its==1 && ((PetscObject)nep)->prefix) PetscViewerASCIIPrintf(viewer,"  Eigenvalue approximations and residual norms for %s solve.\n",((PetscObject)nep)->prefix);
    238:   PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " NEP nconv=%" PetscInt_FMT " Values (Errors)",its,nconv);
    239:   PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);
    240:   for (i=0;i<nest;i++) {
    241: #if defined(PETSC_USE_COMPLEX)
    242:     PetscViewerASCIIPrintf(viewer," %g%+gi",(double)PetscRealPart(eigr[i]),(double)PetscImaginaryPart(eigr[i]));
    243: #else
    244:     PetscViewerASCIIPrintf(viewer," %g",(double)eigr[i]);
    245:     if (eigi[i]!=0.0) PetscViewerASCIIPrintf(viewer,"%+gi",(double)eigi[i]);
    246: #endif
    247:     PetscViewerASCIIPrintf(viewer," (%10.8e)",(double)errest[i]);
    248:   }
    249:   PetscViewerASCIIPrintf(viewer,"\n");
    250:   PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);
    251:   PetscViewerASCIISubtractTab(viewer,((PetscObject)nep)->tablevel);
    252:   PetscViewerPopFormat(viewer);
    253:   return 0;
    254: }

    256: /*@C
    257:    NEPMonitorConverged - Print the approximate values and
    258:    error estimates as they converge.

    260:    Collective on nep

    262:    Input Parameters:
    263: +  nep    - 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:    Level: intermediate

    277: .seealso: NEPMonitorSet(), NEPMonitorFirst(), NEPMonitorAll()
    278: @*/
    279: PetscErrorCode NEPMonitorConverged(NEP nep,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
    280: {
    281:   PetscInt       i;
    282:   PetscViewer    viewer = vf->viewer;
    283:   SlepcConvMon   ctx;

    287:   ctx = (SlepcConvMon)vf->data;
    288:   if (its==1 && ((PetscObject)nep)->prefix) PetscViewerASCIIPrintf(viewer,"  Convergence history for %s solve.\n",((PetscObject)nep)->prefix);
    289:   if (its==1) ctx->oldnconv = 0;
    290:   if (ctx->oldnconv!=nconv) {
    291:     PetscViewerPushFormat(viewer,vf->format);
    292:     PetscViewerASCIIAddTab(viewer,((PetscObject)nep)->tablevel);
    293:     for (i=ctx->oldnconv;i<nconv;i++) {
    294:       PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " NEP converged value (error) #%" PetscInt_FMT,its,i);
    295:       PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);
    296: #if defined(PETSC_USE_COMPLEX)
    297:       PetscViewerASCIIPrintf(viewer," %g%+gi",(double)PetscRealPart(eigr[i]),(double)PetscImaginaryPart(eigr[i]));
    298: #else
    299:       PetscViewerASCIIPrintf(viewer," %g",(double)eigr[i]);
    300:       if (eigi[i]!=0.0) PetscViewerASCIIPrintf(viewer,"%+gi",(double)eigi[i]);
    301: #endif
    302:       PetscViewerASCIIPrintf(viewer," (%10.8e)\n",(double)errest[i]);
    303:       PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);
    304:     }
    305:     PetscViewerASCIISubtractTab(viewer,((PetscObject)nep)->tablevel);
    306:     PetscViewerPopFormat(viewer);
    307:     ctx->oldnconv = nconv;
    308:   }
    309:   return 0;
    310: }

    312: PetscErrorCode NEPMonitorConvergedCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
    313: {
    314:   SlepcConvMon   mctx;

    316:   PetscViewerAndFormatCreate(viewer,format,vf);
    317:   PetscNew(&mctx);
    318:   mctx->ctx = ctx;
    319:   (*vf)->data = (void*)mctx;
    320:   return 0;
    321: }

    323: PetscErrorCode NEPMonitorConvergedDestroy(PetscViewerAndFormat **vf)
    324: {
    325:   if (!*vf) return 0;
    326:   PetscFree((*vf)->data);
    327:   PetscViewerDestroy(&(*vf)->viewer);
    328:   PetscDrawLGDestroy(&(*vf)->lg);
    329:   PetscFree(*vf);
    330:   return 0;
    331: }

    333: /*@C
    334:    NEPMonitorFirstDrawLG - Plots the error estimate of the first unconverged
    335:    approximation at each iteration of the nonlinear eigensolver.

    337:    Collective on nep

    339:    Input Parameters:
    340: +  nep    - nonlinear eigensolver context
    341: .  its    - iteration number
    342: .  its    - iteration number
    343: .  nconv  - number of converged eigenpairs so far
    344: .  eigr   - real part of the eigenvalues
    345: .  eigi   - imaginary part of the eigenvalues
    346: .  errest - error estimates
    347: .  nest   - number of error estimates to display
    348: -  vf     - viewer and format for monitoring

    350:    Options Database Key:
    351: .  -nep_monitor draw::draw_lg - activates NEPMonitorFirstDrawLG()

    353:    Level: intermediate

    355: .seealso: NEPMonitorSet()
    356: @*/
    357: PetscErrorCode NEPMonitorFirstDrawLG(NEP nep,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
    358: {
    359:   PetscViewer    viewer = vf->viewer;
    360:   PetscDrawLG    lg = vf->lg;
    361:   PetscReal      x,y;

    366:   PetscViewerPushFormat(viewer,vf->format);
    367:   if (its==1) {
    368:     PetscDrawLGReset(lg);
    369:     PetscDrawLGSetDimension(lg,1);
    370:     PetscDrawLGSetLimits(lg,1,1,PetscLog10Real(nep->tol)-2,0.0);
    371:   }
    372:   if (nconv<nest) {
    373:     x = (PetscReal)its;
    374:     if (errest[nconv] > 0.0) y = PetscLog10Real(errest[nconv]);
    375:     else y = 0.0;
    376:     PetscDrawLGAddPoint(lg,&x,&y);
    377:     if (its <= 20 || !(its % 5) || nep->reason) {
    378:       PetscDrawLGDraw(lg);
    379:       PetscDrawLGSave(lg);
    380:     }
    381:   }
    382:   PetscViewerPopFormat(viewer);
    383:   return 0;
    384: }

    386: /*@C
    387:    NEPMonitorFirstDrawLGCreate - Creates the plotter for the first error estimate.

    389:    Collective on viewer

    391:    Input Parameters:
    392: +  viewer - the viewer
    393: .  format - the viewer format
    394: -  ctx    - an optional user context

    396:    Output Parameter:
    397: .  vf     - the viewer and format context

    399:    Level: intermediate

    401: .seealso: NEPMonitorSet()
    402: @*/
    403: PetscErrorCode NEPMonitorFirstDrawLGCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
    404: {
    405:   PetscViewerAndFormatCreate(viewer,format,vf);
    406:   (*vf)->data = ctx;
    407:   NEPMonitorLGCreate(PetscObjectComm((PetscObject)viewer),NULL,"First Error Estimate","Log Error Estimate",1,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&(*vf)->lg);
    408:   return 0;
    409: }

    411: /*@C
    412:    NEPMonitorAllDrawLG - Plots the error estimate of all unconverged
    413:    approximations at each iteration of the nonlinear eigensolver.

    415:    Collective on nep

    417:    Input Parameters:
    418: +  nep    - nonlinear eigensolver context
    419: .  its    - iteration number
    420: .  its    - iteration number
    421: .  nconv  - number of converged eigenpairs so far
    422: .  eigr   - real part of the eigenvalues
    423: .  eigi   - imaginary part of the eigenvalues
    424: .  errest - error estimates
    425: .  nest   - number of error estimates to display
    426: -  vf     - viewer and format for monitoring

    428:    Options Database Key:
    429: .  -nep_monitor_all draw::draw_lg - activates NEPMonitorAllDrawLG()

    431:    Level: intermediate

    433: .seealso: NEPMonitorSet()
    434: @*/
    435: PetscErrorCode NEPMonitorAllDrawLG(NEP nep,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
    436: {
    437:   PetscViewer    viewer = vf->viewer;
    438:   PetscDrawLG    lg = vf->lg;
    439:   PetscInt       i,n = PetscMin(nep->nev,255);
    440:   PetscReal      *x,*y;

    445:   PetscViewerPushFormat(viewer,vf->format);
    446:   if (its==1) {
    447:     PetscDrawLGReset(lg);
    448:     PetscDrawLGSetDimension(lg,n);
    449:     PetscDrawLGSetLimits(lg,1,1,PetscLog10Real(nep->tol)-2,0.0);
    450:   }
    451:   PetscMalloc2(n,&x,n,&y);
    452:   for (i=0;i<n;i++) {
    453:     x[i] = (PetscReal)its;
    454:     if (i < nest && errest[i] > 0.0) y[i] = PetscLog10Real(errest[i]);
    455:     else y[i] = 0.0;
    456:   }
    457:   PetscDrawLGAddPoint(lg,x,y);
    458:   if (its <= 20 || !(its % 5) || nep->reason) {
    459:     PetscDrawLGDraw(lg);
    460:     PetscDrawLGSave(lg);
    461:   }
    462:   PetscFree2(x,y);
    463:   PetscViewerPopFormat(viewer);
    464:   return 0;
    465: }

    467: /*@C
    468:    NEPMonitorAllDrawLGCreate - Creates the plotter for all the error estimates.

    470:    Collective on viewer

    472:    Input Parameters:
    473: +  viewer - the viewer
    474: .  format - the viewer format
    475: -  ctx    - an optional user context

    477:    Output Parameter:
    478: .  vf     - the viewer and format context

    480:    Level: intermediate

    482: .seealso: NEPMonitorSet()
    483: @*/
    484: PetscErrorCode NEPMonitorAllDrawLGCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
    485: {
    486:   PetscViewerAndFormatCreate(viewer,format,vf);
    487:   (*vf)->data = ctx;
    488:   NEPMonitorLGCreate(PetscObjectComm((PetscObject)viewer),NULL,"All Error Estimates","Log Error Estimate",1,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&(*vf)->lg);
    489:   return 0;
    490: }

    492: /*@C
    493:    NEPMonitorConvergedDrawLG - Plots the number of converged eigenvalues
    494:    at each iteration of the nonlinear eigensolver.

    496:    Collective on nep

    498:    Input Parameters:
    499: +  nep    - nonlinear eigensolver context
    500: .  its    - iteration number
    501: .  its    - iteration number
    502: .  nconv  - number of converged eigenpairs so far
    503: .  eigr   - real part of the eigenvalues
    504: .  eigi   - imaginary part of the eigenvalues
    505: .  errest - error estimates
    506: .  nest   - number of error estimates to display
    507: -  vf     - viewer and format for monitoring

    509:    Options Database Key:
    510: .  -nep_monitor_conv draw::draw_lg - activates NEPMonitorConvergedDrawLG()

    512:    Level: intermediate

    514: .seealso: NEPMonitorSet()
    515: @*/
    516: PetscErrorCode NEPMonitorConvergedDrawLG(NEP nep,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
    517: {
    518:   PetscViewer      viewer = vf->viewer;
    519:   PetscDrawLG      lg = vf->lg;
    520:   PetscReal        x,y;

    525:   PetscViewerPushFormat(viewer,vf->format);
    526:   if (its==1) {
    527:     PetscDrawLGReset(lg);
    528:     PetscDrawLGSetDimension(lg,1);
    529:     PetscDrawLGSetLimits(lg,1,1,0,nep->nev);
    530:   }
    531:   x = (PetscReal)its;
    532:   y = (PetscReal)nep->nconv;
    533:   PetscDrawLGAddPoint(lg,&x,&y);
    534:   if (its <= 20 || !(its % 5) || nep->reason) {
    535:     PetscDrawLGDraw(lg);
    536:     PetscDrawLGSave(lg);
    537:   }
    538:   PetscViewerPopFormat(viewer);
    539:   return 0;
    540: }

    542: /*@C
    543:    NEPMonitorConvergedDrawLGCreate - Creates the plotter for the convergence history.

    545:    Collective on viewer

    547:    Input Parameters:
    548: +  viewer - the viewer
    549: .  format - the viewer format
    550: -  ctx    - an optional user context

    552:    Output Parameter:
    553: .  vf     - the viewer and format context

    555:    Level: intermediate

    557: .seealso: NEPMonitorSet()
    558: @*/
    559: PetscErrorCode NEPMonitorConvergedDrawLGCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
    560: {
    561:   SlepcConvMon   mctx;

    563:   PetscViewerAndFormatCreate(viewer,format,vf);
    564:   PetscNew(&mctx);
    565:   mctx->ctx = ctx;
    566:   (*vf)->data = (void*)mctx;
    567:   NEPMonitorLGCreate(PetscObjectComm((PetscObject)viewer),NULL,"Convergence History","Number Converged",1,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&(*vf)->lg);
    568:   return 0;
    569: }