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
535 dsic.upv.es!jroman 1
/*                      
6 dsic.upv.es!jroman 2
 
535 dsic.upv.es!jroman 3
   SLEPc eigensolver: "subspace"
4
 
5
   Method: Subspace Iteration
6
 
7
   Algorithm:
8
 
953 dsic.upv.es!jroman 9
       Subspace iteration with Rayleigh-Ritz projection and locking,
10
       based on the SRRIT implementation.
535 dsic.upv.es!jroman 11
 
12
   References:
13
 
953 dsic.upv.es!jroman 14
       [1] "Subspace Iteration in SLEPc", SLEPc Technical Report STR-3,
15
           available at http://www.grycap.upv.es/slepc.
535 dsic.upv.es!jroman 16
 
17
   Last update: June 2004
18
 
1376 slepc 19
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
20
      SLEPc - Scalable Library for Eigenvalue Problem Computations
21
      Copyright (c) 2002-2007, Universidad Politecnica de Valencia, Spain
22
 
23
      This file is part of SLEPc. See the README file for conditions of use
24
      and additional information.
25
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
535 dsic.upv.es!jroman 26
*/
1376 slepc 27
 
62 dsic.upv.es!antodo 28
#include "src/eps/epsimpl.h"                /*I "slepceps.h" I*/
470 dsic.upv.es!antodo 29
#include "slepcblaslapack.h"
6 dsic.upv.es!jroman 30
 
31
#undef __FUNCT__  
32
#define __FUNCT__ "EPSSetUp_SUBSPACE"
476 dsic.upv.es!antodo 33
PetscErrorCode EPSSetUp_SUBSPACE(EPS eps)
6 dsic.upv.es!jroman 34
{
476 dsic.upv.es!antodo 35
  PetscErrorCode ierr;
982 slepc 36
  PetscInt       N;
6 dsic.upv.es!jroman 37
 
38
  PetscFunctionBegin;
1385 slepc 39
  ierr = VecGetSize(eps->vec_initial,&N);CHKERRQ(ierr);
6 dsic.upv.es!jroman 40
  if (eps->ncv) {
41
    if (eps->ncv<eps->nev) SETERRQ(1,"The value of ncv must be at least nev");
42
  }
651 dsic.upv.es!antodo 43
  else eps->ncv = PetscMin(N,PetscMax(2*eps->nev,eps->nev+15));
1220 slepc 44
  if (!eps->max_it) eps->max_it = PetscMax(100,2*N/eps->ncv);
259 dsic.upv.es!antodo 45
  if (eps->which!=EPS_LARGEST_MAGNITUDE)
46
    SETERRQ(1,"Wrong value of eps->which");
1426 slepc 47
  if (!eps->projection) {
48
    ierr = EPSSetProjection(eps,EPS_RITZ);CHKERRQ(ierr);
49
  } else if (eps->projection!=EPS_RITZ) {
50
    SETERRQ(PETSC_ERR_SUP,"Unsupported projection type\n");
51
  }
52
 
259 dsic.upv.es!antodo 53
  ierr = EPSAllocateSolution(eps);CHKERRQ(ierr);
1040 slepc 54
  ierr = PetscFree(eps->T);CHKERRQ(ierr);
508 dsic.upv.es!antodo 55
  ierr = PetscMalloc(eps->ncv*eps->ncv*sizeof(PetscScalar),&eps->T);CHKERRQ(ierr);
432 dsic.upv.es!antodo 56
  ierr = EPSDefaultGetWork(eps,eps->ncv);CHKERRQ(ierr);
6 dsic.upv.es!jroman 57
  PetscFunctionReturn(0);
58
}
59
 
60
#undef __FUNCT__  
535 dsic.upv.es!jroman 61
#define __FUNCT__ "EPSHessCond"
62
/*
63
   EPSHessCond - Compute the inf-norm condition number of the upper
64
   Hessenberg matrix H: cond(H) = norm(H)*norm(inv(H)).
65
   This routine uses Gaussian elimination with partial pivoting to
66
   compute the inverse explicitly.
67
*/
68
static PetscErrorCode EPSHessCond(PetscScalar* H,int n, PetscReal* cond)
6 dsic.upv.es!jroman 69
{
806 dsic.upv.es!antodo 70
#if defined(PETSC_MISSING_LAPACK_GETRF) || defined(SLEPC_MISSING_LAPACK_GETRI) || defined(SLEPC_MISSING_LAPACK_LANGE) || defined(SLEPC_MISSING_LAPACK_LANHS)
817 dsic.upv.es!antodo 71
  PetscFunctionBegin;
806 dsic.upv.es!antodo 72
  SETERRQ(PETSC_ERR_SUP,"GETRF,GETRI - Lapack routines are unavailable.");
73
#else
476 dsic.upv.es!antodo 74
  PetscErrorCode ierr;
75
  int            *ipiv,lwork,info;
76
  PetscScalar    *work;
77
  PetscReal      hn,hin,*rwork;
470 dsic.upv.es!antodo 78
 
6 dsic.upv.es!jroman 79
  PetscFunctionBegin;
1339 slepc 80
  ierr = PetscLogEventBegin(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
470 dsic.upv.es!antodo 81
  ierr = PetscMalloc(sizeof(int)*n,&ipiv);CHKERRQ(ierr);
82
  lwork = n*n;
83
  ierr = PetscMalloc(sizeof(PetscScalar)*lwork,&work);CHKERRQ(ierr);
84
  ierr = PetscMalloc(sizeof(PetscReal)*n,&rwork);CHKERRQ(ierr);
784 dsic.upv.es!antodo 85
  hn = LAPACKlanhs_("I",&n,H,&n,rwork,1);
86
  LAPACKgetrf_(&n,&n,H,&n,ipiv,&info);
476 dsic.upv.es!antodo 87
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack xGETRF %d",info);
784 dsic.upv.es!antodo 88
  LAPACKgetri_(&n,H,&n,ipiv,work,&lwork,&info);
476 dsic.upv.es!antodo 89
  if (info) SETERRQ1(PETSC_ERR_LIB,"Error in Lapack xGETRI %d",info);
784 dsic.upv.es!antodo 90
  hin = LAPACKlange_("I",&n,&n,H,&n,rwork,1);
470 dsic.upv.es!antodo 91
  *cond = hn * hin;
92
  ierr = PetscFree(ipiv);CHKERRQ(ierr);
93
  ierr = PetscFree(work);CHKERRQ(ierr);
94
  ierr = PetscFree(rwork);CHKERRQ(ierr);
1339 slepc 95
  ierr = PetscLogEventEnd(EPS_Dense,0,0,0,0);CHKERRQ(ierr);
470 dsic.upv.es!antodo 96
  PetscFunctionReturn(0);
806 dsic.upv.es!antodo 97
#endif
470 dsic.upv.es!antodo 98
}
6 dsic.upv.es!jroman 99
 
470 dsic.upv.es!antodo 100
#undef __FUNCT__  
535 dsic.upv.es!jroman 101
#define __FUNCT__ "EPSFindGroup"
102
/*
103
   EPSFindGroup - Find a group of nearly equimodular eigenvalues, provided
104
   in arrays wr and wi, according to the tolerance grptol. Also the 2-norms
105
   of the residuals must be passed-in (rsd). Arrays are processed from index
106
   l to index m only. The output information is:
107
 
108
   ngrp - number of entries of the group
893 dsic.upv.es!jroman 109
   ctr  - (w(l)+w(l+ngrp-1))/2
535 dsic.upv.es!jroman 110
   ae   - average of wr(l),...,wr(l+ngrp-1)
111
   arsd - average of rsd(l),...,rsd(l+ngrp-1)
112
*/
113
static PetscErrorCode EPSFindGroup(int l,int m,PetscScalar *wr,PetscScalar *wi,PetscReal *rsd,
470 dsic.upv.es!antodo 114
  PetscReal grptol,int *ngrp,PetscReal *ctr,PetscReal *ae,PetscReal *arsd)
115
{
116
  int       i;
117
  PetscReal rmod,rmod1;
6 dsic.upv.es!jroman 118
 
470 dsic.upv.es!antodo 119
  PetscFunctionBegin;
120
  *ngrp = 0;
121
  *ctr = 0;
122
 
504 dsic.upv.es!antodo 123
  rmod = SlepcAbsEigenvalue(wr[l],wi[l]);
6 dsic.upv.es!jroman 124
 
470 dsic.upv.es!antodo 125
  for (i=l;i<m;) {
504 dsic.upv.es!antodo 126
    rmod1 = SlepcAbsEigenvalue(wr[i],wi[i]);
470 dsic.upv.es!antodo 127
    if (PetscAbsReal(rmod-rmod1) > grptol*(rmod+rmod1)) break;
128
    *ctr = (rmod+rmod1)/2.0;
129
    if (wi[i] != 0.0) {
130
      (*ngrp)+=2;
131
      i+=2;
132
    } else {
133
      (*ngrp)++;
134
      i++;
6 dsic.upv.es!jroman 135
    }
470 dsic.upv.es!antodo 136
  }
6 dsic.upv.es!jroman 137
 
470 dsic.upv.es!antodo 138
  *ae = 0;
139
  *arsd = 0;
6 dsic.upv.es!jroman 140
 
470 dsic.upv.es!antodo 141
  if (*ngrp) {
142
    for (i=l;i<l+*ngrp;i++) {
143
      (*ae) += PetscRealPart(wr[i]);
144
      (*arsd) += rsd[i]*rsd[i];
6 dsic.upv.es!jroman 145
    }
470 dsic.upv.es!antodo 146
    *ae = *ae / *ngrp;
147
    *arsd = PetscSqrtScalar(*arsd / *ngrp);
6 dsic.upv.es!jroman 148
  }
149
  PetscFunctionReturn(0);
150
}
151
 
152
#undef __FUNCT__  
470 dsic.upv.es!antodo 153
#define __FUNCT__ "EPSSchurResidualNorms"
535 dsic.upv.es!jroman 154
/*
155
   EPSSchurResidualNorms - Computes the column norms of residual vectors
156
   OP*V(1:n,l:m) - V*T(1:m,l:m) were on entry, OP*V has been computed and
157
   stored in AV. ldt is the leading dimension of T. On exit, rsd(l) to
158
   rsd(m) contain the computed norms.
159
*/
476 dsic.upv.es!antodo 160
static PetscErrorCode EPSSchurResidualNorms(EPS eps,Vec *V,Vec *AV,PetscScalar *T,int l,int m,int ldt,PetscReal *rsd)
6 dsic.upv.es!jroman 161
{
476 dsic.upv.es!antodo 162
  PetscErrorCode ierr;
163
  int            i;
470 dsic.upv.es!antodo 164
#if defined(PETSC_USE_COMPLEX)
476 dsic.upv.es!antodo 165
  PetscScalar    t;
470 dsic.upv.es!antodo 166
#endif
6 dsic.upv.es!jroman 167
 
168
  PetscFunctionBegin;
470 dsic.upv.es!antodo 169
  for (i=l;i<m;i++) {
828 dsic.upv.es!antodo 170
    ierr = VecSet(eps->work[0],0.0);CHKERRQ(ierr);
171
    ierr = VecMAXPY(eps->work[0],m,T+ldt*i,V);CHKERRQ(ierr);
172
    ierr = VecWAXPY(eps->work[1],-1.0,eps->work[0],AV[i]);CHKERRQ(ierr);
470 dsic.upv.es!antodo 173
#if !defined(PETSC_USE_COMPLEX)
174
    ierr = VecDot(eps->work[1],eps->work[1],rsd+i);CHKERRQ(ierr);
175
#else
176
    ierr = VecDot(eps->work[1],eps->work[1],&t);CHKERRQ(ierr);
177
    rsd[i] = PetscRealPart(t);
178
#endif    
6 dsic.upv.es!jroman 179
  }
470 dsic.upv.es!antodo 180
 
181
  for (i=l;i<m;i++) {
182
    if (i == m-1) {
183
      rsd[i] = sqrt(rsd[i]);  
184
    } else if (T[i+1+(ldt*i)]==0.0) {
185
      rsd[i] = sqrt(rsd[i]);
186
    } else {
187
      rsd[i] = sqrt(rsd[i]+rsd[i+1])/2.0;
188
      rsd[i+1] = rsd[i];
189
      i++;
190
    }
191
  }
6 dsic.upv.es!jroman 192
  PetscFunctionReturn(0);
193
}
194
 
195
#undef __FUNCT__  
470 dsic.upv.es!antodo 196
#define __FUNCT__ "EPSSolve_SUBSPACE"
476 dsic.upv.es!antodo 197
PetscErrorCode EPSSolve_SUBSPACE(EPS eps)
6 dsic.upv.es!jroman 198
{
476 dsic.upv.es!antodo 199
  PetscErrorCode ierr;
1175 slepc 200
  int            i,ngrp,nogrp,*itrsd,*itrsdold,
1220 slepc 201
                 nxtsrr,idsrr,idort,nxtort,ncv = eps->ncv,its;
1175 slepc 202
  PetscScalar    *T=eps->T,*U;
664 dsic.upv.es!antodo 203
  PetscReal      arsd,oarsd,ctr,octr,ae,oae,*rsd,*rsdold,norm,tcond;
550 dsic.upv.es!antodo 204
  PetscTruth     breakdown;
470 dsic.upv.es!antodo 205
  /* Parameters */
535 dsic.upv.es!jroman 206
  int            init = 5;        /* Number of initial iterations */
207
  PetscReal      stpfac = 1.5,    /* Max num of iter before next SRR step */
893 dsic.upv.es!jroman 208
                 alpha = 1.0,     /* Used to predict convergence of next residual */
209
                 beta = 1.1,      /* Used to predict convergence of next residual */
535 dsic.upv.es!jroman 210
                 grptol = 1e-8,   /* Tolerance for EPSFindGroup */
211
                 cnvtol = 1e-6;   /* Convergence criterion for cnv */
212
  int            orttol = 2;      /* Number of decimal digits whose loss
213
                                     can be tolerated in orthogonalization */
6 dsic.upv.es!jroman 214
 
215
  PetscFunctionBegin;
1220 slepc 216
  its = 0;
470 dsic.upv.es!antodo 217
  ierr = PetscMalloc(sizeof(PetscScalar)*ncv*ncv,&U);CHKERRQ(ierr);
664 dsic.upv.es!antodo 218
  ierr = PetscMalloc(sizeof(PetscReal)*ncv,&rsd);CHKERRQ(ierr);
470 dsic.upv.es!antodo 219
  ierr = PetscMalloc(sizeof(PetscReal)*ncv,&rsdold);CHKERRQ(ierr);
220
  ierr = PetscMalloc(sizeof(int)*ncv,&itrsd);CHKERRQ(ierr);
221
  ierr = PetscMalloc(sizeof(int)*ncv,&itrsdold);CHKERRQ(ierr);
535 dsic.upv.es!jroman 222
 
1385 slepc 223
  /* Generate a set of random initial vectors and orthonormalize them */
470 dsic.upv.es!antodo 224
  for (i=0;i<ncv;i++) {
1385 slepc 225
    ierr = SlepcVecSetRandom(eps->V[i]);CHKERRQ(ierr);
664 dsic.upv.es!antodo 226
    rsd[i] = 0.0;
470 dsic.upv.es!antodo 227
    itrsd[i] = -1;
228
  }
1345 slepc 229
  ierr = IPQRDecomposition(eps->ip,eps->V,0,ncv,PETSC_NULL,0,eps->work[0]);CHKERRQ(ierr);
470 dsic.upv.es!antodo 230
 
231
  while (eps->its<eps->max_it) {
1220 slepc 232
    eps->its++;
233
 
535 dsic.upv.es!jroman 234
    /* Find group in previously computed eigenvalues */
664 dsic.upv.es!antodo 235
    ierr = EPSFindGroup(eps->nconv,ncv,eps->eigr,eps->eigi,rsd,grptol,&nogrp,&octr,&oae,&oarsd);CHKERRQ(ierr);
470 dsic.upv.es!antodo 236
 
535 dsic.upv.es!jroman 237
    /* Compute a Rayleigh-Ritz projection step
238
       on the active columns (idx) */
239
 
240
    /* 1. AV(:,idx) = OP * V(:,idx) */
470 dsic.upv.es!antodo 241
    for (i=eps->nconv;i<ncv;i++) {
242
      ierr = STApply(eps->OP,eps->V[i],eps->AV[i]);CHKERRQ(ierr);
231 dsic.upv.es!jroman 243
    }
6 dsic.upv.es!jroman 244
 
535 dsic.upv.es!jroman 245
    /* 2. T(:,idx) = V' * AV(:,idx) */
470 dsic.upv.es!antodo 246
    for (i=eps->nconv;i<ncv;i++) {
1009 slepc 247
      ierr = VecMDot(eps->AV[i],ncv,eps->V,T+i*ncv);CHKERRQ(ierr);
470 dsic.upv.es!antodo 248
    }
6 dsic.upv.es!jroman 249
 
535 dsic.upv.es!jroman 250
    /* 3. Reduce projected matrix to Hessenberg form: [U,T] = hess(T) */
1175 slepc 251
    ierr = EPSDenseHessenberg(ncv,eps->nconv,T,ncv,U);CHKERRQ(ierr);
470 dsic.upv.es!antodo 252
 
535 dsic.upv.es!jroman 253
    /* 4. Reduce T to quasi-triangular (Schur) form */
1057 slepc 254
    ierr = EPSDenseSchur(ncv,eps->nconv,T,ncv,U,eps->eigr,eps->eigi);CHKERRQ(ierr);
535 dsic.upv.es!jroman 255
 
256
    /* 5. Sort diagonal elements in T and accumulate rotations on U */
1174 slepc 257
    ierr = EPSSortDenseSchur(ncv,eps->nconv,T,ncv,U,eps->eigr,eps->eigi,eps->which);CHKERRQ(ierr);
470 dsic.upv.es!antodo 258
 
535 dsic.upv.es!jroman 259
    /* 6. AV(:,idx) = AV * U(:,idx) */
870 dsic.upv.es!antodo 260
    for (i=eps->nconv;i<ncv;i++) {
261
      ierr = VecSet(eps->work[i],0.0);CHKERRQ(ierr);
262
      ierr = VecMAXPY(eps->work[i],ncv,U+ncv*i,eps->AV);CHKERRQ(ierr);
263
    }    
264
    for (i=eps->nconv;i<ncv;i++) {
265
      ierr = VecCopy(eps->work[i],eps->AV[i]);CHKERRQ(ierr);
266
    }    
470 dsic.upv.es!antodo 267
 
535 dsic.upv.es!jroman 268
    /* 7. V(:,idx) = V * U(:,idx) */
870 dsic.upv.es!antodo 269
    for (i=eps->nconv;i<ncv;i++) {
270
      ierr = VecSet(eps->work[i],0.0);CHKERRQ(ierr);
271
      ierr = VecMAXPY(eps->work[i],ncv,U+ncv*i,eps->V);CHKERRQ(ierr);
272
    }    
273
    for (i=eps->nconv;i<ncv;i++) {
274
      ierr = VecCopy(eps->work[i],eps->V[i]);CHKERRQ(ierr);
275
    }    
470 dsic.upv.es!antodo 276
 
535 dsic.upv.es!jroman 277
    /* Compute residuals */
664 dsic.upv.es!antodo 278
    for (i=0;i<ncv;i++) { rsdold[i] = rsd[i]; }
6 dsic.upv.es!jroman 279
 
664 dsic.upv.es!antodo 280
    ierr = EPSSchurResidualNorms(eps,eps->V,eps->AV,T,eps->nconv,ncv,ncv,rsd);CHKERRQ(ierr);
6 dsic.upv.es!jroman 281
 
664 dsic.upv.es!antodo 282
    for (i=0;i<ncv;i++) {
283
      eps->errest[i] = rsd[i] / SlepcAbsEigenvalue(eps->eigr[i],eps->eigi[i]);
284
    }
470 dsic.upv.es!antodo 285
    EPSMonitor(eps,eps->its,eps->nconv,eps->eigr,eps->eigi,eps->errest,ncv);
286
 
535 dsic.upv.es!jroman 287
    /* Convergence check */
470 dsic.upv.es!antodo 288
    for (i=0;i<ncv;i++) { itrsdold[i] = itrsd[i]; }
1220 slepc 289
    for (i=eps->nconv;i<ncv;i++) { itrsd[i] = its; }
470 dsic.upv.es!antodo 290
 
291
    for (;;) {
535 dsic.upv.es!jroman 292
      /* Find group in currently computed eigenvalues */
664 dsic.upv.es!antodo 293
      ierr = EPSFindGroup(eps->nconv,ncv,eps->eigr,eps->eigi,rsd,grptol,&ngrp,&ctr,&ae,&arsd);CHKERRQ(ierr);
470 dsic.upv.es!antodo 294
      if (ngrp!=nogrp) break;
295
      if (ngrp==0) break;
296
      if (PetscAbsScalar(ae-oae)>ctr*cnvtol*(itrsd[eps->nconv]-itrsdold[eps->nconv])) break;
297
      if (arsd>ctr*eps->tol) break;
298
      eps->nconv = eps->nconv + ngrp;
299
      if (eps->nconv>=ncv) break;
300
    }
301
 
302
    if (eps->nconv>=eps->nev) break;
303
 
535 dsic.upv.es!jroman 304
    /* Compute nxtsrr (iteration of next projection step) */
1220 slepc 305
    nxtsrr = PetscMin(eps->max_it,PetscMax((int)floor(stpfac*its), init));
470 dsic.upv.es!antodo 306
 
307
    if (ngrp!=nogrp || ngrp==0 || arsd>=oarsd) {
1220 slepc 308
      idsrr = nxtsrr - its;
470 dsic.upv.es!antodo 309
    } else {
500 dsic.upv.es!jroman 310
      idsrr = (int)floor(alpha+beta*(itrsdold[eps->nconv]-itrsd[eps->nconv])*log(arsd/eps->tol)/log(arsd/oarsd));
470 dsic.upv.es!antodo 311
      idsrr = PetscMax(1,idsrr);
312
    }
1220 slepc 313
    nxtsrr = PetscMin(nxtsrr,its+idsrr);
6 dsic.upv.es!jroman 314
 
535 dsic.upv.es!jroman 315
    /* Compute nxtort (iteration of next orthogonalization step) */
470 dsic.upv.es!antodo 316
    ierr = PetscMemcpy(U,T,sizeof(PetscScalar)*ncv);CHKERRQ(ierr);
535 dsic.upv.es!jroman 317
    ierr = EPSHessCond(U,ncv,&tcond);CHKERRQ(ierr);
500 dsic.upv.es!jroman 318
    idort = PetscMax(1,(int)floor(orttol/PetscMax(1,log10(tcond))));    
1220 slepc 319
    nxtort = PetscMin(its+idort, nxtsrr);
6 dsic.upv.es!jroman 320
 
470 dsic.upv.es!antodo 321
    /* V(:,idx) = AV(:,idx) */
322
    for (i=eps->nconv;i<ncv;i++) {
323
      ierr = VecCopy(eps->AV[i],eps->V[i]);CHKERRQ(ierr);
324
    }
1220 slepc 325
    its++;
6 dsic.upv.es!jroman 326
 
535 dsic.upv.es!jroman 327
    /* Orthogonalization loop */
470 dsic.upv.es!antodo 328
    do {
1220 slepc 329
      while (its<nxtort) {
470 dsic.upv.es!antodo 330
 
535 dsic.upv.es!jroman 331
        /* AV(:,idx) = OP * V(:,idx) */
470 dsic.upv.es!antodo 332
        for (i=eps->nconv;i<ncv;i++) {
333
          ierr = STApply(eps->OP,eps->V[i],eps->AV[i]);CHKERRQ(ierr);
334
        }
335
 
535 dsic.upv.es!jroman 336
        /* V(:,idx) = AV(:,idx) with normalization */
470 dsic.upv.es!antodo 337
        for (i=eps->nconv;i<ncv;i++) {
338
          ierr = VecCopy(eps->AV[i],eps->V[i]);CHKERRQ(ierr);
339
          ierr = VecNorm(eps->V[i],NORM_INFINITY,&norm);CHKERRQ(ierr);
828 dsic.upv.es!antodo 340
          ierr = VecScale(eps->V[i],1/norm);CHKERRQ(ierr);
470 dsic.upv.es!antodo 341
        }
342
 
1220 slepc 343
        its++;
470 dsic.upv.es!antodo 344
      }
535 dsic.upv.es!jroman 345
      /* Orthonormalize vectors */
470 dsic.upv.es!antodo 346
      for (i=eps->nconv;i<ncv;i++) {
1345 slepc 347
        ierr = IPOrthogonalize(eps->ip,i+eps->nds,PETSC_NULL,eps->DSV,eps->V[i],PETSC_NULL,&norm,&breakdown,eps->work[0]);CHKERRQ(ierr);
550 dsic.upv.es!antodo 348
        if (breakdown) {
349
          ierr = SlepcVecSetRandom(eps->V[i]);CHKERRQ(ierr);
1345 slepc 350
          ierr = IPOrthogonalize(eps->ip,i+eps->nds,PETSC_NULL,eps->DSV,eps->V[i],PETSC_NULL,&norm,&breakdown,eps->work[0]);CHKERRQ(ierr);
550 dsic.upv.es!antodo 351
        }
828 dsic.upv.es!antodo 352
        ierr = VecScale(eps->V[i],1/norm);CHKERRQ(ierr);
470 dsic.upv.es!antodo 353
      }
1220 slepc 354
      nxtort = PetscMin(its+idort,nxtsrr);
355
    } while (its<nxtsrr);
470 dsic.upv.es!antodo 356
  }
6 dsic.upv.es!jroman 357
 
470 dsic.upv.es!antodo 358
  ierr = PetscFree(U);CHKERRQ(ierr);
664 dsic.upv.es!antodo 359
  ierr = PetscFree(rsd);CHKERRQ(ierr);
470 dsic.upv.es!antodo 360
  ierr = PetscFree(rsdold);CHKERRQ(ierr);
361
  ierr = PetscFree(itrsd);CHKERRQ(ierr);
362
  ierr = PetscFree(itrsdold);CHKERRQ(ierr);
6 dsic.upv.es!jroman 363
 
470 dsic.upv.es!antodo 364
  if( eps->nconv == eps->nev ) eps->reason = EPS_CONVERGED_TOL;
365
  else eps->reason = EPS_DIVERGED_ITS;
366
 
367
  PetscFunctionReturn(0);
368
}
369
 
6 dsic.upv.es!jroman 370
EXTERN_C_BEGIN
371
#undef __FUNCT__  
372
#define __FUNCT__ "EPSCreate_SUBSPACE"
476 dsic.upv.es!antodo 373
PetscErrorCode EPSCreate_SUBSPACE(EPS eps)
6 dsic.upv.es!jroman 374
{
375
  PetscFunctionBegin;
376
  eps->ops->solve                = EPSSolve_SUBSPACE;
504 dsic.upv.es!antodo 377
  eps->ops->setup                = EPSSetUp_SUBSPACE;
259 dsic.upv.es!antodo 378
  eps->ops->destroy              = EPSDestroy_Default;
176 dsic.upv.es!antodo 379
  eps->ops->backtransform        = EPSBackTransform_Default;
508 dsic.upv.es!antodo 380
  eps->ops->computevectors       = EPSComputeVectors_Schur;
6 dsic.upv.es!jroman 381
  PetscFunctionReturn(0);
382
}
383
EXTERN_C_END
384