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