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: }