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
 
1673 slepc 16
   Last update: Feb 2009
538 dsic.upv.es!jroman 17
 
1376 slepc 18
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1672 slepc 19
   SLEPc - Scalable Library for Eigenvalue Problem Computations
2116 eromero 20
   Copyright (c) 2002-2010, Universidad Politecnica de Valencia, Spain
1376 slepc 21
 
1672 slepc 22
   This file is part of SLEPc.
23
 
24
   SLEPc is free software: you can redistribute it and/or modify it under  the
25
   terms of version 3 of the GNU Lesser General Public License as published by
26
   the Free Software Foundation.
27
 
28
   SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
29
   WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
30
   FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
31
   more details.
32
 
33
   You  should have received a copy of the GNU Lesser General  Public  License
34
   along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
1376 slepc 35
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6 dsic.upv.es!jroman 36
*/
1376 slepc 37
 
2283 jroman 38
#include <private/epsimpl.h>                /*I "slepceps.h" I*/
39
#include <slepcblaslapack.h>
6 dsic.upv.es!jroman 40
 
2324 jroman 41
PetscErrorCode EPSSolve_Arnoldi(EPS);
1947 jroman 42
 
1083 slepc 43
typedef struct {
2216 jroman 44
  PetscBool delayed;
1083 slepc 45
} EPS_ARNOLDI;
46
 
6 dsic.upv.es!jroman 47
#undef __FUNCT__  
2324 jroman 48
#define __FUNCT__ "EPSSetUp_Arnoldi"
49
PetscErrorCode EPSSetUp_Arnoldi(EPS eps)
6 dsic.upv.es!jroman 50
{
476 dsic.upv.es!antodo 51
  PetscErrorCode ierr;
6 dsic.upv.es!jroman 52
 
53
  PetscFunctionBegin;
1580 slepc 54
  if (eps->ncv) { /* ncv set */
2214 jroman 55
    if (eps->ncv<eps->nev) SETERRQ(((PetscObject)eps)->comm,1,"The value of ncv must be at least nev");
6 dsic.upv.es!jroman 56
  }
1580 slepc 57
  else if (eps->mpd) { /* mpd set */
1928 jroman 58
    eps->ncv = PetscMin(eps->n,eps->nev+eps->mpd);
1580 slepc 59
  }
60
  else { /* neither set: defaults depend on nev being small or large */
1928 jroman 61
    if (eps->nev<500) eps->ncv = PetscMin(eps->n,PetscMax(2*eps->nev,eps->nev+15));
62
    else { eps->mpd = 500; eps->ncv = PetscMin(eps->n,eps->nev+eps->mpd); }
1580 slepc 63
  }
64
  if (!eps->mpd) eps->mpd = eps->ncv;
2214 jroman 65
  if (eps->ncv>eps->nev+eps->mpd) SETERRQ(((PetscObject)eps)->comm,1,"The value of ncv must not be larger than nev+mpd");
1928 jroman 66
  if (!eps->max_it) eps->max_it = PetscMax(100,2*eps->n/eps->ncv);
1942 jroman 67
  if (!eps->which) eps->which = EPS_LARGEST_MAGNITUDE;
1181 slepc 68
  if (eps->ishermitian && (eps->which==EPS_LARGEST_IMAGINARY || eps->which==EPS_SMALLEST_IMAGINARY))
2214 jroman 69
    SETERRQ(((PetscObject)eps)->comm,1,"Wrong value of eps->which");
1220 slepc 70
 
1560 slepc 71
  if (!eps->extraction) {
72
    ierr = EPSSetExtraction(eps,EPS_RITZ);CHKERRQ(ierr);
1426 slepc 73
  }
74
 
259 dsic.upv.es!antodo 75
  ierr = EPSAllocateSolution(eps);CHKERRQ(ierr);
1040 slepc 76
  ierr = PetscFree(eps->T);CHKERRQ(ierr);
508 dsic.upv.es!antodo 77
  ierr = PetscMalloc(eps->ncv*eps->ncv*sizeof(PetscScalar),&eps->T);CHKERRQ(ierr);
1947 jroman 78
  if (eps->leftvecs) {
1040 slepc 79
    ierr = PetscFree(eps->Tl);CHKERRQ(ierr);
879 ono.com!jroman 80
    ierr = PetscMalloc(eps->ncv*eps->ncv*sizeof(PetscScalar),&eps->Tl);CHKERRQ(ierr);
2499 jroman 81
    ierr = PetscInfo(eps,"Warning: parameter mpd ignored\n");CHKERRQ(ierr);
1755 antodo 82
    ierr = EPSDefaultGetWork(eps,2);CHKERRQ(ierr);
83
  } else {
84
    ierr = EPSDefaultGetWork(eps,1);CHKERRQ(ierr);
879 ono.com!jroman 85
  }
1947 jroman 86
 
87
  /* dispatch solve method */
2214 jroman 88
  if (eps->leftvecs) SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"Left vectors not supported in this solver");
2324 jroman 89
  eps->ops->solve = EPSSolve_Arnoldi;
6 dsic.upv.es!jroman 90
  PetscFunctionReturn(0);
91
}
92
 
93
#undef __FUNCT__  
1083 slepc 94
#define __FUNCT__ "EPSDelayedArnoldi"
1084 slepc 95
/*
96
   EPSDelayedArnoldi - This function is equivalent to EPSBasicArnoldi but
97
   performs the computation in a different way. The main idea is that
98
   reorthogonalization is delayed to the next Arnoldi step. This version is
1186 slepc 99
   more scalable but in some cases convergence may stagnate.
1084 slepc 100
*/
2216 jroman 101
PetscErrorCode EPSDelayedArnoldi(EPS eps,PetscScalar *H,PetscInt ldh,Vec *V,PetscInt k,PetscInt *M,Vec f,PetscReal *beta,PetscBool *breakdown)
989 slepc 102
{
103
  PetscErrorCode ierr;
1509 slepc 104
  PetscInt       i,j,m=*M;
1755 antodo 105
  Vec            u,t;
1164 slepc 106
  PetscScalar    shh[100],*lhh,dot,dot2;
1114 slepc 107
  PetscReal      norm1=0.0,norm2;
1013 slepc 108
 
109
  PetscFunctionBegin;
110
  if (m<=100) lhh = shh;
111
  else { ierr = PetscMalloc(m*sizeof(PetscScalar),&lhh);CHKERRQ(ierr); }
112
  ierr = VecDuplicate(f,&u);CHKERRQ(ierr);
113
  ierr = VecDuplicate(f,&t);CHKERRQ(ierr);
114
 
115
  for (j=k;j<m;j++) {
1015 slepc 116
    ierr = STApply(eps->OP,V[j],f);CHKERRQ(ierr);
1755 antodo 117
    ierr = IPOrthogonalize(eps->ip,0,PETSC_NULL,eps->nds,PETSC_NULL,eps->DS,f,PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1013 slepc 118
 
1578 slepc 119
    ierr = IPMInnerProductBegin(eps->ip,f,j+1,V,H+ldh*j);CHKERRQ(ierr);
1015 slepc 120
    if (j>k) {
1381 slepc 121
      ierr = IPMInnerProductBegin(eps->ip,V[j],j,V,lhh);CHKERRQ(ierr);
1345 slepc 122
      ierr = IPInnerProductBegin(eps->ip,V[j],V[j],&dot);CHKERRQ(ierr);
1033 slepc 123
    }
124
    if (j>k+1) {
1345 slepc 125
      ierr = IPNormBegin(eps->ip,u,&norm2);CHKERRQ(ierr);
1164 slepc 126
      ierr = VecDotBegin(u,V[j-2],&dot2);CHKERRQ(ierr);
1017 slepc 127
    }
1033 slepc 128
 
1578 slepc 129
    ierr = IPMInnerProductEnd(eps->ip,f,j+1,V,H+ldh*j);CHKERRQ(ierr);
1017 slepc 130
    if (j>k) {
1381 slepc 131
      ierr = IPMInnerProductEnd(eps->ip,V[j],j,V,lhh);CHKERRQ(ierr);
1345 slepc 132
      ierr = IPInnerProductEnd(eps->ip,V[j],V[j],&dot);CHKERRQ(ierr);
1033 slepc 133
    }
134
    if (j>k+1) {
1345 slepc 135
      ierr = IPNormEnd(eps->ip,u,&norm2);CHKERRQ(ierr);
1164 slepc 136
      ierr = VecDotEnd(u,V[j-2],&dot2);CHKERRQ(ierr);
137
      if (PetscAbsScalar(dot2/norm2) > PETSC_MACHINE_EPSILON) {
1113 slepc 138
        *breakdown = PETSC_TRUE;
2316 jroman 139
        *M = j-1;
140
        *beta = norm2;
1065 slepc 141
 
2316 jroman 142
        if (m>100) { ierr = PetscFree(lhh);CHKERRQ(ierr); }
143
        ierr = VecDestroy(&u);CHKERRQ(ierr);
144
        ierr = VecDestroy(&t);CHKERRQ(ierr);
145
        PetscFunctionReturn(0);
1060 slepc 146
      }
1033 slepc 147
    }
148
 
1058 slepc 149
    if (j>k) {      
2473 jroman 150
      norm1 = PetscSqrtReal(PetscRealPart(dot));
1015 slepc 151
      for (i=0;i<j;i++)
2316 jroman 152
        H[ldh*j+i] = H[ldh*j+i]/norm1;
1578 slepc 153
      H[ldh*j+j] = H[ldh*j+j]/dot;
1058 slepc 154
 
1015 slepc 155
      ierr = VecCopy(V[j],t);CHKERRQ(ierr);
156
      ierr = VecScale(V[j],1.0/norm1);CHKERRQ(ierr);
157
      ierr = VecScale(f,1.0/norm1);CHKERRQ(ierr);
1013 slepc 158
    }
159
 
1755 antodo 160
    ierr = SlepcVecMAXPBY(f,1.0,-1.0,j+1,H+ldh*j,V);CHKERRQ(ierr);
1015 slepc 161
 
1045 slepc 162
    if (j>k) {
1755 antodo 163
      ierr = SlepcVecMAXPBY(t,1.0,-1.0,j,lhh,V);CHKERRQ(ierr);
1033 slepc 164
      for (i=0;i<j;i++)
1578 slepc 165
        H[ldh*(j-1)+i] += lhh[i];
1033 slepc 166
    }
167
 
1016 slepc 168
    if (j>k+1) {
169
      ierr = VecCopy(u,V[j-1]);CHKERRQ(ierr);
170
      ierr = VecScale(V[j-1],1.0/norm2);CHKERRQ(ierr);
1578 slepc 171
      H[ldh*(j-2)+j-1] = norm2;
1016 slepc 172
    }
173
 
1015 slepc 174
    if (j<m-1) {
1045 slepc 175
      ierr = VecCopy(f,V[j+1]);CHKERRQ(ierr);
176
      ierr = VecCopy(t,u);CHKERRQ(ierr);
1015 slepc 177
    }
1013 slepc 178
  }
179
 
1345 slepc 180
  ierr = IPNorm(eps->ip,t,&norm2);CHKERRQ(ierr);
1032 slepc 181
  ierr = VecScale(t,1.0/norm2);CHKERRQ(ierr);
1013 slepc 182
  ierr = VecCopy(t,V[m-1]);CHKERRQ(ierr);
1578 slepc 183
  H[ldh*(m-2)+m-1] = norm2;
1013 slepc 184
 
1381 slepc 185
  ierr = IPMInnerProduct(eps->ip,f,m,V,lhh);CHKERRQ(ierr);
1015 slepc 186
 
1755 antodo 187
  ierr = SlepcVecMAXPBY(f,1.0,-1.0,m,lhh,V);CHKERRQ(ierr);
1015 slepc 188
  for (i=0;i<m;i++)
1578 slepc 189
    H[ldh*(m-1)+i] += lhh[i];
1015 slepc 190
 
1345 slepc 191
  ierr = IPNorm(eps->ip,f,beta);CHKERRQ(ierr);
1013 slepc 192
  ierr = VecScale(f,1.0 / *beta);CHKERRQ(ierr);
1113 slepc 193
  *breakdown = PETSC_FALSE;
194
 
1013 slepc 195
  if (m>100) { ierr = PetscFree(lhh);CHKERRQ(ierr); }
2305 jroman 196
  ierr = VecDestroy(&u);CHKERRQ(ierr);
197
  ierr = VecDestroy(&t);CHKERRQ(ierr);
1013 slepc 198
  PetscFunctionReturn(0);
199
}
200
 
201
#undef __FUNCT__  
1117 slepc 202
#define __FUNCT__ "EPSDelayedArnoldi1"
1186 slepc 203
/*
204
   EPSDelayedArnoldi1 - This function is similar to EPSDelayedArnoldi1,
205
   but without reorthogonalization (only delayed normalization).
206
*/
2216 jroman 207
PetscErrorCode EPSDelayedArnoldi1(EPS eps,PetscScalar *H,PetscInt ldh,Vec *V,PetscInt k,PetscInt *M,Vec f,PetscReal *beta,PetscBool *breakdown)
1117 slepc 208
{
209
  PetscErrorCode ierr;
1509 slepc 210
  PetscInt       i,j,m=*M;
1117 slepc 211
  PetscScalar    dot;
212
  PetscReal      norm=0.0;
213
 
214
  PetscFunctionBegin;
215
  for (j=k;j<m;j++) {
216
    ierr = STApply(eps->OP,V[j],f);CHKERRQ(ierr);
1755 antodo 217
    ierr = IPOrthogonalize(eps->ip,0,PETSC_NULL,eps->nds,PETSC_NULL,eps->DS,f,PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1117 slepc 218
 
1578 slepc 219
    ierr = IPMInnerProductBegin(eps->ip,f,j+1,V,H+ldh*j);CHKERRQ(ierr);
1117 slepc 220
    if (j>k) {
1345 slepc 221
      ierr = IPInnerProductBegin(eps->ip,V[j],V[j],&dot);CHKERRQ(ierr);
1117 slepc 222
    }
223
 
1578 slepc 224
    ierr = IPMInnerProductEnd(eps->ip,f,j+1,V,H+ldh*j);CHKERRQ(ierr);
1117 slepc 225
    if (j>k) {
1345 slepc 226
      ierr = IPInnerProductEnd(eps->ip,V[j],V[j],&dot);CHKERRQ(ierr);
1117 slepc 227
    }
228
 
229
    if (j>k) {      
2473 jroman 230
      norm = PetscSqrtReal(PetscRealPart(dot));
1117 slepc 231
      ierr = VecScale(V[j],1.0/norm);CHKERRQ(ierr);
1578 slepc 232
      H[ldh*(j-1)+j] = norm;
1117 slepc 233
 
234
      for (i=0;i<j;i++)
2316 jroman 235
        H[ldh*j+i] = H[ldh*j+i]/norm;
1578 slepc 236
      H[ldh*j+j] = H[ldh*j+j]/dot;      
1117 slepc 237
      ierr = VecScale(f,1.0/norm);CHKERRQ(ierr);
238
    }
239
 
1755 antodo 240
    ierr = SlepcVecMAXPBY(f,1.0,-1.0,j+1,H+ldh*j,V);CHKERRQ(ierr);
1117 slepc 241
 
242
    if (j<m-1) {
243
      ierr = VecCopy(f,V[j+1]);CHKERRQ(ierr);
244
    }
245
  }
246
 
1345 slepc 247
  ierr = IPNorm(eps->ip,f,beta);CHKERRQ(ierr);
1117 slepc 248
  ierr = VecScale(f,1.0 / *beta);CHKERRQ(ierr);
249
  *breakdown = PETSC_FALSE;
250
  PetscFunctionReturn(0);
251
}
252
 
253
#undef __FUNCT__  
1484 slepc 254
#define __FUNCT__ "EPSProjectedArnoldi"
255
/*
256
   EPSProjectedArnoldi - Solves the projected eigenproblem.
257
 
258
   On input:
259
     S is the projected matrix (leading dimension is lds)
260
 
261
   On output:
262
     S has (real) Schur form with diagonal blocks sorted appropriately
263
     Q contains the corresponding Schur vectors (order n, leading dimension n)
264
*/
1509 slepc 265
PetscErrorCode EPSProjectedArnoldi(EPS eps,PetscScalar *S,PetscInt lds,PetscScalar *Q,PetscInt n)
1484 slepc 266
{
267
  PetscErrorCode ierr;
1509 slepc 268
  PetscInt       i;
1484 slepc 269
 
270
  PetscFunctionBegin;
271
  /* Initialize orthogonal matrix */
272
  ierr = PetscMemzero(Q,n*n*sizeof(PetscScalar));CHKERRQ(ierr);
273
  for (i=0;i<n;i++)
274
    Q[i*(n+1)] = 1.0;
275
  /* Reduce S to (quasi-)triangular form, S <- Q S Q' */
276
  ierr = EPSDenseSchur(n,eps->nconv,S,lds,Q,eps->eigr,eps->eigi);CHKERRQ(ierr);
277
  /* Sort the remaining columns of the Schur form */
1823 antodo 278
  ierr = EPSSortDenseSchur(eps,n,eps->nconv,S,lds,Q,eps->eigr,eps->eigi);CHKERRQ(ierr);    
1484 slepc 279
  PetscFunctionReturn(0);
280
}
281
 
282
#undef __FUNCT__  
1614 slepc 283
#define __FUNCT__ "EPSUpdateVectors"
1484 slepc 284
/*
1614 slepc 285
   EPSUpdateVectors - Computes approximate Schur vectors (or eigenvectors) by
1484 slepc 286
   either Ritz extraction (U=U*Q) or refined Ritz extraction
287
 
288
   On input:
1614 slepc 289
     n is the size of U
1484 slepc 290
     U is the orthogonal basis of the subspace used for projecting
1614 slepc 291
     s is the index of the first vector computed
292
     e+1 is the index of the last vector computed
293
     Q contains the corresponding Schur vectors of the projected matrix (size n x n, leading dimension ldq)
1484 slepc 294
     H is the (extended) projected matrix (size n+1 x n, leading dimension ldh)
295
 
296
   On output:
297
     v is the resulting vector
298
*/
1614 slepc 299
PetscErrorCode EPSUpdateVectors(EPS eps,PetscInt n_,Vec *U,PetscInt s,PetscInt e,PetscScalar *Q,PetscInt ldq,PetscScalar *H,PetscInt ldh_)
1484 slepc 300
{
301
#if defined(PETSC_MISSING_LAPACK_GESVD)
2214 jroman 302
  SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"GESVD - Lapack routine is unavailable.");
1484 slepc 303
#else
304
  PetscErrorCode ierr;
2216 jroman 305
  PetscBool      isrefined;
1614 slepc 306
  PetscInt       i,j,k;
1517 slepc 307
  PetscBLASInt   n1,lwork,idummy=1,info,n=n_,ldh=ldh_;
1484 slepc 308
  PetscScalar    *B,sdummy,*work;
309
  PetscReal      *sigma;
310
 
311
  PetscFunctionBegin;
1560 slepc 312
  isrefined = (eps->extraction==EPS_REFINED || eps->extraction==EPS_REFINED_HARMONIC)?PETSC_TRUE:PETSC_FALSE;
1614 slepc 313
  if (isrefined) {
1484 slepc 314
    /* Refined Ritz extraction */
315
    n1 = n+1;
316
    ierr = PetscMalloc(n1*n*sizeof(PetscScalar),&B);CHKERRQ(ierr);
317
    ierr = PetscMalloc(6*n*sizeof(PetscReal),&sigma);CHKERRQ(ierr);
318
    lwork = 10*n;
319
    ierr = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr);
1614 slepc 320
 
321
    for (k=s;k<e;k++) {
322
      /* copy H to B */
323
      for (i=0;i<=n;i++) {
324
        for (j=0;j<n;j++) {
325
          B[i+j*n1] = H[i+j*ldh];
326
        }
1484 slepc 327
      }
1614 slepc 328
      /* subtract ritz value from diagonal of B^ */
329
      for (i=0;i<n;i++) {
330
        B[i+i*n1] -= eps->eigr[k];  /* MISSING: complex case */
331
      }
332
      /* compute SVD of [H-mu*I] */
333
  #if !defined(PETSC_USE_COMPLEX)
334
      LAPACKgesvd_("N","O",&n1,&n,B,&n1,sigma,&sdummy,&idummy,&sdummy,&idummy,work,&lwork,&info);
335
  #else
336
      LAPACKgesvd_("N","O",&n1,&n,B,&n1,sigma,&sdummy,&idummy,&sdummy,&idummy,work,&lwork,sigma+n,&info);
337
  #endif
2214 jroman 338
      if (info) SETERRQ1(((PetscObject)eps)->comm,PETSC_ERR_LIB,"Error in Lapack xGESVD %d",info);
1614 slepc 339
      /* the smallest singular value is the new error estimate */
340
      eps->errest[k] = sigma[n-1];
341
      /* update vector with right singular vector associated to smallest singular value */
342
      for (i=0;i<n;i++)
343
        Q[k*ldq+i] = B[n-1+i*n1];
1484 slepc 344
    }
345
    /* free workspace */
346
    ierr = PetscFree(B);CHKERRQ(ierr);
347
    ierr = PetscFree(sigma);CHKERRQ(ierr);
348
    ierr = PetscFree(work);CHKERRQ(ierr);
349
  }
1614 slepc 350
  /* Ritz extraction: v = U*q */
351
  ierr = SlepcUpdateVectors(n_,U,s,e,Q,ldq,PETSC_FALSE);CHKERRQ(ierr);
1484 slepc 352
  PetscFunctionReturn(0);
353
#endif
354
}
355
 
356
#undef __FUNCT__  
2324 jroman 357
#define __FUNCT__ "EPSSolve_Arnoldi"
358
PetscErrorCode EPSSolve_Arnoldi(EPS eps)
6 dsic.upv.es!jroman 359
{
2370 jroman 360
  PetscErrorCode     ierr;
361
  PetscInt           i,k,lwork,nv;
362
  Vec                f=eps->work[0];
363
  PetscScalar        *H=eps->T,*U,*g,*work,*Hcopy;
364
  PetscReal          beta,gnorm,corrf=1.0;
365
  PetscBool          breakdown;
366
  IPOrthogRefineType orthog_ref;
367
  EPS_ARNOLDI        *arnoldi = (EPS_ARNOLDI *)eps->data;
431 dsic.upv.es!antodo 368
 
369
  PetscFunctionBegin;
1052 slepc 370
  ierr = PetscMemzero(eps->T,eps->ncv*eps->ncv*sizeof(PetscScalar));CHKERRQ(ierr);
1830 antodo 371
  ierr = PetscMalloc(eps->ncv*eps->ncv*sizeof(PetscScalar),&U);CHKERRQ(ierr);
2062 jroman 372
  lwork = PetscMax((eps->ncv+1)*eps->ncv,7*eps->ncv);
373
  ierr = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr);
1560 slepc 374
  if (eps->extraction==EPS_HARMONIC || eps->extraction==EPS_REFINED_HARMONIC) {
1484 slepc 375
    ierr = PetscMalloc(eps->ncv*sizeof(PetscScalar),&g);CHKERRQ(ierr);
376
  }
1560 slepc 377
  if (eps->extraction==EPS_REFINED || eps->extraction==EPS_REFINED_HARMONIC) {
1484 slepc 378
    ierr = PetscMalloc((eps->ncv+1)*eps->ncv*sizeof(PetscScalar),&Hcopy);CHKERRQ(ierr);
379
  }
989 slepc 380
 
1345 slepc 381
  ierr = IPGetOrthogonalization(eps->ip,PETSC_NULL,&orthog_ref,PETSC_NULL);CHKERRQ(ierr);
382
 
689 dsic.upv.es!jroman 383
  /* Get the starting Arnoldi vector */
1057 slepc 384
  ierr = EPSGetStartVector(eps,0,eps->V[0],PETSC_NULL);CHKERRQ(ierr);
689 dsic.upv.es!jroman 385
 
538 dsic.upv.es!jroman 386
  /* Restart loop */
1055 slepc 387
  while (eps->reason == EPS_CONVERGED_ITERATING) {
1220 slepc 388
    eps->its++;
879 ono.com!jroman 389
 
1083 slepc 390
    /* Compute an nv-step Arnoldi factorization */
1830 antodo 391
    nv = PetscMin(eps->nconv+eps->mpd,eps->ncv);
1122 slepc 392
    if (!arnoldi->delayed) {
1830 antodo 393
      ierr = EPSBasicArnoldi(eps,PETSC_FALSE,H,eps->ncv,eps->V,eps->nconv,&nv,f,&beta,&breakdown);CHKERRQ(ierr);
2370 jroman 394
    } else if (orthog_ref == IP_ORTHOG_REFINE_NEVER) {
1830 antodo 395
      ierr = EPSDelayedArnoldi1(eps,H,eps->ncv,eps->V,eps->nconv,&nv,f,&beta,&breakdown);CHKERRQ(ierr);
1083 slepc 396
    } else {
1830 antodo 397
      ierr = EPSDelayedArnoldi(eps,H,eps->ncv,eps->V,eps->nconv,&nv,f,&beta,&breakdown);CHKERRQ(ierr);
1083 slepc 398
    }
399
 
1560 slepc 400
    if (eps->extraction==EPS_REFINED || eps->extraction==EPS_REFINED_HARMONIC) {
1484 slepc 401
      ierr = PetscMemcpy(Hcopy,H,eps->ncv*eps->ncv*sizeof(PetscScalar));CHKERRQ(ierr);
1830 antodo 402
      for (i=0;i<nv-1;i++) Hcopy[nv+i*eps->ncv] = 0.0;
403
      Hcopy[nv+(nv-1)*eps->ncv] = beta;
1484 slepc 404
    }
538 dsic.upv.es!jroman 405
 
1560 slepc 406
    /* Compute translation of Krylov decomposition if harmonic extraction used */
407
    if (eps->extraction==EPS_HARMONIC || eps->extraction==EPS_REFINED_HARMONIC) {
1830 antodo 408
      ierr = EPSTranslateHarmonic(nv,H,eps->ncv,eps->target,(PetscScalar)beta,g,work);CHKERRQ(ierr);
1484 slepc 409
      gnorm = 0.0;
1830 antodo 410
      for (i=0;i<nv;i++)
1484 slepc 411
        gnorm = gnorm + PetscRealPart(g[i]*PetscConj(g[i]));
2473 jroman 412
      corrf = PetscSqrtReal(1.0+gnorm);
1484 slepc 413
    }
414
 
2062 jroman 415
    /* Solve projected problem */
2026 jroman 416
    ierr = EPSProjectedArnoldi(eps,H,eps->ncv,U,nv);CHKERRQ(ierr);
417
 
2062 jroman 418
    /* Check convergence */
419
    ierr = EPSKrylovConvergence(eps,PETSC_FALSE,eps->nconv,nv-eps->nconv,H,eps->ncv,U,eps->V,nv,beta,corrf,&k,work);CHKERRQ(ierr);
420
 
1830 antodo 421
    ierr = EPSUpdateVectors(eps,nv,eps->V,eps->nconv,PetscMin(k+1,nv),U,nv,Hcopy,eps->ncv);CHKERRQ(ierr);
516 dsic.upv.es!antodo 422
    eps->nconv = k;
879 ono.com!jroman 423
 
2313 jroman 424
    ierr = EPSMonitor(eps,eps->its,eps->nconv,eps->eigr,eps->eigi,eps->errest,nv);CHKERRQ(ierr);
1135 slepc 425
    if (breakdown) {
2499 jroman 426
      ierr = PetscInfo2(eps,"Breakdown in Arnoldi method (it=%D norm=%G)\n",eps->its,beta);CHKERRQ(ierr);
1057 slepc 427
      ierr = EPSGetStartVector(eps,k,eps->V[k],&breakdown);CHKERRQ(ierr);
428
      if (breakdown) {
429
        eps->reason = EPS_DIVERGED_BREAKDOWN;
2499 jroman 430
        ierr = PetscInfo(eps,"Unable to generate more start vectors\n");CHKERRQ(ierr);
1057 slepc 431
      }
432
    }
1055 slepc 433
    if (eps->its >= eps->max_it) eps->reason = EPS_DIVERGED_ITS;
434
    if (eps->nconv >= eps->nev) eps->reason = EPS_CONVERGED_TOL;
431 dsic.upv.es!antodo 435
  }
436
 
2062 jroman 437
  ierr = PetscFree(U);CHKERRQ(ierr);
431 dsic.upv.es!antodo 438
  ierr = PetscFree(work);CHKERRQ(ierr);
1560 slepc 439
  if (eps->extraction==EPS_HARMONIC || eps->extraction==EPS_REFINED_HARMONIC) {
1484 slepc 440
    ierr = PetscFree(g);CHKERRQ(ierr);
441
  }
1560 slepc 442
  if (eps->extraction==EPS_REFINED || eps->extraction==EPS_REFINED_HARMONIC) {
1484 slepc 443
    ierr = PetscFree(Hcopy);CHKERRQ(ierr);
444
  }
431 dsic.upv.es!antodo 445
  PetscFunctionReturn(0);
446
}
447
 
1083 slepc 448
#undef __FUNCT__  
2324 jroman 449
#define __FUNCT__ "EPSSetFromOptions_Arnoldi"
450
PetscErrorCode EPSSetFromOptions_Arnoldi(EPS eps)
1083 slepc 451
{
452
  PetscErrorCode ierr;
2216 jroman 453
  PetscBool      set,val;
1083 slepc 454
  EPS_ARNOLDI    *arnoldi = (EPS_ARNOLDI *)eps->data;
455
 
456
  PetscFunctionBegin;
2384 jroman 457
  ierr = PetscOptionsHead("EPS Arnoldi Options");CHKERRQ(ierr);
2216 jroman 458
  ierr = PetscOptionsBool("-eps_arnoldi_delayed","Arnoldi with delayed reorthogonalization","EPSArnoldiSetDelayed",arnoldi->delayed,&val,&set);CHKERRQ(ierr);
1923 jroman 459
  if (set) {
460
    ierr = EPSArnoldiSetDelayed(eps,val);CHKERRQ(ierr);
461
  }
2384 jroman 462
  ierr = PetscOptionsTail();CHKERRQ(ierr);
1083 slepc 463
  PetscFunctionReturn(0);
464
}
465
 
466
EXTERN_C_BEGIN
467
#undef __FUNCT__  
2324 jroman 468
#define __FUNCT__ "EPSArnoldiSetDelayed_Arnoldi"
469
PetscErrorCode EPSArnoldiSetDelayed_Arnoldi(EPS eps,PetscBool delayed)
1083 slepc 470
{
2317 jroman 471
  EPS_ARNOLDI *arnoldi = (EPS_ARNOLDI *)eps->data;
1083 slepc 472
 
473
  PetscFunctionBegin;
474
  arnoldi->delayed = delayed;
475
  PetscFunctionReturn(0);
476
}
477
EXTERN_C_END
478
 
479
#undef __FUNCT__  
480
#define __FUNCT__ "EPSArnoldiSetDelayed"
481
/*@
1084 slepc 482
   EPSArnoldiSetDelayed - Activates or deactivates delayed reorthogonalization
483
   in the Arnoldi iteration.
1083 slepc 484
 
2328 jroman 485
   Logically Collective on EPS
1083 slepc 486
 
487
   Input Parameters:
488
+  eps - the eigenproblem solver context
1186 slepc 489
-  delayed - boolean flag
1083 slepc 490
 
491
   Options Database Key:
1084 slepc 492
.  -eps_arnoldi_delayed - Activates delayed reorthogonalization in Arnoldi
1083 slepc 493
 
1084 slepc 494
   Note:
495
   Delayed reorthogonalization is an aggressive optimization for the Arnoldi
1186 slepc 496
   eigensolver than may provide better scalability, but sometimes makes the
497
   solver converge less than the default algorithm.
1084 slepc 498
 
1083 slepc 499
   Level: advanced
500
 
501
.seealso: EPSArnoldiGetDelayed()
502
@*/
2216 jroman 503
PetscErrorCode EPSArnoldiSetDelayed(EPS eps,PetscBool delayed)
1083 slepc 504
{
2221 jroman 505
  PetscErrorCode ierr;
1083 slepc 506
 
507
  PetscFunctionBegin;
2213 jroman 508
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
2326 jroman 509
  PetscValidLogicalCollectiveBool(eps,delayed,2);
2221 jroman 510
  ierr = PetscTryMethod(eps,"EPSArnoldiSetDelayed_C",(EPS,PetscBool),(eps,delayed));CHKERRQ(ierr);
1083 slepc 511
  PetscFunctionReturn(0);
512
}
513
 
514
EXTERN_C_BEGIN
515
#undef __FUNCT__  
2324 jroman 516
#define __FUNCT__ "EPSArnoldiGetDelayed_Arnoldi"
517
PetscErrorCode EPSArnoldiGetDelayed_Arnoldi(EPS eps,PetscBool *delayed)
1083 slepc 518
{
2317 jroman 519
  EPS_ARNOLDI *arnoldi = (EPS_ARNOLDI *)eps->data;
1083 slepc 520
 
521
  PetscFunctionBegin;
522
  *delayed = arnoldi->delayed;
523
  PetscFunctionReturn(0);
524
}
525
EXTERN_C_END
526
 
527
#undef __FUNCT__  
528
#define __FUNCT__ "EPSArnoldiGetDelayed"
529
/*@C
530
   EPSArnoldiGetDelayed - Gets the type of reorthogonalization used during the Arnoldi
531
   iteration.
532
 
2328 jroman 533
   Not Collective
1083 slepc 534
 
535
   Input Parameter:
536
.  eps - the eigenproblem solver context
537
 
538
   Input Parameter:
1084 slepc 539
.  delayed - boolean flag indicating if delayed reorthogonalization has been enabled
1083 slepc 540
 
541
   Level: advanced
542
 
1084 slepc 543
.seealso: EPSArnoldiSetDelayed()
1083 slepc 544
@*/
2216 jroman 545
PetscErrorCode EPSArnoldiGetDelayed(EPS eps,PetscBool *delayed)
1083 slepc 546
{
2221 jroman 547
  PetscErrorCode ierr;
1083 slepc 548
 
549
  PetscFunctionBegin;
2213 jroman 550
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
2326 jroman 551
  PetscValidPointer(delayed,2);
2221 jroman 552
  ierr = PetscTryMethod(eps,"EPSArnoldiGetDelayed_C",(EPS,PetscBool*),(eps,delayed));CHKERRQ(ierr);
1083 slepc 553
  PetscFunctionReturn(0);
554
}
555
 
556
#undef __FUNCT__  
2348 jroman 557
#define __FUNCT__ "EPSReset_Arnoldi"
558
PetscErrorCode EPSReset_Arnoldi(EPS eps)
559
{
560
  PetscErrorCode ierr;
561
 
562
  PetscFunctionBegin;
563
  ierr = PetscFree(eps->T);CHKERRQ(ierr);
564
  ierr = PetscFree(eps->Tl);CHKERRQ(ierr);
565
  ierr = EPSReset_Default(eps);CHKERRQ(ierr);
566
  PetscFunctionReturn(0);
567
}
568
 
569
#undef __FUNCT__  
2324 jroman 570
#define __FUNCT__ "EPSDestroy_Arnoldi"
571
PetscErrorCode EPSDestroy_Arnoldi(EPS eps)
1925 jroman 572
{
573
  PetscErrorCode ierr;
574
 
575
  PetscFunctionBegin;
2348 jroman 576
  ierr = PetscFree(eps->data);CHKERRQ(ierr);
1925 jroman 577
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSArnoldiSetDelayed_C","",PETSC_NULL);CHKERRQ(ierr);
578
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSArnoldiGetDelayed_C","",PETSC_NULL);CHKERRQ(ierr);
579
  PetscFunctionReturn(0);
580
}
581
 
582
#undef __FUNCT__  
2324 jroman 583
#define __FUNCT__ "EPSView_Arnoldi"
584
PetscErrorCode EPSView_Arnoldi(EPS eps,PetscViewer viewer)
1083 slepc 585
{
586
  PetscErrorCode ierr;
2216 jroman 587
  PetscBool      isascii;
1083 slepc 588
  EPS_ARNOLDI    *arnoldi = (EPS_ARNOLDI *)eps->data;
589
 
590
  PetscFunctionBegin;
2215 jroman 591
  ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
1083 slepc 592
  if (!isascii) {
2324 jroman 593
    SETERRQ1(((PetscObject)eps)->comm,1,"Viewer type %s not supported for EPS Arnoldi",((PetscObject)viewer)->type_name);
1083 slepc 594
  }
595
  if (arnoldi->delayed) {
2365 jroman 596
    ierr = PetscViewerASCIIPrintf(viewer,"  Arnoldi: using delayed reorthogonalization\n");CHKERRQ(ierr);
1083 slepc 597
  }  
598
  PetscFunctionReturn(0);
599
}
600
 
2324 jroman 601
extern PetscErrorCode EPSSolve_TS_Arnoldi(EPS);
904 dsic.upv.es!antodo 602
 
6 dsic.upv.es!jroman 603
EXTERN_C_BEGIN
604
#undef __FUNCT__  
2324 jroman 605
#define __FUNCT__ "EPSCreate_Arnoldi"
606
PetscErrorCode EPSCreate_Arnoldi(EPS eps)
6 dsic.upv.es!jroman 607
{
1083 slepc 608
  PetscErrorCode ierr;
609
 
6 dsic.upv.es!jroman 610
  PetscFunctionBegin;
2329 jroman 611
  ierr = PetscNewLog(eps,EPS_ARNOLDI,&eps->data);CHKERRQ(ierr);
2324 jroman 612
  eps->ops->setup                = EPSSetUp_Arnoldi;
613
  eps->ops->setfromoptions       = EPSSetFromOptions_Arnoldi;
614
  eps->ops->destroy              = EPSDestroy_Arnoldi;
2348 jroman 615
  eps->ops->reset                = EPSReset_Arnoldi;
2324 jroman 616
  eps->ops->view                 = EPSView_Arnoldi;
176 dsic.upv.es!antodo 617
  eps->ops->backtransform        = EPSBackTransform_Default;
508 dsic.upv.es!antodo 618
  eps->ops->computevectors       = EPSComputeVectors_Schur;
2324 jroman 619
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSArnoldiSetDelayed_C","EPSArnoldiSetDelayed_Arnoldi",EPSArnoldiSetDelayed_Arnoldi);CHKERRQ(ierr);
620
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSArnoldiGetDelayed_C","EPSArnoldiGetDelayed_Arnoldi",EPSArnoldiGetDelayed_Arnoldi);CHKERRQ(ierr);
6 dsic.upv.es!jroman 621
  PetscFunctionReturn(0);
622
}
623
EXTERN_C_END
624