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