Actual source code: mfnmon.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:    MFN routines related to monitors
 12: */

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

 17: /*
 18:    Runs the user provided monitor routines, if any.
 19: */
 20: PetscErrorCode MFNMonitor(MFN mfn,PetscInt it,PetscReal errest)
 21: {
 22:   PetscInt       i,n = mfn->numbermonitors;

 24:   PetscFunctionBegin;
 25:   for (i=0;i<n;i++) PetscCall((*mfn->monitor[i])(mfn,it,errest,mfn->monitorcontext[i]));
 26:   PetscFunctionReturn(PETSC_SUCCESS);
 27: }

 29: /*@C
 30:    MFNMonitorSet - Sets an ADDITIONAL function to be called at every
 31:    iteration to monitor convergence.

 33:    Logically Collective

 35:    Input Parameters:
 36: +  mfn            - the matrix function solver context
 37: .  monitor        - pointer to function (if this is `NULL`, it turns off monitoring),
 38:                     see `MFNMonitorFn`
 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: +  -mfn_monitor               - print the error estimate
 46: .  -mfn_monitor draw::draw_lg - sets line graph monitor for the error estimate
 47: -  -mfn_monitor_cancel        - cancels all monitors that have been hardwired into
 48:                                 a code by calls to `MFNMonitorSet()`, but does not cancel
 49:                                 those set via the options database.

 51:    Notes:
 52:    The options database option `-mfn_monitor` and related options are the easiest way
 53:    to turn on `MFN` iteration monitoring.

 55:    `MFNMonitorRegister()` provides a way to associate an options database key with `MFN`
 56:    monitor function.

 58:    Several different monitoring routines may be set by calling `MFNMonitorSet()` multiple
 59:    times; all will be called in the order in which they were set.

 61:    Fortran Note:
 62:    Only a single monitor function can be set for each `LME` object.

 64:    Level: intermediate

 66: .seealso: [](ch:mfn), `MFNMonitorDefault()`, `MFNMonitorDefaultDrawLG()`, `MFNMonitorCancel()`
 67: @*/
 68: PetscErrorCode MFNMonitorSet(MFN mfn,MFNMonitorFn *monitor,void *mctx,PetscCtxDestroyFn *monitordestroy)
 69: {
 70:   PetscInt  i;
 71:   PetscBool identical;

 73:   PetscFunctionBegin;
 75:   for (i=0;i<mfn->numbermonitors;i++) {
 76:     PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))(PetscVoidFn*)monitor,mctx,monitordestroy,(PetscErrorCode (*)(void))(PetscVoidFn*)mfn->monitor[i],mfn->monitorcontext[i],mfn->monitordestroy[i],&identical));
 77:     if (identical) PetscFunctionReturn(PETSC_SUCCESS);
 78:   }
 79:   PetscCheck(mfn->numbermonitors<MAXMFNMONITORS,PetscObjectComm((PetscObject)mfn),PETSC_ERR_ARG_OUTOFRANGE,"Too many MFN monitors set");
 80:   mfn->monitor[mfn->numbermonitors]           = monitor;
 81:   mfn->monitorcontext[mfn->numbermonitors]    = mctx;
 82:   mfn->monitordestroy[mfn->numbermonitors++]  = monitordestroy;
 83:   PetscFunctionReturn(PETSC_SUCCESS);
 84: }

 86: /*@
 87:    MFNMonitorCancel - Clears all monitors for an `MFN` object.

 89:    Logically Collective

 91:    Input Parameter:
 92: .  mfn - the matrix function solver context

 94:    Options Database Key:
 95: .  -mfn_monitor_cancel - cancels all monitors that have been hardwired into a code by calls to
 96:                          `MFNMonitorSet()`, but does not cancel those set via the options database.

 98:    Level: intermediate

100: .seealso: [](ch:mfn), `MFNMonitorSet()`
101: @*/
102: PetscErrorCode MFNMonitorCancel(MFN mfn)
103: {
104:   PetscInt       i;

106:   PetscFunctionBegin;
108:   for (i=0; i<mfn->numbermonitors; i++) {
109:     if (mfn->monitordestroy[i]) PetscCall((*mfn->monitordestroy[i])(&mfn->monitorcontext[i]));
110:   }
111:   mfn->numbermonitors = 0;
112:   PetscFunctionReturn(PETSC_SUCCESS);
113: }

115: /*@C
116:    MFNGetMonitorContext - Gets the monitor context, as set by
117:    `MFNMonitorSet()` for the FIRST monitor only.

119:    Not Collective

121:    Input Parameter:
122: .  mfn - the matrix function solver context

124:    Output Parameter:
125: .  ctx - monitor context

127:    Level: intermediate

129: .seealso: [](ch:mfn), `MFNMonitorSet()`
130: @*/
131: PetscErrorCode MFNGetMonitorContext(MFN mfn,void *ctx)
132: {
133:   PetscFunctionBegin;
135:   *(void**)ctx = mfn->monitorcontext[0];
136:   PetscFunctionReturn(PETSC_SUCCESS);
137: }

139: /*@C
140:    MFNMonitorDefault - Print the error estimate of the current approximation at each
141:    iteration of the matrix function solver.

143:    Collective

145:    Input Parameters:
146: +  mfn    - the matrix function solver context
147: .  its    - iteration number
148: .  errest - error estimate
149: -  vf     - viewer and format for monitoring

151:    Options Database Key:
152: .  -mfn_monitor - activates `MFNMonitorDefault()`

154:    Level: intermediate

156: .seealso: [](ch:mfn), `MFNMonitorSet()`
157: @*/
158: PetscErrorCode MFNMonitorDefault(MFN mfn,PetscInt its,PetscReal errest,PetscViewerAndFormat *vf)
159: {
160:   PetscViewer    viewer = vf->viewer;

162:   PetscFunctionBegin;
165:   PetscCall(PetscViewerPushFormat(viewer,vf->format));
166:   PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)mfn)->tablevel));
167:   if (its == 1 && ((PetscObject)mfn)->prefix) PetscCall(PetscViewerASCIIPrintf(viewer,"  Error estimates for %s solve.\n",((PetscObject)mfn)->prefix));
168:   PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " MFN Error estimate %14.12e\n",its,(double)errest));
169:   PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)mfn)->tablevel));
170:   PetscCall(PetscViewerPopFormat(viewer));
171:   PetscFunctionReturn(PETSC_SUCCESS);
172: }

174: /*@C
175:    MFNMonitorDefaultDrawLG - Plots the error estimate of the current approximation at each
176:    iteration of the matrix function solver.

178:    Collective

180:    Input Parameters:
181: +  mfn    - the matrix function solver context
182: .  its    - iteration number
183: .  errest - error estimate
184: -  vf     - viewer and format for monitoring

186:    Options Database Key:
187: .  -mfn_monitor draw::draw_lg - activates `MFNMonitorDefaultDrawLG()`

189:    Notes:
190:    This is not called directly by users, rather one calls `MFNMonitorSet()`, with this
191:    function as an argument, to cause the monitor to be used during the `MFN` solve.

193:    Call `MFNMonitorDefaultDrawLGCreate()` to create the context used with this monitor.

195:    Level: intermediate

197: .seealso: [](ch:mfn), `MFNMonitorSet()`, `MFNMonitorDefaultDrawLGCreate()`
198: @*/
199: PetscErrorCode MFNMonitorDefaultDrawLG(MFN mfn,PetscInt its,PetscReal errest,PetscViewerAndFormat *vf)
200: {
201:   PetscViewer    viewer = vf->viewer;
202:   PetscDrawLG    lg;
203:   PetscReal      x,y;

205:   PetscFunctionBegin;
208:   PetscCall(PetscViewerPushFormat(viewer,vf->format));
209:   PetscCall(PetscViewerDrawGetDrawLG(viewer,0,&lg));
210:   if (its==1) {
211:     PetscCall(PetscDrawLGReset(lg));
212:     PetscCall(PetscDrawLGSetDimension(lg,1));
213:     PetscCall(PetscDrawLGSetLimits(lg,1,1.0,PetscLog10Real(mfn->tol)-2,0.0));
214:   }
215:   x = (PetscReal)its;
216:   if (errest > 0.0) y = PetscLog10Real(errest);
217:   else y = 0.0;
218:   PetscCall(PetscDrawLGAddPoint(lg,&x,&y));
219:   if (its <= 20 || !(its % 5) || mfn->reason) {
220:     PetscCall(PetscDrawLGDraw(lg));
221:     PetscCall(PetscDrawLGSave(lg));
222:   }
223:   PetscCall(PetscViewerPopFormat(viewer));
224:   PetscFunctionReturn(PETSC_SUCCESS);
225: }

227: /*@C
228:    MFNMonitorDefaultDrawLGCreate - Creates the plotter for the error estimate.

230:    Collective

232:    Input Parameters:
233: +  viewer - the viewer
234: .  format - the viewer format
235: -  ctx    - an optional user context

237:    Output Parameter:
238: .  vf     - the viewer and format context

240:    Level: intermediate

242: .seealso: [](ch:mfn), `MFNMonitorSet()`
243: @*/
244: PetscErrorCode MFNMonitorDefaultDrawLGCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
245: {
246:   PetscFunctionBegin;
247:   PetscCall(PetscViewerAndFormatCreate(viewer,format,vf));
248:   (*vf)->data = ctx;
249:   PetscCall(PetscViewerMonitorLGSetUp(viewer,NULL,"Error Estimate","Log Error Estimate",1,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300));
250:   PetscFunctionReturn(PETSC_SUCCESS);
251: }