Actual source code: arnoldi.c

  1: /*                       

  3:    SLEPc eigensolver: "arnoldi"

  5:    Method: Explicitly Restarted Arnoldi

  7:    Algorithm:

  9:        Arnoldi method with explicit restart and deflation.

 11:    References:

 13:        [1] "Arnoldi Methods in SLEPc", SLEPc Technical Report STR-4, 
 14:            available at http://www.grycap.upv.es/slepc.

 16:    Last update: Feb 2009

 18:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 19:    SLEPc - Scalable Library for Eigenvalue Problem Computations
 20:    Copyright (c) 2002-2011, Universitat Politecnica de Valencia, Spain

 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.

 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.

 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/>.
 35:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 36: */

 38: #include <private/epsimpl.h>                /*I "slepceps.h" I*/
 39: #include <slepcblaslapack.h>

 41: PetscErrorCode EPSSolve_Arnoldi(EPS);

 43: typedef struct {
 44:   PetscBool delayed;
 45: } EPS_ARNOLDI;

 49: PetscErrorCode EPSSetUp_Arnoldi(EPS eps)
 50: {

 54:   if (eps->ncv) { /* ncv set */
 55:     if (eps->ncv<eps->nev) SETERRQ(((PetscObject)eps)->comm,1,"The value of ncv must be at least nev");
 56:   }
 57:   else if (eps->mpd) { /* mpd set */
 58:     eps->ncv = PetscMin(eps->n,eps->nev+eps->mpd);
 59:   }
 60:   else { /* neither set: defaults depend on nev being small or large */
 61:     if (eps->nev<500) eps->ncv = PetscMin(eps->n,PetscMax(2*eps->nev,eps->nev+15));
 62:     else { eps->mpd = 500; eps->ncv = PetscMin(eps->n,eps->nev+eps->mpd); }
 63:   }
 64:   if (!eps->mpd) eps->mpd = eps->ncv;
 65:   if (eps->ncv>eps->nev+eps->mpd) SETERRQ(((PetscObject)eps)->comm,1,"The value of ncv must not be larger than nev+mpd");
 66:   if (!eps->max_it) eps->max_it = PetscMax(100,2*eps->n/eps->ncv);
 67:   if (!eps->which) { EPSDefaultSetWhich(eps); }
 68:   if (eps->ishermitian && (eps->which==EPS_LARGEST_IMAGINARY || eps->which==EPS_SMALLEST_IMAGINARY))
 69:     SETERRQ(((PetscObject)eps)->comm,1,"Wrong value of eps->which");

 71:   if (!eps->extraction) {
 72:     EPSSetExtraction(eps,EPS_RITZ);
 73:   }

 75:   EPSAllocateSolution(eps);
 76:   PetscFree(eps->T);
 77:   PetscMalloc(eps->ncv*eps->ncv*sizeof(PetscScalar),&eps->T);
 78:   if (eps->leftvecs) {
 79:     PetscFree(eps->Tl);
 80:     PetscMalloc(eps->ncv*eps->ncv*sizeof(PetscScalar),&eps->Tl);
 81:     PetscInfo(eps,"Warning: parameter mpd ignored\n");
 82:     EPSDefaultGetWork(eps,2);
 83:   } else {
 84:     EPSDefaultGetWork(eps,1);
 85:   }

 87:   /* dispatch solve method */
 88:   if (eps->leftvecs) SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"Left vectors not supported in this solver");
 89:   eps->ops->solve = EPSSolve_Arnoldi;
 90:   return(0);
 91: }

 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
 99:    more scalable but in some cases convergence may stagnate.
100: */
101: PetscErrorCode EPSDelayedArnoldi(EPS eps,PetscScalar *H,PetscInt ldh,Vec *V,PetscInt k,PetscInt *M,Vec f,PetscReal *beta,PetscBool *breakdown)
102: {
104:   PetscInt       i,j,m=*M;
105:   Vec            u,t;
106:   PetscScalar    shh[100],*lhh,dot,dot2;
107:   PetscReal      norm1=0.0,norm2;

110:   if (m<=100) lhh = shh;
111:   else { PetscMalloc(m*sizeof(PetscScalar),&lhh); }
112:   VecDuplicate(f,&u);
113:   VecDuplicate(f,&t);

115:   for (j=k;j<m;j++) {
116:     STApply(eps->OP,V[j],f);
117:     IPOrthogonalize(eps->ip,0,PETSC_NULL,eps->nds,PETSC_NULL,eps->DS,f,PETSC_NULL,PETSC_NULL,PETSC_NULL);

119:     IPMInnerProductBegin(eps->ip,f,j+1,V,H+ldh*j);
120:     if (j>k) {
121:       IPMInnerProductBegin(eps->ip,V[j],j,V,lhh);
122:       IPInnerProductBegin(eps->ip,V[j],V[j],&dot);
123:     }
124:     if (j>k+1) {
125:       IPNormBegin(eps->ip,u,&norm2);
126:       VecDotBegin(u,V[j-2],&dot2);
127:     }
128: 
129:     IPMInnerProductEnd(eps->ip,f,j+1,V,H+ldh*j);
130:     if (j>k) {
131:       IPMInnerProductEnd(eps->ip,V[j],j,V,lhh);
132:       IPInnerProductEnd(eps->ip,V[j],V[j],&dot);
133:     }
134:     if (j>k+1) {
135:       IPNormEnd(eps->ip,u,&norm2);
136:       VecDotEnd(u,V[j-2],&dot2);
137:       if (PetscAbsScalar(dot2/norm2) > PETSC_MACHINE_EPSILON) {
138:         *breakdown = PETSC_TRUE;
139:         *M = j-1;
140:         *beta = norm2;

142:         if (m>100) { PetscFree(lhh); }
143:         VecDestroy(&u);
144:         VecDestroy(&t);
145:         return(0);
146:       }
147:     }
148: 
149:     if (j>k) {
150:       norm1 = PetscSqrtReal(PetscRealPart(dot));
151:       for (i=0;i<j;i++)
152:         H[ldh*j+i] = H[ldh*j+i]/norm1;
153:       H[ldh*j+j] = H[ldh*j+j]/dot;
154: 
155:       VecCopy(V[j],t);
156:       VecScale(V[j],1.0/norm1);
157:       VecScale(f,1.0/norm1);
158:     }

160:     SlepcVecMAXPBY(f,1.0,-1.0,j+1,H+ldh*j,V);

162:     if (j>k) {
163:       SlepcVecMAXPBY(t,1.0,-1.0,j,lhh,V);
164:       for (i=0;i<j;i++)
165:         H[ldh*(j-1)+i] += lhh[i];
166:     }

168:     if (j>k+1) {
169:       VecCopy(u,V[j-1]);
170:       VecScale(V[j-1],1.0/norm2);
171:       H[ldh*(j-2)+j-1] = norm2;
172:     }

174:     if (j<m-1) {
175:       VecCopy(f,V[j+1]);
176:       VecCopy(t,u);
177:     }
178:   }

180:   IPNorm(eps->ip,t,&norm2);
181:   VecScale(t,1.0/norm2);
182:   VecCopy(t,V[m-1]);
183:   H[ldh*(m-2)+m-1] = norm2;

185:   IPMInnerProduct(eps->ip,f,m,V,lhh);
186: 
187:   SlepcVecMAXPBY(f,1.0,-1.0,m,lhh,V);
188:   for (i=0;i<m;i++)
189:     H[ldh*(m-1)+i] += lhh[i];

191:   IPNorm(eps->ip,f,beta);
192:   VecScale(f,1.0 / *beta);
193:   *breakdown = PETSC_FALSE;
194: 
195:   if (m>100) { PetscFree(lhh); }
196:   VecDestroy(&u);
197:   VecDestroy(&t);
198:   return(0);
199: }

203: /*
204:    EPSDelayedArnoldi1 - This function is similar to EPSDelayedArnoldi1,
205:    but without reorthogonalization (only delayed normalization).
206: */
207: PetscErrorCode EPSDelayedArnoldi1(EPS eps,PetscScalar *H,PetscInt ldh,Vec *V,PetscInt k,PetscInt *M,Vec f,PetscReal *beta,PetscBool *breakdown)
208: {
210:   PetscInt       i,j,m=*M;
211:   PetscScalar    dot;
212:   PetscReal      norm=0.0;

215:   for (j=k;j<m;j++) {
216:     STApply(eps->OP,V[j],f);
217:     IPOrthogonalize(eps->ip,0,PETSC_NULL,eps->nds,PETSC_NULL,eps->DS,f,PETSC_NULL,PETSC_NULL,PETSC_NULL);

219:     IPMInnerProductBegin(eps->ip,f,j+1,V,H+ldh*j);
220:     if (j>k) {
221:       IPInnerProductBegin(eps->ip,V[j],V[j],&dot);
222:     }
223: 
224:     IPMInnerProductEnd(eps->ip,f,j+1,V,H+ldh*j);
225:     if (j>k) {
226:       IPInnerProductEnd(eps->ip,V[j],V[j],&dot);
227:     }
228: 
229:     if (j>k) {
230:       norm = PetscSqrtReal(PetscRealPart(dot));
231:       VecScale(V[j],1.0/norm);
232:       H[ldh*(j-1)+j] = norm;

234:       for (i=0;i<j;i++)
235:         H[ldh*j+i] = H[ldh*j+i]/norm;
236:       H[ldh*j+j] = H[ldh*j+j]/dot;
237:       VecScale(f,1.0/norm);
238:     }

240:     SlepcVecMAXPBY(f,1.0,-1.0,j+1,H+ldh*j,V);

242:     if (j<m-1) {
243:       VecCopy(f,V[j+1]);
244:     }
245:   }

247:   IPNorm(eps->ip,f,beta);
248:   VecScale(f,1.0 / *beta);
249:   *breakdown = PETSC_FALSE;
250:   return(0);
251: }

255: /*
256:    EPSProjectedArnoldi - Solves the projected eigenproblem.

258:    On input:
259:      S is the projected matrix (leading dimension is lds)

261:    On output:
262:      S has (real) Schur form with diagonal blocks sorted appropriately
263:      Q contains the corresponding Schur vectors (order n, leading dimension n)
264: */
265: PetscErrorCode EPSProjectedArnoldi(EPS eps,PetscScalar *S,PetscInt lds,PetscScalar *Q,PetscInt n)
266: {
268:   PetscInt       i;

271:   /* Initialize orthogonal matrix */
272:   PetscMemzero(Q,n*n*sizeof(PetscScalar));
273:   for (i=0;i<n;i++)
274:     Q[i*(n+1)] = 1.0;
275:   /* Reduce S to (quasi-)triangular form, S <- Q S Q' */
276:   EPSDenseSchur(n,eps->nconv,S,lds,Q,eps->eigr,eps->eigi);
277:   /* Sort the remaining columns of the Schur form */
278:   EPSSortDenseSchur(eps,n,eps->nconv,S,lds,Q,eps->eigr,eps->eigi);
279:   return(0);
280: }

284: /*
285:    EPSUpdateVectors - Computes approximate Schur vectors (or eigenvectors) by
286:    either Ritz extraction (U=U*Q) or refined Ritz extraction 

288:    On input:
289:      n is the size of U
290:      U is the orthogonal basis of the subspace used for projecting
291:      s is the index of the first vector computed
292:      e+1 is the index of the last vector computed
293:      Q contains the corresponding Schur vectors of the projected matrix (size n x n, leading dimension ldq)
294:      H is the (extended) projected matrix (size n+1 x n, leading dimension ldh)

296:    On output:
297:      v is the resulting vector
298: */
299: PetscErrorCode EPSUpdateVectors(EPS eps,PetscInt n_,Vec *U,PetscInt s,PetscInt e,PetscScalar *Q,PetscInt ldq,PetscScalar *H,PetscInt ldh_)
300: {
301: #if defined(PETSC_MISSING_LAPACK_GESVD) 
302:   SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"GESVD - Lapack routine is unavailable.");
303: #else
305:   PetscBool      isrefined;
306:   PetscInt       i,j,k;
307:   PetscBLASInt   n1,lwork,idummy=1,info,n=n_,ldh=ldh_;
308:   PetscScalar    *B,sdummy,*work;
309:   PetscReal      *sigma;

312:   isrefined = (eps->extraction==EPS_REFINED || eps->extraction==EPS_REFINED_HARMONIC)?PETSC_TRUE:PETSC_FALSE;
313:   if (isrefined) {
314:     /* Refined Ritz extraction */
315:     n1 = n+1;
316:     PetscMalloc(n1*n*sizeof(PetscScalar),&B);
317:     PetscMalloc(6*n*sizeof(PetscReal),&sigma);
318:     lwork = 10*n;
319:     PetscMalloc(lwork*sizeof(PetscScalar),&work);
320: 
321:     for (k=s;k<e;k++) {
322:       /* copy H to B */
323:       for (i=0;i<=n;i++) {
324:         for (j=0;j<n;j++) {
325:           B[i+j*n1] = H[i+j*ldh];
326:         }
327:       }
328:       /* subtract ritz value from diagonal of B^ */
329:       for (i=0;i<n;i++) {
330:         B[i+i*n1] -= eps->eigr[k];  /* MISSING: complex case */
331:       }
332:       /* compute SVD of [H-mu*I] */
333:   #if !defined(PETSC_USE_COMPLEX)
334:       LAPACKgesvd_("N","O",&n1,&n,B,&n1,sigma,&sdummy,&idummy,&sdummy,&idummy,work,&lwork,&info);
335:   #else
336:       LAPACKgesvd_("N","O",&n1,&n,B,&n1,sigma,&sdummy,&idummy,&sdummy,&idummy,work,&lwork,sigma+n,&info);
337:   #endif
338:       if (info) SETERRQ1(((PetscObject)eps)->comm,PETSC_ERR_LIB,"Error in Lapack xGESVD %d",info);
339:       /* the smallest singular value is the new error estimate */
340:       eps->errest[k] = sigma[n-1];
341:       /* update vector with right singular vector associated to smallest singular value */
342:       for (i=0;i<n;i++)
343:         Q[k*ldq+i] = B[n-1+i*n1];
344:     }
345:     /* free workspace */
346:     PetscFree(B);
347:     PetscFree(sigma);
348:     PetscFree(work);
349:   }
350:   /* Ritz extraction: v = U*q */
351:   SlepcUpdateVectors(n_,U,s,e,Q,ldq,PETSC_FALSE);
352:   return(0);
353: #endif
354: }

358: PetscErrorCode EPSSolve_Arnoldi(EPS eps)
359: {
360:   PetscErrorCode     ierr;
361:   PetscInt           i,k,lwork,nv;
362:   Vec                f=eps->work[0];
363:   PetscScalar        *H=eps->T,*U,*g,*work,*Hcopy;
364:   PetscReal          beta,gnorm,corrf=1.0;
365:   PetscBool          breakdown;
366:   IPOrthogRefineType orthog_ref;
367:   EPS_ARNOLDI        *arnoldi = (EPS_ARNOLDI *)eps->data;

370:   PetscMemzero(eps->T,eps->ncv*eps->ncv*sizeof(PetscScalar));
371:   PetscMalloc(eps->ncv*eps->ncv*sizeof(PetscScalar),&U);
372:   lwork = PetscMax((eps->ncv+1)*eps->ncv,7*eps->ncv);
373:   PetscMalloc(lwork*sizeof(PetscScalar),&work);
374:   if (eps->extraction==EPS_HARMONIC || eps->extraction==EPS_REFINED_HARMONIC) {
375:     PetscMalloc(eps->ncv*sizeof(PetscScalar),&g);
376:   }
377:   if (eps->extraction==EPS_REFINED || eps->extraction==EPS_REFINED_HARMONIC) {
378:     PetscMalloc((eps->ncv+1)*eps->ncv*sizeof(PetscScalar),&Hcopy);
379:   }
380: 
381:   IPGetOrthogonalization(eps->ip,PETSC_NULL,&orthog_ref,PETSC_NULL);

383:   /* Get the starting Arnoldi vector */
384:   EPSGetStartVector(eps,0,eps->V[0],PETSC_NULL);
385: 
386:   /* Restart loop */
387:   while (eps->reason == EPS_CONVERGED_ITERATING) {
388:     eps->its++;

390:     /* Compute an nv-step Arnoldi factorization */
391:     nv = PetscMin(eps->nconv+eps->mpd,eps->ncv);
392:     if (!arnoldi->delayed) {
393:       EPSBasicArnoldi(eps,PETSC_FALSE,H,eps->ncv,eps->V,eps->nconv,&nv,f,&beta,&breakdown);
394:     } else if (orthog_ref == IP_ORTHOG_REFINE_NEVER) {
395:       EPSDelayedArnoldi1(eps,H,eps->ncv,eps->V,eps->nconv,&nv,f,&beta,&breakdown);
396:     } else {
397:       EPSDelayedArnoldi(eps,H,eps->ncv,eps->V,eps->nconv,&nv,f,&beta,&breakdown);
398:     }

400:     if (eps->extraction==EPS_REFINED || eps->extraction==EPS_REFINED_HARMONIC) {
401:       PetscMemcpy(Hcopy,H,eps->ncv*eps->ncv*sizeof(PetscScalar));
402:       for (i=0;i<nv-1;i++) Hcopy[nv+i*eps->ncv] = 0.0;
403:       Hcopy[nv+(nv-1)*eps->ncv] = beta;
404:     }

406:     /* Compute translation of Krylov decomposition if harmonic extraction used */
407:     if (eps->extraction==EPS_HARMONIC || eps->extraction==EPS_REFINED_HARMONIC) {
408:       EPSTranslateHarmonic(nv,H,eps->ncv,eps->target,(PetscScalar)beta,g,work);
409:       gnorm = 0.0;
410:       for (i=0;i<nv;i++)
411:         gnorm = gnorm + PetscRealPart(g[i]*PetscConj(g[i]));
412:       corrf = PetscSqrtReal(1.0+gnorm);
413:     }

415:     /* Solve projected problem */
416:     EPSProjectedArnoldi(eps,H,eps->ncv,U,nv);

418:     /* Check convergence */
419:     EPSKrylovConvergence(eps,PETSC_FALSE,eps->trackall,eps->nconv,nv-eps->nconv,H,eps->ncv,U,eps->V,nv,beta,corrf,&k,work);

421:     EPSUpdateVectors(eps,nv,eps->V,eps->nconv,PetscMin(k+1,nv),U,nv,Hcopy,eps->ncv);
422:     eps->nconv = k;

424:     EPSMonitor(eps,eps->its,eps->nconv,eps->eigr,eps->eigi,eps->errest,nv);
425:     if (breakdown) {
426:       PetscInfo2(eps,"Breakdown in Arnoldi method (it=%D norm=%G)\n",eps->its,beta);
427:       EPSGetStartVector(eps,k,eps->V[k],&breakdown);
428:       if (breakdown) {
429:         eps->reason = EPS_DIVERGED_BREAKDOWN;
430:         PetscInfo(eps,"Unable to generate more start vectors\n");
431:       }
432:     }
433:     if (eps->its >= eps->max_it) eps->reason = EPS_DIVERGED_ITS;
434:     if (eps->nconv >= eps->nev) eps->reason = EPS_CONVERGED_TOL;
435:   }
436: 
437:   PetscFree(U);
438:   PetscFree(work);
439:   if (eps->extraction==EPS_HARMONIC || eps->extraction==EPS_REFINED_HARMONIC) {
440:     PetscFree(g);
441:   }
442:   if (eps->extraction==EPS_REFINED || eps->extraction==EPS_REFINED_HARMONIC) {
443:     PetscFree(Hcopy);
444:   }
445:   return(0);
446: }

450: PetscErrorCode EPSSetFromOptions_Arnoldi(EPS eps)
451: {
453:   PetscBool      set,val;
454:   EPS_ARNOLDI    *arnoldi = (EPS_ARNOLDI *)eps->data;

457:   PetscOptionsHead("EPS Arnoldi Options");
458:   PetscOptionsBool("-eps_arnoldi_delayed","Arnoldi with delayed reorthogonalization","EPSArnoldiSetDelayed",arnoldi->delayed,&val,&set);
459:   if (set) {
460:     EPSArnoldiSetDelayed(eps,val);
461:   }
462:   PetscOptionsTail();
463:   return(0);
464: }

466: EXTERN_C_BEGIN
469: PetscErrorCode EPSArnoldiSetDelayed_Arnoldi(EPS eps,PetscBool delayed)
470: {
471:   EPS_ARNOLDI *arnoldi = (EPS_ARNOLDI *)eps->data;

474:   arnoldi->delayed = delayed;
475:   return(0);
476: }
477: EXTERN_C_END

481: /*@
482:    EPSArnoldiSetDelayed - Activates or deactivates delayed reorthogonalization 
483:    in the Arnoldi iteration. 

485:    Logically Collective on EPS

487:    Input Parameters:
488: +  eps - the eigenproblem solver context
489: -  delayed - boolean flag

491:    Options Database Key:
492: .  -eps_arnoldi_delayed - Activates delayed reorthogonalization in Arnoldi
493:    
494:    Note:
495:    Delayed reorthogonalization is an aggressive optimization for the Arnoldi
496:    eigensolver than may provide better scalability, but sometimes makes the
497:    solver converge less than the default algorithm.

499:    Level: advanced

501: .seealso: EPSArnoldiGetDelayed()
502: @*/
503: PetscErrorCode EPSArnoldiSetDelayed(EPS eps,PetscBool delayed)
504: {

510:   PetscTryMethod(eps,"EPSArnoldiSetDelayed_C",(EPS,PetscBool),(eps,delayed));
511:   return(0);
512: }

514: EXTERN_C_BEGIN
517: PetscErrorCode EPSArnoldiGetDelayed_Arnoldi(EPS eps,PetscBool *delayed)
518: {
519:   EPS_ARNOLDI *arnoldi = (EPS_ARNOLDI *)eps->data;

522:   *delayed = arnoldi->delayed;
523:   return(0);
524: }
525: EXTERN_C_END

529: /*@C
530:    EPSArnoldiGetDelayed - Gets the type of reorthogonalization used during the Arnoldi
531:    iteration. 

533:    Not Collective

535:    Input Parameter:
536: .  eps - the eigenproblem solver context

538:    Input Parameter:
539: .  delayed - boolean flag indicating if delayed reorthogonalization has been enabled

541:    Level: advanced

543: .seealso: EPSArnoldiSetDelayed()
544: @*/
545: PetscErrorCode EPSArnoldiGetDelayed(EPS eps,PetscBool *delayed)
546: {

552:   PetscTryMethod(eps,"EPSArnoldiGetDelayed_C",(EPS,PetscBool*),(eps,delayed));
553:   return(0);
554: }

558: PetscErrorCode EPSReset_Arnoldi(EPS eps)
559: {

563:   PetscFree(eps->T);
564:   PetscFree(eps->Tl);
565:   EPSReset_Default(eps);
566:   return(0);
567: }

571: PetscErrorCode EPSDestroy_Arnoldi(EPS eps)
572: {

576:   PetscFree(eps->data);
577:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSArnoldiSetDelayed_C","",PETSC_NULL);
578:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSArnoldiGetDelayed_C","",PETSC_NULL);
579:   return(0);
580: }

584: PetscErrorCode EPSView_Arnoldi(EPS eps,PetscViewer viewer)
585: {
587:   PetscBool      isascii;
588:   EPS_ARNOLDI    *arnoldi = (EPS_ARNOLDI *)eps->data;

591:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
592:   if (!isascii) {
593:     SETERRQ1(((PetscObject)eps)->comm,1,"Viewer type %s not supported for EPS Arnoldi",((PetscObject)viewer)->type_name);
594:   }
595:   if (arnoldi->delayed) {
596:     PetscViewerASCIIPrintf(viewer,"  Arnoldi: using delayed reorthogonalization\n");
597:   }
598:   return(0);
599: }

601: extern PetscErrorCode EPSSolve_TS_Arnoldi(EPS);

603: EXTERN_C_BEGIN
606: PetscErrorCode EPSCreate_Arnoldi(EPS eps)
607: {
609: 
611:   PetscNewLog(eps,EPS_ARNOLDI,&eps->data);
612:   eps->ops->setup                = EPSSetUp_Arnoldi;
613:   eps->ops->setfromoptions       = EPSSetFromOptions_Arnoldi;
614:   eps->ops->destroy              = EPSDestroy_Arnoldi;
615:   eps->ops->reset                = EPSReset_Arnoldi;
616:   eps->ops->view                 = EPSView_Arnoldi;
617:   eps->ops->backtransform        = EPSBackTransform_Default;
618:   eps->ops->computevectors       = EPSComputeVectors_Schur;
619:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSArnoldiSetDelayed_C","EPSArnoldiSetDelayed_Arnoldi",EPSArnoldiSetDelayed_Arnoldi);
620:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSArnoldiGetDelayed_C","EPSArnoldiGetDelayed_Arnoldi",EPSArnoldiGetDelayed_Arnoldi);
621:   return(0);
622: }
623: EXTERN_C_END