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 48322 : PetscErrorCode EPSMonitor(EPS eps,PetscInt it,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest)
40 : {
41 48322 : PetscInt i,n = eps->numbermonitors;
42 :
43 48322 : PetscFunctionBegin;
44 53181 : for (i=0;i<n;i++) PetscCall((*eps->monitor[i])(eps,it,nconv,eigr,eigi,errest,nest,eps->monitorcontext[i]));
45 48322 : 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 125 : 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 125 : PetscFunctionBegin;
99 125 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
100 125 : PetscCheck(eps->numbermonitors<MAXEPSMONITORS,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Too many EPS monitors set");
101 125 : eps->monitor[eps->numbermonitors] = monitor;
102 125 : eps->monitorcontext[eps->numbermonitors] = (void*)mctx;
103 125 : eps->monitordestroy[eps->numbermonitors++] = monitordestroy;
104 125 : 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 649 : PetscErrorCode EPSMonitorCancel(EPS eps)
125 : {
126 649 : PetscInt i;
127 :
128 649 : PetscFunctionBegin;
129 649 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
130 774 : for (i=0; i<eps->numbermonitors; i++) {
131 125 : if (eps->monitordestroy[i]) PetscCall((*eps->monitordestroy[i])(&eps->monitorcontext[i]));
132 : }
133 649 : eps->numbermonitors = 0;
134 649 : 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 22 : static inline PetscErrorCode EPSMonitorPrintEval(EPS eps,PetscViewer viewer,PetscScalar er,PetscScalar ei)
162 : {
163 22 : PetscFunctionBegin;
164 22 : if (eps->problem_type==EPS_HEP || eps->problem_type==EPS_GHEP || eps->problem_type==EPS_BSE) PetscCall(PetscViewerASCIIPrintf(viewer," %g",(double)PetscRealPart(er)));
165 : else {
166 : #if defined(PETSC_USE_COMPLEX)
167 : PetscCall(PetscViewerASCIIPrintf(viewer," %g%+gi",(double)PetscRealPart(er),(double)PetscImaginaryPart(er)));
168 : #else
169 22 : PetscCall(PetscViewerASCIIPrintf(viewer," %g",(double)er));
170 22 : if (ei!=0.0) PetscCall(PetscViewerASCIIPrintf(viewer,"%+gi",(double)ei));
171 : #endif
172 : }
173 22 : PetscFunctionReturn(PETSC_SUCCESS);
174 : }
175 :
176 : /*@C
177 : EPSMonitorFirst - Print the first unconverged approximate value and
178 : error estimate at each iteration of the eigensolver.
179 :
180 : Collective
181 :
182 : Input Parameters:
183 : + eps - eigensolver context
184 : . its - iteration number
185 : . nconv - number of converged eigenpairs so far
186 : . eigr - real part of the eigenvalues
187 : . eigi - imaginary part of the eigenvalues
188 : . errest - error estimates
189 : . nest - number of error estimates to display
190 : - vf - viewer and format for monitoring
191 :
192 : Options Database Key:
193 : . -eps_monitor - activates EPSMonitorFirst()
194 :
195 : Level: intermediate
196 :
197 : .seealso: EPSMonitorSet(), EPSMonitorAll(), EPSMonitorConverged()
198 : @*/
199 2 : PetscErrorCode EPSMonitorFirst(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
200 : {
201 2 : PetscScalar er,ei;
202 2 : PetscViewer viewer = vf->viewer;
203 :
204 2 : PetscFunctionBegin;
205 2 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
206 2 : PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,8);
207 2 : if (its==1 && ((PetscObject)eps)->prefix) PetscCall(PetscViewerASCIIPrintf(viewer," Eigenvalue approximations and residual norms for %s solve.\n",((PetscObject)eps)->prefix));
208 2 : if (nconv<nest) {
209 2 : PetscCall(PetscViewerPushFormat(viewer,vf->format));
210 2 : PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)eps)->tablevel));
211 2 : PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " EPS nconv=%" PetscInt_FMT " first unconverged value (error)",its,nconv));
212 2 : PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
213 2 : er = eigr[nconv]; ei = eigi[nconv];
214 2 : PetscCall(STBackTransform(eps->st,1,&er,&ei));
215 2 : PetscCall(EPSMonitorPrintEval(eps,viewer,er,ei));
216 2 : PetscCall(PetscViewerASCIIPrintf(viewer," (%10.8e)\n",(double)errest[nconv]));
217 2 : PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
218 2 : PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)eps)->tablevel));
219 2 : PetscCall(PetscViewerPopFormat(viewer));
220 : }
221 2 : PetscFunctionReturn(PETSC_SUCCESS);
222 : }
223 :
224 : /*@C
225 : EPSMonitorAll - Print the current approximate values and
226 : error estimates at each iteration of the eigensolver.
227 :
228 : Collective
229 :
230 : Input Parameters:
231 : + eps - eigensolver context
232 : . its - iteration number
233 : . nconv - number of converged eigenpairs so far
234 : . eigr - real part of the eigenvalues
235 : . eigi - imaginary part of the eigenvalues
236 : . errest - error estimates
237 : . nest - number of error estimates to display
238 : - vf - viewer and format for monitoring
239 :
240 : Options Database Key:
241 : . -eps_monitor_all - activates EPSMonitorAll()
242 :
243 : Level: intermediate
244 :
245 : .seealso: EPSMonitorSet(), EPSMonitorFirst(), EPSMonitorConverged()
246 : @*/
247 9 : PetscErrorCode EPSMonitorAll(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
248 : {
249 9 : PetscInt i;
250 9 : PetscScalar er,ei;
251 9 : PetscViewer viewer = vf->viewer;
252 :
253 9 : PetscFunctionBegin;
254 9 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
255 9 : PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,8);
256 9 : PetscCall(PetscViewerPushFormat(viewer,vf->format));
257 9 : PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)eps)->tablevel));
258 9 : if (its==1 && ((PetscObject)eps)->prefix) PetscCall(PetscViewerASCIIPrintf(viewer," Eigenvalue approximations and residual norms for %s solve.\n",((PetscObject)eps)->prefix));
259 9 : PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " EPS nconv=%" PetscInt_FMT " Values (Errors)",its,nconv));
260 9 : PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
261 23 : for (i=0;i<nest;i++) {
262 14 : er = eigr[i]; ei = eigi[i];
263 14 : PetscCall(STBackTransform(eps->st,1,&er,&ei));
264 14 : PetscCall(EPSMonitorPrintEval(eps,viewer,er,ei));
265 14 : PetscCall(PetscViewerASCIIPrintf(viewer," (%10.8e)",(double)errest[i]));
266 : }
267 9 : PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
268 9 : PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
269 9 : PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)eps)->tablevel));
270 9 : PetscCall(PetscViewerPopFormat(viewer));
271 9 : PetscFunctionReturn(PETSC_SUCCESS);
272 : }
273 :
274 : /*@C
275 : EPSMonitorConverged - Print the approximate values and
276 : error estimates as they converge.
277 :
278 : Collective
279 :
280 : Input Parameters:
281 : + eps - eigensolver context
282 : . its - iteration number
283 : . nconv - number of converged eigenpairs so far
284 : . eigr - real part of the eigenvalues
285 : . eigi - imaginary part of the eigenvalues
286 : . errest - error estimates
287 : . nest - number of error estimates to display
288 : - vf - viewer and format for monitoring
289 :
290 : Options Database Key:
291 : . -eps_monitor_conv - activates EPSMonitorConverged()
292 :
293 : Level: intermediate
294 :
295 : .seealso: EPSMonitorSet(), EPSMonitorFirst(), EPSMonitorAll()
296 : @*/
297 1 : PetscErrorCode EPSMonitorConverged(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,PetscViewerAndFormat *vf)
298 : {
299 1 : PetscInt i;
300 1 : PetscScalar er,ei;
301 1 : PetscViewer viewer = vf->viewer;
302 1 : SlepcConvMon ctx;
303 :
304 1 : PetscFunctionBegin;
305 1 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
306 1 : PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,8);
307 1 : ctx = (SlepcConvMon)vf->data;
308 1 : if (its==1 && ((PetscObject)eps)->prefix) PetscCall(PetscViewerASCIIPrintf(viewer," Convergence history for %s solve.\n",((PetscObject)eps)->prefix));
309 1 : if (its==1) ctx->oldnconv = 0;
310 1 : if (ctx->oldnconv!=nconv) {
311 1 : PetscCall(PetscViewerPushFormat(viewer,vf->format));
312 1 : PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)eps)->tablevel));
313 7 : for (i=ctx->oldnconv;i<nconv;i++) {
314 6 : PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT " EPS converged value (error) #%" PetscInt_FMT,its,i));
315 6 : PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
316 6 : er = eigr[i]; ei = eigi[i];
317 6 : PetscCall(STBackTransform(eps->st,1,&er,&ei));
318 6 : PetscCall(EPSMonitorPrintEval(eps,viewer,er,ei));
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 : }
|