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
 
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
 
1083 slepc 43
typedef struct {
44
  PetscTruth delayed;
45
} EPS_ARNOLDI;
46
 
6 dsic.upv.es!jroman 47
#undef __FUNCT__  
48
#define __FUNCT__ "EPSSetUp_ARNOLDI"
476 dsic.upv.es!antodo 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 */
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 */
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;
65
  if (eps->ncv>eps->nev+eps->mpd) SETERRQ(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))
69
    SETERRQ(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);
1581 slepc 81
    PetscInfo(eps,"Warning: parameter mpd ignored\n");
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 */
2025 jroman 88
  if (eps->leftvecs) SETERRQ(PETSC_ERR_SUP,"Left vectors not supported in this solver");
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
*/
1578 slepc 101
PetscErrorCode EPSDelayedArnoldi(EPS eps,PetscScalar *H,PetscInt ldh,Vec *V,PetscInt k,PetscInt *M,Vec f,PetscReal *beta,PetscTruth *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;
1060 slepc 139
        *M = j-1;
140
        *beta = norm2;
1065 slepc 141
 
142
        if (m>100) { ierr = PetscFree(lhh);CHKERRQ(ierr); }
143
        ierr = VecDestroy(u);CHKERRQ(ierr);
144
        ierr = VecDestroy(t);CHKERRQ(ierr);
1060 slepc 145
        PetscFunctionReturn(0);
146
      }
1033 slepc 147
    }
148
 
1058 slepc 149
    if (j>k) {      
1085 slepc 150
      norm1 = sqrt(PetscRealPart(dot));
1015 slepc 151
      for (i=0;i<j;i++)
1578 slepc 152
        H[ldh*j+i] = H[ldh*j+i]/norm1;
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); }
196
  ierr = VecDestroy(u);CHKERRQ(ierr);
197
  ierr = VecDestroy(t);CHKERRQ(ierr);
198
 
199
  PetscFunctionReturn(0);
200
}
201
 
202
#undef __FUNCT__  
1117 slepc 203
#define __FUNCT__ "EPSDelayedArnoldi1"
1186 slepc 204
/*
205
   EPSDelayedArnoldi1 - This function is similar to EPSDelayedArnoldi1,
206
   but without reorthogonalization (only delayed normalization).
207
*/
1578 slepc 208
PetscErrorCode EPSDelayedArnoldi1(EPS eps,PetscScalar *H,PetscInt ldh,Vec *V,PetscInt k,PetscInt *M,Vec f,PetscReal *beta,PetscTruth *breakdown)
1117 slepc 209
{
210
  PetscErrorCode ierr;
1509 slepc 211
  PetscInt       i,j,m=*M;
1117 slepc 212
  PetscScalar    dot;
213
  PetscReal      norm=0.0;
214
 
215
  PetscFunctionBegin;
216
 
217
  for (j=k;j<m;j++) {
218
    ierr = STApply(eps->OP,V[j],f);CHKERRQ(ierr);
1755 antodo 219
    ierr = IPOrthogonalize(eps->ip,0,PETSC_NULL,eps->nds,PETSC_NULL,eps->DS,f,PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1117 slepc 220
 
1578 slepc 221
    ierr = IPMInnerProductBegin(eps->ip,f,j+1,V,H+ldh*j);CHKERRQ(ierr);
1117 slepc 222
    if (j>k) {
1345 slepc 223
      ierr = IPInnerProductBegin(eps->ip,V[j],V[j],&dot);CHKERRQ(ierr);
1117 slepc 224
    }
225
 
1578 slepc 226
    ierr = IPMInnerProductEnd(eps->ip,f,j+1,V,H+ldh*j);CHKERRQ(ierr);
1117 slepc 227
    if (j>k) {
1345 slepc 228
      ierr = IPInnerProductEnd(eps->ip,V[j],V[j],&dot);CHKERRQ(ierr);
1117 slepc 229
    }
230
 
231
    if (j>k) {      
232
      norm = sqrt(PetscRealPart(dot));
233
      ierr = VecScale(V[j],1.0/norm);CHKERRQ(ierr);
1578 slepc 234
      H[ldh*(j-1)+j] = norm;
1117 slepc 235
 
236
      for (i=0;i<j;i++)
1578 slepc 237
        H[ldh*j+i] = H[ldh*j+i]/norm;
238
      H[ldh*j+j] = H[ldh*j+j]/dot;      
1117 slepc 239
      ierr = VecScale(f,1.0/norm);CHKERRQ(ierr);
240
    }
241
 
1755 antodo 242
    ierr = SlepcVecMAXPBY(f,1.0,-1.0,j+1,H+ldh*j,V);CHKERRQ(ierr);
1117 slepc 243
 
244
    if (j<m-1) {
245
      ierr = VecCopy(f,V[j+1]);CHKERRQ(ierr);
246
    }
247
  }
248
 
1345 slepc 249
  ierr = IPNorm(eps->ip,f,beta);CHKERRQ(ierr);
1117 slepc 250
  ierr = VecScale(f,1.0 / *beta);CHKERRQ(ierr);
251
  *breakdown = PETSC_FALSE;
252
 
253
  PetscFunctionReturn(0);
254
}
255
 
256
#undef __FUNCT__  
1484 slepc 257
#define __FUNCT__ "EPSProjectedArnoldi"
258
/*
259
   EPSProjectedArnoldi - Solves the projected eigenproblem.
260
 
261
   On input:
262
     S is the projected matrix (leading dimension is lds)
263
 
264
   On output:
265
     S has (real) Schur form with diagonal blocks sorted appropriately
266
     Q contains the corresponding Schur vectors (order n, leading dimension n)
267
*/
1509 slepc 268
PetscErrorCode EPSProjectedArnoldi(EPS eps,PetscScalar *S,PetscInt lds,PetscScalar *Q,PetscInt n)
1484 slepc 269
{
270
  PetscErrorCode ierr;
1509 slepc 271
  PetscInt       i;
1484 slepc 272
 
273
  PetscFunctionBegin;
274
  /* Initialize orthogonal matrix */
275
  ierr = PetscMemzero(Q,n*n*sizeof(PetscScalar));CHKERRQ(ierr);
276
  for (i=0;i<n;i++)
277
    Q[i*(n+1)] = 1.0;
278
  /* Reduce S to (quasi-)triangular form, S <- Q S Q' */
279
  ierr = EPSDenseSchur(n,eps->nconv,S,lds,Q,eps->eigr,eps->eigi);CHKERRQ(ierr);
280
  /* Sort the remaining columns of the Schur form */
1823 antodo 281
  ierr = EPSSortDenseSchur(eps,n,eps->nconv,S,lds,Q,eps->eigr,eps->eigi);CHKERRQ(ierr);    
1484 slepc 282
  PetscFunctionReturn(0);
283
}
284
 
285
#undef __FUNCT__  
1614 slepc 286
#define __FUNCT__ "EPSUpdateVectors"
1484 slepc 287
/*
1614 slepc 288
   EPSUpdateVectors - Computes approximate Schur vectors (or eigenvectors) by
1484 slepc 289
   either Ritz extraction (U=U*Q) or refined Ritz extraction
290
 
291
   On input:
1614 slepc 292
     n is the size of U
1484 slepc 293
     U is the orthogonal basis of the subspace used for projecting
1614 slepc 294
     s is the index of the first vector computed
295
     e+1 is the index of the last vector computed
296
     Q contains the corresponding Schur vectors of the projected matrix (size n x n, leading dimension ldq)
1484 slepc 297
     H is the (extended) projected matrix (size n+1 x n, leading dimension ldh)
298
 
299
   On output:
300
     v is the resulting vector
301
*/
1614 slepc 302
PetscErrorCode EPSUpdateVectors(EPS eps,PetscInt n_,Vec *U,PetscInt s,PetscInt e,PetscScalar *Q,PetscInt ldq,PetscScalar *H,PetscInt ldh_)
1484 slepc 303
{
304
#if defined(PETSC_MISSING_LAPACK_GESVD)
305
  SETERRQ(PETSC_ERR_SUP,"GESVD - Lapack routine is unavailable.");
306
#else
307
  PetscErrorCode ierr;
308
  PetscTruth     isrefined;
1614 slepc 309
  PetscInt       i,j,k;
1517 slepc 310
  PetscBLASInt   n1,lwork,idummy=1,info,n=n_,ldh=ldh_;
1484 slepc 311
  PetscScalar    *B,sdummy,*work;
312
  PetscReal      *sigma;
313
 
314
  PetscFunctionBegin;
1560 slepc 315
  isrefined = (eps->extraction==EPS_REFINED || eps->extraction==EPS_REFINED_HARMONIC)?PETSC_TRUE:PETSC_FALSE;
1614 slepc 316
  if (isrefined) {
1484 slepc 317
    /* Refined Ritz extraction */
318
    n1 = n+1;
319
    ierr = PetscMalloc(n1*n*sizeof(PetscScalar),&B);CHKERRQ(ierr);
320
    ierr = PetscMalloc(6*n*sizeof(PetscReal),&sigma);CHKERRQ(ierr);
321
    lwork = 10*n;
322
    ierr = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr);
1614 slepc 323
 
324
    for (k=s;k<e;k++) {
325
      /* copy H to B */
326
      for (i=0;i<=n;i++) {
327
        for (j=0;j<n;j++) {
328
          B[i+j*n1] = H[i+j*ldh];
329
        }
1484 slepc 330
      }
1614 slepc 331
      /* subtract ritz value from diagonal of B^ */
332
      for (i=0;i<n;i++) {
333
        B[i+i*n1] -= eps->eigr[k];  /* MISSING: complex case */
334
      }
335
      /* compute SVD of [H-mu*I] */
336
  #if !defined(PETSC_USE_COMPLEX)
337
      LAPACKgesvd_("N","O",&n1,&n,B,&n1,sigma,&sdummy,&idummy,&sdummy,&idummy,work,&lwork,&info);
338
  #else
339
      LAPACKgesvd_("N","O",&n1,&n,B,&n1,sigma,&sdummy,&idummy,&sdummy,&idummy,work,&lwork,sigma+n,&info);
340
  #endif
341
      if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack xGESVD %d",info);
342
      /* the smallest singular value is the new error estimate */
343
      eps->errest[k] = sigma[n-1];
344
      /* update vector with right singular vector associated to smallest singular value */
345
      for (i=0;i<n;i++)
346
        Q[k*ldq+i] = B[n-1+i*n1];
1484 slepc 347
    }
348
    /* free workspace */
349
    ierr = PetscFree(B);CHKERRQ(ierr);
350
    ierr = PetscFree(sigma);CHKERRQ(ierr);
351
    ierr = PetscFree(work);CHKERRQ(ierr);
352
  }
1614 slepc 353
  /* Ritz extraction: v = U*q */
354
  ierr = SlepcUpdateVectors(n_,U,s,e,Q,ldq,PETSC_FALSE);CHKERRQ(ierr);
1484 slepc 355
  PetscFunctionReturn(0);
356
#endif
357
}
358
 
359
#undef __FUNCT__  
6 dsic.upv.es!jroman 360
#define __FUNCT__ "EPSSolve_ARNOLDI"
476 dsic.upv.es!antodo 361
PetscErrorCode EPSSolve_ARNOLDI(EPS eps)
6 dsic.upv.es!jroman 362
{
476 dsic.upv.es!antodo 363
  PetscErrorCode ierr;
2062 jroman 364
  PetscInt       i,k,lwork,nv;
1755 antodo 365
  Vec            f=eps->work[0];
2062 jroman 366
  PetscScalar    *H=eps->T,*U,*g,*work,*Hcopy;
367
  PetscReal      beta,gnorm,corrf=1.0;
368
  PetscTruth     breakdown;
1345 slepc 369
  IPOrthogonalizationRefinementType orthog_ref;
1083 slepc 370
  EPS_ARNOLDI    *arnoldi = (EPS_ARNOLDI *)eps->data;
431 dsic.upv.es!antodo 371
 
372
  PetscFunctionBegin;
1052 slepc 373
  ierr = PetscMemzero(eps->T,eps->ncv*eps->ncv*sizeof(PetscScalar));CHKERRQ(ierr);
1830 antodo 374
  ierr = PetscMalloc(eps->ncv*eps->ncv*sizeof(PetscScalar),&U);CHKERRQ(ierr);
2062 jroman 375
  lwork = PetscMax((eps->ncv+1)*eps->ncv,7*eps->ncv);
376
  ierr = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr);
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
      gnorm = 0.0;
1830 antodo 413
      for (i=0;i<nv;i++)
1484 slepc 414
        gnorm = gnorm + PetscRealPart(g[i]*PetscConj(g[i]));
2062 jroman 415
      corrf = sqrt(1.0+gnorm);
1484 slepc 416
    }
417
 
2062 jroman 418
    /* Solve projected problem */
2026 jroman 419
    ierr = EPSProjectedArnoldi(eps,H,eps->ncv,U,nv);CHKERRQ(ierr);
420
 
2062 jroman 421
    /* Check convergence */
422
    ierr = EPSKrylovConvergence(eps,PETSC_FALSE,eps->nconv,nv-eps->nconv,H,eps->ncv,U,eps->V,nv,beta,corrf,&k,work);CHKERRQ(ierr);
423
 
1830 antodo 424
    ierr = EPSUpdateVectors(eps,nv,eps->V,eps->nconv,PetscMin(k+1,nv),U,nv,Hcopy,eps->ncv);CHKERRQ(ierr);
516 dsic.upv.es!antodo 425
    eps->nconv = k;
879 ono.com!jroman 426
 
1830 antodo 427
    EPSMonitor(eps,eps->its,eps->nconv,eps->eigr,eps->eigi,eps->errest,nv);
1135 slepc 428
    if (breakdown) {
429
      PetscInfo2(eps,"Breakdown in Arnoldi method (it=%i norm=%g)\n",eps->its,beta);
1057 slepc 430
      ierr = EPSGetStartVector(eps,k,eps->V[k],&breakdown);CHKERRQ(ierr);
431
      if (breakdown) {
432
        eps->reason = EPS_DIVERGED_BREAKDOWN;
433
        PetscInfo(eps,"Unable to generate more start vectors\n");
434
      }
435
    }
1055 slepc 436
    if (eps->its >= eps->max_it) eps->reason = EPS_DIVERGED_ITS;
437
    if (eps->nconv >= eps->nev) eps->reason = EPS_CONVERGED_TOL;
431 dsic.upv.es!antodo 438
  }
439
 
2062 jroman 440
  ierr = PetscFree(U);CHKERRQ(ierr);
431 dsic.upv.es!antodo 441
  ierr = PetscFree(work);CHKERRQ(ierr);
1560 slepc 442
  if (eps->extraction==EPS_HARMONIC || eps->extraction==EPS_REFINED_HARMONIC) {
1484 slepc 443
    ierr = PetscFree(g);CHKERRQ(ierr);
444
  }
1560 slepc 445
  if (eps->extraction==EPS_REFINED || eps->extraction==EPS_REFINED_HARMONIC) {
1484 slepc 446
    ierr = PetscFree(Hcopy);CHKERRQ(ierr);
447
  }
431 dsic.upv.es!antodo 448
  PetscFunctionReturn(0);
449
}
450
 
1083 slepc 451
#undef __FUNCT__  
452
#define __FUNCT__ "EPSSetFromOptions_ARNOLDI"
453
PetscErrorCode EPSSetFromOptions_ARNOLDI(EPS eps)
454
{
455
  PetscErrorCode ierr;
1923 jroman 456
  PetscTruth     set,val;
1083 slepc 457
  EPS_ARNOLDI    *arnoldi = (EPS_ARNOLDI *)eps->data;
458
 
459
  PetscFunctionBegin;
2102 eromero 460
  ierr = PetscOptionsBegin(((PetscObject)eps)->comm,((PetscObject)eps)->prefix,"ARNOLDI Options","EPS");CHKERRQ(ierr);
1923 jroman 461
  ierr = PetscOptionsTruth("-eps_arnoldi_delayed","Arnoldi with delayed reorthogonalization","EPSArnoldiSetDelayed",arnoldi->delayed,&val,&set);CHKERRQ(ierr);
462
  if (set) {
463
    ierr = EPSArnoldiSetDelayed(eps,val);CHKERRQ(ierr);
464
  }
2102 eromero 465
  ierr = PetscOptionsEnd();CHKERRQ(ierr);
1083 slepc 466
  PetscFunctionReturn(0);
467
}
468
 
469
EXTERN_C_BEGIN
470
#undef __FUNCT__  
471
#define __FUNCT__ "EPSArnoldiSetDelayed_ARNOLDI"
472
PetscErrorCode EPSArnoldiSetDelayed_ARNOLDI(EPS eps,PetscTruth delayed)
473
{
474
  EPS_ARNOLDI    *arnoldi = (EPS_ARNOLDI *)eps->data;
475
 
476
  PetscFunctionBegin;
477
  arnoldi->delayed = delayed;
478
  PetscFunctionReturn(0);
479
}
480
EXTERN_C_END
481
 
482
#undef __FUNCT__  
483
#define __FUNCT__ "EPSArnoldiSetDelayed"
484
/*@
1084 slepc 485
   EPSArnoldiSetDelayed - Activates or deactivates delayed reorthogonalization
486
   in the Arnoldi iteration.
1083 slepc 487
 
488
   Collective on EPS
489
 
490
   Input Parameters:
491
+  eps - the eigenproblem solver context
1186 slepc 492
-  delayed - boolean flag
1083 slepc 493
 
494
   Options Database Key:
1084 slepc 495
.  -eps_arnoldi_delayed - Activates delayed reorthogonalization in Arnoldi
1083 slepc 496
 
1084 slepc 497
   Note:
498
   Delayed reorthogonalization is an aggressive optimization for the Arnoldi
1186 slepc 499
   eigensolver than may provide better scalability, but sometimes makes the
500
   solver converge less than the default algorithm.
1084 slepc 501
 
1083 slepc 502
   Level: advanced
503
 
504
.seealso: EPSArnoldiGetDelayed()
505
@*/
506
PetscErrorCode EPSArnoldiSetDelayed(EPS eps,PetscTruth delayed)
507
{
508
  PetscErrorCode ierr, (*f)(EPS,PetscTruth);
509
 
510
  PetscFunctionBegin;
511
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
1084 slepc 512
  ierr = PetscObjectQueryFunction((PetscObject)eps,"EPSArnoldiSetDelayed_C",(void (**)())&f);CHKERRQ(ierr);
1083 slepc 513
  if (f) {
514
    ierr = (*f)(eps,delayed);CHKERRQ(ierr);
515
  }
516
  PetscFunctionReturn(0);
517
}
518
 
519
EXTERN_C_BEGIN
520
#undef __FUNCT__  
521
#define __FUNCT__ "EPSArnoldiGetDelayed_ARNOLDI"
522
PetscErrorCode EPSArnoldiGetDelayed_ARNOLDI(EPS eps,PetscTruth *delayed)
523
{
524
  EPS_ARNOLDI    *arnoldi = (EPS_ARNOLDI *)eps->data;
525
 
526
  PetscFunctionBegin;
527
  *delayed = arnoldi->delayed;
528
  PetscFunctionReturn(0);
529
}
530
EXTERN_C_END
531
 
532
#undef __FUNCT__  
533
#define __FUNCT__ "EPSArnoldiGetDelayed"
534
/*@C
535
   EPSArnoldiGetDelayed - Gets the type of reorthogonalization used during the Arnoldi
536
   iteration.
537
 
538
   Collective on EPS
539
 
540
   Input Parameter:
541
.  eps - the eigenproblem solver context
542
 
543
   Input Parameter:
1084 slepc 544
.  delayed - boolean flag indicating if delayed reorthogonalization has been enabled
1083 slepc 545
 
546
   Level: advanced
547
 
1084 slepc 548
.seealso: EPSArnoldiSetDelayed()
1083 slepc 549
@*/
550
PetscErrorCode EPSArnoldiGetDelayed(EPS eps,PetscTruth *delayed)
551
{
552
  PetscErrorCode ierr, (*f)(EPS,PetscTruth*);
553
 
554
  PetscFunctionBegin;
555
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
556
  ierr = PetscObjectQueryFunction((PetscObject)eps,"EPSArnoldiGetDelayed_C",(void (**)())&f);CHKERRQ(ierr);
557
  if (f) {
558
    ierr = (*f)(eps,delayed);CHKERRQ(ierr);
559
  }
560
  PetscFunctionReturn(0);
561
}
562
 
563
#undef __FUNCT__  
1925 jroman 564
#define __FUNCT__ "EPSDestroy_ARNOLDI"
565
PetscErrorCode EPSDestroy_ARNOLDI(EPS eps)
566
{
567
  PetscErrorCode ierr;
568
 
569
  PetscFunctionBegin;
570
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
571
  ierr = EPSDestroy_Default(eps);CHKERRQ(ierr);
572
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSArnoldiSetDelayed_C","",PETSC_NULL);CHKERRQ(ierr);
573
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSArnoldiGetDelayed_C","",PETSC_NULL);CHKERRQ(ierr);
574
  PetscFunctionReturn(0);
575
}
576
 
577
#undef __FUNCT__  
1083 slepc 578
#define __FUNCT__ "EPSView_ARNOLDI"
579
PetscErrorCode EPSView_ARNOLDI(EPS eps,PetscViewer viewer)
580
{
581
  PetscErrorCode ierr;
582
  PetscTruth     isascii;
583
  EPS_ARNOLDI    *arnoldi = (EPS_ARNOLDI *)eps->data;
584
 
585
  PetscFunctionBegin;
586
  ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
587
  if (!isascii) {
588
    SETERRQ1(1,"Viewer type %s not supported for EPSARNOLDI",((PetscObject)viewer)->type_name);
589
  }
590
  if (arnoldi->delayed) {
591
    ierr = PetscViewerASCIIPrintf(viewer,"using delayed reorthogonalization\n");CHKERRQ(ierr);
592
  }  
593
  PetscFunctionReturn(0);
594
}
595
 
904 dsic.upv.es!antodo 596
EXTERN PetscErrorCode EPSSolve_TS_ARNOLDI(EPS);
597
 
6 dsic.upv.es!jroman 598
EXTERN_C_BEGIN
599
#undef __FUNCT__  
600
#define __FUNCT__ "EPSCreate_ARNOLDI"
476 dsic.upv.es!antodo 601
PetscErrorCode EPSCreate_ARNOLDI(EPS eps)
6 dsic.upv.es!jroman 602
{
1083 slepc 603
  PetscErrorCode ierr;
604
  EPS_ARNOLDI    *arnoldi;
605
 
6 dsic.upv.es!jroman 606
  PetscFunctionBegin;
1083 slepc 607
  ierr = PetscNew(EPS_ARNOLDI,&arnoldi);CHKERRQ(ierr);
608
  PetscLogObjectMemory(eps,sizeof(EPS_ARNOLDI));
609
  eps->data                      = (void *)arnoldi;
503 dsic.upv.es!antodo 610
  eps->ops->setup                = EPSSetUp_ARNOLDI;
1083 slepc 611
  eps->ops->setfromoptions       = EPSSetFromOptions_ARNOLDI;
1925 jroman 612
  eps->ops->destroy              = EPSDestroy_ARNOLDI;
1083 slepc 613
  eps->ops->view                 = EPSView_ARNOLDI;
176 dsic.upv.es!antodo 614
  eps->ops->backtransform        = EPSBackTransform_Default;
508 dsic.upv.es!antodo 615
  eps->ops->computevectors       = EPSComputeVectors_Schur;
1083 slepc 616
  arnoldi->delayed               = PETSC_FALSE;
1085 slepc 617
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSArnoldiSetDelayed_C","EPSArnoldiSetDelayed_ARNOLDI",EPSArnoldiSetDelayed_ARNOLDI);CHKERRQ(ierr);
618
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSArnoldiGetDelayed_C","EPSArnoldiGetDelayed_ARNOLDI",EPSArnoldiGetDelayed_ARNOLDI);CHKERRQ(ierr);
6 dsic.upv.es!jroman 619
  PetscFunctionReturn(0);
620
}
621
EXTERN_C_END
622