Actual source code: lmemon.c

slepc-3.23.0 2025-03-29
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:    LME routines related to monitors
 12: */

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

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

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

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

 33:    Logically Collective

 35:    Input Parameters:
 36: +  lme     - linear matrix equation solver context obtained from LMECreate()
 37: .  monitor - pointer to function (if this is NULL, it turns off monitoring)
 38: .  mctx    - [optional] context for private data for the
 39:              monitor routine (use NULL if no context is desired)
 40: -  monitordestroy - [optional] routine that frees monitor context (may be NULL),
 41:              see PetscCtxDestroyFn for the calling sequence

 43:    Calling sequence of monitor:
 44: $  PetscErrorCode monitor(LME lme,PetscInt its,PetscReal errest,void*mctx)
 45: +  lme    - linear matrix equation solver context obtained from LMECreate()
 46: .  its    - iteration number
 47: .  errest - error estimate
 48: -  mctx   - optional monitoring context, as set by LMEMonitorSet()

 50:    Options Database Keys:
 51: +    -lme_monitor - print the error estimate
 52: .    -lme_monitor draw::draw_lg - sets line graph monitor for the error estimate
 53: -    -lme_monitor_cancel - cancels all monitors that have been hardwired into
 54:       a code by calls to LMEMonitorSet(), but does not cancel those set via
 55:       the options database.

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

 62:    Level: intermediate

 64: .seealso: LMEMonitorCancel()
 65: @*/
 66: PetscErrorCode LMEMonitorSet(LME lme,PetscErrorCode (*monitor)(LME lme,PetscInt its,PetscReal errest,void*mctx),void *mctx,PetscCtxDestroyFn *monitordestroy)
 67: {
 68:   PetscFunctionBegin;
 70:   PetscCheck(lme->numbermonitors<MAXLMEMONITORS,PetscObjectComm((PetscObject)lme),PETSC_ERR_ARG_OUTOFRANGE,"Too many LME monitors set");
 71:   lme->monitor[lme->numbermonitors]           = monitor;
 72:   lme->monitorcontext[lme->numbermonitors]    = (void*)mctx;
 73:   lme->monitordestroy[lme->numbermonitors++]  = monitordestroy;
 74:   PetscFunctionReturn(PETSC_SUCCESS);
 75: }

 77: /*@
 78:    LMEMonitorCancel - Clears all monitors for an LME object.

 80:    Logically Collective

 82:    Input Parameters:
 83: .  lme - linear matrix equation solver context obtained from LMECreate()

 85:    Options Database Key:
 86: .    -lme_monitor_cancel - cancels all monitors that have been hardwired
 87:       into a code by calls to LMEMonitorSet(),
 88:       but does not cancel those set via the options database.

 90:    Level: intermediate

 92: .seealso: LMEMonitorSet()
 93: @*/
 94: PetscErrorCode LMEMonitorCancel(LME lme)
 95: {
 96:   PetscInt       i;

 98:   PetscFunctionBegin;
100:   for (i=0; i<lme->numbermonitors; i++) {
101:     if (lme->monitordestroy[i]) PetscCall((*lme->monitordestroy[i])(&lme->monitorcontext[i]));
102:   }
103:   lme->numbermonitors = 0;
104:   PetscFunctionReturn(PETSC_SUCCESS);
105: }

107: /*@C
108:    LMEGetMonitorContext - Gets the monitor context, as set by
109:    LMEMonitorSet() for the FIRST monitor only.

111:    Not Collective

113:    Input Parameter:
114: .  lme - linear matrix equation solver context obtained from LMECreate()

116:    Output Parameter:
117: .  ctx - monitor context

119:    Level: intermediate

121: .seealso: LMEMonitorSet()
122: @*/
123: PetscErrorCode LMEGetMonitorContext(LME lme,void *ctx)
124: {
125:   PetscFunctionBegin;
127:   *(void**)ctx = lme->monitorcontext[0];
128:   PetscFunctionReturn(PETSC_SUCCESS);
129: }

131: /*@C
132:    LMEMonitorDefault - Print the error estimate of the current approximation at each
133:    iteration of the linear matrix equation solver.

135:    Collective

137:    Input Parameters:
138: +  lme    - linear matrix equation solver context
139: .  its    - iteration number
140: .  errest - error estimate
141: -  vf     - viewer and format for monitoring

143:    Options Database Key:
144: .  -lme_monitor - activates LMEMonitorDefault()

146:    Level: intermediate

148: .seealso: LMEMonitorSet()
149: @*/
150: PetscErrorCode LMEMonitorDefault(LME lme,PetscInt its,PetscReal errest,PetscViewerAndFormat *vf)
151: {
152:   PetscViewer    viewer = vf->viewer;

154:   PetscFunctionBegin;
157:   PetscCall(PetscViewerPushFormat(viewer,vf->format));
158:   PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)lme)->tablevel));
159:   if (its == 1 && ((PetscObject)lme)->prefix) PetscCall(PetscViewerASCIIPrintf(viewer,"  Error estimates for %s solve.\n",((PetscObject)lme)->prefix));
160:   PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " LME Error estimate %14.12e\n",its,(double)errest));
161:   PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)lme)->tablevel));
162:   PetscCall(PetscViewerPopFormat(viewer));
163:   PetscFunctionReturn(PETSC_SUCCESS);
164: }

166: /*@C
167:    LMEMonitorDefaultDrawLG - Plots the error estimate of the current approximation at each
168:    iteration of the linear matrix equation solver.

170:    Collective

172:    Input Parameters:
173: +  lme    - linear matrix equation solver context
174: .  its    - iteration number
175: .  errest - error estimate
176: -  vf     - viewer and format for monitoring

178:    Options Database Key:
179: .  -lme_monitor draw::draw_lg - activates LMEMonitorDefaultDrawLG()

181:    Level: intermediate

183: .seealso: LMEMonitorSet()
184: @*/
185: PetscErrorCode LMEMonitorDefaultDrawLG(LME lme,PetscInt its,PetscReal errest,PetscViewerAndFormat *vf)
186: {
187:   PetscViewer    viewer = vf->viewer;
188:   PetscDrawLG    lg;
189:   PetscReal      x,y;

191:   PetscFunctionBegin;
194:   PetscCall(PetscViewerPushFormat(viewer,vf->format));
195:   PetscCall(PetscViewerDrawGetDrawLG(viewer,0,&lg));
196:   if (its==1) {
197:     PetscCall(PetscDrawLGReset(lg));
198:     PetscCall(PetscDrawLGSetDimension(lg,1));
199:     PetscCall(PetscDrawLGSetLimits(lg,1,1.0,PetscLog10Real(lme->tol)-2,0.0));
200:   }
201:   x = (PetscReal)its;
202:   if (errest > 0.0) y = PetscLog10Real(errest);
203:   else y = 0.0;
204:   PetscCall(PetscDrawLGAddPoint(lg,&x,&y));
205:   if (its <= 20 || !(its % 5) || lme->reason) {
206:     PetscCall(PetscDrawLGDraw(lg));
207:     PetscCall(PetscDrawLGSave(lg));
208:   }
209:   PetscCall(PetscViewerPopFormat(viewer));
210:   PetscFunctionReturn(PETSC_SUCCESS);
211: }

213: /*@C
214:    LMEMonitorDefaultDrawLGCreate - Creates the plotter for the error estimate.

216:    Collective

218:    Input Parameters:
219: +  viewer - the viewer
220: .  format - the viewer format
221: -  ctx    - an optional user context

223:    Output Parameter:
224: .  vf     - the viewer and format context

226:    Level: intermediate

228: .seealso: LMEMonitorSet()
229: @*/
230: PetscErrorCode LMEMonitorDefaultDrawLGCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
231: {
232:   PetscFunctionBegin;
233:   PetscCall(PetscViewerAndFormatCreate(viewer,format,vf));
234:   (*vf)->data = ctx;
235:   PetscCall(PetscViewerMonitorLGSetUp(viewer,NULL,"Error Estimate","Log Error Estimate",1,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300));
236:   PetscFunctionReturn(PETSC_SUCCESS);
237: }