1: /*
2: MFN routines related to monitors.
4: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5: SLEPc - Scalable Library for Eigenvalue Problem Computations
6: Copyright (c) 2002-2015, 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: - monctx - monitor context (contains viewer, can be NULL)
169: Level: intermediate
171: .seealso: MFNMonitorSet()
172: @*/
173: PetscErrorCode MFNMonitorDefault(MFN mfn,PetscInt its,PetscReal errest,void *monctx)174: {
176: PetscViewer viewer = monctx? (PetscViewer)monctx: PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)mfn));
179: PetscViewerASCIIAddTab(viewer,((PetscObject)mfn)->tablevel);
180: if (its == 0 && ((PetscObject)mfn)->prefix) {
181: PetscViewerASCIIPrintf(viewer," Monitor for %s solve.\n",((PetscObject)mfn)->prefix);
182: }
183: PetscViewerASCIIPrintf(viewer,"%3D MFN value %14.12e\n",its,(double)errest);
184: PetscViewerASCIISubtractTab(viewer,((PetscObject)mfn)->tablevel);
185: return(0);
186: }
190: PetscErrorCode MFNMonitorLG(MFN mfn,PetscInt its,PetscReal errest,void *monctx)191: {
192: PetscViewer viewer = (PetscViewer)monctx;
193: PetscDraw draw;
194: PetscDrawLG lg;
196: PetscReal x,y;
199: if (!viewer) viewer = PETSC_VIEWER_DRAW_(PetscObjectComm((PetscObject)mfn));
200: PetscViewerDrawGetDraw(viewer,0,&draw);
201: PetscViewerDrawGetDrawLG(viewer,0,&lg);
202: if (!its) {
203: PetscDrawSetTitle(draw,"Error estimate");
204: PetscDrawSetDoubleBuffer(draw);
205: PetscDrawLGSetDimension(lg,1);
206: PetscDrawLGReset(lg);
207: PetscDrawLGSetLimits(lg,0,1.0,PetscLog10Real(mfn->tol)-2,0.0);
208: }
209: x = (PetscReal)its;
210: if (errest>0.0) y = PetscLog10Real(errest); else y = 0.0;
211: PetscDrawLGAddPoint(lg,&x,&y);
212: PetscDrawLGDraw(lg);
213: return(0);
214: }