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