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