Date: 2016-03-29T14:57:57+00:00

Actual source code: ks-symm.c
slepc-3.6.3 2016-03-29
Report Typos and Errors

      1: /*

      3:    SLEPc eigensolver: "krylovschur"

      5:    Method: Krylov-Schur for symmetric eigenproblems

      7:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      8:    SLEPc - Scalable Library for Eigenvalue Problem Computations
      9:    Copyright (c) 2002-2015, Universitat Politecnica de Valencia, Spain

     11:    This file is part of SLEPc.

     13:    SLEPc is free software: you can redistribute it and/or modify it under  the
     14:    terms of version 3 of the GNU Lesser General Public License as published by
     15:    the Free Software Foundation.

     17:    SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
     18:    WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
     19:    FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
     20:    more details.

     22:    You  should have received a copy of the GNU Lesser General  Public  License
     23:    along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
     24:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     25: */

     27: #include <slepc/private/epsimpl.h>
     28:  #include krylovschur.h

     32: PetscErrorCode EPSSolve_KrylovSchur_Symm(EPS eps)
     33: {
     34:   PetscErrorCode  ierr;
     35:   EPS_KRYLOVSCHUR *ctx = (EPS_KRYLOVSCHUR*)eps->data;
     36:   PetscInt        k,l,ld,nv,nconv;
     37:   Mat             U;
     38:   PetscReal       *a,*b,beta;
     39:   PetscBool       breakdown;

     42:   DSGetLeadingDimension(eps->ds,&ld);

     44:   /* Get the starting Lanczos vector */
     45:   EPSGetStartVector(eps,0,NULL);
     46:   l = 0;

     48:   /* Restart loop */
     49:   while (eps->reason == EPS_CONVERGED_ITERATING) {
     50:     eps->its++;

     52:     /* Compute an nv-step Lanczos factorization */
     53:     nv = PetscMin(eps->nconv+eps->mpd,eps->ncv);
     54:     DSGetArrayReal(eps->ds,DS_MAT_T,&a);
     55:     b = a + ld;
     56:     EPSFullLanczos(eps,a,b,eps->nconv+l,&nv,&breakdown);
     57:     beta = b[nv-1];
     58:     DSRestoreArrayReal(eps->ds,DS_MAT_T,&a);
     59:     DSSetDimensions(eps->ds,nv,0,eps->nconv,eps->nconv+l);
     60:     if (l==0) {
     61:       DSSetState(eps->ds,DS_STATE_INTERMEDIATE);
     62:     } else {
     63:       DSSetState(eps->ds,DS_STATE_RAW);
     64:     }
     65:     BVSetActiveColumns(eps->V,eps->nconv,nv);

     67:     /* Solve projected problem */
     68:     DSSolve(eps->ds,eps->eigr,NULL);
     69:     if (eps->arbitrary) { EPSGetArbitraryValues(eps,eps->rr,eps->ri); }
     70:     DSSort(eps->ds,eps->eigr,NULL,eps->rr,eps->ri,NULL);
     71:     DSUpdateExtraRow(eps->ds);

     73:     /* Check convergence */
     74:     EPSKrylovConvergence(eps,PETSC_FALSE,eps->nconv,nv-eps->nconv,beta,1.0,&k);
     75:     if (eps->its >= eps->max_it) eps->reason = EPS_DIVERGED_ITS;
     76:     if (k >= eps->nev) eps->reason = EPS_CONVERGED_TOL;
     77:     nconv = k;

     79:     /* Update l */
     80:     if (eps->reason != EPS_CONVERGED_ITERATING || breakdown) l = 0;
     81:     else l = PetscMax(1,(PetscInt)((nv-k)*ctx->keep));
     82:     if (!ctx->lock && l>0) { l += k; k = 0; } /* non-locking variant: reset no. of converged pairs */

     84:     if (eps->reason == EPS_CONVERGED_ITERATING) {
     85:       if (breakdown) {
     86:         /* Start a new Lanczos factorization */
     87:         PetscInfo2(eps,"Breakdown in Krylov-Schur method (it=%D norm=%g)\n",eps->its,(double)beta);
     88:         if (k<eps->nev) {
     89:           EPSGetStartVector(eps,k,&breakdown);
     90:           if (breakdown) {
     91:             eps->reason = EPS_DIVERGED_BREAKDOWN;
     92:             PetscInfo(eps,"Unable to generate more start vectors\n");
     93:           }
     94:         }
     95:       } else {
     96:         /* Prepare the Rayleigh quotient for restart */
     97:         DSTruncate(eps->ds,k+l);
     98:       }
     99:     }
    100:     /* Update the corresponding vectors V(:,idx) = V*Q(:,idx) */
    101:     DSGetMat(eps->ds,DS_MAT_Q,&U);
    102:     BVMultInPlace(eps->V,U,eps->nconv,k+l);
    103:     MatDestroy(&U);

    105:     /* Normalize u and append it to V */
    106:     if (eps->reason == EPS_CONVERGED_ITERATING && !breakdown) {
    107:       BVCopyColumn(eps->V,nv,k+l);
    108:     }

    110:     eps->nconv = k;
    111:     EPSMonitor(eps,eps->its,nconv,eps->eigr,eps->eigi,eps->errest,nv);
    112:   }
    113:   return(0);
    114: }