LCOV - code coverage report
Current view: top level - eps/impls/davidson - davidson.c (source / functions) Hit Total Coverage
Test: SLEPc Lines: 211 225 93.8 %
Date: 2024-11-21 00:40:22 Functions: 14 14 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             :    Skeleton of Davidson solver. Actual solvers are GD and JD.
      12             : 
      13             :    References:
      14             : 
      15             :        [1] E. Romero and J.E. Roman, "A parallel implementation of Davidson
      16             :            methods for large-scale eigenvalue problems in SLEPc", ACM Trans.
      17             :            Math. Software 40(2):13, 2014.
      18             : */
      19             : 
      20             : #include "davidson.h"
      21             : 
      22             : static PetscBool  cited = PETSC_FALSE;
      23             : static const char citation[] =
      24             :   "@Article{slepc-davidson,\n"
      25             :   "   author = \"E. Romero and J. E. Roman\",\n"
      26             :   "   title = \"A parallel implementation of {Davidson} methods for large-scale eigenvalue problems in {SLEPc}\",\n"
      27             :   "   journal = \"{ACM} Trans. Math. Software\",\n"
      28             :   "   volume = \"40\",\n"
      29             :   "   number = \"2\",\n"
      30             :   "   pages = \"13:1--13:29\",\n"
      31             :   "   year = \"2014,\"\n"
      32             :   "   doi = \"https://doi.org/10.1145/2543696\"\n"
      33             :   "}\n";
      34             : 
      35          97 : PetscErrorCode EPSSetUp_XD(EPS eps)
      36             : {
      37          97 :   EPS_DAVIDSON   *data = (EPS_DAVIDSON*)eps->data;
      38          97 :   dvdDashboard   *dvd = &data->ddb;
      39          97 :   dvdBlackboard  b;
      40          97 :   PetscInt       min_size_V,bs,initv,nmat;
      41          97 :   Mat            A,B;
      42          97 :   KSP            ksp;
      43          97 :   PetscBool      ipB,ispositive;
      44          97 :   HarmType_t     harm;
      45          97 :   InitType_t     init;
      46          97 :   PetscScalar    target;
      47             : 
      48          97 :   PetscFunctionBegin;
      49          97 :   EPSCheckNotStructured(eps);
      50             :   /* Setup EPS options and get the problem specification */
      51          97 :   bs = data->blocksize;
      52          97 :   if (bs <= 0) bs = 1;
      53          97 :   if (eps->ncv!=PETSC_DETERMINE) {
      54          41 :     PetscCheck(eps->ncv>=eps->nev,PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"The value of ncv must be at least nev");
      55          56 :   } else if (eps->mpd!=PETSC_DETERMINE) eps->ncv = eps->mpd + eps->nev + bs;
      56          55 :   else if (eps->n < 10) eps->ncv = eps->n+eps->nev+bs;
      57          55 :   else if (eps->nev < 500) eps->ncv = PetscMax(eps->nev,PetscMin(eps->n-bs,PetscMax(2*eps->nev,eps->nev+15))+bs);
      58           0 :   else eps->ncv = PetscMax(eps->nev,PetscMin(eps->n-bs,eps->nev+500)+bs);
      59          97 :   if (eps->mpd==PETSC_DETERMINE) eps->mpd = PetscMin(eps->n,eps->ncv);
      60          97 :   PetscCheck(eps->mpd<=eps->ncv,PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"The mpd parameter has to be less than or equal to ncv");
      61          97 :   PetscCheck(eps->mpd>=2,PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"The mpd parameter has to be greater than 2");
      62          97 :   if (eps->max_it == PETSC_DETERMINE) eps->max_it = PetscMax(100*eps->ncv,2*eps->n);
      63          97 :   if (!eps->which) eps->which = EPS_LARGEST_MAGNITUDE;
      64          97 :   PetscCheck(eps->nev+bs<=eps->ncv,PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"The value of ncv has to be greater than nev plus blocksize");
      65          97 :   PetscCheck(!eps->trueres,PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"-eps_true_residual is disabled in this solver.");
      66          97 :   EPSCheckUnsupported(eps,EPS_FEATURE_REGION | EPS_FEATURE_TWOSIDED);
      67             : 
      68          97 :   if (!data->minv) data->minv = (eps->n && eps->n<10)? 1: PetscMin(PetscMax(bs,6),eps->mpd/2);
      69          97 :   min_size_V = data->minv;
      70          97 :   PetscCheck(min_size_V+bs<=eps->mpd,PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"The value of minv must be less than mpd minus blocksize");
      71          97 :   if (data->plusk == PETSC_DETERMINE) {
      72          64 :     if (eps->problem_type == EPS_GHIEP || eps->nev+bs>eps->ncv) data->plusk = 0;
      73          62 :     else data->plusk = 1;
      74             :   }
      75         161 :   if (!data->initialsize) data->initialsize = (eps->n && eps->n<10)? 1: 6;
      76          97 :   initv = data->initialsize;
      77          97 :   PetscCheck(eps->mpd>=initv,PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"The initv parameter has to be less than or equal to mpd");
      78             : 
      79             :   /* Change the default sigma to inf if necessary */
      80          97 :   if (eps->which == EPS_LARGEST_MAGNITUDE || eps->which == EPS_LARGEST_REAL || eps->which == EPS_LARGEST_IMAGINARY) PetscCall(STSetDefaultShift(eps->st,PETSC_MAX_REAL));
      81             : 
      82             :   /* Set up preconditioner */
      83          97 :   PetscCall(STSetUp(eps->st));
      84             : 
      85             :   /* Setup problem specification in dvd */
      86          97 :   PetscCall(STGetNumMatrices(eps->st,&nmat));
      87          97 :   PetscCall(STGetMatrix(eps->st,0,&A));
      88          97 :   if (nmat>1) PetscCall(STGetMatrix(eps->st,1,&B));
      89          97 :   PetscCall(EPSReset_XD(eps));
      90          97 :   PetscCall(PetscMemzero(dvd,sizeof(dvdDashboard)));
      91          97 :   dvd->A = A; dvd->B = eps->isgeneralized? B: NULL;
      92          97 :   ispositive = eps->ispositive;
      93         120 :   dvd->sA = DVD_MAT_IMPLICIT | (eps->ishermitian? DVD_MAT_HERMITIAN: 0) | ((ispositive && !eps->isgeneralized) ? DVD_MAT_POS_DEF: 0);
      94             :   /* Assume -eps_hermitian means hermitian-definite in generalized problems */
      95          97 :   if (!ispositive && !eps->isgeneralized && eps->ishermitian) ispositive = PETSC_TRUE;
      96          97 :   if (!eps->isgeneralized) dvd->sB = DVD_MAT_IMPLICIT | DVD_MAT_HERMITIAN | DVD_MAT_IDENTITY | DVD_MAT_UNITARY | DVD_MAT_POS_DEF;
      97          24 :   else dvd->sB = DVD_MAT_IMPLICIT | (eps->ishermitian? DVD_MAT_HERMITIAN: 0) | (ispositive? DVD_MAT_POS_DEF: 0);
      98          97 :   ipB = (dvd->B && data->ipB && DVD_IS(dvd->sB,DVD_MAT_HERMITIAN))?PETSC_TRUE:PETSC_FALSE;
      99         126 :   dvd->sEP = ((!eps->isgeneralized || (eps->isgeneralized && ipB))? DVD_EP_STD: 0) | (ispositive? DVD_EP_HERMITIAN: 0) | ((eps->problem_type == EPS_GHIEP && ipB) ? DVD_EP_INDEFINITE : 0);
     100          97 :   if (data->ipB && !ipB) data->ipB = PETSC_FALSE;
     101          97 :   dvd->correctXnorm = (dvd->B && (DVD_IS(dvd->sB,DVD_MAT_HERMITIAN)||DVD_IS(dvd->sEP,DVD_EP_INDEFINITE)))?PETSC_TRUE:PETSC_FALSE;
     102          97 :   dvd->nev        = eps->nev;
     103          97 :   dvd->which      = eps->which;
     104          97 :   dvd->withTarget = PETSC_TRUE;
     105          97 :   switch (eps->which) {
     106          15 :     case EPS_TARGET_MAGNITUDE:
     107             :     case EPS_TARGET_IMAGINARY:
     108          15 :       dvd->target[0] = target = eps->target;
     109          15 :       dvd->target[1] = 1.0;
     110          15 :       break;
     111           0 :     case EPS_TARGET_REAL:
     112           0 :       dvd->target[0] = PetscRealPart(target = eps->target);
     113           0 :       dvd->target[1] = 1.0;
     114           0 :       break;
     115          48 :     case EPS_LARGEST_REAL:
     116             :     case EPS_LARGEST_MAGNITUDE:
     117             :     case EPS_LARGEST_IMAGINARY: /* TODO: think about this case */
     118          48 :       dvd->target[0] = 1.0;
     119          48 :       dvd->target[1] = target = 0.0;
     120          48 :       break;
     121          30 :     case EPS_SMALLEST_MAGNITUDE:
     122             :     case EPS_SMALLEST_REAL:
     123             :     case EPS_SMALLEST_IMAGINARY: /* TODO: think about this case */
     124          30 :       dvd->target[0] = target = 0.0;
     125          30 :       dvd->target[1] = 1.0;
     126          30 :       break;
     127           4 :     case EPS_WHICH_USER:
     128           4 :       PetscCall(STGetShift(eps->st,&target));
     129           4 :       dvd->target[0] = target;
     130           4 :       dvd->target[1] = 1.0;
     131           4 :       break;
     132           0 :     case EPS_ALL:
     133           0 :       SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"This solver does not support computing all eigenvalues");
     134           0 :     default:
     135           0 :       SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Unsupported value of option 'which'");
     136             :   }
     137          97 :   dvd->tol = SlepcDefaultTol(eps->tol);
     138          97 :   dvd->eps = eps;
     139             : 
     140             :   /* Setup the extraction technique */
     141          97 :   if (!eps->extraction) {
     142          88 :     if (ipB || ispositive) eps->extraction = EPS_RITZ;
     143             :     else {
     144          17 :       switch (eps->which) {
     145           6 :         case EPS_TARGET_REAL:
     146             :         case EPS_TARGET_MAGNITUDE:
     147             :         case EPS_TARGET_IMAGINARY:
     148             :         case EPS_SMALLEST_MAGNITUDE:
     149             :         case EPS_SMALLEST_REAL:
     150             :         case EPS_SMALLEST_IMAGINARY:
     151           6 :           eps->extraction = EPS_HARMONIC;
     152           6 :           break;
     153           8 :         case EPS_LARGEST_REAL:
     154             :         case EPS_LARGEST_MAGNITUDE:
     155             :         case EPS_LARGEST_IMAGINARY:
     156           8 :           eps->extraction = EPS_HARMONIC_LARGEST;
     157           8 :           break;
     158           3 :         default:
     159           3 :           eps->extraction = EPS_RITZ;
     160             :       }
     161           9 :     }
     162             :   }
     163          97 :   switch (eps->extraction) {
     164             :     case EPS_RITZ:              harm = DVD_HARM_NONE; break;
     165          13 :     case EPS_HARMONIC:          harm = DVD_HARM_RR; break;
     166           0 :     case EPS_HARMONIC_RELATIVE: harm = DVD_HARM_RRR; break;
     167           0 :     case EPS_HARMONIC_RIGHT:    harm = DVD_HARM_REIGS; break;
     168          10 :     case EPS_HARMONIC_LARGEST:  harm = DVD_HARM_LEIGS; break;
     169           0 :     default: SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Unsupported extraction type");
     170             :   }
     171             : 
     172             :   /* Setup the type of starting subspace */
     173          97 :   init = data->krylovstart? DVD_INITV_KRYLOV: DVD_INITV_CLASSIC;
     174             : 
     175             :   /* Preconfigure dvd */
     176          97 :   PetscCall(STGetKSP(eps->st,&ksp));
     177          97 :   PetscCall(dvd_schm_basic_preconf(dvd,&b,eps->mpd,min_size_V,bs,initv,PetscAbs(eps->nini),data->plusk,harm,ksp,init,eps->trackall,data->ipB,data->doubleexp));
     178             : 
     179             :   /* Allocate memory */
     180          97 :   PetscCall(EPSAllocateSolution(eps,0));
     181             : 
     182             :   /* Setup orthogonalization */
     183          97 :   PetscCall(EPS_SetInnerProduct(eps));
     184          97 :   if (!(ipB && dvd->B)) PetscCall(BVSetMatrix(eps->V,NULL,PETSC_FALSE));
     185             : 
     186             :   /* Configure dvd for a basic GD */
     187          97 :   PetscCall(dvd_schm_basic_conf(dvd,&b,eps->mpd,min_size_V,bs,initv,PetscAbs(eps->nini),data->plusk,harm,dvd->withTarget,target,ksp,data->fix,init,eps->trackall,data->ipB,data->dynamic,data->doubleexp));
     188          97 :   PetscFunctionReturn(PETSC_SUCCESS);
     189             : }
     190             : 
     191          97 : PetscErrorCode EPSSolve_XD(EPS eps)
     192             : {
     193          97 :   EPS_DAVIDSON   *data = (EPS_DAVIDSON*)eps->data;
     194          97 :   dvdDashboard   *d = &data->ddb;
     195          97 :   PetscInt       l,k;
     196             : 
     197          97 :   PetscFunctionBegin;
     198          97 :   PetscCall(PetscCitationsRegister(citation,&cited));
     199             :   /* Call the starting routines */
     200          97 :   PetscCall(EPSDavidsonFLCall(d->startList,d));
     201             : 
     202        9045 :   while (eps->reason == EPS_CONVERGED_ITERATING) {
     203             : 
     204             :     /* Initialize V, if it is needed */
     205        9045 :     PetscCall(BVGetActiveColumns(d->eps->V,&l,&k));
     206        9045 :     if (PetscUnlikely(l == k)) PetscCall(d->initV(d));
     207             : 
     208             :     /* Find the best approximated eigenpairs in V, X */
     209        9045 :     PetscCall(d->calcPairs(d));
     210             : 
     211             :     /* Test for convergence */
     212        9045 :     PetscCall((*eps->stopping)(eps,eps->its,eps->max_it,eps->nconv,eps->nev,&eps->reason,eps->stoppingctx));
     213        9045 :     if (eps->reason != EPS_CONVERGED_ITERATING) break;
     214             : 
     215             :     /* Expand the subspace */
     216        8948 :     PetscCall(d->updateV(d));
     217             : 
     218             :     /* Monitor progress */
     219        8948 :     eps->nconv = d->nconv;
     220        8948 :     eps->its++;
     221        8948 :     PetscCall(BVGetActiveColumns(d->eps->V,NULL,&k));
     222        9045 :     PetscCall(EPSMonitor(eps,eps->its,eps->nconv+d->npreconv,eps->eigr,eps->eigi,eps->errest,PetscMin(k,eps->nev)));
     223             :   }
     224             : 
     225             :   /* Call the ending routines */
     226          97 :   PetscCall(EPSDavidsonFLCall(d->endList,d));
     227          97 :   PetscFunctionReturn(PETSC_SUCCESS);
     228             : }
     229             : 
     230         169 : PetscErrorCode EPSReset_XD(EPS eps)
     231             : {
     232         169 :   EPS_DAVIDSON   *data = (EPS_DAVIDSON*)eps->data;
     233         169 :   dvdDashboard   *dvd = &data->ddb;
     234             : 
     235         169 :   PetscFunctionBegin;
     236             :   /* Call step destructors and destroys the list */
     237         169 :   PetscCall(EPSDavidsonFLCall(dvd->destroyList,dvd));
     238         169 :   PetscCall(EPSDavidsonFLDestroy(&dvd->destroyList));
     239         169 :   PetscCall(EPSDavidsonFLDestroy(&dvd->startList));
     240         169 :   PetscCall(EPSDavidsonFLDestroy(&dvd->endList));
     241         169 :   PetscFunctionReturn(PETSC_SUCCESS);
     242             : }
     243             : 
     244           4 : PetscErrorCode EPSXDSetKrylovStart_XD(EPS eps,PetscBool krylovstart)
     245             : {
     246           4 :   EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
     247             : 
     248           4 :   PetscFunctionBegin;
     249           4 :   data->krylovstart = krylovstart;
     250           4 :   PetscFunctionReturn(PETSC_SUCCESS);
     251             : }
     252             : 
     253          62 : PetscErrorCode EPSXDGetKrylovStart_XD(EPS eps,PetscBool *krylovstart)
     254             : {
     255          62 :   EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
     256             : 
     257          62 :   PetscFunctionBegin;
     258          62 :   *krylovstart = data->krylovstart;
     259          62 :   PetscFunctionReturn(PETSC_SUCCESS);
     260             : }
     261             : 
     262           3 : PetscErrorCode EPSXDSetBlockSize_XD(EPS eps,PetscInt blocksize)
     263             : {
     264           3 :   EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
     265             : 
     266           3 :   PetscFunctionBegin;
     267           3 :   if (blocksize == PETSC_DEFAULT || blocksize == PETSC_DECIDE) blocksize = 1;
     268           3 :   PetscCheck(blocksize>0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid blocksize value, must be >0");
     269           3 :   if (data->blocksize != blocksize) {
     270           3 :     data->blocksize = blocksize;
     271           3 :     eps->state      = EPS_STATE_INITIAL;
     272             :   }
     273           3 :   PetscFunctionReturn(PETSC_SUCCESS);
     274             : }
     275             : 
     276          62 : PetscErrorCode EPSXDGetBlockSize_XD(EPS eps,PetscInt *blocksize)
     277             : {
     278          62 :   EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
     279             : 
     280          62 :   PetscFunctionBegin;
     281          62 :   *blocksize = data->blocksize;
     282          62 :   PetscFunctionReturn(PETSC_SUCCESS);
     283             : }
     284             : 
     285           3 : PetscErrorCode EPSXDSetRestart_XD(EPS eps,PetscInt minv,PetscInt plusk)
     286             : {
     287           3 :   EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
     288             : 
     289           3 :   PetscFunctionBegin;
     290           3 :   if (minv == PETSC_DETERMINE) {
     291           0 :     if (data->minv != 0) eps->state = EPS_STATE_INITIAL;
     292           0 :     data->minv = 0;
     293           3 :   } else if (minv != PETSC_CURRENT) {
     294           3 :     PetscCheck(minv>0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid minv value, must be >0");
     295           3 :     if (data->minv != minv) eps->state = EPS_STATE_INITIAL;
     296           3 :     data->minv = minv;
     297             :   }
     298           3 :   if (plusk == PETSC_DETERMINE) {
     299           1 :     if (data->plusk != PETSC_DETERMINE) eps->state = EPS_STATE_INITIAL;
     300           1 :     data->plusk = PETSC_DETERMINE;
     301           2 :   } else if (plusk != PETSC_CURRENT) {
     302           2 :     PetscCheck(plusk>=0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid plusk value, must be >0");
     303           2 :     if (data->plusk != plusk) eps->state = EPS_STATE_INITIAL;
     304           2 :     data->plusk = plusk;
     305             :   }
     306           3 :   PetscFunctionReturn(PETSC_SUCCESS);
     307             : }
     308             : 
     309          62 : PetscErrorCode EPSXDGetRestart_XD(EPS eps,PetscInt *minv,PetscInt *plusk)
     310             : {
     311          62 :   EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
     312             : 
     313          62 :   PetscFunctionBegin;
     314          62 :   if (minv) *minv = data->minv;
     315          62 :   if (plusk) *plusk = data->plusk;
     316          62 :   PetscFunctionReturn(PETSC_SUCCESS);
     317             : }
     318             : 
     319          61 : PetscErrorCode EPSXDGetInitialSize_XD(EPS eps,PetscInt *initialsize)
     320             : {
     321          61 :   EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
     322             : 
     323          61 :   PetscFunctionBegin;
     324          61 :   *initialsize = data->initialsize;
     325          61 :   PetscFunctionReturn(PETSC_SUCCESS);
     326             : }
     327             : 
     328           2 : PetscErrorCode EPSXDSetInitialSize_XD(EPS eps,PetscInt initialsize)
     329             : {
     330           2 :   EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
     331             : 
     332           2 :   PetscFunctionBegin;
     333           2 :   if (initialsize == PETSC_DEFAULT || initialsize == PETSC_DECIDE) initialsize = 0;
     334           2 :   else PetscCheck(initialsize>0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid initial size value, must be >0");
     335           2 :   if (data->initialsize != initialsize) {
     336           2 :     data->initialsize = initialsize;
     337           2 :     eps->state        = EPS_STATE_INITIAL;
     338             :   }
     339           2 :   PetscFunctionReturn(PETSC_SUCCESS);
     340             : }
     341             : 
     342           2 : PetscErrorCode EPSXDSetBOrth_XD(EPS eps,PetscBool borth)
     343             : {
     344           2 :   EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
     345             : 
     346           2 :   PetscFunctionBegin;
     347           2 :   data->ipB = borth;
     348           2 :   PetscFunctionReturn(PETSC_SUCCESS);
     349             : }
     350             : 
     351          62 : PetscErrorCode EPSXDGetBOrth_XD(EPS eps,PetscBool *borth)
     352             : {
     353          62 :   EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
     354             : 
     355          62 :   PetscFunctionBegin;
     356          62 :   *borth = data->ipB;
     357          62 :   PetscFunctionReturn(PETSC_SUCCESS);
     358             : }
     359             : 
     360             : /*
     361             :   EPSComputeVectors_XD - Compute eigenvectors from the vectors
     362             :   provided by the eigensolver. This version is intended for solvers
     363             :   that provide Schur vectors from the QZ decomposition. Given the partial
     364             :   Schur decomposition OP*V=V*T, the following steps are performed:
     365             :       1) compute eigenvectors of (S,T): S*Z=T*Z*D
     366             :       2) compute eigenvectors of OP: X=V*Z
     367             :  */
     368          93 : PetscErrorCode EPSComputeVectors_XD(EPS eps)
     369             : {
     370          93 :   Mat            X;
     371          93 :   PetscBool      symm;
     372             : 
     373          93 :   PetscFunctionBegin;
     374          93 :   PetscCall(PetscObjectTypeCompare((PetscObject)eps->ds,DSHEP,&symm));
     375          93 :   if (symm) PetscFunctionReturn(PETSC_SUCCESS);
     376          26 :   PetscCall(DSVectors(eps->ds,DS_MAT_X,NULL,NULL));
     377             : 
     378             :   /* V <- V * X */
     379          26 :   PetscCall(DSGetMat(eps->ds,DS_MAT_X,&X));
     380          26 :   PetscCall(BVSetActiveColumns(eps->V,0,eps->nconv));
     381          26 :   PetscCall(BVMultInPlace(eps->V,X,0,eps->nconv));
     382          26 :   PetscCall(DSRestoreMat(eps->ds,DS_MAT_X,&X));
     383          26 :   PetscFunctionReturn(PETSC_SUCCESS);
     384             : }

Generated by: LCOV version 1.14