Subversion Repositories slepc-dev

Rev

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

Rev Author Line No. Line
1887 jroman 1
/*
2
      QEP routines related to monitors.
3
 
4
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5
   SLEPc - Scalable Library for Eigenvalue Problem Computations
2116 eromero 6
   Copyright (c) 2002-2010, Universidad Politecnica de Valencia, Spain
1887 jroman 7
 
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/>.
21
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
22
*/
23
 
24
#include "private/qepimpl.h"   /*I "slepcqep.h" I*/
25
 
26
#undef __FUNCT__  
27
#define __FUNCT__ "QEPMonitorSet"
28
/*@C
29
   QEPMonitorSet - Sets an ADDITIONAL function to be called at every
30
   iteration to monitor the error estimates for each requested eigenpair.
31
 
32
   Collective on QEP
33
 
34
   Input Parameters:
35
+  qep     - eigensolver context obtained from QEPCreate()
36
.  monitor - pointer to function (if this is PETSC_NULL, it turns off monitoring)
37
.  mctx    - [optional] context for private data for the
38
             monitor routine (use PETSC_NULL if no context is desired)
39
-  monitordestroy - [optional] routine that frees monitor context
40
          (may be PETSC_NULL)
41
 
42
   Calling Sequence of monitor:
43
$     monitor (QEP qep, int its, int nconv, PetscScalar *eigr, PetscScalar *eigi, PetscReal* errest, int nest, void *mctx)
44
 
45
+  qep    - quadratic eigensolver context obtained from QEPCreate()
46
.  its    - iteration number
47
.  nconv  - number of converged eigenpairs
48
.  eigr   - real part of the eigenvalues
49
.  eigi   - imaginary part of the eigenvalues
50
.  errest - relative error estimates for each eigenpair
51
.  nest   - number of error estimates
52
-  mctx   - optional monitoring context, as set by QEPMonitorSet()
53
 
54
   Options Database Keys:
2054 eromero 55
+    -qep_monitor          - print only the first error estimate
56
.    -qep_monitor_all      - print error estimates at each iteration
57
.    -qep_monitor_conv     - print the eigenvalue approximations only when
1887 jroman 58
      convergence has been reached
2054 eromero 59
.    -qep_monitor_draw     - sets line graph monitor for the first unconverged
60
      approximate eigenvalue
61
.    -qep_monitor_draw_all - sets line graph monitor for all unconverged
62
      approximate eigenvalue
63
-    -qep_monitor_cancel   - cancels all monitors that have been hardwired into
1887 jroman 64
      a code by calls to QEPMonitorSet(), but does not cancel those set via
65
      the options database.
66
 
67
   Notes:  
68
   Several different monitoring routines may be set by calling
69
   QEPMonitorSet() multiple times; all will be called in the
70
   order in which they were set.
71
 
72
   Level: intermediate
73
 
2134 eromero 74
.seealso: QEPMonitorFirst(), QEPMonitorAll(), QEPMonitorLG(), QEPMonitorLGAll(), QEPMonitorCancel()
1887 jroman 75
@*/
76
PetscErrorCode QEPMonitorSet(QEP qep,PetscErrorCode (*monitor)(QEP,PetscInt,PetscInt,PetscScalar*,PetscScalar*,PetscReal*,PetscInt,void*),
77
                             void *mctx,PetscErrorCode (*monitordestroy)(void*))
78
{
79
  PetscFunctionBegin;
2213 jroman 80
  PetscValidHeaderSpecific(qep,QEP_CLASSID,1);
1887 jroman 81
  if (qep->numbermonitors >= MAXQEPMONITORS) {
2214 jroman 82
    SETERRQ(((PetscObject)qep)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Too many QEP monitors set");
1887 jroman 83
  }
84
  qep->monitor[qep->numbermonitors]           = monitor;
85
  qep->monitorcontext[qep->numbermonitors]    = (void*)mctx;
86
  qep->monitordestroy[qep->numbermonitors++]  = monitordestroy;
87
  PetscFunctionReturn(0);
88
}
89
 
90
#undef __FUNCT__  
91
#define __FUNCT__ "QEPMonitorCancel"
92
/*@
93
   QEPMonitorCancel - Clears all monitors for a QEP object.
94
 
95
   Collective on QEP
96
 
97
   Input Parameters:
98
.  qep - eigensolver context obtained from QEPCreate()
99
 
100
   Options Database Key:
101
.    -qep_monitor_cancel - Cancels all monitors that have been hardwired
102
      into a code by calls to QEPMonitorSet(),
103
      but does not cancel those set via the options database.
104
 
105
   Level: intermediate
106
 
107
.seealso: QEPMonitorSet()
108
@*/
109
PetscErrorCode QEPMonitorCancel(QEP qep)
110
{
111
  PetscErrorCode ierr;
112
  PetscInt       i;
113
 
114
  PetscFunctionBegin;
2213 jroman 115
  PetscValidHeaderSpecific(qep,QEP_CLASSID,1);
1887 jroman 116
  for (i=0; i<qep->numbermonitors; i++) {
117
    if (qep->monitordestroy[i]) {
118
      ierr = (*qep->monitordestroy[i])(qep->monitorcontext[i]);CHKERRQ(ierr);
119
    }
120
  }
121
  qep->numbermonitors = 0;
122
  PetscFunctionReturn(0);
123
}
124
 
125
#undef __FUNCT__  
126
#define __FUNCT__ "QEPGetMonitorContext"
127
/*@C
128
   QEPGetMonitorContext - Gets the monitor context, as set by
2242 jroman 129
   QEPMonitorSet() for the FIRST monitor only.
1887 jroman 130
 
131
   Not Collective
132
 
133
   Input Parameter:
134
.  qep - eigensolver context obtained from QEPCreate()
135
 
136
   Output Parameter:
137
.  ctx - monitor context
138
 
139
   Level: intermediate
140
 
2242 jroman 141
.seealso: QEPMonitorSet(), QEPDefaultMonitor()
1887 jroman 142
@*/
143
PetscErrorCode QEPGetMonitorContext(QEP qep, void **ctx)
144
{
145
  PetscFunctionBegin;
2213 jroman 146
  PetscValidHeaderSpecific(qep,QEP_CLASSID,1);
1887 jroman 147
  *ctx =      (qep->monitorcontext[0]);
148
  PetscFunctionReturn(0);
149
}
150
 
151
#undef __FUNCT__  
2054 eromero 152
#define __FUNCT__ "QEPMonitorAll"
1887 jroman 153
/*@C
2054 eromero 154
   QEPMonitorAll - Print the current approximate values and
1887 jroman 155
   error estimates at each iteration of the quadratic eigensolver.
156
 
157
   Collective on QEP
158
 
159
   Input Parameters:
160
+  qep    - quadratic eigensolver context
161
.  its    - iteration number
162
.  nconv  - number of converged eigenpairs so far
163
.  eigr   - real part of the eigenvalues
164
.  eigi   - imaginary part of the eigenvalues
165
.  errest - error estimates
166
.  nest   - number of error estimates to display
167
-  dummy  - unused monitor context
168
 
169
   Level: intermediate
170
 
171
.seealso: QEPMonitorSet()
172
@*/
2054 eromero 173
PetscErrorCode QEPMonitorAll(QEP qep,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *dummy)
1887 jroman 174
{
175
  PetscErrorCode          ierr;
176
  PetscInt                i;
177
  PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor) dummy;
178
 
179
  PetscFunctionBegin;
180
  if (its) {
181
    if (!dummy) {ierr = PetscViewerASCIIMonitorCreate(((PetscObject)qep)->comm,"stdout",0,&viewer);CHKERRQ(ierr);}
182
    ierr = PetscViewerASCIIMonitorPrintf(viewer,"%3d QEP nconv=%d Values (Errors)",its,nconv);CHKERRQ(ierr);
183
    for (i=0;i<nest;i++) {
184
#if defined(PETSC_USE_COMPLEX)
185
      ierr = PetscViewerASCIIMonitorPrintf(viewer," %g%+gi",PetscRealPart(eigr[i]),PetscImaginaryPart(eigr[i]));CHKERRQ(ierr);
186
#else
187
      ierr = PetscViewerASCIIMonitorPrintf(viewer," %g",eigr[i]);CHKERRQ(ierr);
188
      if (eigi[i]!=0.0) { ierr = PetscViewerASCIIMonitorPrintf(viewer,"%+gi",eigi[i]);CHKERRQ(ierr); }
189
#endif
190
      ierr = PetscViewerASCIIMonitorPrintf(viewer," (%10.8e)",errest[i]);CHKERRQ(ierr);
191
    }
192
    ierr = PetscViewerASCIIMonitorPrintf(viewer,"\n");CHKERRQ(ierr);
193
    if (!dummy) {ierr = PetscViewerASCIIMonitorDestroy(viewer);CHKERRQ(ierr);}
194
  }
195
  PetscFunctionReturn(0);
196
}
197
 
198
#undef __FUNCT__  
199
#define __FUNCT__ "QEPMonitorFirst"
200
/*@C
201
   QEPMonitorFirst - Print the first unconverged approximate value and
202
   error estimate at each iteration of the quadratic eigensolver.
203
 
204
   Collective on QEP
205
 
206
   Input Parameters:
207
+  qep    - quadratic eigensolver context
208
.  its    - iteration number
209
.  nconv  - number of converged eigenpairs so far
210
.  eigr   - real part of the eigenvalues
211
.  eigi   - imaginary part of the eigenvalues
212
.  errest - error estimates
213
.  nest   - number of error estimates to display
214
-  dummy  - unused monitor context
215
 
216
   Level: intermediate
217
 
218
.seealso: QEPMonitorSet()
219
@*/
220
PetscErrorCode QEPMonitorFirst(QEP qep,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *dummy)
221
{
222
  PetscErrorCode          ierr;
223
  PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor) dummy;
224
 
225
  PetscFunctionBegin;
226
  if (its && nconv<nest) {
227
    if (!dummy) {ierr = PetscViewerASCIIMonitorCreate(((PetscObject)qep)->comm,"stdout",0,&viewer);CHKERRQ(ierr);}
228
    ierr = PetscViewerASCIIMonitorPrintf(viewer,"%3d QEP nconv=%d first unconverged value (error)",its,nconv);CHKERRQ(ierr);
229
#if defined(PETSC_USE_COMPLEX)
230
    ierr = PetscViewerASCIIMonitorPrintf(viewer," %g%+gi",PetscRealPart(eigr[nconv]),PetscImaginaryPart(eigr[nconv]));CHKERRQ(ierr);
231
#else
232
    ierr = PetscViewerASCIIMonitorPrintf(viewer," %g",eigr[nconv]);CHKERRQ(ierr);
233
    if (eigi[nconv]!=0.0) { ierr = PetscViewerASCIIMonitorPrintf(viewer,"%+gi",eigi[nconv]);CHKERRQ(ierr); }
234
#endif
235
    ierr = PetscViewerASCIIMonitorPrintf(viewer," (%10.8e)\n",errest[nconv]);CHKERRQ(ierr);
236
    if (!dummy) {ierr = PetscViewerASCIIMonitorDestroy(viewer);CHKERRQ(ierr);}
237
  }
238
  PetscFunctionReturn(0);
239
}
240
 
241
#undef __FUNCT__  
242
#define __FUNCT__ "QEPMonitorConverged"
243
/*@C
244
   QEPMonitorConverged - Print the approximate values and
245
   error estimates as they converge.
246
 
247
   Collective on QEP
248
 
249
   Input Parameters:
250
+  qep    - quadratic eigensolver context
251
.  its    - iteration number
252
.  nconv  - number of converged eigenpairs so far
253
.  eigr   - real part of the eigenvalues
254
.  eigi   - imaginary part of the eigenvalues
255
.  errest - error estimates
256
.  nest   - number of error estimates to display
257
-  dummy  - unused monitor context
258
 
259
   Level: intermediate
260
 
261
.seealso: QEPMonitorSet()
262
@*/
263
PetscErrorCode QEPMonitorConverged(QEP qep,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *dummy)
264
{
1951 jroman 265
  PetscErrorCode  ierr;
266
  PetscInt        i;
267
  QEPMONITOR_CONV *ctx = (QEPMONITOR_CONV*) dummy;
1887 jroman 268
 
269
  PetscFunctionBegin;
270
  if (!its) {
1951 jroman 271
    ctx->oldnconv = 0;
1887 jroman 272
  } else {
1951 jroman 273
    for (i=ctx->oldnconv;i<nconv;i++) {
274
      ierr = PetscViewerASCIIMonitorPrintf(ctx->viewer,"%3d QEP converged value (error) #%d",its,i);CHKERRQ(ierr);
1887 jroman 275
#if defined(PETSC_USE_COMPLEX)
1951 jroman 276
      ierr = PetscViewerASCIIMonitorPrintf(ctx->viewer," %g%+gi",PetscRealPart(eigr[i]),PetscImaginaryPart(eigr[i]));CHKERRQ(ierr);
1887 jroman 277
#else
1951 jroman 278
      ierr = PetscViewerASCIIMonitorPrintf(ctx->viewer," %g",eigr[i]);CHKERRQ(ierr);
279
      if (eigi[i]!=0.0) { ierr = PetscViewerASCIIMonitorPrintf(ctx->viewer,"%+gi",eigi[i]);CHKERRQ(ierr); }
1887 jroman 280
#endif
1951 jroman 281
      ierr = PetscViewerASCIIMonitorPrintf(ctx->viewer," (%10.8e)\n",errest[i]);CHKERRQ(ierr);
1887 jroman 282
    }
1951 jroman 283
    ctx->oldnconv = nconv;
1887 jroman 284
  }
285
  PetscFunctionReturn(0);
286
}
287
 
1951 jroman 288
PetscErrorCode QEPMonitorDestroy_Converged(QEPMONITOR_CONV *ctx)
289
{
290
  PetscErrorCode  ierr;
291
  PetscFunctionBegin;
292
  ierr = PetscViewerASCIIMonitorDestroy(ctx->viewer);CHKERRQ(ierr);
293
  ierr = PetscFree(ctx);CHKERRQ(ierr);
294
  PetscFunctionReturn(0);
295
}
296
 
1887 jroman 297
#undef __FUNCT__  
298
#define __FUNCT__ "QEPMonitorLG"
299
PetscErrorCode QEPMonitorLG(QEP qep,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *monctx)
300
{
301
  PetscViewer    viewer = (PetscViewer) monctx;
302
  PetscDraw      draw;
303
  PetscDrawLG    lg;
304
  PetscErrorCode ierr;
2054 eromero 305
  PetscReal      x,y;
306
 
307
  PetscFunctionBegin;
308
 
309
  if (!viewer) { viewer = PETSC_VIEWER_DRAW_(((PetscObject)qep)->comm); }
310
 
311
  ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
312
  ierr = PetscViewerDrawGetDrawLG(viewer,0,&lg);CHKERRQ(ierr);
313
  if (!its) {
314
    ierr = PetscDrawSetTitle(draw,"Error estimates");CHKERRQ(ierr);
315
    ierr = PetscDrawSetDoubleBuffer(draw);CHKERRQ(ierr);
316
    ierr = PetscDrawLGSetDimension(lg,1);CHKERRQ(ierr);
317
    ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);
318
    ierr = PetscDrawLGSetLimits(lg,0,1.0,log10(qep->tol)-2,0.0);CHKERRQ(ierr);
319
  }
320
 
321
  x = (PetscReal) its;
322
  if (errest[nconv] > 0.0) y = log10(errest[nconv]); else y = 0.0;
323
  ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
324
 
325
  ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
326
  PetscFunctionReturn(0);
327
}
328
 
329
#undef __FUNCT__  
330
#define __FUNCT__ "QEPMonitorLGAll"
331
PetscErrorCode QEPMonitorLGAll(QEP qep,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *monctx)
332
{
333
  PetscViewer    viewer = (PetscViewer) monctx;
334
  PetscDraw      draw;
335
  PetscDrawLG    lg;
336
  PetscErrorCode ierr;
1887 jroman 337
  PetscReal      *x,*y;
338
  PetscInt       i;
2011 jroman 339
  int            n = PetscMin(qep->nev,255);
1887 jroman 340
 
341
  PetscFunctionBegin;
342
 
343
  if (!viewer) { viewer = PETSC_VIEWER_DRAW_(((PetscObject)qep)->comm); }
344
 
345
  ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
346
  ierr = PetscViewerDrawGetDrawLG(viewer,0,&lg);CHKERRQ(ierr);
347
  if (!its) {
348
    ierr = PetscDrawSetTitle(draw,"Error estimates");CHKERRQ(ierr);
349
    ierr = PetscDrawSetDoubleBuffer(draw);CHKERRQ(ierr);
350
    ierr = PetscDrawLGSetDimension(lg,n);CHKERRQ(ierr);
351
    ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);
352
    ierr = PetscDrawLGSetLimits(lg,0,1.0,log10(qep->tol)-2,0.0);CHKERRQ(ierr);
353
  }
354
 
355
  ierr = PetscMalloc(sizeof(PetscReal)*n,&x);CHKERRQ(ierr);
356
  ierr = PetscMalloc(sizeof(PetscReal)*n,&y);CHKERRQ(ierr);
357
  for (i=0;i<n;i++) {
358
    x[i] = (PetscReal) its;
2054 eromero 359
    if (i < nest && errest[i] > 0.0) y[i] = log10(errest[i]);
360
    else y[i] = 0.0;
1887 jroman 361
  }
362
  ierr = PetscDrawLGAddPoint(lg,x,y);CHKERRQ(ierr);
363
 
364
  ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
365
  ierr = PetscFree(x);CHKERRQ(ierr);
366
  ierr = PetscFree(y);CHKERRQ(ierr);  
367
  PetscFunctionReturn(0);
368
}
369