LCOV - code coverage report
Current view: top level - eps/impls/external/blopex - blopex.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 195 208 93.8 %
Date: 2019-10-20 05:41:02 Functions: 18 18 100.0 %

          Line data    Source code
       1             : /*
       2             :    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       3             :    SLEPc - Scalable Library for Eigenvalue Problem Computations
       4             :    Copyright (c) 2002-2019, 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             :    This file implements a wrapper to the BLOPEX package
      12             : */
      13             : 
      14             : #include <slepc/private/epsimpl.h>                /*I "slepceps.h" I*/
      15             : #include "blopex.h"
      16             : #include <blopex_lobpcg.h>
      17             : #include <blopex_interpreter.h>
      18             : #include <blopex_multivector.h>
      19             : #include <blopex_temp_multivector.h>
      20             : 
      21             : PetscInt slepc_blopex_useconstr = -1;
      22             : 
      23             : typedef struct {
      24             :   lobpcg_Tolerance           tol;
      25             :   lobpcg_BLASLAPACKFunctions blap_fn;
      26             :   mv_InterfaceInterpreter    ii;
      27             :   ST                         st;
      28             :   Vec                        w;
      29             :   PetscInt                   bs;     /* block size */
      30             : } EPS_BLOPEX;
      31             : 
      32        1525 : static void Precond_FnSingleVector(void *data,void *x,void *y)
      33             : {
      34             :   PetscErrorCode ierr;
      35        1525 :   EPS_BLOPEX     *blopex = (EPS_BLOPEX*)data;
      36        1525 :   MPI_Comm       comm = PetscObjectComm((PetscObject)blopex->st);
      37             :   KSP            ksp;
      38             : 
      39        1525 :   PetscFunctionBegin;
      40        1525 :   ierr = STGetKSP(blopex->st,&ksp);CHKERRABORT(comm,ierr);
      41        1525 :   ierr = KSPSolve(ksp,(Vec)x,(Vec)y);CHKERRABORT(comm,ierr);
      42        1525 :   PetscFunctionReturnVoid();
      43             : }
      44             : 
      45         505 : static void Precond_FnMultiVector(void *data,void *x,void *y)
      46             : {
      47         505 :   EPS_BLOPEX *blopex = (EPS_BLOPEX*)data;
      48             : 
      49         505 :   PetscFunctionBegin;
      50         505 :   blopex->ii.Eval(Precond_FnSingleVector,data,x,y);
      51         505 :   PetscFunctionReturnVoid();
      52             : }
      53             : 
      54        1560 : static void OperatorASingleVector(void *data,void *x,void *y)
      55             : {
      56             :   PetscErrorCode ierr;
      57        1560 :   EPS_BLOPEX     *blopex = (EPS_BLOPEX*)data;
      58        1560 :   MPI_Comm       comm = PetscObjectComm((PetscObject)blopex->st);
      59             :   Mat            A,B;
      60             :   PetscScalar    sigma;
      61             :   PetscInt       nmat;
      62             : 
      63        1560 :   PetscFunctionBegin;
      64        1560 :   ierr = STGetNumMatrices(blopex->st,&nmat);CHKERRABORT(comm,ierr);
      65        1560 :   ierr = STGetMatrix(blopex->st,0,&A);CHKERRABORT(comm,ierr);
      66        1560 :   if (nmat>1) { ierr = STGetMatrix(blopex->st,1,&B);CHKERRABORT(comm,ierr); }
      67        1560 :   ierr = MatMult(A,(Vec)x,(Vec)y);CHKERRABORT(comm,ierr);
      68        1560 :   ierr = STGetShift(blopex->st,&sigma);CHKERRABORT(comm,ierr);
      69        1560 :   if (sigma != 0.0) {
      70         528 :     if (nmat>1) {
      71         123 :       ierr = MatMult(B,(Vec)x,blopex->w);CHKERRABORT(comm,ierr);
      72             :     } else {
      73         405 :       ierr = VecCopy((Vec)x,blopex->w);CHKERRABORT(comm,ierr);
      74             :     }
      75         528 :     ierr = VecAXPY((Vec)y,-sigma,blopex->w);CHKERRABORT(comm,ierr);
      76             :   }
      77        1560 :   PetscFunctionReturnVoid();
      78             : }
      79             : 
      80         514 : static void OperatorAMultiVector(void *data,void *x,void *y)
      81             : {
      82         514 :   EPS_BLOPEX *blopex = (EPS_BLOPEX*)data;
      83             : 
      84         514 :   PetscFunctionBegin;
      85         514 :   blopex->ii.Eval(OperatorASingleVector,data,x,y);
      86         514 :   PetscFunctionReturnVoid();
      87             : }
      88             : 
      89         552 : static void OperatorBSingleVector(void *data,void *x,void *y)
      90             : {
      91             :   PetscErrorCode ierr;
      92         552 :   EPS_BLOPEX     *blopex = (EPS_BLOPEX*)data;
      93         552 :   MPI_Comm       comm = PetscObjectComm((PetscObject)blopex->st);
      94             :   Mat            B;
      95             : 
      96         552 :   PetscFunctionBegin;
      97         552 :   ierr = STGetMatrix(blopex->st,1,&B);CHKERRABORT(comm,ierr);
      98         552 :   ierr = MatMult(B,(Vec)x,(Vec)y);CHKERRABORT(comm,ierr);
      99         552 :   PetscFunctionReturnVoid();
     100             : }
     101             : 
     102         198 : static void OperatorBMultiVector(void *data,void *x,void *y)
     103             : {
     104         198 :   EPS_BLOPEX *blopex = (EPS_BLOPEX*)data;
     105             : 
     106         198 :   PetscFunctionBegin;
     107         198 :   blopex->ii.Eval(OperatorBSingleVector,data,x,y);
     108         198 :   PetscFunctionReturnVoid();
     109             : }
     110             : 
     111           7 : PetscErrorCode EPSSetDimensions_BLOPEX(EPS eps,PetscInt nev,PetscInt *ncv,PetscInt *mpd)
     112             : {
     113             :   PetscErrorCode ierr;
     114           7 :   EPS_BLOPEX     *ctx = (EPS_BLOPEX*)eps->data;
     115             :   PetscInt       k;
     116             : 
     117           7 :   PetscFunctionBegin;
     118           7 :   k = ((eps->nev-1)/ctx->bs+1)*ctx->bs;
     119           7 :   if (*ncv) { /* ncv set */
     120           1 :     if (*ncv<k) SETERRQ(PetscObjectComm((PetscObject)eps),1,"The value of ncv is not sufficiently large");
     121           6 :   } else *ncv = k;
     122           7 :   if (!*mpd) *mpd = *ncv;
     123           1 :   else { ierr = PetscInfo(eps,"Warning: given value of mpd ignored\n");CHKERRQ(ierr); }
     124           7 :   PetscFunctionReturn(0);
     125             : }
     126             : 
     127           7 : PetscErrorCode EPSSetUp_BLOPEX(EPS eps)
     128             : {
     129             : #if defined(PETSC_MISSING_LAPACK_POTRF) || defined(PETSC_MISSING_LAPACK_SYGV)
     130             :   PetscFunctionBegin;
     131             :   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRF/SYGV - Lapack routines are unavailable");
     132             : #else
     133             :   PetscErrorCode ierr;
     134           7 :   EPS_BLOPEX     *blopex = (EPS_BLOPEX*)eps->data;
     135             :   PetscBool      istrivial,flg;
     136             : 
     137           7 :   PetscFunctionBegin;
     138           7 :   if (!eps->ishermitian || (eps->isgeneralized && !eps->ispositive)) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"blopex only works for Hermitian problems");
     139           7 :   if (!blopex->bs) blopex->bs = PetscMin(16,eps->nev);
     140           7 :   ierr = EPSSetDimensions_BLOPEX(eps,eps->nev,&eps->ncv,&eps->mpd);CHKERRQ(ierr);
     141           7 :   if (!eps->max_it) eps->max_it = PetscMax(100,2*eps->n/eps->ncv);
     142           7 :   if (!eps->which) eps->which = EPS_SMALLEST_REAL;
     143           7 :   if (eps->which!=EPS_SMALLEST_REAL) SETERRQ(PetscObjectComm((PetscObject)eps),1,"Wrong value of eps->which");
     144           7 :   if (eps->arbitrary) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Arbitrary selection of eigenpairs not supported in this solver");
     145           7 :   if (eps->stopping!=EPSStoppingBasic) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"External packages do not support user-defined stopping test");
     146           7 :   if (eps->extraction) { ierr = PetscInfo(eps,"Warning: extraction type ignored\n");CHKERRQ(ierr); }
     147           7 :   ierr = RGIsTrivial(eps->rg,&istrivial);CHKERRQ(ierr);
     148           7 :   if (!istrivial) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"This solver does not support region filtering");
     149             : 
     150           7 :   blopex->st = eps->st;
     151             : 
     152           7 :   if (eps->converged == EPSConvergedRelative) {
     153           4 :     blopex->tol.absolute = 0.0;
     154           4 :     blopex->tol.relative = eps->tol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL:eps->tol;
     155           3 :   } else if (eps->converged == EPSConvergedAbsolute) {
     156           3 :     blopex->tol.absolute = eps->tol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL:eps->tol;
     157           3 :     blopex->tol.relative = 0.0;
     158           0 :   } else SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Convergence test not supported in this solver");
     159             : 
     160           7 :   SLEPCSetupInterpreter(&blopex->ii);
     161             : 
     162             :   /* allocate memory */
     163           7 :   if (!eps->V) { ierr = EPSGetBV(eps,&eps->V);CHKERRQ(ierr); }
     164           7 :   ierr = PetscObjectTypeCompareAny((PetscObject)eps->V,&flg,BVVECS,BVCONTIGUOUS,"");CHKERRQ(ierr);
     165           7 :   if (!flg) {  /* blopex only works with BVVECS or BVCONTIGUOUS */
     166           6 :     ierr = BVSetType(eps->V,BVCONTIGUOUS);CHKERRQ(ierr);
     167             :   }
     168           7 :   ierr = EPSAllocateSolution(eps,0);CHKERRQ(ierr);
     169           7 :   if (!blopex->w) {
     170           6 :     ierr = BVCreateVec(eps->V,&blopex->w);CHKERRQ(ierr);
     171           6 :     ierr = PetscLogObjectParent((PetscObject)eps,(PetscObject)blopex->w);CHKERRQ(ierr);
     172             :   }
     173             : 
     174             : #if defined(PETSC_USE_COMPLEX)
     175             :   blopex->blap_fn.zpotrf = PETSC_zpotrf_interface;
     176             :   blopex->blap_fn.zhegv = PETSC_zsygv_interface;
     177             : #else
     178           7 :   blopex->blap_fn.dpotrf = PETSC_dpotrf_interface;
     179           7 :   blopex->blap_fn.dsygv = PETSC_dsygv_interface;
     180             : #endif
     181           7 :   PetscFunctionReturn(0);
     182             : #endif
     183             : }
     184             : 
     185           7 : PetscErrorCode EPSSolve_BLOPEX(EPS eps)
     186             : {
     187           7 :   EPS_BLOPEX        *blopex = (EPS_BLOPEX*)eps->data;
     188           7 :   PetscScalar       sigma,*eigr=NULL;
     189           7 :   PetscReal         *errest=NULL;
     190             :   int               i,j,info,its,nconv;
     191           7 :   double            *residhist=NULL;
     192             :   PetscErrorCode    ierr;
     193             :   mv_MultiVectorPtr eigenvectors,constraints;
     194             : #if defined(PETSC_USE_COMPLEX)
     195             :   komplex           *lambda=NULL,*lambdahist=NULL;
     196             : #else
     197           7 :   double            *lambda=NULL,*lambdahist=NULL;
     198             : #endif
     199             : 
     200           7 :   PetscFunctionBegin;
     201           7 :   ierr = STGetShift(eps->st,&sigma);CHKERRQ(ierr);
     202           7 :   ierr = PetscMalloc1(blopex->bs,&lambda);CHKERRQ(ierr);
     203           7 :   if (eps->numbermonitors>0) {
     204           0 :     ierr = PetscMalloc4(blopex->bs*(eps->max_it+1),&lambdahist,eps->ncv,&eigr,blopex->bs*(eps->max_it+1),&residhist,eps->ncv,&errest);CHKERRQ(ierr);
     205             :   }
     206             : 
     207             :   /* Complete the initial basis with random vectors */
     208           1 :   for (i=0;i<eps->nini;i++) {  /* in case the initial vectors were also set with VecSetRandom */
     209           1 :     ierr = BVSetRandomColumn(eps->V,eps->nini);CHKERRQ(ierr);
     210             :   }
     211          34 :   for (i=eps->nini;i<eps->ncv;i++) {
     212          34 :     ierr = BVSetRandomColumn(eps->V,i);CHKERRQ(ierr);
     213             :   }
     214             : 
     215          16 :   while (eps->reason == EPS_CONVERGED_ITERATING) {
     216             : 
     217             :     /* Create multivector of constraints from leading columns of V */
     218           9 :     ierr = PetscObjectComposedDataSetInt((PetscObject)eps->V,slepc_blopex_useconstr,1);CHKERRQ(ierr);
     219           9 :     ierr = BVSetActiveColumns(eps->V,0,eps->nconv);CHKERRQ(ierr);
     220           9 :     constraints = mv_MultiVectorCreateFromSampleVector(&blopex->ii,eps->nds+eps->nconv,eps->V);
     221             : 
     222             :     /* Create multivector where eigenvectors of this run will be stored */
     223           9 :     ierr = PetscObjectComposedDataSetInt((PetscObject)eps->V,slepc_blopex_useconstr,0);CHKERRQ(ierr);
     224           9 :     ierr = BVSetActiveColumns(eps->V,eps->nconv,eps->nconv+blopex->bs);CHKERRQ(ierr);
     225           9 :     eigenvectors = mv_MultiVectorCreateFromSampleVector(&blopex->ii,blopex->bs,eps->V);
     226             : 
     227             : #if defined(PETSC_USE_COMPLEX)
     228             :     info = lobpcg_solve_complex(eigenvectors,blopex,OperatorAMultiVector,
     229             :           eps->isgeneralized?blopex:NULL,eps->isgeneralized?OperatorBMultiVector:NULL,
     230             :           blopex,Precond_FnMultiVector,constraints,
     231             :           blopex->blap_fn,blopex->tol,eps->max_it,0,&its,
     232             :           lambda,lambdahist,blopex->bs,eps->errest+eps->nconv,residhist,blopex->bs);
     233             : #else
     234          27 :     info = lobpcg_solve_double(eigenvectors,blopex,OperatorAMultiVector,
     235           9 :           eps->isgeneralized?blopex:NULL,eps->isgeneralized?OperatorBMultiVector:NULL,
     236             :           blopex,Precond_FnMultiVector,constraints,
     237             :           blopex->blap_fn,blopex->tol,eps->max_it,0,&its,
     238           9 :           lambda,lambdahist,blopex->bs,eps->errest+eps->nconv,residhist,blopex->bs);
     239             : #endif
     240           9 :     if (info>0) SETERRQ1(PetscObjectComm((PetscObject)eps),PETSC_ERR_LIB,"BLOPEX failed with exit code=%d",info);
     241           9 :     mv_MultiVectorDestroy(constraints);
     242           9 :     mv_MultiVectorDestroy(eigenvectors);
     243             : 
     244          44 :     for (j=0;j<blopex->bs;j++) {
     245             : #if defined(PETSC_USE_COMPLEX)
     246             :       eps->eigr[eps->nconv+j] = PetscCMPLX(lambda[j].real,lambda[j].imag);
     247             : #else
     248          35 :       eps->eigr[eps->nconv+j] = lambda[j];
     249             : #endif
     250             :     }
     251             : 
     252           9 :     if (eps->numbermonitors>0) {
     253           0 :       for (i=0;i<its;i++) {
     254             :         nconv = 0;
     255           0 :         for (j=0;j<blopex->bs;j++) {
     256             : #if defined(PETSC_USE_COMPLEX)
     257             :           eigr[eps->nconv+j] = PetscCMPLX(lambdahist[j+i*blopex->bs].real,lambdahist[j+i*blopex->bs].imag);
     258             : #else
     259           0 :           eigr[eps->nconv+j] = lambdahist[j+i*blopex->bs];
     260             : #endif
     261           0 :           errest[eps->nconv+j] = residhist[j+i*blopex->bs];
     262           0 :           if (residhist[j+i*blopex->bs]<=eps->tol) nconv++;
     263             :         }
     264           0 :         ierr = EPSMonitor(eps,eps->its+i,eps->nconv+nconv,eigr,eps->eigi,errest,eps->nconv+blopex->bs);CHKERRQ(ierr);
     265             :       }
     266             :     }
     267             : 
     268           9 :     eps->its += its;
     269           9 :     if (info==-1) {
     270           0 :       eps->reason = EPS_DIVERGED_ITS;
     271           0 :       break;
     272             :     } else {
     273          35 :       for (i=0;i<blopex->bs;i++) {
     274          35 :         if (sigma != 0.0) eps->eigr[eps->nconv+i] += sigma;
     275             :       }
     276           9 :       eps->nconv += blopex->bs;
     277           9 :       if (eps->nconv>=eps->nev) eps->reason = EPS_CONVERGED_TOL;
     278             :     }
     279             :   }
     280             : 
     281           7 :   ierr = PetscFree(lambda);CHKERRQ(ierr);
     282           7 :   if (eps->numbermonitors>0) {
     283           0 :     ierr = PetscFree4(lambdahist,eigr,residhist,errest);CHKERRQ(ierr);
     284             :   }
     285           7 :   PetscFunctionReturn(0);
     286             : }
     287             : 
     288           2 : static PetscErrorCode EPSBLOPEXSetBlockSize_BLOPEX(EPS eps,PetscInt bs)
     289             : {
     290           2 :   EPS_BLOPEX *ctx = (EPS_BLOPEX*)eps->data;
     291             : 
     292           2 :   PetscFunctionBegin;
     293           2 :   if (bs==PETSC_DEFAULT) {
     294           0 :     ctx->bs    = 0;
     295           0 :     eps->state = EPS_STATE_INITIAL;
     296             :   } else {
     297           2 :     if (bs<=0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Block size must be >0");
     298           2 :     ctx->bs = bs;
     299             :   }
     300           2 :   PetscFunctionReturn(0);
     301             : }
     302             : 
     303             : /*@
     304             :    EPSBLOPEXSetBlockSize - Sets the block size of the BLOPEX solver.
     305             : 
     306             :    Logically Collective on eps
     307             : 
     308             :    Input Parameters:
     309             : +  eps - the eigenproblem solver context
     310             : -  bs  - the block size
     311             : 
     312             :    Options Database Key:
     313             : .  -eps_blopex_blocksize - Sets the block size
     314             : 
     315             :    Level: advanced
     316             : 
     317             : .seealso: EPSBLOPEXGetBlockSize()
     318             : @*/
     319           2 : PetscErrorCode EPSBLOPEXSetBlockSize(EPS eps,PetscInt bs)
     320             : {
     321             :   PetscErrorCode ierr;
     322             : 
     323           2 :   PetscFunctionBegin;
     324           2 :   PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
     325           4 :   PetscValidLogicalCollectiveInt(eps,bs,2);
     326           2 :   ierr = PetscTryMethod(eps,"EPSBLOPEXSetBlockSize_C",(EPS,PetscInt),(eps,bs));CHKERRQ(ierr);
     327           4 :   PetscFunctionReturn(0);
     328             : }
     329             : 
     330           1 : static PetscErrorCode EPSBLOPEXGetBlockSize_BLOPEX(EPS eps,PetscInt *bs)
     331             : {
     332           1 :   EPS_BLOPEX *ctx = (EPS_BLOPEX*)eps->data;
     333             : 
     334           1 :   PetscFunctionBegin;
     335           1 :   *bs = ctx->bs;
     336           1 :   PetscFunctionReturn(0);
     337             : }
     338             : 
     339             : /*@
     340             :    EPSBLOPEXGetBlockSize - Gets the block size used in the BLOPEX solver.
     341             : 
     342             :    Not Collective
     343             : 
     344             :    Input Parameter:
     345             : .  eps - the eigenproblem solver context
     346             : 
     347             :    Output Parameter:
     348             : .  bs - the block size
     349             : 
     350             :    Level: advanced
     351             : 
     352             : .seealso: EPSBLOPEXSetBlockSize()
     353             : @*/
     354           1 : PetscErrorCode EPSBLOPEXGetBlockSize(EPS eps,PetscInt *bs)
     355             : {
     356             :   PetscErrorCode ierr;
     357             : 
     358           1 :   PetscFunctionBegin;
     359           1 :   PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
     360           1 :   PetscValidIntPointer(bs,2);
     361           1 :   ierr = PetscUseMethod(eps,"EPSBLOPEXGetBlockSize_C",(EPS,PetscInt*),(eps,bs));CHKERRQ(ierr);
     362           2 :   PetscFunctionReturn(0);
     363             : }
     364             : 
     365           6 : PetscErrorCode EPSReset_BLOPEX(EPS eps)
     366             : {
     367             :   PetscErrorCode ierr;
     368           6 :   EPS_BLOPEX     *blopex = (EPS_BLOPEX*)eps->data;
     369             : 
     370           6 :   PetscFunctionBegin;
     371           6 :   ierr = VecDestroy(&blopex->w);CHKERRQ(ierr);
     372           6 :   PetscFunctionReturn(0);
     373             : }
     374             : 
     375           6 : PetscErrorCode EPSDestroy_BLOPEX(EPS eps)
     376             : {
     377             :   PetscErrorCode ierr;
     378             : 
     379           6 :   PetscFunctionBegin;
     380           6 :   LOBPCG_DestroyRandomContext();
     381           6 :   ierr = PetscFree(eps->data);CHKERRQ(ierr);
     382           6 :   ierr = PetscObjectComposeFunction((PetscObject)eps,"EPSBLOPEXSetBlockSize_C",NULL);CHKERRQ(ierr);
     383           6 :   ierr = PetscObjectComposeFunction((PetscObject)eps,"EPSBLOPEXGetBlockSize_C",NULL);CHKERRQ(ierr);
     384           6 :   PetscFunctionReturn(0);
     385             : }
     386             : 
     387           1 : PetscErrorCode EPSView_BLOPEX(EPS eps,PetscViewer viewer)
     388             : {
     389             :   PetscErrorCode ierr;
     390           1 :   EPS_BLOPEX     *ctx = (EPS_BLOPEX*)eps->data;
     391             :   PetscBool      isascii;
     392             : 
     393           1 :   PetscFunctionBegin;
     394           1 :   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
     395           1 :   if (isascii) {
     396           1 :     ierr = PetscViewerASCIIPrintf(viewer,"  block size %D\n",ctx->bs);CHKERRQ(ierr);
     397             :   }
     398           1 :   PetscFunctionReturn(0);
     399             : }
     400             : 
     401           6 : PetscErrorCode EPSSetFromOptions_BLOPEX(PetscOptionItems *PetscOptionsObject,EPS eps)
     402             : {
     403             :   PetscErrorCode ierr;
     404             :   PetscBool      flg;
     405             :   PetscInt       bs;
     406             : 
     407           6 :   PetscFunctionBegin;
     408           6 :   ierr = PetscOptionsHead(PetscOptionsObject,"EPS BLOPEX Options");CHKERRQ(ierr);
     409             : 
     410           6 :     ierr = PetscOptionsInt("-eps_blopex_blocksize","Block size","EPSBLOPEXSetBlockSize",20,&bs,&flg);CHKERRQ(ierr);
     411           6 :     if (flg) { ierr = EPSBLOPEXSetBlockSize(eps,bs);CHKERRQ(ierr); }
     412             : 
     413           6 :   ierr = PetscOptionsTail();CHKERRQ(ierr);
     414             : 
     415           6 :   LOBPCG_SetFromOptionsRandomContext();
     416           6 :   PetscFunctionReturn(0);
     417             : }
     418             : 
     419           6 : SLEPC_EXTERN PetscErrorCode EPSCreate_BLOPEX(EPS eps)
     420             : {
     421             :   EPS_BLOPEX     *ctx;
     422             :   PetscErrorCode ierr;
     423             : 
     424           6 :   PetscFunctionBegin;
     425           6 :   ierr = PetscNewLog(eps,&ctx);CHKERRQ(ierr);
     426           6 :   eps->data = (void*)ctx;
     427             : 
     428           6 :   eps->categ = EPS_CATEGORY_PRECOND;
     429             : 
     430           6 :   eps->ops->solve          = EPSSolve_BLOPEX;
     431           6 :   eps->ops->setup          = EPSSetUp_BLOPEX;
     432           6 :   eps->ops->setfromoptions = EPSSetFromOptions_BLOPEX;
     433           6 :   eps->ops->destroy        = EPSDestroy_BLOPEX;
     434           6 :   eps->ops->reset          = EPSReset_BLOPEX;
     435           6 :   eps->ops->view           = EPSView_BLOPEX;
     436           6 :   eps->ops->backtransform  = EPSBackTransform_Default;
     437           6 :   eps->ops->setdefaultst   = EPSSetDefaultST_Precond;
     438             : 
     439           6 :   LOBPCG_InitRandomContext(PetscObjectComm((PetscObject)eps),NULL);
     440           6 :   ierr = PetscObjectComposeFunction((PetscObject)eps,"EPSBLOPEXSetBlockSize_C",EPSBLOPEXSetBlockSize_BLOPEX);CHKERRQ(ierr);
     441           6 :   ierr = PetscObjectComposeFunction((PetscObject)eps,"EPSBLOPEXGetBlockSize_C",EPSBLOPEXGetBlockSize_BLOPEX);CHKERRQ(ierr);
     442           6 :   if (slepc_blopex_useconstr < 0) { ierr = PetscObjectComposedDataRegister(&slepc_blopex_useconstr);CHKERRQ(ierr); }
     443           6 :   PetscFunctionReturn(0);
     444             : }
     445             : 

Generated by: LCOV version 1.13