Subversion Repositories slepc-dev

Rev

Go to most recent revision | 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.
525 dsic.upv.es!antodo 3
*/
4
#include "src/eps/epsimpl.h"   /*I "slepceps.h" I*/
5
 
6
#undef __FUNCT__  
7
#define __FUNCT__ "EPSSetMonitor"
8
/*@C
9
   EPSSetMonitor - Sets an ADDITIONAL function to be called at every
10
   iteration to monitor the error estimates for each requested eigenpair.
11
 
12
   Collective on EPS
13
 
14
   Input Parameters:
15
+  eps     - eigensolver context obtained from EPSCreate()
1021 slepc 16
.  monitor - pointer to function (if this is PETSC_NULL, it turns off monitoring)
1287 slepc 17
.  mctx    - [optional] context for private data for the
525 dsic.upv.es!antodo 18
             monitor routine (use PETSC_NULL if no context is desired)
1287 slepc 19
-  monitordestroy - [optional] routine that frees monitor context
20
          (may be PETSC_NULL)
525 dsic.upv.es!antodo 21
 
22
   Calling Sequence of monitor:
617 dsic.upv.es!antodo 23
$     monitor (EPS eps, int its, int nconv, PetscScalar *eigr, PetscScalar *eigi, PetscReal* errest, int nest, void *mctx)
525 dsic.upv.es!antodo 24
 
25
+  eps    - eigensolver context obtained from EPSCreate()
26
.  its    - iteration number
27
.  nconv  - number of converged eigenpairs
617 dsic.upv.es!antodo 28
.  eigr   - real part of the eigenvalues
29
.  eigi   - imaginary part of the eigenvalues
663 dsic.upv.es!antodo 30
.  errest - relative error estimates for each eigenpair
525 dsic.upv.es!antodo 31
.  nest   - number of error estimates
32
-  mctx   - optional monitoring context, as set by EPSSetMonitor()
33
 
34
   Options Database Keys:
35
+    -eps_monitor        - print error estimates at each iteration
1287 slepc 36
.    -eps_xmonitor       - sets line graph monitor
525 dsic.upv.es!antodo 37
-    -eps_cancelmonitors - cancels all monitors that have been hardwired into
1287 slepc 38
      a code by calls to EPSSetMonitor(), but does not cancel those set via
525 dsic.upv.es!antodo 39
      the options database.
40
 
41
   Notes:  
42
   Several different monitoring routines may be set by calling
43
   EPSSetMonitor() multiple times; all will be called in the
44
   order in which they were set.
45
 
46
   Level: intermediate
47
 
1021 slepc 48
.seealso: EPSDefaultMonitor(), EPSClearMonitor()
525 dsic.upv.es!antodo 49
@*/
1288 slepc 50
PetscErrorCode EPSSetMonitor(EPS eps,PetscErrorCode (*monitor)(EPS,int,int,PetscScalar*,PetscScalar*,PetscReal*,int,void*),
51
                             void *mctx,PetscErrorCode (*monitordestroy)(void*))
525 dsic.upv.es!antodo 52
{
53
  PetscFunctionBegin;
54
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
55
  if (eps->numbermonitors >= MAXEPSMONITORS) {
56
    SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many EPS monitors set");
57
  }
58
  eps->monitor[eps->numbermonitors]           = monitor;
1287 slepc 59
  eps->monitorcontext[eps->numbermonitors]    = (void*)mctx;
60
  eps->monitordestroy[eps->numbermonitors++]  = monitordestroy;
525 dsic.upv.es!antodo 61
  PetscFunctionReturn(0);
62
}
63
 
64
#undef __FUNCT__  
65
#define __FUNCT__ "EPSClearMonitor"
1021 slepc 66
/*@
525 dsic.upv.es!antodo 67
   EPSClearMonitor - Clears all monitors for an EPS object.
68
 
69
   Collective on EPS
70
 
71
   Input Parameters:
72
.  eps - eigensolver context obtained from EPSCreate()
73
 
74
   Options Database Key:
75
.    -eps_cancelmonitors - Cancels all monitors that have been hardwired
1021 slepc 76
      into a code by calls to EPSSetMonitor(),
525 dsic.upv.es!antodo 77
      but does not cancel those set via the options database.
78
 
79
   Level: intermediate
80
 
623 dsic.upv.es!antodo 81
.seealso: EPSSetMonitor()
525 dsic.upv.es!antodo 82
@*/
83
PetscErrorCode EPSClearMonitor(EPS eps)
84
{
1287 slepc 85
  PetscErrorCode ierr;
86
  PetscInt       i;
87
 
525 dsic.upv.es!antodo 88
  PetscFunctionBegin;
89
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
1287 slepc 90
  for (i=0; i<eps->numbermonitors; i++) {
91
    if (eps->monitordestroy[i]) {
92
      ierr = (*eps->monitordestroy[i])(eps->monitorcontext[i]);CHKERRQ(ierr);
93
    }
94
  }
525 dsic.upv.es!antodo 95
  eps->numbermonitors = 0;
96
  PetscFunctionReturn(0);
97
}
98
 
99
#undef __FUNCT__  
100
#define __FUNCT__ "EPSGetMonitorContext"
101
/*@C
1021 slepc 102
   EPSGetMonitorContext - Gets the monitor context, as set by
525 dsic.upv.es!antodo 103
   EPSSetMonitor() for the FIRST monitor only.
104
 
105
   Not Collective
106
 
107
   Input Parameter:
108
.  eps - eigensolver context obtained from EPSCreate()
109
 
110
   Output Parameter:
111
.  ctx - monitor context
112
 
113
   Level: intermediate
114
 
1021 slepc 115
.seealso: EPSSetMonitor(), EPSDefaultMonitor()
525 dsic.upv.es!antodo 116
@*/
117
PetscErrorCode EPSGetMonitorContext(EPS eps, void **ctx)
118
{
119
  PetscFunctionBegin;
120
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
121
  *ctx =      (eps->monitorcontext[0]);
122
  PetscFunctionReturn(0);
123
}
124
 
125
#undef __FUNCT__  
126
#define __FUNCT__ "EPSDefaultMonitor"
127
/*@C
1021 slepc 128
   EPSDefaultMonitor - Print the current approximate values and
525 dsic.upv.es!antodo 129
   error estimates at each iteration of the eigensolver.
130
 
131
   Collective on EPS
132
 
133
   Input Parameters:
134
+  eps    - eigensolver context
135
.  its    - iteration number
136
.  nconv  - number of converged eigenpairs so far
137
.  eigr   - real part of the eigenvalues
138
.  eigi   - imaginary part of the eigenvalues
139
.  errest - error estimates
140
.  nest   - number of error estimates to display
141
-  dummy  - unused monitor context
142
 
143
   Level: intermediate
144
 
145
.seealso: EPSSetMonitor()
146
@*/
147
PetscErrorCode EPSDefaultMonitor(EPS eps,int its,int nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,int nest,void *dummy)
148
{
149
  PetscErrorCode ierr;
150
  int            i;
151
  PetscViewer    viewer = (PetscViewer) dummy;
152
 
153
  PetscFunctionBegin;
1220 slepc 154
  if (its) {
155
    if (!viewer) viewer = PETSC_VIEWER_STDOUT_(eps->comm);
156
    ierr = PetscViewerASCIIPrintf(viewer,"%3d EPS nconv=%d Values (Errors)",its,nconv);CHKERRQ(ierr);
157
    for (i=0;i<nest;i++) {
525 dsic.upv.es!antodo 158
#if defined(PETSC_USE_COMPLEX)
1220 slepc 159
      ierr = PetscViewerASCIIPrintf(viewer," %g%+gi",PetscRealPart(eigr[i]),PetscImaginaryPart(eigr[i]));CHKERRQ(ierr);
525 dsic.upv.es!antodo 160
#else
1220 slepc 161
      ierr = PetscViewerASCIIPrintf(viewer," %g",eigr[i]);CHKERRQ(ierr);
162
      if (eigi[i]!=0.0) { ierr = PetscViewerASCIIPrintf(viewer,"%+gi",eigi[i]);CHKERRQ(ierr); }
525 dsic.upv.es!antodo 163
#endif
1220 slepc 164
      ierr = PetscViewerASCIIPrintf(viewer," (%10.8e)",errest[i]);CHKERRQ(ierr);
165
    }
166
    ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
525 dsic.upv.es!antodo 167
  }
168
  PetscFunctionReturn(0);
169
}
623 dsic.upv.es!antodo 170
 
171
#undef __FUNCT__  
172
#define __FUNCT__ "EPSLGMonitor"
173
PetscErrorCode EPSLGMonitor(EPS eps,int its,int nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,int nest,void *monctx)
174
{
626 dsic.upv.es!antodo 175
  PetscViewer    viewer = (PetscViewer) monctx;
176
  PetscDraw      draw;
177
  PetscDrawLG    lg;
623 dsic.upv.es!antodo 178
  PetscErrorCode ierr;
179
  PetscReal      *x,*y;
180
  int            i,n = eps->nev;
626 dsic.upv.es!antodo 181
#if !defined(PETSC_USE_COMPLEX)
1004 slepc 182
  int            p;
626 dsic.upv.es!antodo 183
  PetscDraw      draw1;
184
  PetscDrawLG    lg1;
185
#endif
623 dsic.upv.es!antodo 186
 
187
  PetscFunctionBegin;
188
 
626 dsic.upv.es!antodo 189
  if (!viewer) { viewer = PETSC_VIEWER_DRAW_(eps->comm); }
190
 
191
  ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
192
  ierr = PetscViewerDrawGetDrawLG(viewer,0,&lg);CHKERRQ(ierr);
193
  if (!its) {
628 dsic.upv.es!antodo 194
    ierr = PetscDrawSetTitle(draw,"Error estimates");CHKERRQ(ierr);
626 dsic.upv.es!antodo 195
    ierr = PetscDrawSetDoubleBuffer(draw);CHKERRQ(ierr);
196
    ierr = PetscDrawLGSetDimension(lg,n);CHKERRQ(ierr);
197
    ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);
198
    ierr = PetscDrawLGSetLimits(lg,0,1.0,log10(eps->tol)-2,0.0);CHKERRQ(ierr);
199
  }
200
 
201
#if !defined(PETSC_USE_COMPLEX)
202
  if (eps->ishermitian) {
203
    ierr = PetscViewerDrawGetDraw(viewer,1,&draw1);CHKERRQ(ierr);
204
    ierr = PetscViewerDrawGetDrawLG(viewer,1,&lg1);CHKERRQ(ierr);
623 dsic.upv.es!antodo 205
    if (!its) {
628 dsic.upv.es!antodo 206
      ierr = PetscDrawSetTitle(draw1,"Approximate eigenvalues");CHKERRQ(ierr);
626 dsic.upv.es!antodo 207
      ierr = PetscDrawSetDoubleBuffer(draw1);CHKERRQ(ierr);
208
      ierr = PetscDrawLGSetDimension(lg1,n);CHKERRQ(ierr);
209
      ierr = PetscDrawLGReset(lg1);CHKERRQ(ierr);
210
      ierr = PetscDrawLGSetLimits(lg1,0,1.0,1.e20,-1.e20);CHKERRQ(ierr);
623 dsic.upv.es!antodo 211
    }
212
  }
626 dsic.upv.es!antodo 213
#endif
623 dsic.upv.es!antodo 214
 
215
  ierr = PetscMalloc(sizeof(PetscReal)*n,&x);CHKERRQ(ierr);
216
  ierr = PetscMalloc(sizeof(PetscReal)*n,&y);CHKERRQ(ierr);
217
  for (i=0;i<n;i++) {
218
    x[i] = (PetscReal) its;
219
    if (errest[i] > 0.0) y[i] = log10(errest[i]); else y[i] = 0.0;
220
  }
221
  ierr = PetscDrawLGAddPoint(lg,x,y);CHKERRQ(ierr);
626 dsic.upv.es!antodo 222
#if !defined(PETSC_USE_COMPLEX)
223
  if (eps->ishermitian) {
224
    ierr = PetscDrawLGAddPoint(lg1,x,eps->eigr);CHKERRQ(ierr);
1004 slepc 225
    ierr = PetscDrawGetPause(draw1,&p);CHKERRQ(ierr);
626 dsic.upv.es!antodo 226
    ierr = PetscDrawSetPause(draw1,0);CHKERRQ(ierr);    
227
    ierr = PetscDrawLGDraw(lg1);CHKERRQ(ierr);
1004 slepc 228
    ierr = PetscDrawSetPause(draw1,p);CHKERRQ(ierr);    
626 dsic.upv.es!antodo 229
  }
230
#endif  
705 dsic.upv.es!antodo 231
  ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
623 dsic.upv.es!antodo 232
  ierr = PetscFree(x);CHKERRQ(ierr);
233
  ierr = PetscFree(y);CHKERRQ(ierr);  
234
  PetscFunctionReturn(0);
235
}
1021 slepc 236