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