Subversion Repositories slepc-dev

Rev

Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
525 dsic.upv.es!antodo 1
/*
545 dsic.upv.es!jroman 2
      EPS routines related to monitors.
1376 slepc 3
 
4
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1672 slepc 5
   SLEPc - Scalable Library for Eigenvalue Problem Computations
2575 eromero 6
   Copyright (c) 2002-2011, Universitat Politecnica de Valencia, Spain
1376 slepc 7
 
1672 slepc 8
   This file is part of SLEPc.
9
 
10
   SLEPc is free software: you can redistribute it and/or modify it under  the
11
   terms of version 3 of the GNU Lesser General Public License as published by
12
   the Free Software Foundation.
13
 
14
   SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
15
   WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
16
   FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
17
   more details.
18
 
19
   You  should have received a copy of the GNU Lesser General  Public  License
20
   along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
1376 slepc 21
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
525 dsic.upv.es!antodo 22
*/
1376 slepc 23
 
2283 jroman 24
#include <private/epsimpl.h>   /*I "slepceps.h" I*/
525 dsic.upv.es!antodo 25
 
26
#undef __FUNCT__  
2313 jroman 27
#define __FUNCT__ "EPSMonitor"
28
/*
29
   Runs the user provided monitor routines, if any.
30
*/
31
PetscErrorCode EPSMonitor(EPS eps,PetscInt it,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest)
32
{
33
  PetscErrorCode ierr;
34
  PetscInt       i,n = eps->numbermonitors;
35
 
36
  PetscFunctionBegin;
37
  for (i=0;i<n;i++) {
38
    ierr = (*eps->monitor[i])(eps,it,nconv,eigr,eigi,errest,nest,eps->monitorcontext[i]);CHKERRQ(ierr);
39
  }
40
  PetscFunctionReturn(0);
41
}
42
 
43
#undef __FUNCT__  
1331 slepc 44
#define __FUNCT__ "EPSMonitorSet"
525 dsic.upv.es!antodo 45
/*@C
1331 slepc 46
   EPSMonitorSet - Sets an ADDITIONAL function to be called at every
525 dsic.upv.es!antodo 47
   iteration to monitor the error estimates for each requested eigenpair.
48
 
2328 jroman 49
   Logically Collective on EPS
525 dsic.upv.es!antodo 50
 
51
   Input Parameters:
52
+  eps     - eigensolver context obtained from EPSCreate()
1021 slepc 53
.  monitor - pointer to function (if this is PETSC_NULL, it turns off monitoring)
1287 slepc 54
.  mctx    - [optional] context for private data for the
525 dsic.upv.es!antodo 55
             monitor routine (use PETSC_NULL if no context is desired)
1287 slepc 56
-  monitordestroy - [optional] routine that frees monitor context
57
          (may be PETSC_NULL)
525 dsic.upv.es!antodo 58
 
59
   Calling Sequence of monitor:
617 dsic.upv.es!antodo 60
$     monitor (EPS eps, int its, int nconv, PetscScalar *eigr, PetscScalar *eigi, PetscReal* errest, int nest, void *mctx)
525 dsic.upv.es!antodo 61
 
62
+  eps    - eigensolver context obtained from EPSCreate()
63
.  its    - iteration number
64
.  nconv  - number of converged eigenpairs
617 dsic.upv.es!antodo 65
.  eigr   - real part of the eigenvalues
66
.  eigi   - imaginary part of the eigenvalues
663 dsic.upv.es!antodo 67
.  errest - relative error estimates for each eigenpair
525 dsic.upv.es!antodo 68
.  nest   - number of error estimates
1331 slepc 69
-  mctx   - optional monitoring context, as set by EPSMonitorSet()
525 dsic.upv.es!antodo 70
 
71
   Options Database Keys:
2048 eromero 72
+    -eps_monitor          - print only the first error estimate
73
.    -eps_monitor_all      - print error estimates at each iteration
74
.    -eps_monitor_conv     - print the eigenvalue approximations only when
1811 jroman 75
      convergence has been reached
2048 eromero 76
.    -eps_monitor_draw     - sets line graph monitor for the first unconverged
77
      approximate eigenvalue
78
.    -eps_monitor_draw_all - sets line graph monitor for all unconverged
79
      approximate eigenvalue
80
-    -eps_monitor_cancel   - cancels all monitors that have been hardwired into
1331 slepc 81
      a code by calls to EPSMonitorSet(), but does not cancel those set via
525 dsic.upv.es!antodo 82
      the options database.
83
 
84
   Notes:  
85
   Several different monitoring routines may be set by calling
1331 slepc 86
   EPSMonitorSet() multiple times; all will be called in the
525 dsic.upv.es!antodo 87
   order in which they were set.
88
 
89
   Level: intermediate
90
 
2654 jroman 91
.seealso: EPSMonitorFirst(), EPSMonitorAll(), EPSMonitorCancel()
525 dsic.upv.es!antodo 92
@*/
2351 jroman 93
PetscErrorCode EPSMonitorSet(EPS eps,PetscErrorCode (*monitor)(EPS,PetscInt,PetscInt,PetscScalar*,PetscScalar*,PetscReal*,PetscInt,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
525 dsic.upv.es!antodo 94
{
95
  PetscFunctionBegin;
2213 jroman 96
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
525 dsic.upv.es!antodo 97
  if (eps->numbermonitors >= MAXEPSMONITORS) {
2214 jroman 98
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Too many EPS monitors set");
525 dsic.upv.es!antodo 99
  }
100
  eps->monitor[eps->numbermonitors]           = monitor;
1287 slepc 101
  eps->monitorcontext[eps->numbermonitors]    = (void*)mctx;
102
  eps->monitordestroy[eps->numbermonitors++]  = monitordestroy;
525 dsic.upv.es!antodo 103
  PetscFunctionReturn(0);
104
}
105
 
106
#undef __FUNCT__  
1331 slepc 107
#define __FUNCT__ "EPSMonitorCancel"
1021 slepc 108
/*@
1331 slepc 109
   EPSMonitorCancel - Clears all monitors for an EPS object.
525 dsic.upv.es!antodo 110
 
2328 jroman 111
   Logically Collective on EPS
525 dsic.upv.es!antodo 112
 
113
   Input Parameters:
114
.  eps - eigensolver context obtained from EPSCreate()
115
 
116
   Options Database Key:
1331 slepc 117
.    -eps_monitor_cancel - Cancels all monitors that have been hardwired
118
      into a code by calls to EPSMonitorSet(),
525 dsic.upv.es!antodo 119
      but does not cancel those set via the options database.
120
 
121
   Level: intermediate
122
 
1331 slepc 123
.seealso: EPSMonitorSet()
525 dsic.upv.es!antodo 124
@*/
1331 slepc 125
PetscErrorCode EPSMonitorCancel(EPS eps)
525 dsic.upv.es!antodo 126
{
1287 slepc 127
  PetscErrorCode ierr;
128
  PetscInt       i;
129
 
525 dsic.upv.es!antodo 130
  PetscFunctionBegin;
2213 jroman 131
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1287 slepc 132
  for (i=0; i<eps->numbermonitors; i++) {
133
    if (eps->monitordestroy[i]) {
2311 jroman 134
      ierr = (*eps->monitordestroy[i])(&eps->monitorcontext[i]);CHKERRQ(ierr);
1287 slepc 135
    }
136
  }
525 dsic.upv.es!antodo 137
  eps->numbermonitors = 0;
138
  PetscFunctionReturn(0);
139
}
140
 
141
#undef __FUNCT__  
142
#define __FUNCT__ "EPSGetMonitorContext"
143
/*@C
1021 slepc 144
   EPSGetMonitorContext - Gets the monitor context, as set by
2242 jroman 145
   EPSMonitorSet() for the FIRST monitor only.
525 dsic.upv.es!antodo 146
 
147
   Not Collective
148
 
149
   Input Parameter:
150
.  eps - eigensolver context obtained from EPSCreate()
151
 
152
   Output Parameter:
153
.  ctx - monitor context
154
 
155
   Level: intermediate
156
 
2242 jroman 157
.seealso: EPSMonitorSet()
525 dsic.upv.es!antodo 158
@*/
2331 jroman 159
PetscErrorCode EPSGetMonitorContext(EPS eps,void **ctx)
525 dsic.upv.es!antodo 160
{
161
  PetscFunctionBegin;
2213 jroman 162
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
2317 jroman 163
  *ctx = eps->monitorcontext[0];
525 dsic.upv.es!antodo 164
  PetscFunctionReturn(0);
165
}
166
 
167
#undef __FUNCT__  
2041 eromero 168
#define __FUNCT__ "EPSMonitorAll"
525 dsic.upv.es!antodo 169
/*@C
2041 eromero 170
   EPSMonitorAll - Print the current approximate values and
525 dsic.upv.es!antodo 171
   error estimates at each iteration of the eigensolver.
172
 
173
   Collective on EPS
174
 
175
   Input Parameters:
176
+  eps    - eigensolver context
177
.  its    - iteration number
178
.  nconv  - number of converged eigenpairs so far
179
.  eigr   - real part of the eigenvalues
180
.  eigi   - imaginary part of the eigenvalues
181
.  errest - error estimates
182
.  nest   - number of error estimates to display
2670 jroman 183
-  monctx - monitor context (contains viewer, can be PETSC_NULL)
525 dsic.upv.es!antodo 184
 
185
   Level: intermediate
186
 
2328 jroman 187
.seealso: EPSMonitorSet(), EPSMonitorFirst(), EPSMonitorConverged()
525 dsic.upv.es!antodo 188
@*/
2670 jroman 189
PetscErrorCode EPSMonitorAll(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *monctx)
525 dsic.upv.es!antodo 190
{
2419 jroman 191
  PetscErrorCode ierr;
192
  PetscInt       i;
193
  PetscScalar    er,ei;
2670 jroman 194
  PetscViewer    viewer = monctx? (PetscViewer)monctx: PETSC_VIEWER_STDOUT_(((PetscObject)eps)->comm);
525 dsic.upv.es!antodo 195
 
196
  PetscFunctionBegin;
1220 slepc 197
  if (its) {
2419 jroman 198
    ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)eps)->tablevel);CHKERRQ(ierr);
199
    ierr = PetscViewerASCIIPrintf(viewer,"%3D EPS nconv=%D Values (Errors)",its,nconv);CHKERRQ(ierr);
1220 slepc 200
    for (i=0;i<nest;i++) {
2054 eromero 201
      er = eigr[i]; ei = eigi[i];
2331 jroman 202
      ierr = STBackTransform(eps->OP,1,&er,&ei);CHKERRQ(ierr);
525 dsic.upv.es!antodo 203
#if defined(PETSC_USE_COMPLEX)
2419 jroman 204
      ierr = PetscViewerASCIIPrintf(viewer," %G%+Gi",PetscRealPart(er),PetscImaginaryPart(er));CHKERRQ(ierr);
525 dsic.upv.es!antodo 205
#else
2419 jroman 206
      ierr = PetscViewerASCIIPrintf(viewer," %G",er);CHKERRQ(ierr);
207
      if (ei!=0.0) { ierr = PetscViewerASCIIPrintf(viewer,"%+Gi",ei);CHKERRQ(ierr); }
525 dsic.upv.es!antodo 208
#endif
2419 jroman 209
      ierr = PetscViewerASCIIPrintf(viewer," (%10.8e)",(double)errest[i]);CHKERRQ(ierr);
1220 slepc 210
    }
2419 jroman 211
    ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
212
    ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)eps)->tablevel);CHKERRQ(ierr);
525 dsic.upv.es!antodo 213
  }
214
  PetscFunctionReturn(0);
215
}
623 dsic.upv.es!antodo 216
 
217
#undef __FUNCT__  
1721 antodo 218
#define __FUNCT__ "EPSMonitorFirst"
219
/*@C
220
   EPSMonitorFirst - Print the first approximate value and
221
   error estimate at each iteration of the eigensolver.
222
 
223
   Collective on EPS
224
 
225
   Input Parameters:
226
+  eps    - eigensolver context
227
.  its    - iteration number
228
.  nconv  - number of converged eigenpairs so far
229
.  eigr   - real part of the eigenvalues
230
.  eigi   - imaginary part of the eigenvalues
231
.  errest - error estimates
232
.  nest   - number of error estimates to display
2670 jroman 233
-  monctx - monitor context (contains viewer, can be PETSC_NULL)
1721 antodo 234
 
235
   Level: intermediate
236
 
2328 jroman 237
.seealso: EPSMonitorSet(), EPSMonitorAll(), EPSMonitorConverged()
1721 antodo 238
@*/
2670 jroman 239
PetscErrorCode EPSMonitorFirst(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *monctx)
1721 antodo 240
{
2419 jroman 241
  PetscErrorCode ierr;
242
  PetscScalar    er,ei;
2670 jroman 243
  PetscViewer    viewer = monctx? (PetscViewer)monctx: PETSC_VIEWER_STDOUT_(((PetscObject)eps)->comm);
1721 antodo 244
 
245
  PetscFunctionBegin;
246
  if (its && nconv<nest) {
2419 jroman 247
    ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)eps)->tablevel);CHKERRQ(ierr);
248
    ierr = PetscViewerASCIIPrintf(viewer,"%3D EPS nconv=%D first unconverged value (error)",its,nconv);CHKERRQ(ierr);
2054 eromero 249
    er = eigr[nconv]; ei = eigi[nconv];
2331 jroman 250
    ierr = STBackTransform(eps->OP,1,&er,&ei);CHKERRQ(ierr);
1721 antodo 251
#if defined(PETSC_USE_COMPLEX)
2419 jroman 252
    ierr = PetscViewerASCIIPrintf(viewer," %G%+Gi",PetscRealPart(er),PetscImaginaryPart(er));CHKERRQ(ierr);
1721 antodo 253
#else
2419 jroman 254
    ierr = PetscViewerASCIIPrintf(viewer," %G",er);CHKERRQ(ierr);
255
    if (ei!=0.0) { ierr = PetscViewerASCIIPrintf(viewer,"%+Gi",ei);CHKERRQ(ierr); }
1721 antodo 256
#endif
2419 jroman 257
    ierr = PetscViewerASCIIPrintf(viewer," (%10.8e)\n",(double)errest[nconv]);CHKERRQ(ierr);
258
    ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)eps)->tablevel);CHKERRQ(ierr);
1721 antodo 259
  }
260
  PetscFunctionReturn(0);
261
}
262
 
263
#undef __FUNCT__  
264
#define __FUNCT__ "EPSMonitorConverged"
265
/*@C
266
   EPSMonitorConverged - Print the approximate values and
267
   error estimates as they converge.
268
 
269
   Collective on EPS
270
 
271
   Input Parameters:
272
+  eps    - eigensolver context
273
.  its    - iteration number
274
.  nconv  - number of converged eigenpairs so far
275
.  eigr   - real part of the eigenvalues
276
.  eigi   - imaginary part of the eigenvalues
277
.  errest - error estimates
278
.  nest   - number of error estimates to display
2670 jroman 279
-  monctx - monitor context
1721 antodo 280
 
2670 jroman 281
   Note:
282
   The monitor context must contain a struct with a PetscViewer and a
283
   PetscInt. In Fortran, pass a PETSC_NULL_OBJECT.
284
 
1721 antodo 285
   Level: intermediate
286
 
2328 jroman 287
.seealso: EPSMonitorSet(), EPSMonitorFirst(), EPSMonitorAll()
1721 antodo 288
@*/
2670 jroman 289
PetscErrorCode EPSMonitorConverged(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *monctx)
1721 antodo 290
{
2311 jroman 291
  PetscErrorCode   ierr;
292
  PetscInt         i;
293
  PetscScalar      er,ei;
2670 jroman 294
  PetscViewer      viewer;
295
  SlepcConvMonitor ctx = (SlepcConvMonitor)monctx;
1721 antodo 296
 
297
  PetscFunctionBegin;
2670 jroman 298
  if (!monctx) SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_WRONG,"Must provide a context for EPSMonitorConverged");
1721 antodo 299
  if (!its) {
1950 jroman 300
    ctx->oldnconv = 0;
1721 antodo 301
  } else {
2670 jroman 302
    viewer = ctx->viewer? ctx->viewer: PETSC_VIEWER_STDOUT_(((PetscObject)eps)->comm);
1950 jroman 303
    for (i=ctx->oldnconv;i<nconv;i++) {
2670 jroman 304
      ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)eps)->tablevel);CHKERRQ(ierr);
305
      ierr = PetscViewerASCIIPrintf(viewer,"%3D EPS converged value (error) #%D",its,i);CHKERRQ(ierr);
2054 eromero 306
      er = eigr[i]; ei = eigi[i];
2331 jroman 307
      ierr = STBackTransform(eps->OP,1,&er,&ei);CHKERRQ(ierr);
1721 antodo 308
#if defined(PETSC_USE_COMPLEX)
2670 jroman 309
      ierr = PetscViewerASCIIPrintf(viewer," %G%+Gi",PetscRealPart(er),PetscImaginaryPart(er));CHKERRQ(ierr);
1721 antodo 310
#else
2670 jroman 311
      ierr = PetscViewerASCIIPrintf(viewer," %G",er);CHKERRQ(ierr);
312
      if (ei!=0.0) { ierr = PetscViewerASCIIPrintf(viewer,"%+Gi",ei);CHKERRQ(ierr); }
1721 antodo 313
#endif
2670 jroman 314
      ierr = PetscViewerASCIIPrintf(viewer," (%10.8e)\n",(double)errest[i]);CHKERRQ(ierr);
315
      ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)eps)->tablevel);CHKERRQ(ierr);
1721 antodo 316
    }
1950 jroman 317
    ctx->oldnconv = nconv;
1721 antodo 318
  }
319
  PetscFunctionReturn(0);
320
}
321
 
2311 jroman 322
#undef __FUNCT__  
1331 slepc 323
#define __FUNCT__ "EPSMonitorLG"
1509 slepc 324
PetscErrorCode EPSMonitorLG(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *monctx)
623 dsic.upv.es!antodo 325
{
626 dsic.upv.es!antodo 326
  PetscViewer    viewer = (PetscViewer) monctx;
2041 eromero 327
  PetscDraw      draw,draw1;
328
  PetscDrawLG    lg,lg1;
623 dsic.upv.es!antodo 329
  PetscErrorCode ierr;
2041 eromero 330
  PetscReal      x,y,myeigr,p;
2054 eromero 331
  PetscScalar    er,ei;
623 dsic.upv.es!antodo 332
 
333
  PetscFunctionBegin;
1422 slepc 334
  if (!viewer) { viewer = PETSC_VIEWER_DRAW_(((PetscObject)eps)->comm); }
626 dsic.upv.es!antodo 335
  ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
336
  ierr = PetscViewerDrawGetDrawLG(viewer,0,&lg);CHKERRQ(ierr);
337
  if (!its) {
628 dsic.upv.es!antodo 338
    ierr = PetscDrawSetTitle(draw,"Error estimates");CHKERRQ(ierr);
626 dsic.upv.es!antodo 339
    ierr = PetscDrawSetDoubleBuffer(draw);CHKERRQ(ierr);
2041 eromero 340
    ierr = PetscDrawLGSetDimension(lg,1);CHKERRQ(ierr);
341
    ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);
342
    ierr = PetscDrawLGSetLimits(lg,0,1.0,log10(eps->tol)-2,0.0);CHKERRQ(ierr);
343
  }
344
 
345
  /* In the hermitian case, the eigenvalues are real and can be plotted */
346
  if (eps->ishermitian) {
347
    ierr = PetscViewerDrawGetDraw(viewer,1,&draw1);CHKERRQ(ierr);
348
    ierr = PetscViewerDrawGetDrawLG(viewer,1,&lg1);CHKERRQ(ierr);
349
    if (!its) {
350
      ierr = PetscDrawSetTitle(draw1,"Approximate eigenvalues");CHKERRQ(ierr);
351
      ierr = PetscDrawSetDoubleBuffer(draw1);CHKERRQ(ierr);
352
      ierr = PetscDrawLGSetDimension(lg1,1);CHKERRQ(ierr);
353
      ierr = PetscDrawLGReset(lg1);CHKERRQ(ierr);
354
      ierr = PetscDrawLGSetLimits(lg1,0,1.0,1.e20,-1.e20);CHKERRQ(ierr);
355
    }
356
  }
357
 
358
  x = (PetscReal) its;
359
  if (errest[nconv] > 0.0) y = log10(errest[nconv]); else y = 0.0;
360
  ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
361
  if (eps->ishermitian) {
2054 eromero 362
    er = eigr[nconv]; ei = eigi[nconv];
2331 jroman 363
    ierr = STBackTransform(eps->OP,1,&er,&ei);CHKERRQ(ierr);
2054 eromero 364
    myeigr = PetscRealPart(er);
2041 eromero 365
    ierr = PetscDrawLGAddPoint(lg1,&x,&myeigr);CHKERRQ(ierr);
366
    ierr = PetscDrawGetPause(draw1,&p);CHKERRQ(ierr);
367
    ierr = PetscDrawSetPause(draw1,0);CHKERRQ(ierr);    
368
    ierr = PetscDrawLGDraw(lg1);CHKERRQ(ierr);
369
    ierr = PetscDrawSetPause(draw1,p);CHKERRQ(ierr);    
370
  }
371
  ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
372
  PetscFunctionReturn(0);
373
}
374
 
375
#undef __FUNCT__  
376
#define __FUNCT__ "EPSMonitorLGAll"
377
PetscErrorCode EPSMonitorLGAll(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *monctx)
378
{
379
  PetscViewer    viewer = (PetscViewer) monctx;
380
  PetscDraw      draw,draw1;
381
  PetscDrawLG    lg,lg1;
382
  PetscErrorCode ierr;
383
  PetscReal      *x,*y,*myeigr,p;
384
  PetscInt       i,n = PetscMin(eps->nev,255);
2054 eromero 385
  PetscScalar    er,ei;
2041 eromero 386
 
387
  PetscFunctionBegin;
388
  if (!viewer) { viewer = PETSC_VIEWER_DRAW_(((PetscObject)eps)->comm); }
389
  ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
390
  ierr = PetscViewerDrawGetDrawLG(viewer,0,&lg);CHKERRQ(ierr);
391
  if (!its) {
392
    ierr = PetscDrawSetTitle(draw,"Error estimates");CHKERRQ(ierr);
393
    ierr = PetscDrawSetDoubleBuffer(draw);CHKERRQ(ierr);
626 dsic.upv.es!antodo 394
    ierr = PetscDrawLGSetDimension(lg,n);CHKERRQ(ierr);
395
    ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);
396
    ierr = PetscDrawLGSetLimits(lg,0,1.0,log10(eps->tol)-2,0.0);CHKERRQ(ierr);
397
  }
398
 
2041 eromero 399
  /* In the hermitian case, the eigenvalues are real and can be plotted */
626 dsic.upv.es!antodo 400
  if (eps->ishermitian) {
401
    ierr = PetscViewerDrawGetDraw(viewer,1,&draw1);CHKERRQ(ierr);
402
    ierr = PetscViewerDrawGetDrawLG(viewer,1,&lg1);CHKERRQ(ierr);
623 dsic.upv.es!antodo 403
    if (!its) {
628 dsic.upv.es!antodo 404
      ierr = PetscDrawSetTitle(draw1,"Approximate eigenvalues");CHKERRQ(ierr);
626 dsic.upv.es!antodo 405
      ierr = PetscDrawSetDoubleBuffer(draw1);CHKERRQ(ierr);
406
      ierr = PetscDrawLGSetDimension(lg1,n);CHKERRQ(ierr);
407
      ierr = PetscDrawLGReset(lg1);CHKERRQ(ierr);
408
      ierr = PetscDrawLGSetLimits(lg1,0,1.0,1.e20,-1.e20);CHKERRQ(ierr);
623 dsic.upv.es!antodo 409
    }
410
  }
411
 
412
  ierr = PetscMalloc(sizeof(PetscReal)*n,&x);CHKERRQ(ierr);
413
  ierr = PetscMalloc(sizeof(PetscReal)*n,&y);CHKERRQ(ierr);
414
  for (i=0;i<n;i++) {
415
    x[i] = (PetscReal) its;
2048 eromero 416
    if (i < nest && errest[i] > 0.0) y[i] = log10(errest[i]);
417
    else y[i] = 0.0;
623 dsic.upv.es!antodo 418
  }
419
  ierr = PetscDrawLGAddPoint(lg,x,y);CHKERRQ(ierr);
626 dsic.upv.es!antodo 420
  if (eps->ishermitian) {
2041 eromero 421
    ierr = PetscMalloc(sizeof(PetscReal)*n,&myeigr);CHKERRQ(ierr);
2048 eromero 422
    for(i=0;i<n;i++) {
2054 eromero 423
      er = eigr[i]; ei = eigi[i];
2331 jroman 424
      ierr = STBackTransform(eps->OP,1,&er,&ei);CHKERRQ(ierr);
2054 eromero 425
      if (i < nest) myeigr[i] = PetscRealPart(er);
2048 eromero 426
      else myeigr[i] = 0.0;
427
    }
2041 eromero 428
    ierr = PetscDrawLGAddPoint(lg1,x,myeigr);CHKERRQ(ierr);
1004 slepc 429
    ierr = PetscDrawGetPause(draw1,&p);CHKERRQ(ierr);
626 dsic.upv.es!antodo 430
    ierr = PetscDrawSetPause(draw1,0);CHKERRQ(ierr);    
431
    ierr = PetscDrawLGDraw(lg1);CHKERRQ(ierr);
1004 slepc 432
    ierr = PetscDrawSetPause(draw1,p);CHKERRQ(ierr);    
2041 eromero 433
    ierr = PetscFree(myeigr);CHKERRQ(ierr);
626 dsic.upv.es!antodo 434
  }
705 dsic.upv.es!antodo 435
  ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
623 dsic.upv.es!antodo 436
  ierr = PetscFree(x);CHKERRQ(ierr);
437
  ierr = PetscFree(y);CHKERRQ(ierr);  
438
  PetscFunctionReturn(0);
439
}
1021 slepc 440