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