Line data Source code
1 : /*
2 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3 : SLEPc - Scalable Library for Eigenvalue Problem Computations
4 : Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain
5 :
6 : This file is part of SLEPc.
7 : SLEPc is distributed under a 2-clause BSD license (see LICENSE).
8 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9 : */
10 : /*
11 : EPS routines related to monitors
12 : */
13 :
14 : #include <slepc/private/epsimpl.h> /*I "slepceps.h" I*/
15 : #include <petscdraw.h>
16 :
17 0 : PetscErrorCode EPSMonitorLGCreate(MPI_Comm comm,const char host[],const char label[],const char metric[],PetscInt l,const char *names[],int x,int y,int m,int n,PetscDrawLG *lgctx)
18 : {
19 0 : PetscDraw draw;
20 0 : PetscDrawAxis axis;
21 0 : PetscDrawLG lg;
22 :
23 0 : PetscFunctionBegin;
24 0 : PetscCall(PetscDrawCreate(comm,host,label,x,y,m,n,&draw));
25 0 : PetscCall(PetscDrawSetFromOptions(draw));
26 0 : PetscCall(PetscDrawLGCreate(draw,l,&lg));
27 0 : if (names) PetscCall(PetscDrawLGSetLegend(lg,names));
28 0 : PetscCall(PetscDrawLGSetFromOptions(lg));
29 0 : PetscCall(PetscDrawLGGetAxis(lg,&axis));
30 0 : PetscCall(PetscDrawAxisSetLabels(axis,"Convergence","Iteration",metric));
31 0 : PetscCall(PetscDrawDestroy(&draw));
32 0 : *lgctx = lg;
33 0 : PetscFunctionReturn(PETSC_SUCCESS);
34 : }
35 :
36 : /*
37 : Runs the user provided monitor routines, if any.
38 : */
39 45228 : PetscErrorCode EPSMonitor(EPS eps,PetscInt it,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest)
40 : {
41 45228 : PetscInt i,n = eps->numbermonitors;
42 :
43 45228 : PetscFunctionBegin;
44 46419 : for (i=0;i<n;i++) PetscCall((*eps->monitor[i])(eps,it,nconv,eigr,eigi,errest,nest,eps->monitorcontext[i]));
45 45228 : PetscFunctionReturn(PETSC_SUCCESS);
46 : }
47 :
48 : /*@C
49 : EPSMonitorSet - Sets an ADDITIONAL function to be called at every
50 : iteration to monitor the error estimates for each requested eigenpair.
51 :
52 : Logically Collective
53 :
54 : Input Parameters:
55 : + eps - eigensolver context obtained from EPSCreate()
56 : . monitor - pointer to function (if this is NULL, it turns off monitoring)
57 : . mctx - [optional] context for private data for the
58 : monitor routine (use NULL if no context is desired)
59 : - monitordestroy - [optional] routine that frees monitor context (may be NULL),
60 : see PetscCtxDestroyFn for the calling sequence
61 :
62 : Calling sequence of monitor:
63 : $ PetscErrorCode monitor(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *mctx)
64 : + eps - eigensolver context obtained from EPSCreate()
65 : . its - iteration number
66 : . nconv - number of converged eigenpairs
67 : . eigr - real part of the eigenvalues
68 : . eigi - imaginary part of the eigenvalues
69 : . errest - relative error estimates for each eigenpair
70 : . nest - number of error estimates
71 : - mctx - optional monitoring context, as set by EPSMonitorSet()
72 :
73 : Options Database Keys:
74 : + -eps_monitor - print only the first error estimate
75 : . -eps_monitor_all - print error estimates at each iteration
76 : . -eps_monitor_conv - print the eigenvalue approximations only when
77 : convergence has been reached
78 : . -eps_monitor draw::draw_lg - sets line graph monitor for the first unconverged
79 : approximate eigenvalue
80 : . -eps_monitor_all draw::draw_lg - sets line graph monitor for all unconverged
81 : approximate eigenvalues
82 : . -eps_monitor_conv draw::draw_lg - sets line graph monitor for convergence history
83 : - -eps_monitor_cancel - cancels all monitors that have been hardwired into
84 : a code by calls to EPSMonitorSet(), but does not cancel those set via
85 : the options database.
86 :
87 : Notes:
88 : Several different monitoring routines may be set by calling
89 : EPSMonitorSet() multiple times; all will be called in the
90 : order in which they were set.
91 :
92 : Level: intermediate
93 :
94 : .seealso: EPSMonitorFirst(), EPSMonitorAll(), EPSMonitorCancel()
95 : @*/
96 108 : PetscErrorCode EPSMonitorSet(EPS eps,PetscErrorCode (*monitor)(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *mctx),void *mctx,PetscCtxDestroyFn *monitordestroy)
97 : {
98 108 : PetscFunctionBegin;
99 108 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
100 108 : PetscCheck(eps->numbermonitors<MAXEPSMONITORS,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Too many EPS monitors set");
101 108 : eps->monitor[eps->numbermonitors] = monitor;
102 108 : eps->monitorcontext[eps->numbermonitors] = (void*)mctx;
103 108 : eps->monitordestroy[eps->numbermonitors++] = monitordestroy;
104 108 : PetscFunctionReturn(PETSC_SUCCESS);
105 : }
106 :
107 : /*@
108 : EPSMonitorCancel - Clears all monitors for an EPS object.
109 :
110 : Logically Collective
111 :
112 : Input Parameters:
113 : . eps - eigensolver context obtained from EPSCreate()
114 :
115 : Options Database Key:
116 : . -eps_monitor_cancel - Cancels all monitors that have been hardwired
117 : into a code by calls to EPSMonitorSet(),
118 : but does not cancel those set via the options database.
119 :
120 : Level: intermediate
121 :
122 : .seealso: EPSMonitorSet()
123 : @*/
124 600 : PetscErrorCode EPSMonitorCancel(EPS eps)
125 : {
126 600 : PetscInt i;
127 :
128 600 : PetscFunctionBegin;
129 600 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
130 708 : for (i=0; i<eps->numbermonitors; i++) {
131 108 : if (eps->monitordestroy[i]) PetscCall((*eps->monitordestroy[i])(&eps->monitorcontext[i]));
132 : }
133 600 : eps->numbermonitors = 0;
134 600 : PetscFunctionReturn(PETSC_SUCCESS);
135 : }
136 :
137 : /*@C
138 : EPSGetMonitorContext - Gets the monitor context, as set by
139 : EPSMonitorSet() for the FIRST monitor only.
140 :
141 : Not Collective
142 :
143 : Input Parameter:
144 : . eps - eigensolver context obtained from EPSCreate()
145 :
146 : Output Parameter:
147 : . ctx - monitor context
148 :
149 : Level: intermediate
150 :
151 : .seealso: EPSMonitorSet()
152 : @*/
153 0 : PetscErrorCode EPSGetMonitorContext(EPS eps,void *ctx)
154 : {
155 0 : PetscFunctionBegin;
156 0 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
157 0 : *(void**)ctx = eps->monitorcontext[0];
158 0 : PetscFunctionReturn(PETSC_SUCCESS);
159 : }
160 :
161 : /*@C
162 : EPSMonitorFirst - Print the first unconverged approximate value and
163 : error estimate at each iteration of the eigensolver.
164 :
165 : Collective
166 :
167 : Input Parameters:
168 : + eps - eigensolver context
169 : . its - iteration number
170 : . nconv - number of converged eigenpairs so far
171 : . eigr - real part of the eigenvalues
172 : . eigi - imaginary part of the eigenvalues
173 : . errest - error estimates
174 : . nest - number of error estimates to display
175 : - vf - viewer and format for monitoring
176 :
177 : Options Database Key:
178 : . -eps_monitor - activates EPSMonitorFirst()
179 :
180 : Level: intermediate
181 :
182 : .seealso: EPSMonitorSet(), EPSMonitorAll(), EPSMonitorConverged()
183 : @*/
184 2 : PetscErrorCode EPSMonitorFirst(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
185 : {
186 2 : PetscScalar er,ei;
187 2 : PetscViewer viewer = vf->viewer;
188 :
189 2 : PetscFunctionBegin;
190 2 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
191 2 : PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,8);
192 2 : if (its==1 && ((PetscObject)eps)->prefix) PetscCall(PetscViewerASCIIPrintf(viewer," Eigenvalue approximations and residual norms for %s solve.\n",((PetscObject)eps)->prefix));
193 2 : if (nconv<nest) {
194 2 : PetscCall(PetscViewerPushFormat(viewer,vf->format));
195 2 : PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)eps)->tablevel));
196 2 : PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " EPS nconv=%" PetscInt_FMT " first unconverged value (error)",its,nconv));
197 2 : PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
198 2 : er = eigr[nconv]; ei = eigi[nconv];
199 2 : PetscCall(STBackTransform(eps->st,1,&er,&ei));
200 : #if defined(PETSC_USE_COMPLEX)
201 2 : PetscCall(PetscViewerASCIIPrintf(viewer," %g%+gi",(double)PetscRealPart(er),(double)PetscImaginaryPart(er)));
202 : #else
203 : PetscCall(PetscViewerASCIIPrintf(viewer," %g",(double)er));
204 : if (ei!=0.0) PetscCall(PetscViewerASCIIPrintf(viewer,"%+gi",(double)ei));
205 : #endif
206 2 : PetscCall(PetscViewerASCIIPrintf(viewer," (%10.8e)\n",(double)errest[nconv]));
207 2 : PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
208 2 : PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)eps)->tablevel));
209 2 : PetscCall(PetscViewerPopFormat(viewer));
210 : }
211 2 : PetscFunctionReturn(PETSC_SUCCESS);
212 : }
213 :
214 : /*@C
215 : EPSMonitorAll - Print the current approximate values and
216 : error estimates at each iteration of the eigensolver.
217 :
218 : Collective
219 :
220 : Input Parameters:
221 : + eps - eigensolver context
222 : . its - iteration number
223 : . nconv - number of converged eigenpairs so far
224 : . eigr - real part of the eigenvalues
225 : . eigi - imaginary part of the eigenvalues
226 : . errest - error estimates
227 : . nest - number of error estimates to display
228 : - vf - viewer and format for monitoring
229 :
230 : Options Database Key:
231 : . -eps_monitor_all - activates EPSMonitorAll()
232 :
233 : Level: intermediate
234 :
235 : .seealso: EPSMonitorSet(), EPSMonitorFirst(), EPSMonitorConverged()
236 : @*/
237 13 : PetscErrorCode EPSMonitorAll(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
238 : {
239 13 : PetscInt i;
240 13 : PetscScalar er,ei;
241 13 : PetscViewer viewer = vf->viewer;
242 :
243 13 : PetscFunctionBegin;
244 13 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
245 13 : PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,8);
246 13 : PetscCall(PetscViewerPushFormat(viewer,vf->format));
247 13 : PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)eps)->tablevel));
248 13 : if (its==1 && ((PetscObject)eps)->prefix) PetscCall(PetscViewerASCIIPrintf(viewer," Eigenvalue approximations and residual norms for %s solve.\n",((PetscObject)eps)->prefix));
249 13 : PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " EPS nconv=%" PetscInt_FMT " Values (Errors)",its,nconv));
250 13 : PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
251 31 : for (i=0;i<nest;i++) {
252 18 : er = eigr[i]; ei = eigi[i];
253 18 : PetscCall(STBackTransform(eps->st,1,&er,&ei));
254 : #if defined(PETSC_USE_COMPLEX)
255 18 : PetscCall(PetscViewerASCIIPrintf(viewer," %g%+gi",(double)PetscRealPart(er),(double)PetscImaginaryPart(er)));
256 : #else
257 : PetscCall(PetscViewerASCIIPrintf(viewer," %g",(double)er));
258 : if (ei!=0.0) PetscCall(PetscViewerASCIIPrintf(viewer,"%+gi",(double)ei));
259 : #endif
260 18 : PetscCall(PetscViewerASCIIPrintf(viewer," (%10.8e)",(double)errest[i]));
261 : }
262 13 : PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
263 13 : PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
264 13 : PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)eps)->tablevel));
265 13 : PetscCall(PetscViewerPopFormat(viewer));
266 13 : PetscFunctionReturn(PETSC_SUCCESS);
267 : }
268 :
269 : /*@C
270 : EPSMonitorConverged - Print the approximate values and
271 : error estimates as they converge.
272 :
273 : Collective
274 :
275 : Input Parameters:
276 : + eps - eigensolver context
277 : . its - iteration number
278 : . nconv - number of converged eigenpairs so far
279 : . eigr - real part of the eigenvalues
280 : . eigi - imaginary part of the eigenvalues
281 : . errest - error estimates
282 : . nest - number of error estimates to display
283 : - vf - viewer and format for monitoring
284 :
285 : Options Database Key:
286 : . -eps_monitor_conv - activates EPSMonitorConverged()
287 :
288 : Level: intermediate
289 :
290 : .seealso: EPSMonitorSet(), EPSMonitorFirst(), EPSMonitorAll()
291 : @*/
292 1 : PetscErrorCode EPSMonitorConverged(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
293 : {
294 1 : PetscInt i;
295 1 : PetscScalar er,ei;
296 1 : PetscViewer viewer = vf->viewer;
297 1 : SlepcConvMon ctx;
298 :
299 1 : PetscFunctionBegin;
300 1 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
301 1 : PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,8);
302 1 : ctx = (SlepcConvMon)vf->data;
303 1 : if (its==1 && ((PetscObject)eps)->prefix) PetscCall(PetscViewerASCIIPrintf(viewer," Convergence history for %s solve.\n",((PetscObject)eps)->prefix));
304 1 : if (its==1) ctx->oldnconv = 0;
305 1 : if (ctx->oldnconv!=nconv) {
306 1 : PetscCall(PetscViewerPushFormat(viewer,vf->format));
307 1 : PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)eps)->tablevel));
308 7 : for (i=ctx->oldnconv;i<nconv;i++) {
309 6 : PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " EPS converged value (error) #%" PetscInt_FMT,its,i));
310 6 : PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
311 6 : er = eigr[i]; ei = eigi[i];
312 6 : PetscCall(STBackTransform(eps->st,1,&er,&ei));
313 : #if defined(PETSC_USE_COMPLEX)
314 6 : PetscCall(PetscViewerASCIIPrintf(viewer," %g%+gi",(double)PetscRealPart(er),(double)PetscImaginaryPart(er)));
315 : #else
316 : PetscCall(PetscViewerASCIIPrintf(viewer," %g",(double)er));
317 : if (ei!=0.0) PetscCall(PetscViewerASCIIPrintf(viewer,"%+gi",(double)ei));
318 : #endif
319 6 : PetscCall(PetscViewerASCIIPrintf(viewer," (%10.8e)\n",(double)errest[i]));
320 6 : PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
321 : }
322 1 : PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)eps)->tablevel));
323 1 : PetscCall(PetscViewerPopFormat(viewer));
324 1 : ctx->oldnconv = nconv;
325 : }
326 1 : PetscFunctionReturn(PETSC_SUCCESS);
327 : }
328 :
329 1 : PetscErrorCode EPSMonitorConvergedCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
330 : {
331 1 : SlepcConvMon mctx;
332 :
333 1 : PetscFunctionBegin;
334 1 : PetscCall(PetscViewerAndFormatCreate(viewer,format,vf));
335 1 : PetscCall(PetscNew(&mctx));
336 1 : mctx->ctx = ctx;
337 1 : (*vf)->data = (void*)mctx;
338 1 : PetscFunctionReturn(PETSC_SUCCESS);
339 : }
340 :
341 1 : PetscErrorCode EPSMonitorConvergedDestroy(PetscViewerAndFormat **vf)
342 : {
343 1 : PetscFunctionBegin;
344 1 : if (!*vf) PetscFunctionReturn(PETSC_SUCCESS);
345 1 : PetscCall(PetscFree((*vf)->data));
346 1 : PetscCall(PetscViewerDestroy(&(*vf)->viewer));
347 1 : PetscCall(PetscDrawLGDestroy(&(*vf)->lg));
348 1 : PetscCall(PetscFree(*vf));
349 1 : PetscFunctionReturn(PETSC_SUCCESS);
350 : }
351 :
352 : /*@C
353 : EPSMonitorFirstDrawLG - Plots the error estimate of the first unconverged
354 : approximation at each iteration of the eigensolver.
355 :
356 : Collective
357 :
358 : Input Parameters:
359 : + eps - eigensolver context
360 : . its - iteration number
361 : . nconv - number of converged eigenpairs so far
362 : . eigr - real part of the eigenvalues
363 : . eigi - imaginary part of the eigenvalues
364 : . errest - error estimates
365 : . nest - number of error estimates to display
366 : - vf - viewer and format for monitoring
367 :
368 : Options Database Key:
369 : . -eps_monitor draw::draw_lg - activates EPSMonitorFirstDrawLG()
370 :
371 : Level: intermediate
372 :
373 : .seealso: EPSMonitorSet()
374 : @*/
375 0 : PetscErrorCode EPSMonitorFirstDrawLG(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
376 : {
377 0 : PetscViewer viewer = vf->viewer;
378 0 : PetscDrawLG lg = vf->lg;
379 0 : PetscReal x,y;
380 :
381 0 : PetscFunctionBegin;
382 0 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
383 0 : PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,8);
384 0 : PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,8);
385 0 : PetscCall(PetscViewerPushFormat(viewer,vf->format));
386 0 : if (its==1) {
387 0 : PetscCall(PetscDrawLGReset(lg));
388 0 : PetscCall(PetscDrawLGSetDimension(lg,1));
389 0 : PetscCall(PetscDrawLGSetLimits(lg,1,1,PetscLog10Real(eps->tol)-2,0.0));
390 : }
391 0 : if (nconv<nest) {
392 0 : x = (PetscReal)its;
393 0 : if (errest[nconv] > 0.0) y = PetscLog10Real(errest[nconv]);
394 0 : else y = 0.0;
395 0 : PetscCall(PetscDrawLGAddPoint(lg,&x,&y));
396 0 : if (its <= 20 || !(its % 5) || eps->reason) {
397 0 : PetscCall(PetscDrawLGDraw(lg));
398 0 : PetscCall(PetscDrawLGSave(lg));
399 : }
400 : }
401 0 : PetscCall(PetscViewerPopFormat(viewer));
402 0 : PetscFunctionReturn(PETSC_SUCCESS);
403 : }
404 :
405 : /*@C
406 : EPSMonitorFirstDrawLGCreate - Creates the plotter for the first error estimate.
407 :
408 : Collective
409 :
410 : Input Parameters:
411 : + viewer - the viewer
412 : . format - the viewer format
413 : - ctx - an optional user context
414 :
415 : Output Parameter:
416 : . vf - the viewer and format context
417 :
418 : Level: intermediate
419 :
420 : .seealso: EPSMonitorSet()
421 : @*/
422 0 : PetscErrorCode EPSMonitorFirstDrawLGCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
423 : {
424 0 : PetscFunctionBegin;
425 0 : PetscCall(PetscViewerAndFormatCreate(viewer,format,vf));
426 0 : (*vf)->data = ctx;
427 0 : PetscCall(EPSMonitorLGCreate(PetscObjectComm((PetscObject)viewer),NULL,"First Error Estimate","Log Error Estimate",1,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&(*vf)->lg));
428 0 : PetscFunctionReturn(PETSC_SUCCESS);
429 : }
430 :
431 : /*@C
432 : EPSMonitorAllDrawLG - Plots the error estimate of all unconverged
433 : approximations at each iteration of the eigensolver.
434 :
435 : Collective
436 :
437 : Input Parameters:
438 : + eps - eigensolver context
439 : . its - iteration number
440 : . nconv - number of converged eigenpairs so far
441 : . eigr - real part of the eigenvalues
442 : . eigi - imaginary part of the eigenvalues
443 : . errest - error estimates
444 : . nest - number of error estimates to display
445 : - vf - viewer and format for monitoring
446 :
447 : Options Database Key:
448 : . -eps_monitor_all draw::draw_lg - activates EPSMonitorAllDrawLG()
449 :
450 : Level: intermediate
451 :
452 : .seealso: EPSMonitorSet()
453 : @*/
454 0 : PetscErrorCode EPSMonitorAllDrawLG(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
455 : {
456 0 : PetscViewer viewer = vf->viewer;
457 0 : PetscDrawLG lg = vf->lg;
458 0 : PetscInt i,n = PetscMin(eps->nev,255);
459 0 : PetscReal *x,*y;
460 :
461 0 : PetscFunctionBegin;
462 0 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
463 0 : PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,8);
464 0 : PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,8);
465 0 : PetscCall(PetscViewerPushFormat(viewer,vf->format));
466 0 : if (its==1) {
467 0 : PetscCall(PetscDrawLGReset(lg));
468 0 : PetscCall(PetscDrawLGSetDimension(lg,n));
469 0 : PetscCall(PetscDrawLGSetLimits(lg,1,1,PetscLog10Real(eps->tol)-2,0.0));
470 : }
471 0 : PetscCall(PetscMalloc2(n,&x,n,&y));
472 0 : for (i=0;i<n;i++) {
473 0 : x[i] = (PetscReal)its;
474 0 : if (i < nest && errest[i] > 0.0) y[i] = PetscLog10Real(errest[i]);
475 0 : else y[i] = 0.0;
476 : }
477 0 : PetscCall(PetscDrawLGAddPoint(lg,x,y));
478 0 : if (its <= 20 || !(its % 5) || eps->reason) {
479 0 : PetscCall(PetscDrawLGDraw(lg));
480 0 : PetscCall(PetscDrawLGSave(lg));
481 : }
482 0 : PetscCall(PetscFree2(x,y));
483 0 : PetscCall(PetscViewerPopFormat(viewer));
484 0 : PetscFunctionReturn(PETSC_SUCCESS);
485 : }
486 :
487 : /*@C
488 : EPSMonitorAllDrawLGCreate - Creates the plotter for all the error estimates.
489 :
490 : Collective
491 :
492 : Input Parameters:
493 : + viewer - the viewer
494 : . format - the viewer format
495 : - ctx - an optional user context
496 :
497 : Output Parameter:
498 : . vf - the viewer and format context
499 :
500 : Level: intermediate
501 :
502 : .seealso: EPSMonitorSet()
503 : @*/
504 0 : PetscErrorCode EPSMonitorAllDrawLGCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
505 : {
506 0 : PetscFunctionBegin;
507 0 : PetscCall(PetscViewerAndFormatCreate(viewer,format,vf));
508 0 : (*vf)->data = ctx;
509 0 : PetscCall(EPSMonitorLGCreate(PetscObjectComm((PetscObject)viewer),NULL,"All Error Estimates","Log Error Estimate",1,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&(*vf)->lg));
510 0 : PetscFunctionReturn(PETSC_SUCCESS);
511 : }
512 :
513 : /*@C
514 : EPSMonitorConvergedDrawLG - Plots the number of converged eigenvalues
515 : at each iteration of the eigensolver.
516 :
517 : Collective
518 :
519 : Input Parameters:
520 : + eps - eigensolver context
521 : . its - iteration number
522 : . nconv - number of converged eigenpairs so far
523 : . eigr - real part of the eigenvalues
524 : . eigi - imaginary part of the eigenvalues
525 : . errest - error estimates
526 : . nest - number of error estimates to display
527 : - vf - viewer and format for monitoring
528 :
529 : Options Database Key:
530 : . -eps_monitor_conv draw::draw_lg - activates EPSMonitorConvergedDrawLG()
531 :
532 : Level: intermediate
533 :
534 : .seealso: EPSMonitorSet()
535 : @*/
536 0 : PetscErrorCode EPSMonitorConvergedDrawLG(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
537 : {
538 0 : PetscViewer viewer = vf->viewer;
539 0 : PetscDrawLG lg = vf->lg;
540 0 : PetscReal x,y;
541 :
542 0 : PetscFunctionBegin;
543 0 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
544 0 : PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,8);
545 0 : PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,8);
546 0 : PetscCall(PetscViewerPushFormat(viewer,vf->format));
547 0 : if (its==1) {
548 0 : PetscCall(PetscDrawLGReset(lg));
549 0 : PetscCall(PetscDrawLGSetDimension(lg,1));
550 0 : PetscCall(PetscDrawLGSetLimits(lg,1,1,0,eps->nev));
551 : }
552 0 : x = (PetscReal)its;
553 0 : y = (PetscReal)eps->nconv;
554 0 : PetscCall(PetscDrawLGAddPoint(lg,&x,&y));
555 0 : if (its <= 20 || !(its % 5) || eps->reason) {
556 0 : PetscCall(PetscDrawLGDraw(lg));
557 0 : PetscCall(PetscDrawLGSave(lg));
558 : }
559 0 : PetscCall(PetscViewerPopFormat(viewer));
560 0 : PetscFunctionReturn(PETSC_SUCCESS);
561 : }
562 :
563 : /*@C
564 : EPSMonitorConvergedDrawLGCreate - Creates the plotter for the convergence history.
565 :
566 : Collective
567 :
568 : Input Parameters:
569 : + viewer - the viewer
570 : . format - the viewer format
571 : - ctx - an optional user context
572 :
573 : Output Parameter:
574 : . vf - the viewer and format context
575 :
576 : Level: intermediate
577 :
578 : .seealso: EPSMonitorSet()
579 : @*/
580 0 : PetscErrorCode EPSMonitorConvergedDrawLGCreate(PetscViewer viewer,PetscViewerFormat format,void *ctx,PetscViewerAndFormat **vf)
581 : {
582 0 : SlepcConvMon mctx;
583 :
584 0 : PetscFunctionBegin;
585 0 : PetscCall(PetscViewerAndFormatCreate(viewer,format,vf));
586 0 : PetscCall(PetscNew(&mctx));
587 0 : mctx->ctx = ctx;
588 0 : (*vf)->data = (void*)mctx;
589 0 : PetscCall(EPSMonitorLGCreate(PetscObjectComm((PetscObject)viewer),NULL,"Convergence History","Number Converged",1,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&(*vf)->lg));
590 0 : PetscFunctionReturn(PETSC_SUCCESS);
591 : }
|