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
538 dsic.upv.es!jroman 1
/*                      
6 dsic.upv.es!jroman 2
 
538 dsic.upv.es!jroman 3
   SLEPc eigensolver: "arnoldi"
4
 
5
   Method: Explicitly Restarted Arnoldi
6
 
7
   Algorithm:
8
 
919 dsic.upv.es!antodo 9
       Arnoldi method with explicit restart and deflation.
538 dsic.upv.es!jroman 10
 
11
   References:
12
 
919 dsic.upv.es!antodo 13
       [1] "Arnoldi Methods in SLEPc", SLEPc Technical Report STR-4,
14
           available at http://www.grycap.upv.es/slepc.
538 dsic.upv.es!jroman 15
 
1217 slepc 16
   Last update: Oct 2006
538 dsic.upv.es!jroman 17
 
1376 slepc 18
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
19
      SLEPc - Scalable Library for Eigenvalue Problem Computations
20
      Copyright (c) 2002-2007, Universidad Politecnica de Valencia, Spain
21
 
22
      This file is part of SLEPc. See the README file for conditions of use
23
      and additional information.
24
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6 dsic.upv.es!jroman 25
*/
1376 slepc 26
 
1098 slepc 27
#include "src/eps/epsimpl.h"                /*I "slepceps.h" I*/
6 dsic.upv.es!jroman 28
#include "slepcblaslapack.h"
29
 
1083 slepc 30
typedef struct {
31
  PetscTruth delayed;
32
} EPS_ARNOLDI;
33
 
6 dsic.upv.es!jroman 34
#undef __FUNCT__  
35
#define __FUNCT__ "EPSSetUp_ARNOLDI"
476 dsic.upv.es!antodo 36
PetscErrorCode EPSSetUp_ARNOLDI(EPS eps)
6 dsic.upv.es!jroman 37
{
476 dsic.upv.es!antodo 38
  PetscErrorCode ierr;
982 slepc 39
  PetscInt       N;
6 dsic.upv.es!jroman 40
 
41
  PetscFunctionBegin;
1343 slepc 42
  ierr = VecGetSize(eps->IV[0],&N);CHKERRQ(ierr);
6 dsic.upv.es!jroman 43
  if (eps->ncv) {
44
    if (eps->ncv<eps->nev) SETERRQ(1,"The value of ncv must be at least nev");
45
  }
651 dsic.upv.es!antodo 46
  else eps->ncv = PetscMin(N,PetscMax(2*eps->nev,eps->nev+15));
1220 slepc 47
  if (!eps->max_it) eps->max_it = PetscMax(100,2*N/eps->ncv);
1181 slepc 48
  if (eps->ishermitian && (eps->which==EPS_LARGEST_IMAGINARY || eps->which==EPS_SMALLEST_IMAGINARY))
49
    SETERRQ(1,"Wrong value of eps->which");
1220 slepc 50
 
259 dsic.upv.es!antodo 51
  ierr = EPSAllocateSolution(eps);CHKERRQ(ierr);
1040 slepc 52
  ierr = PetscFree(eps->T);CHKERRQ(ierr);
508 dsic.upv.es!antodo 53
  ierr = PetscMalloc(eps->ncv*eps->ncv*sizeof(PetscScalar),&eps->T);CHKERRQ(ierr);
879 ono.com!jroman 54
  if (eps->solverclass==EPS_TWO_SIDE) {
1040 slepc 55
    ierr = PetscFree(eps->Tl);CHKERRQ(ierr);
879 ono.com!jroman 56
    ierr = PetscMalloc(eps->ncv*eps->ncv*sizeof(PetscScalar),&eps->Tl);CHKERRQ(ierr);
57
  }
1345 slepc 58
  ierr = EPSDefaultGetWork(eps,2);CHKERRQ(ierr);
6 dsic.upv.es!jroman 59
  PetscFunctionReturn(0);
60
}
61
 
62
#undef __FUNCT__  
431 dsic.upv.es!antodo 63
#define __FUNCT__ "EPSBasicArnoldi"
538 dsic.upv.es!jroman 64
/*
65
   EPSBasicArnoldi - Computes an m-step Arnoldi factorization. The first k
66
   columns are assumed to be locked and therefore they are not modified. On
67
   exit, the following relation is satisfied:
68
 
69
                    OP * V - V * H = f * e_m^T
70
 
71
   where the columns of V are the Arnoldi vectors (which are B-orthonormal),
591 dsic.upv.es!jroman 72
   H is an upper Hessenberg matrix, f is the residual vector and e_m is
73
   the m-th vector of the canonical basis. The vector f is B-orthogonal to
74
   the columns of V. On exit, beta contains the B-norm of f and the next
75
   Arnoldi vector can be computed as v_{m+1} = f / beta.
538 dsic.upv.es!jroman 76
*/
1113 slepc 77
PetscErrorCode EPSBasicArnoldi(EPS eps,PetscTruth trans,PetscScalar *H,Vec *V,int k,int *M,Vec f,PetscReal *beta,PetscTruth *breakdown)
431 dsic.upv.es!antodo 78
{
476 dsic.upv.es!antodo 79
  PetscErrorCode ierr;
1049 slepc 80
  int            j,m = *M;
476 dsic.upv.es!antodo 81
  PetscReal      norm;
431 dsic.upv.es!antodo 82
 
83
  PetscFunctionBegin;
574 dsic.upv.es!antodo 84
  for (j=k;j<m-1;j++) {
879 ono.com!jroman 85
    if (trans) { ierr = STApplyTranspose(eps->OP,V[j],V[j+1]);CHKERRQ(ierr); }
86
    else { ierr = STApply(eps->OP,V[j],V[j+1]);CHKERRQ(ierr); }
1345 slepc 87
    ierr = IPOrthogonalize(eps->ip,eps->nds,PETSC_NULL,eps->DS,V[j+1],PETSC_NULL,PETSC_NULL,PETSC_NULL,eps->work[0]);CHKERRQ(ierr);
88
    ierr = IPOrthogonalize(eps->ip,j+1,PETSC_NULL,V,V[j+1],H+m*j,&norm,breakdown,eps->work[0]);CHKERRQ(ierr);
574 dsic.upv.es!antodo 89
    H[(m+1)*j+1] = norm;
1113 slepc 90
    if (*breakdown) {
1049 slepc 91
      *M = j+1;
92
      *beta = norm;
93
      PetscFunctionReturn(0);
828 dsic.upv.es!antodo 94
    } else {
95
      ierr = VecScale(V[j+1],1/norm);CHKERRQ(ierr);
549 dsic.upv.es!antodo 96
    }
431 dsic.upv.es!antodo 97
  }
574 dsic.upv.es!antodo 98
  ierr = STApply(eps->OP,V[m-1],f);CHKERRQ(ierr);
1345 slepc 99
  ierr = IPOrthogonalize(eps->ip,eps->nds,PETSC_NULL,eps->DS,f,PETSC_NULL,PETSC_NULL,PETSC_NULL,eps->work[0]);CHKERRQ(ierr);
100
  ierr = IPOrthogonalize(eps->ip,m,PETSC_NULL,V,f,H+m*(m-1),beta,PETSC_NULL,eps->work[0]);CHKERRQ(ierr);
431 dsic.upv.es!antodo 101
  PetscFunctionReturn(0);
102
}
103
 
104
#undef __FUNCT__  
1083 slepc 105
#define __FUNCT__ "EPSDelayedArnoldi"
1084 slepc 106
/*
107
   EPSDelayedArnoldi - This function is equivalent to EPSBasicArnoldi but
108
   performs the computation in a different way. The main idea is that
109
   reorthogonalization is delayed to the next Arnoldi step. This version is
1186 slepc 110
   more scalable but in some cases convergence may stagnate.
1084 slepc 111
*/
1113 slepc 112
PetscErrorCode EPSDelayedArnoldi(EPS eps,PetscScalar *H,Vec *V,int k,int *M,Vec f,PetscReal *beta,PetscTruth *breakdown)
989 slepc 113
{
114
  PetscErrorCode ierr;
1060 slepc 115
  int            i,j,m=*M;
1013 slepc 116
  Vec            w,u,t;
1164 slepc 117
  PetscScalar    shh[100],*lhh,dot,dot2;
1114 slepc 118
  PetscReal      norm1=0.0,norm2;
1013 slepc 119
 
120
  PetscFunctionBegin;
121
  if (m<=100) lhh = shh;
122
  else { ierr = PetscMalloc(m*sizeof(PetscScalar),&lhh);CHKERRQ(ierr); }
123
  ierr = VecDuplicate(f,&w);CHKERRQ(ierr);
124
  ierr = VecDuplicate(f,&u);CHKERRQ(ierr);
125
  ierr = VecDuplicate(f,&t);CHKERRQ(ierr);
126
 
127
  for (j=k;j<m;j++) {
1015 slepc 128
    ierr = STApply(eps->OP,V[j],f);CHKERRQ(ierr);
1345 slepc 129
    ierr = IPOrthogonalize(eps->ip,eps->nds,PETSC_NULL,eps->DS,f,PETSC_NULL,PETSC_NULL,PETSC_NULL,eps->work[0]);CHKERRQ(ierr);
1013 slepc 130
 
1345 slepc 131
    ierr = IPMInnerProductBegin(eps->ip,j+1,f,V,H+m*j);CHKERRQ(ierr);
1015 slepc 132
    if (j>k) {
1345 slepc 133
      ierr = IPMInnerProductBegin(eps->ip,j,V[j],V,lhh);CHKERRQ(ierr);
134
      ierr = IPInnerProductBegin(eps->ip,V[j],V[j],&dot);CHKERRQ(ierr);
1033 slepc 135
    }
136
    if (j>k+1) {
1345 slepc 137
      ierr = IPNormBegin(eps->ip,u,&norm2);CHKERRQ(ierr);
1164 slepc 138
      ierr = VecDotBegin(u,V[j-2],&dot2);CHKERRQ(ierr);
1017 slepc 139
    }
1033 slepc 140
 
1345 slepc 141
    ierr = IPMInnerProductEnd(eps->ip,j+1,f,V,H+m*j);CHKERRQ(ierr);
1017 slepc 142
    if (j>k) {
1345 slepc 143
      ierr = IPMInnerProductEnd(eps->ip,j,V[j],V,lhh);CHKERRQ(ierr);
144
      ierr = IPInnerProductEnd(eps->ip,V[j],V[j],&dot);CHKERRQ(ierr);
1033 slepc 145
    }
146
    if (j>k+1) {
1345 slepc 147
      ierr = IPNormEnd(eps->ip,u,&norm2);CHKERRQ(ierr);
1164 slepc 148
      ierr = VecDotEnd(u,V[j-2],&dot2);CHKERRQ(ierr);
149
      if (PetscAbsScalar(dot2/norm2) > PETSC_MACHINE_EPSILON) {
1113 slepc 150
        *breakdown = PETSC_TRUE;
1060 slepc 151
        *M = j-1;
152
        *beta = norm2;
1065 slepc 153
 
154
        if (m>100) { ierr = PetscFree(lhh);CHKERRQ(ierr); }
155
        ierr = VecDestroy(w);CHKERRQ(ierr);
156
        ierr = VecDestroy(u);CHKERRQ(ierr);
157
        ierr = VecDestroy(t);CHKERRQ(ierr);
1060 slepc 158
        PetscFunctionReturn(0);
159
      }
1033 slepc 160
    }
161
 
1058 slepc 162
    if (j>k) {      
1085 slepc 163
      norm1 = sqrt(PetscRealPart(dot));
1015 slepc 164
      for (i=0;i<j;i++)
165
        H[m*j+i] = H[m*j+i]/norm1;
1060 slepc 166
      H[m*j+j] = H[m*j+j]/dot;
1058 slepc 167
 
1015 slepc 168
      ierr = VecCopy(V[j],t);CHKERRQ(ierr);
169
      ierr = VecScale(V[j],1.0/norm1);CHKERRQ(ierr);
170
      ierr = VecScale(f,1.0/norm1);CHKERRQ(ierr);
1013 slepc 171
    }
172
 
1015 slepc 173
    ierr = VecSet(w,0.0);CHKERRQ(ierr);
174
    ierr = VecMAXPY(w,j+1,H+m*j,V);CHKERRQ(ierr);
175
    ierr = VecAXPY(f,-1.0,w);CHKERRQ(ierr);
176
 
1045 slepc 177
    if (j>k) {
1033 slepc 178
      ierr = VecSet(w,0.0);CHKERRQ(ierr);
179
      ierr = VecMAXPY(w,j,lhh,V);CHKERRQ(ierr);
180
      ierr = VecAXPY(t,-1.0,w);CHKERRQ(ierr);
181
      for (i=0;i<j;i++)
182
        H[m*(j-1)+i] += lhh[i];
183
    }
184
 
1016 slepc 185
    if (j>k+1) {
186
      ierr = VecCopy(u,V[j-1]);CHKERRQ(ierr);
187
      ierr = VecScale(V[j-1],1.0/norm2);CHKERRQ(ierr);
188
      H[m*(j-2)+j-1] = norm2;
189
    }
190
 
1015 slepc 191
    if (j<m-1) {
1045 slepc 192
      ierr = VecCopy(f,V[j+1]);CHKERRQ(ierr);
193
      ierr = VecCopy(t,u);CHKERRQ(ierr);
1015 slepc 194
    }
1013 slepc 195
  }
196
 
1345 slepc 197
  ierr = IPNorm(eps->ip,t,&norm2);CHKERRQ(ierr);
1032 slepc 198
  ierr = VecScale(t,1.0/norm2);CHKERRQ(ierr);
1013 slepc 199
  ierr = VecCopy(t,V[m-1]);CHKERRQ(ierr);
1032 slepc 200
  H[m*(m-2)+m-1] = norm2;
1013 slepc 201
 
1345 slepc 202
  ierr = IPMInnerProduct(eps->ip,m,f,V,lhh);CHKERRQ(ierr);
1015 slepc 203
 
1013 slepc 204
  ierr = VecSet(w,0.0);CHKERRQ(ierr);
205
  ierr = VecMAXPY(w,m,lhh,V);CHKERRQ(ierr);
206
  ierr = VecAXPY(f,-1.0,w);CHKERRQ(ierr);
1015 slepc 207
  for (i=0;i<m;i++)
1013 slepc 208
    H[m*(m-1)+i] += lhh[i];
1015 slepc 209
 
1345 slepc 210
  ierr = IPNorm(eps->ip,f,beta);CHKERRQ(ierr);
1013 slepc 211
  ierr = VecScale(f,1.0 / *beta);CHKERRQ(ierr);
1113 slepc 212
  *breakdown = PETSC_FALSE;
213
 
1013 slepc 214
  if (m>100) { ierr = PetscFree(lhh);CHKERRQ(ierr); }
215
  ierr = VecDestroy(w);CHKERRQ(ierr);
216
  ierr = VecDestroy(u);CHKERRQ(ierr);
217
  ierr = VecDestroy(t);CHKERRQ(ierr);
218
 
219
  PetscFunctionReturn(0);
220
}
221
 
222
#undef __FUNCT__  
1117 slepc 223
#define __FUNCT__ "EPSDelayedArnoldi1"
1186 slepc 224
/*
225
   EPSDelayedArnoldi1 - This function is similar to EPSDelayedArnoldi1,
226
   but without reorthogonalization (only delayed normalization).
227
*/
1117 slepc 228
PetscErrorCode EPSDelayedArnoldi1(EPS eps,PetscScalar *H,Vec *V,int k,int *M,Vec f,PetscReal *beta,PetscTruth *breakdown)
229
{
230
  PetscErrorCode ierr;
231
  int            i,j,m=*M;
232
  Vec            w;
233
  PetscScalar    dot;
234
  PetscReal      norm=0.0;
235
 
236
  PetscFunctionBegin;
237
  ierr = VecDuplicate(f,&w);CHKERRQ(ierr);
238
 
239
  for (j=k;j<m;j++) {
240
    ierr = STApply(eps->OP,V[j],f);CHKERRQ(ierr);
1345 slepc 241
    ierr = IPOrthogonalize(eps->ip,eps->nds,PETSC_NULL,eps->DS,f,PETSC_NULL,PETSC_NULL,PETSC_NULL,eps->work[0]);CHKERRQ(ierr);
1117 slepc 242
 
1345 slepc 243
    ierr = IPMInnerProductBegin(eps->ip,j+1,f,V,H+m*j);CHKERRQ(ierr);
1117 slepc 244
    if (j>k) {
1345 slepc 245
      ierr = IPInnerProductBegin(eps->ip,V[j],V[j],&dot);CHKERRQ(ierr);
1117 slepc 246
    }
247
 
1345 slepc 248
    ierr = IPMInnerProductEnd(eps->ip,j+1,f,V,H+m*j);CHKERRQ(ierr);
1117 slepc 249
    if (j>k) {
1345 slepc 250
      ierr = IPInnerProductEnd(eps->ip,V[j],V[j],&dot);CHKERRQ(ierr);
1117 slepc 251
    }
252
 
253
    if (j>k) {      
254
      norm = sqrt(PetscRealPart(dot));
255
      ierr = VecScale(V[j],1.0/norm);CHKERRQ(ierr);
256
      H[m*(j-1)+j] = norm;
257
 
258
      for (i=0;i<j;i++)
259
        H[m*j+i] = H[m*j+i]/norm;
260
      H[m*j+j] = H[m*j+j]/dot;      
261
      ierr = VecScale(f,1.0/norm);CHKERRQ(ierr);
262
    }
263
 
264
    ierr = VecSet(w,0.0);CHKERRQ(ierr);
265
    ierr = VecMAXPY(w,j+1,H+m*j,V);CHKERRQ(ierr);
266
    ierr = VecAXPY(f,-1.0,w);CHKERRQ(ierr);
267
 
268
    if (j<m-1) {
269
      ierr = VecCopy(f,V[j+1]);CHKERRQ(ierr);
270
    }
271
  }
272
 
1345 slepc 273
  ierr = IPNorm(eps->ip,f,beta);CHKERRQ(ierr);
1117 slepc 274
  ierr = VecScale(f,1.0 / *beta);CHKERRQ(ierr);
275
  *breakdown = PETSC_FALSE;
276
 
277
  ierr = VecDestroy(w);CHKERRQ(ierr);
278
  PetscFunctionReturn(0);
279
}
280
 
281
#undef __FUNCT__  
879 ono.com!jroman 282
#define __FUNCT__ "ArnoldiResiduals"
283
/*
284
   EPSArnoldiResiduals - Computes the 2-norm of the residual vectors from
285
   the information provided by the m-step Arnoldi factorization,
286
 
287
                    OP * V - V * H = f * e_m^T
288
 
289
   For the approximate eigenpair (k_i,V*y_i), the residual norm is computed as
290
   |beta*y(end,i)| where beta is the norm of f and y is the corresponding
291
   eigenvector of H.
292
*/
1057 slepc 293
PetscErrorCode ArnoldiResiduals(PetscScalar *H,int ldh,PetscScalar *U,PetscReal beta,int nconv,int ncv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscScalar *work)
879 ono.com!jroman 294
{
883 ono.com!jroman 295
#if defined(SLEPC_MISSING_LAPACK_TREVC)
296
  PetscFunctionBegin;
297
  SETERRQ(PETSC_ERR_SUP,"TREVC - Lapack routine is unavailable.");
298
#else
879 ono.com!jroman 299
  PetscErrorCode ierr;
300
  int            i,mout,info;
301
  PetscScalar    *Y=work+4*ncv;
1176 slepc 302
  PetscReal      w;
879 ono.com!jroman 303
#if defined(PETSC_USE_COMPLEX)
304
  PetscReal      *rwork=(PetscReal*)(work+3*ncv);
305
#endif
306
 
307
  PetscFunctionBegin;
308
 
309
  /* Compute eigenvectors Y of H */
310
  ierr = PetscMemcpy(Y,U,ncv*ncv*sizeof(PetscScalar));CHKERRQ(ierr);
1339 slepc 311
  ierr = PetscLogEventBegin(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
879 ono.com!jroman 312
#if !defined(PETSC_USE_COMPLEX)
1057 slepc 313
  LAPACKtrevc_("R","B",PETSC_NULL,&ncv,H,&ldh,PETSC_NULL,&ncv,Y,&ncv,&ncv,&mout,work,&info,1,1);
879 ono.com!jroman 314
#else
1057 slepc 315
  LAPACKtrevc_("R","B",PETSC_NULL,&ncv,H,&ldh,PETSC_NULL,&ncv,Y,&ncv,&ncv,&mout,work,rwork,&info,1,1);
879 ono.com!jroman 316
#endif
1339 slepc 317
  ierr = PetscLogEventEnd(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
879 ono.com!jroman 318
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack xTREVC %i",info);
319
 
320
  /* Compute residual norm estimates as beta*abs(Y(m,:)) */
321
  for (i=nconv;i<ncv;i++) {
322
#if !defined(PETSC_USE_COMPLEX)
323
    if (eigi[i] != 0 && i<ncv-1) {
1176 slepc 324
      errest[i] = beta*SlepcAbsEigenvalue(Y[i*ncv+ncv-1],Y[(i+1)*ncv+ncv-1]);
325
      w = SlepcAbsEigenvalue(eigr[i],eigi[i]);
326
      if (w > errest[i])
327
        errest[i] = errest[i] / w;
328
      errest[i+1] = errest[i];
329
      i++;
879 ono.com!jroman 330
    } else
331
#endif
1176 slepc 332
    {
333
      errest[i] = beta*PetscAbsScalar(Y[i*ncv+ncv-1]);
334
      w = PetscAbsScalar(eigr[i]);
335
      if (w > errest[i])
336
        errest[i] = errest[i] / w;
337
    }
879 ono.com!jroman 338
  }  
339
  PetscFunctionReturn(0);
883 ono.com!jroman 340
#endif
879 ono.com!jroman 341
}
342
 
343
#undef __FUNCT__  
6 dsic.upv.es!jroman 344
#define __FUNCT__ "EPSSolve_ARNOLDI"
476 dsic.upv.es!antodo 345
PetscErrorCode EPSSolve_ARNOLDI(EPS eps)
6 dsic.upv.es!jroman 346
{
476 dsic.upv.es!antodo 347
  PetscErrorCode ierr;
1083 slepc 348
  int            i,k;
1345 slepc 349
  Vec            f=eps->work[1];
1055 slepc 350
  PetscScalar    *H=eps->T,*U,*work;
1081 slepc 351
  PetscReal      beta;
1122 slepc 352
  PetscTruth     breakdown;
1345 slepc 353
  IPOrthogonalizationRefinementType orthog_ref;
1083 slepc 354
  EPS_ARNOLDI    *arnoldi = (EPS_ARNOLDI *)eps->data;
431 dsic.upv.es!antodo 355
 
356
  PetscFunctionBegin;
1052 slepc 357
  ierr = PetscMemzero(eps->T,eps->ncv*eps->ncv*sizeof(PetscScalar));CHKERRQ(ierr);
1049 slepc 358
  ierr = PetscMalloc(eps->ncv*eps->ncv*sizeof(PetscScalar),&U);CHKERRQ(ierr);
359
  ierr = PetscMalloc((eps->ncv+4)*eps->ncv*sizeof(PetscScalar),&work);CHKERRQ(ierr);
989 slepc 360
 
1345 slepc 361
  ierr = IPGetOrthogonalization(eps->ip,PETSC_NULL,&orthog_ref,PETSC_NULL);CHKERRQ(ierr);
362
 
689 dsic.upv.es!jroman 363
  /* Get the starting Arnoldi vector */
1057 slepc 364
  ierr = EPSGetStartVector(eps,0,eps->V[0],PETSC_NULL);CHKERRQ(ierr);
689 dsic.upv.es!jroman 365
 
538 dsic.upv.es!jroman 366
  /* Restart loop */
1055 slepc 367
  while (eps->reason == EPS_CONVERGED_ITERATING) {
1220 slepc 368
    eps->its++;
879 ono.com!jroman 369
 
1083 slepc 370
    /* Compute an nv-step Arnoldi factorization */
1057 slepc 371
    eps->nv = eps->ncv;
1122 slepc 372
    if (!arnoldi->delayed) {
373
      ierr = EPSBasicArnoldi(eps,PETSC_FALSE,H,eps->V,eps->nconv,&eps->nv,f,&beta,&breakdown);CHKERRQ(ierr);
1345 slepc 374
    } else if (orthog_ref == IP_ORTH_REFINE_NEVER) {
1117 slepc 375
      ierr = EPSDelayedArnoldi1(eps,H,eps->V,eps->nconv,&eps->nv,f,&beta,&breakdown);CHKERRQ(ierr);
1083 slepc 376
    } else {
1122 slepc 377
      ierr = EPSDelayedArnoldi(eps,H,eps->V,eps->nconv,&eps->nv,f,&beta,&breakdown);CHKERRQ(ierr);
1083 slepc 378
    }
379
 
538 dsic.upv.es!jroman 380
    /* Reduce H to (quasi-)triangular form, H <- U H U' */
1057 slepc 381
    ierr = PetscMemzero(U,eps->nv*eps->nv*sizeof(PetscScalar));CHKERRQ(ierr);
382
    for (i=0;i<eps->nv;i++) { U[i*(eps->nv+1)] = 1.0; }
383
    ierr = EPSDenseSchur(eps->nv,eps->nconv,H,eps->ncv,U,eps->eigr,eps->eigi);CHKERRQ(ierr);
538 dsic.upv.es!jroman 384
 
879 ono.com!jroman 385
    /* Sort the remaining columns of the Schur form */
1174 slepc 386
    ierr = EPSSortDenseSchur(eps->nv,eps->nconv,H,eps->ncv,U,eps->eigr,eps->eigi,eps->which);CHKERRQ(ierr);
605 dsic.upv.es!antodo 387
 
879 ono.com!jroman 388
    /* Compute residual norm estimates */
1057 slepc 389
    ierr = ArnoldiResiduals(H,eps->ncv,U,beta,eps->nconv,eps->nv,eps->eigr,eps->eigi,eps->errest,work);CHKERRQ(ierr);
1045 slepc 390
 
879 ono.com!jroman 391
    /* Lock converged eigenpairs and update the corresponding vectors,
392
       including the restart vector: V(:,idx) = V*U(:,idx) */
516 dsic.upv.es!antodo 393
    k = eps->nconv;
1057 slepc 394
    while (k<eps->nv && eps->errest[k]<eps->tol) k++;
395
    for (i=eps->nconv;i<=k && i<eps->nv;i++) {
870 dsic.upv.es!antodo 396
      ierr = VecSet(eps->AV[i],0.0);CHKERRQ(ierr);
1057 slepc 397
      ierr = VecMAXPY(eps->AV[i],eps->nv,U+eps->nv*i,eps->V);CHKERRQ(ierr);
870 dsic.upv.es!antodo 398
    }
1057 slepc 399
    for (i=eps->nconv;i<=k && i<eps->nv;i++) {
870 dsic.upv.es!antodo 400
      ierr = VecCopy(eps->AV[i],eps->V[i]);CHKERRQ(ierr);
401
    }
516 dsic.upv.es!antodo 402
    eps->nconv = k;
879 ono.com!jroman 403
 
1057 slepc 404
    EPSMonitor(eps,eps->its,eps->nconv,eps->eigr,eps->eigi,eps->errest,eps->nv);
1135 slepc 405
    if (breakdown) {
406
      PetscInfo2(eps,"Breakdown in Arnoldi method (it=%i norm=%g)\n",eps->its,beta);
1057 slepc 407
      ierr = EPSGetStartVector(eps,k,eps->V[k],&breakdown);CHKERRQ(ierr);
408
      if (breakdown) {
409
        eps->reason = EPS_DIVERGED_BREAKDOWN;
410
        PetscInfo(eps,"Unable to generate more start vectors\n");
411
      }
412
    }
1055 slepc 413
    if (eps->its >= eps->max_it) eps->reason = EPS_DIVERGED_ITS;
414
    if (eps->nconv >= eps->nev) eps->reason = EPS_CONVERGED_TOL;
431 dsic.upv.es!antodo 415
  }
416
 
417
  ierr = PetscFree(U);CHKERRQ(ierr);
418
  ierr = PetscFree(work);CHKERRQ(ierr);
419
  PetscFunctionReturn(0);
420
}
421
 
1083 slepc 422
#undef __FUNCT__  
423
#define __FUNCT__ "EPSSetFromOptions_ARNOLDI"
424
PetscErrorCode EPSSetFromOptions_ARNOLDI(EPS eps)
425
{
426
  PetscErrorCode ierr;
427
  EPS_ARNOLDI    *arnoldi = (EPS_ARNOLDI *)eps->data;
428
 
429
  PetscFunctionBegin;
430
  ierr = PetscOptionsHead("ARNOLDI options");CHKERRQ(ierr);
1084 slepc 431
  ierr = PetscOptionsTruth("-eps_arnoldi_delayed","Arnoldi with delayed reorthogonalization","EPSArnoldiSetDelayed",PETSC_FALSE,&arnoldi->delayed,PETSC_NULL);CHKERRQ(ierr);
1083 slepc 432
  ierr = PetscOptionsTail();CHKERRQ(ierr);
433
  PetscFunctionReturn(0);
434
}
435
 
436
EXTERN_C_BEGIN
437
#undef __FUNCT__  
438
#define __FUNCT__ "EPSArnoldiSetDelayed_ARNOLDI"
439
PetscErrorCode EPSArnoldiSetDelayed_ARNOLDI(EPS eps,PetscTruth delayed)
440
{
441
  EPS_ARNOLDI    *arnoldi = (EPS_ARNOLDI *)eps->data;
442
 
443
  PetscFunctionBegin;
444
  arnoldi->delayed = delayed;
445
  PetscFunctionReturn(0);
446
}
447
EXTERN_C_END
448
 
449
#undef __FUNCT__  
450
#define __FUNCT__ "EPSArnoldiSetDelayed"
451
/*@
1084 slepc 452
   EPSArnoldiSetDelayed - Activates or deactivates delayed reorthogonalization
453
   in the Arnoldi iteration.
1083 slepc 454
 
455
   Collective on EPS
456
 
457
   Input Parameters:
458
+  eps - the eigenproblem solver context
1186 slepc 459
-  delayed - boolean flag
1083 slepc 460
 
461
   Options Database Key:
1084 slepc 462
.  -eps_arnoldi_delayed - Activates delayed reorthogonalization in Arnoldi
1083 slepc 463
 
1084 slepc 464
   Note:
465
   Delayed reorthogonalization is an aggressive optimization for the Arnoldi
1186 slepc 466
   eigensolver than may provide better scalability, but sometimes makes the
467
   solver converge less than the default algorithm.
1084 slepc 468
 
1083 slepc 469
   Level: advanced
470
 
471
.seealso: EPSArnoldiGetDelayed()
472
@*/
473
PetscErrorCode EPSArnoldiSetDelayed(EPS eps,PetscTruth delayed)
474
{
475
  PetscErrorCode ierr, (*f)(EPS,PetscTruth);
476
 
477
  PetscFunctionBegin;
478
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
1084 slepc 479
  ierr = PetscObjectQueryFunction((PetscObject)eps,"EPSArnoldiSetDelayed_C",(void (**)())&f);CHKERRQ(ierr);
1083 slepc 480
  if (f) {
481
    ierr = (*f)(eps,delayed);CHKERRQ(ierr);
482
  }
483
  PetscFunctionReturn(0);
484
}
485
 
486
EXTERN_C_BEGIN
487
#undef __FUNCT__  
488
#define __FUNCT__ "EPSArnoldiGetDelayed_ARNOLDI"
489
PetscErrorCode EPSArnoldiGetDelayed_ARNOLDI(EPS eps,PetscTruth *delayed)
490
{
491
  EPS_ARNOLDI    *arnoldi = (EPS_ARNOLDI *)eps->data;
492
 
493
  PetscFunctionBegin;
494
  *delayed = arnoldi->delayed;
495
  PetscFunctionReturn(0);
496
}
497
EXTERN_C_END
498
 
499
#undef __FUNCT__  
500
#define __FUNCT__ "EPSArnoldiGetDelayed"
501
/*@C
502
   EPSArnoldiGetDelayed - Gets the type of reorthogonalization used during the Arnoldi
503
   iteration.
504
 
505
   Collective on EPS
506
 
507
   Input Parameter:
508
.  eps - the eigenproblem solver context
509
 
510
   Input Parameter:
1084 slepc 511
.  delayed - boolean flag indicating if delayed reorthogonalization has been enabled
1083 slepc 512
 
513
   Level: advanced
514
 
1084 slepc 515
.seealso: EPSArnoldiSetDelayed()
1083 slepc 516
@*/
517
PetscErrorCode EPSArnoldiGetDelayed(EPS eps,PetscTruth *delayed)
518
{
519
  PetscErrorCode ierr, (*f)(EPS,PetscTruth*);
520
 
521
  PetscFunctionBegin;
522
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
523
  ierr = PetscObjectQueryFunction((PetscObject)eps,"EPSArnoldiGetDelayed_C",(void (**)())&f);CHKERRQ(ierr);
524
  if (f) {
525
    ierr = (*f)(eps,delayed);CHKERRQ(ierr);
526
  }
527
  PetscFunctionReturn(0);
528
}
529
 
530
#undef __FUNCT__  
531
#define __FUNCT__ "EPSView_ARNOLDI"
532
PetscErrorCode EPSView_ARNOLDI(EPS eps,PetscViewer viewer)
533
{
534
  PetscErrorCode ierr;
535
  PetscTruth     isascii;
536
  EPS_ARNOLDI    *arnoldi = (EPS_ARNOLDI *)eps->data;
537
 
538
  PetscFunctionBegin;
539
  ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
540
  if (!isascii) {
541
    SETERRQ1(1,"Viewer type %s not supported for EPSARNOLDI",((PetscObject)viewer)->type_name);
542
  }
543
  if (arnoldi->delayed) {
544
    ierr = PetscViewerASCIIPrintf(viewer,"using delayed reorthogonalization\n");CHKERRQ(ierr);
545
  }  
546
  PetscFunctionReturn(0);
547
}
548
 
904 dsic.upv.es!antodo 549
EXTERN PetscErrorCode EPSSolve_TS_ARNOLDI(EPS);
550
 
6 dsic.upv.es!jroman 551
EXTERN_C_BEGIN
552
#undef __FUNCT__  
553
#define __FUNCT__ "EPSCreate_ARNOLDI"
476 dsic.upv.es!antodo 554
PetscErrorCode EPSCreate_ARNOLDI(EPS eps)
6 dsic.upv.es!jroman 555
{
1083 slepc 556
  PetscErrorCode ierr;
557
  EPS_ARNOLDI    *arnoldi;
558
 
6 dsic.upv.es!jroman 559
  PetscFunctionBegin;
1083 slepc 560
  ierr = PetscNew(EPS_ARNOLDI,&arnoldi);CHKERRQ(ierr);
561
  PetscLogObjectMemory(eps,sizeof(EPS_ARNOLDI));
562
  eps->data                      = (void *)arnoldi;
6 dsic.upv.es!jroman 563
  eps->ops->solve                = EPSSolve_ARNOLDI;
879 ono.com!jroman 564
  eps->ops->solvets              = EPSSolve_TS_ARNOLDI;
503 dsic.upv.es!antodo 565
  eps->ops->setup                = EPSSetUp_ARNOLDI;
1083 slepc 566
  eps->ops->setfromoptions       = EPSSetFromOptions_ARNOLDI;
259 dsic.upv.es!antodo 567
  eps->ops->destroy              = EPSDestroy_Default;
1083 slepc 568
  eps->ops->view                 = EPSView_ARNOLDI;
176 dsic.upv.es!antodo 569
  eps->ops->backtransform        = EPSBackTransform_Default;
508 dsic.upv.es!antodo 570
  eps->ops->computevectors       = EPSComputeVectors_Schur;
1083 slepc 571
  arnoldi->delayed               = PETSC_FALSE;
1085 slepc 572
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSArnoldiSetDelayed_C","EPSArnoldiSetDelayed_ARNOLDI",EPSArnoldiSetDelayed_ARNOLDI);CHKERRQ(ierr);
573
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSArnoldiGetDelayed_C","EPSArnoldiGetDelayed_ARNOLDI",EPSArnoldiGetDelayed_ARNOLDI);CHKERRQ(ierr);
6 dsic.upv.es!jroman 574
  PetscFunctionReturn(0);
575
}
576
EXTERN_C_END
577