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