LCOV - code coverage report
Current view: top level - eps/impls/krylov/krylovschur - ks-indef.c (source / functions) Hit Total Coverage
Test: SLEPc Lines: 61 63 96.8 %
Date: 2024-11-21 00:34:55 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       3             :    SLEPc - Scalable Library for Eigenvalue Problem Computations
       4             :    Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain
       5             : 
       6             :    This file is part of SLEPc.
       7             :    SLEPc is distributed under a 2-clause BSD license (see LICENSE).
       8             :    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       9             : */
      10             : /*
      11             :    SLEPc eigensolver: "krylovschur"
      12             : 
      13             :    Method: Krylov-Schur for symmetric-indefinite eigenproblems
      14             : */
      15             : #include <slepc/private/epsimpl.h>
      16             : #include "krylovschur.h"
      17             : 
      18          16 : PetscErrorCode EPSSolve_KrylovSchur_Indefinite(EPS eps)
      19             : {
      20          16 :   EPS_KRYLOVSCHUR *ctx = (EPS_KRYLOVSCHUR*)eps->data;
      21          16 :   PetscInt        k,l,ld,nv,t,nconv=0;
      22          16 :   Mat             U,D;
      23          16 :   Vec             vomega,w=eps->work[0];
      24          16 :   PetscReal       *a,*b,beta,beta1=1.0,*omega;
      25          16 :   PetscBool       breakdown=PETSC_FALSE,symmlost=PETSC_FALSE;
      26             : 
      27          16 :   PetscFunctionBegin;
      28          16 :   PetscCall(DSGetLeadingDimension(eps->ds,&ld));
      29             : 
      30             :   /* Get the starting Lanczos vector */
      31          16 :   PetscCall(EPSGetStartVector(eps,0,NULL));
      32             : 
      33             :   /* Extract sigma[0] from BV, computed during normalization */
      34          16 :   PetscCall(DSSetDimensions(eps->ds,1,PETSC_DETERMINE,PETSC_DETERMINE));
      35          16 :   PetscCall(BVSetActiveColumns(eps->V,0,1));
      36          16 :   PetscCall(DSGetMatAndColumn(eps->ds,DS_MAT_D,0,&D,&vomega));
      37          16 :   PetscCall(BVGetSignature(eps->V,vomega));
      38          16 :   PetscCall(DSRestoreMatAndColumn(eps->ds,DS_MAT_D,0,&D,&vomega));
      39          16 :   l = 0;
      40             : 
      41             :   /* Restart loop */
      42          16 :   while (eps->reason == EPS_CONVERGED_ITERATING) {
      43        2440 :     eps->its++;
      44             : 
      45             :     /* Compute an nv-step Lanczos factorization */
      46        2440 :     nv = PetscMin(eps->nconv+eps->mpd,eps->ncv);
      47        2440 :     PetscCall(DSSetDimensions(eps->ds,nv,eps->nconv,eps->nconv+l));
      48        2440 :     PetscCall(DSGetArrayReal(eps->ds,DS_MAT_T,&a));
      49        2440 :     b = a + ld;
      50        2440 :     PetscCall(DSGetArrayReal(eps->ds,DS_MAT_D,&omega));
      51        2440 :     PetscCall(EPSPseudoLanczos(eps,a,b,omega,eps->nconv+l,&nv,&breakdown,&symmlost,NULL,w));
      52        2440 :     if (symmlost) {
      53           0 :       eps->reason = EPS_DIVERGED_SYMMETRY_LOST;
      54           0 :       if (nv==eps->nconv+l+1) { eps->nconv = nconv; break; }
      55             :     }
      56        2440 :     beta = b[nv-1];
      57        2440 :     PetscCall(DSRestoreArrayReal(eps->ds,DS_MAT_T,&a));
      58        2440 :     PetscCall(DSRestoreArrayReal(eps->ds,DS_MAT_D,&omega));
      59        2440 :     PetscCall(DSSetDimensions(eps->ds,nv,eps->nconv,eps->nconv+l));
      60        2440 :     PetscCall(DSSetState(eps->ds,l?DS_STATE_RAW:DS_STATE_INTERMEDIATE));
      61        2440 :     PetscCall(BVSetActiveColumns(eps->V,eps->nconv,nv));
      62             : 
      63             :     /* Solve projected problem */
      64        2440 :     PetscCall(DSSolve(eps->ds,eps->eigr,eps->eigi));
      65        2440 :     PetscCall(DSSort(eps->ds,eps->eigr,eps->eigi,NULL,NULL,NULL));
      66        2440 :     PetscCall(DSUpdateExtraRow(eps->ds));
      67        2440 :     PetscCall(DSSynchronize(eps->ds,eps->eigr,eps->eigi));
      68             : 
      69             :     /* Check convergence */
      70        2440 :     PetscCall(DSGetDimensions(eps->ds,NULL,NULL,NULL,&t));
      71             : #if 0
      72             :     /* take into account also left residual */
      73             :     PetscCall(BVGetColumn(eps->V,nv,&u));
      74             :     PetscCall(VecNorm(u,NORM_2,&beta1));
      75             :     PetscCall(BVRestoreColumn(eps->V,nv,&u));
      76             :     PetscCall(VecNorm(w,NORM_2,&beta2));  /* w contains B*V[nv] */
      77             :     beta1 = PetscMax(beta1,beta2);
      78             : #endif
      79        2440 :     PetscCall(EPSKrylovConvergence(eps,PETSC_FALSE,eps->nconv,t-eps->nconv,beta*beta1,0.0,1.0,&k));
      80        2440 :     if (!symmlost) PetscCall((*eps->stopping)(eps,eps->its,eps->max_it,k,eps->nev,&eps->reason,eps->stoppingctx));
      81        2440 :     nconv = k;
      82             : 
      83             :     /* Update l */
      84        2440 :     if (eps->reason != EPS_CONVERGED_ITERATING || breakdown) l = 0;
      85             :     else {
      86        2424 :       l = PetscMax(1,(PetscInt)((nv-k)*ctx->keep));
      87        2424 :       l = PetscMin(l,t);
      88        2424 :       PetscCall(DSGetTruncateSize(eps->ds,k,t,&l));
      89             :     }
      90        2440 :     if (!ctx->lock && l>0) { l += k; k = 0; } /* non-locking variant: reset no. of converged pairs */
      91        2440 :     if (l) PetscCall(PetscInfo(eps,"Preparing to restart keeping l=%" PetscInt_FMT " vectors\n",l));
      92             : 
      93        2440 :     if (eps->reason == EPS_CONVERGED_ITERATING) {
      94        2424 :       PetscCheck(!breakdown,PetscObjectComm((PetscObject)eps),PETSC_ERR_CONV_FAILED,"Breakdown in Indefinite Krylov-Schur (beta=%g)",(double)beta);
      95             :       /* Prepare the Rayleigh quotient for restart */
      96        2424 :       PetscCall(DSTruncate(eps->ds,k+l,PETSC_FALSE));
      97             :     }
      98             :     /* Update the corresponding vectors V(:,idx) = V*Q(:,idx) */
      99        2440 :     PetscCall(DSGetMat(eps->ds,DS_MAT_Q,&U));
     100        2440 :     PetscCall(BVMultInPlace(eps->V,U,eps->nconv,k+l));
     101        2440 :     PetscCall(DSRestoreMat(eps->ds,DS_MAT_Q,&U));
     102             : 
     103             :     /* Move restart vector and update signature */
     104        2440 :     if (eps->reason == EPS_CONVERGED_ITERATING && !breakdown) {
     105        2424 :       PetscCall(BVCopyColumn(eps->V,nv,k+l));
     106        2424 :       PetscCall(BVSetActiveColumns(eps->V,0,k+l));
     107        2424 :       PetscCall(DSGetMatAndColumn(eps->ds,DS_MAT_D,0,&D,&vomega));
     108        2424 :       PetscCall(BVSetSignature(eps->V,vomega));
     109        2424 :       PetscCall(DSRestoreMatAndColumn(eps->ds,DS_MAT_D,0,&D,&vomega));
     110             :     }
     111             : 
     112        2440 :     eps->nconv = k;
     113        2456 :     PetscCall(EPSMonitor(eps,eps->its,nconv,eps->eigr,eps->eigi,eps->errest,nv));
     114             :   }
     115          16 :   PetscCall(DSTruncate(eps->ds,eps->nconv,PETSC_TRUE));
     116          16 :   PetscFunctionReturn(PETSC_SUCCESS);
     117             : }

Generated by: LCOV version 1.14