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

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

      1: /*

      3:    SLEPc eigensolver: "krylovschur"

      5:    Method: Krylov-Schur for symmetric-indefinite 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: */
     26: #include <slepc/private/epsimpl.h>
     27:  #include krylovschur.h

     31: PetscErrorCode EPSSolve_KrylovSchur_Indefinite(EPS eps)
     32: {
     33:   PetscErrorCode  ierr;
     34:   EPS_KRYLOVSCHUR *ctx = (EPS_KRYLOVSCHUR*)eps->data;
     35:   PetscInt        i,k,l,ld,nv,t,nconv=0;
     36:   Mat             U;
     37:   Vec             vomega,w=eps->work[0];
     38:   PetscScalar     *Q,*aux;
     39:   PetscReal       *a,*b,*r,beta,beta1=1.0,*omega;
     40:   PetscBool       breakdown=PETSC_FALSE,symmlost=PETSC_FALSE;

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

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

     48:   /* Extract sigma[0] from BV, computed during normalization */
     49:   BVSetActiveColumns(eps->V,0,1);
     50:   VecCreateSeq(PETSC_COMM_SELF,1,&vomega);
     51:   BVGetSignature(eps->V,vomega);
     52:   VecGetArray(vomega,&aux);
     53:   DSGetArrayReal(eps->ds,DS_MAT_D,&omega);
     54:   omega[0] = PetscRealPart(aux[0]);
     55:   DSRestoreArrayReal(eps->ds,DS_MAT_D,&omega);
     56:   VecRestoreArray(vomega,&aux);
     57:   VecDestroy(&vomega);
     58:   l = 0;

     60:   /* Restart loop */
     61:   while (eps->reason == EPS_CONVERGED_ITERATING) {
     62:     eps->its++;

     64:     /* Compute an nv-step Lanczos factorization */
     65:     nv = PetscMin(eps->nconv+eps->mpd,eps->ncv);
     66:     DSGetArrayReal(eps->ds,DS_MAT_T,&a);
     67:     b = a + ld;
     68:     DSGetArrayReal(eps->ds,DS_MAT_D,&omega);
     69:     EPSPseudoLanczos(eps,a,b,omega,eps->nconv+l,&nv,&breakdown,&symmlost,NULL,w);
     70:     if (symmlost) {
     71:       eps->reason = EPS_DIVERGED_SYMMETRY_LOST;
     72:       if (nv==eps->nconv+l+1) { eps->nconv = nconv; break; }
     73:     }
     74:     beta = b[nv-1];
     75:     DSRestoreArrayReal(eps->ds,DS_MAT_T,&a);
     76:     DSRestoreArrayReal(eps->ds,DS_MAT_D,&omega);
     77:     DSSetDimensions(eps->ds,nv,0,eps->nconv,eps->nconv+l);
     78:     if (l==0) {
     79:       DSSetState(eps->ds,DS_STATE_INTERMEDIATE);
     80:     } else {
     81:       DSSetState(eps->ds,DS_STATE_RAW);
     82:     }
     83:     BVSetActiveColumns(eps->V,eps->nconv,nv);

     85:     /* Solve projected problem */
     86:     DSSolve(eps->ds,eps->eigr,eps->eigi);
     87:     DSSort(eps->ds,eps->eigr,eps->eigi,NULL,NULL,NULL);

     89:     /* Check convergence */
     90:     DSGetDimensions(eps->ds,NULL,NULL,NULL,NULL,&t);
     91: #if 0
     92:     /* take into account also left residual */
     93:     BVGetColumn(eps->V,nv,&u);
     94:     VecNorm(u,NORM_2,&beta1);
     95:     BVRestoreColumn(eps->V,nv,&u);
     96:     VecNorm(w,NORM_2,&beta2);  /* w contains B*V[nv] */
     97:     beta1 = PetscMax(beta1,beta2);
     98: #endif
     99:     EPSKrylovConvergence(eps,PETSC_FALSE,eps->nconv,t-eps->nconv,beta*beta1,1.0,&k);
    100:     if (eps->its >= eps->max_it) eps->reason = EPS_DIVERGED_ITS;
    101:     if (k >= eps->nev) eps->reason = EPS_CONVERGED_TOL;
    102:     nconv = k;

    104:     /* Update l */
    105:     if (eps->reason != EPS_CONVERGED_ITERATING || breakdown) l = 0;
    106:     else {
    107:       l = PetscMax(1,(PetscInt)((nv-k)*ctx->keep));
    108:       l = PetscMin(l,t);
    109:       DSGetArrayReal(eps->ds,DS_MAT_T,&a);
    110:       if (*(a+ld+k+l-1)!=0) {
    111:         if (k+l<t-1) l = l+1;
    112:         else l = l-1;
    113:       }
    114:       DSRestoreArrayReal(eps->ds,DS_MAT_T,&a);
    115:     }
    116:     if (!ctx->lock && l>0) { l += k; k = 0; } /* non-locking variant: reset no. of converged pairs */

    118:     if (eps->reason == EPS_CONVERGED_ITERATING) {
    119:       if (breakdown) {
    120:         SETERRQ1(PetscObjectComm((PetscObject)eps),PETSC_ERR_CONV_FAILED,"Breakdown in Indefinite Krylov-Schur (beta=%g)",beta);
    121:       } else {
    122:         /* Prepare the Rayleigh quotient for restart */
    123:         DSGetArray(eps->ds,DS_MAT_Q,&Q);
    124:         DSGetArrayReal(eps->ds,DS_MAT_T,&a);
    125:         DSGetArrayReal(eps->ds,DS_MAT_D,&omega);
    126:         b = a + ld;
    127:         r = a + 2*ld;
    128:         for (i=k;i<k+l;i++) {
    129:           r[i] = PetscRealPart(Q[nv-1+i*ld]*beta);
    130:         }
    131:         b[k+l-1] = r[k+l-1];
    132:         omega[k+l] = omega[nv];
    133:         DSRestoreArrayReal(eps->ds,DS_MAT_T,&a);
    134:         DSRestoreArray(eps->ds,DS_MAT_Q,&Q);
    135:         DSRestoreArrayReal(eps->ds,DS_MAT_D,&omega);
    136:       }
    137:     }
    138:     /* Update the corresponding vectors V(:,idx) = V*Q(:,idx) */
    139:     DSGetMat(eps->ds,DS_MAT_Q,&U);
    140:     BVMultInPlace(eps->V,U,eps->nconv,k+l);
    141:     MatDestroy(&U);

    143:     /* Move restart vector and update signature */
    144:     if (eps->reason == EPS_CONVERGED_ITERATING && !breakdown) {
    145:       BVCopyColumn(eps->V,nv,k+l);
    146:       DSGetArrayReal(eps->ds,DS_MAT_D,&omega);
    147:       VecCreateSeq(PETSC_COMM_SELF,k+l,&vomega);
    148:       VecGetArray(vomega,&aux);
    149:       for (i=0;i<k+l;i++) aux[i] = omega[i];
    150:       VecRestoreArray(vomega,&aux);
    151:       BVSetActiveColumns(eps->V,0,k+l);
    152:       BVSetSignature(eps->V,vomega);
    153:       VecDestroy(&vomega);
    154:       DSRestoreArrayReal(eps->ds,DS_MAT_D,&omega);
    155:     }

    157:     eps->nconv = k;
    158:     EPSMonitor(eps,eps->its,nconv,eps->eigr,eps->eigi,eps->errest,nv);
    159:   }
    160:   DSSetDimensions(eps->ds,eps->nconv,0,0,0);
    161:   DSSetState(eps->ds,DS_STATE_RAW);
    162:   return(0);
    163: }