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