1: /*
2: MFN routines related to monitors.
4: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5: SLEPc - Scalable Library for Eigenvalue Problem Computations
6: Copyright (c) 2002-2016, Universitat Politecnica de Valencia, Spain
8: This file is part of SLEPc.
10: SLEPc is free software: you can redistribute it and/or modify it under the
11: terms of version 3 of the GNU Lesser General Public License as published by
12: the Free Software Foundation.
14: SLEPc is distributed in the hope that it will be useful, but WITHOUT ANY
15: WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16: FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
17: more details.
19: You should have received a copy of the GNU Lesser General Public License
20: along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
21: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
22: */
24: #include <slepc/private/mfnimpl.h> /*I "slepcmfn.h" I*/
25: #include <petscdraw.h>
29: /*
30: Runs the user provided monitor routines, if any.
31: */
32: PetscErrorCode MFNMonitor(MFN mfn,PetscInt it,PetscReal errest) 33: {
35: PetscInt i,n = mfn->numbermonitors;
38: for (i=0;i<n;i++) {
39: (*mfn->monitor[i])(mfn,it,errest,mfn->monitorcontext[i]);
40: }
41: return(0);
42: }
46: /*@C
47: MFNMonitorSet - Sets an ADDITIONAL function to be called at every
48: iteration to monitor convergence.
50: Logically Collective on MFN 52: Input Parameters:
53: + mfn - matrix function context obtained from MFNCreate()
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(MFN mfn,int its,PetscReal errest,void *mctx)
62: + mfn - matrix function context obtained from MFNCreate()
63: . its - iteration number
64: . errest - error estimate
65: - mctx - optional monitoring context, as set by MFNMonitorSet()
67: Options Database Keys:
68: + -mfn_monitor - print the error estimate
69: . -mfn_monitor_lg - sets line graph monitor for the error estimate
70: - -mfn_monitor_cancel - cancels all monitors that have been hardwired into
71: a code by calls to MFNMonitorSet(), but does not cancel those set via
72: the options database.
74: Notes:
75: Several different monitoring routines may be set by calling
76: MFNMonitorSet() multiple times; all will be called in the
77: order in which they were set.
79: Level: intermediate
81: .seealso: MFNMonitorFirst(), MFNMonitorAll(), MFNMonitorCancel()
82: @*/
83: PetscErrorCode MFNMonitorSet(MFN mfn,PetscErrorCode (*monitor)(MFN,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 84: {
87: if (mfn->numbermonitors >= MAXMFNMONITORS) SETERRQ(PetscObjectComm((PetscObject)mfn),PETSC_ERR_ARG_OUTOFRANGE,"Too many MFN monitors set");
88: mfn->monitor[mfn->numbermonitors] = monitor;
89: mfn->monitorcontext[mfn->numbermonitors] = (void*)mctx;
90: mfn->monitordestroy[mfn->numbermonitors++] = monitordestroy;
91: return(0);
92: }
96: /*@
97: MFNMonitorCancel - Clears all monitors for an MFN object.
99: Logically Collective on MFN101: Input Parameters:
102: . mfn - matrix function context obtained from MFNCreate()
104: Options Database Key:
105: . -mfn_monitor_cancel - Cancels all monitors that have been hardwired
106: into a code by calls to MFNMonitorSet(),
107: but does not cancel those set via the options database.
109: Level: intermediate
111: .seealso: MFNMonitorSet()
112: @*/
113: PetscErrorCode MFNMonitorCancel(MFN mfn)114: {
116: PetscInt i;
120: for (i=0; i<mfn->numbermonitors; i++) {
121: if (mfn->monitordestroy[i]) {
122: (*mfn->monitordestroy[i])(&mfn->monitorcontext[i]);
123: }
124: }
125: mfn->numbermonitors = 0;
126: return(0);
127: }
131: /*@C
132: MFNGetMonitorContext - Gets the monitor context, as set by
133: MFNMonitorSet() for the FIRST monitor only.
135: Not Collective
137: Input Parameter:
138: . mfn - matrix function context obtained from MFNCreate()
140: Output Parameter:
141: . ctx - monitor context
143: Level: intermediate
145: .seealso: MFNMonitorSet()
146: @*/
147: PetscErrorCode MFNGetMonitorContext(MFN mfn,void **ctx)148: {
151: *ctx = mfn->monitorcontext[0];
152: return(0);
153: }
157: /*@C
158: MFNMonitorDefault - Print the error estimate of the current approximation at each
159: iteration of the matrix function solver.
161: Collective on MFN163: Input Parameters:
164: + mfn - matrix function context
165: . its - iteration number
166: . errest - error estimate
167: - vf - viewer and format for monitoring
169: Level: intermediate
171: .seealso: MFNMonitorSet()
172: @*/
173: PetscErrorCode MFNMonitorDefault(MFN mfn,PetscInt its,PetscReal errest,PetscViewerAndFormat *vf)174: {
176: PetscViewer viewer;
181: viewer = vf->viewer;
183: PetscViewerPushFormat(viewer,vf->format);
184: PetscViewerASCIIAddTab(viewer,((PetscObject)mfn)->tablevel);
185: if (its == 1 && ((PetscObject)mfn)->prefix) {
186: PetscViewerASCIIPrintf(viewer," Error estimates for %s solve.\n",((PetscObject)mfn)->prefix);
187: }
188: PetscViewerASCIIPrintf(viewer,"%3D MFN Error estimate %14.12e\n",its,(double)errest);
189: PetscViewerASCIISubtractTab(viewer,((PetscObject)mfn)->tablevel);
190: PetscViewerPopFormat(viewer);
191: return(0);
192: }
196: /*@C
197: MFNMonitorLGCreate - Creates a line graph context for use with
198: MFN to monitor convergence.
200: Collective on MPI_Comm
202: Input Parameters:
203: + comm - communicator context
204: . host - the X display to open, or null for the local machine
205: . label - the title to put in the title bar
206: . x, y - the screen coordinates of the upper left coordinate of
207: the window
208: - m, n - the screen width and height in pixels
210: Output Parameter:
211: . lgctx - the drawing context
213: Options Database Keys:
214: . -mfn_monitor_lg - Sets line graph monitor
216: Notes:
217: Use PetscDrawLGDestroy() to destroy this line graph.
219: Level: intermediate
221: .seealso: MFNMonitorSet()
222: @*/
223: PetscErrorCode MFNMonitorLGCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *lgctx)224: {
225: PetscDraw draw;
226: PetscDrawLG lg;
230: PetscDrawCreate(comm,host,label,x,y,m,n,&draw);
231: PetscDrawSetFromOptions(draw);
232: PetscDrawLGCreate(draw,1,&lg);
233: PetscDrawLGSetFromOptions(lg);
234: PetscDrawDestroy(&draw);
235: *lgctx = lg;
236: return(0);
237: }
241: PetscErrorCode MFNMonitorLG(MFN mfn,PetscInt its,PetscReal errest,void *ctx)242: {
243: PetscDrawLG lg = (PetscDrawLG)ctx;
244: PetscReal x,y;
249: if (its==1) {
250: PetscDrawLGReset(lg);
251: PetscDrawLGSetDimension(lg,1);
252: PetscDrawLGSetLimits(lg,1,1.0,PetscLog10Real(mfn->tol)-2,0.0);
253: }
254: x = (PetscReal)its;
255: if (errest > 0.0) y = PetscLog10Real(errest);
256: else y = 0.0;
257: PetscDrawLGAddPoint(lg,&x,&y);
258: if (its <= 20 || !(its % 5) || mfn->reason) {
259: PetscDrawLGDraw(lg);
260: PetscDrawLGSave(lg);
261: }
262: return(0);
263: }