LCOV - code coverage report
Current view: top level - eps/impls/external/trlan - trlan.c (source / functions) Hit Total Coverage
Test: SLEPc Lines: 105 105 100.0 %
Date: 2024-11-21 00:34:55 Functions: 6 6 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             :    This file implements a wrapper to the TRLAN package
      12             : */
      13             : 
      14             : #include <slepc/private/epsimpl.h>
      15             : #include "trlan.h"
      16             : 
      17             : /* Nasty global variable to access EPS data from TRLan_ */
      18             : static struct {
      19             :   EPS eps;
      20             :   Vec x,y;
      21             : } globaldata;
      22             : 
      23           7 : static PetscErrorCode EPSSetUp_TRLAN(EPS eps)
      24             : {
      25           7 :   EPS_TRLAN      *tr = (EPS_TRLAN*)eps->data;
      26             : 
      27           7 :   PetscFunctionBegin;
      28           7 :   EPSCheckHermitian(eps);
      29           7 :   EPSCheckStandard(eps);
      30           7 :   EPSCheckNotStructured(eps);
      31           7 :   PetscCall(PetscBLASIntCast(PetscMax(7,eps->nev+PetscMin(eps->nev,6)),&tr->maxlan));
      32           7 :   if (eps->ncv!=PETSC_DETERMINE) {
      33           2 :     PetscCheck(eps->ncv>=eps->nev,PetscObjectComm((PetscObject)eps),PETSC_ERR_USER_INPUT,"The value of ncv must be at least nev");
      34           5 :   } else eps->ncv = tr->maxlan;
      35           7 :   if (eps->mpd!=PETSC_DETERMINE) PetscCall(PetscInfo(eps,"Warning: parameter mpd ignored\n"));
      36           7 :   if (eps->max_it==PETSC_DETERMINE) eps->max_it = PetscMax(1000,eps->n);
      37             : 
      38           7 :   if (!eps->which) eps->which = EPS_LARGEST_REAL;
      39           7 :   PetscCheck(eps->which==EPS_SMALLEST_REAL || eps->which==EPS_LARGEST_REAL || eps->which==EPS_TARGET_REAL,PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"This solver supports only smallest, largest or target real eigenvalues");
      40           7 :   EPSCheckUnsupported(eps,EPS_FEATURE_ARBITRARY | EPS_FEATURE_REGION | EPS_FEATURE_CONVERGENCE | EPS_FEATURE_STOPPING);
      41           7 :   EPSCheckIgnored(eps,EPS_FEATURE_BALANCE | EPS_FEATURE_EXTRACTION);
      42             : 
      43           7 :   tr->restart = 0;
      44           7 :   if (tr->maxlan+1-eps->ncv<=0) PetscCall(PetscBLASIntCast(tr->maxlan*(tr->maxlan+10),&tr->lwork));
      45           7 :   else PetscCall(PetscBLASIntCast(eps->nloc*(tr->maxlan+1-eps->ncv) + tr->maxlan*(tr->maxlan+10),&tr->lwork));
      46           7 :   if (tr->work) PetscCall(PetscFree(tr->work));
      47           7 :   PetscCall(PetscMalloc1(tr->lwork,&tr->work));
      48             : 
      49           7 :   PetscCall(EPSAllocateSolution(eps,0));
      50           7 :   PetscFunctionReturn(PETSC_SUCCESS);
      51             : }
      52             : 
      53         657 : static PetscBLASInt MatMult_TRLAN(PetscBLASInt *n,PetscBLASInt *m,PetscReal *xin,PetscBLASInt *ldx,PetscReal *yout,PetscBLASInt *ldy)
      54             : {
      55         657 :   Vec            x=globaldata.x,y=globaldata.y;
      56         657 :   EPS            eps=globaldata.eps;
      57         657 :   PetscBLASInt   i;
      58             : 
      59         657 :   PetscFunctionBegin;
      60        1314 :   for (i=0;i<*m;i++) {
      61         657 :     PetscCall(VecPlaceArray(x,(PetscScalar*)xin+i*(*ldx)));
      62         657 :     PetscCall(VecPlaceArray(y,(PetscScalar*)yout+i*(*ldy)));
      63         657 :     PetscCall(STApply(eps->st,x,y));
      64         657 :     PetscCall(BVOrthogonalizeVec(eps->V,y,NULL,NULL,NULL));
      65         657 :     PetscCall(VecResetArray(x));
      66         657 :     PetscCall(VecResetArray(y));
      67             :   }
      68         657 :   PetscFunctionReturn(PETSC_SUCCESS);
      69             : }
      70             : 
      71           7 : static PetscErrorCode EPSSolve_TRLAN(EPS eps)
      72             : {
      73           7 :   PetscInt       i;
      74           7 :   PetscBLASInt   ipar[32],n,lohi,stat,ncv;
      75           7 :   EPS_TRLAN      *tr = (EPS_TRLAN*)eps->data;
      76           7 :   PetscScalar    *pV;
      77           7 :   Vec            v0;
      78           7 :   Mat            A;
      79             : #if !defined(PETSC_HAVE_MPIUNI)
      80           7 :   MPI_Fint       fcomm;
      81             : #endif
      82             : 
      83           7 :   PetscFunctionBegin;
      84           7 :   PetscCall(PetscBLASIntCast(eps->ncv,&ncv));
      85           7 :   PetscCall(PetscBLASIntCast(eps->nloc,&n));
      86             : 
      87           7 :   PetscCheck(eps->which==EPS_LARGEST_REAL || eps->which==EPS_TARGET_REAL || eps->which==EPS_SMALLEST_REAL,PetscObjectComm((PetscObject)eps),PETSC_ERR_USER_INPUT,"Wrong value of eps->which");
      88           7 :   lohi = (eps->which==EPS_SMALLEST_REAL)? -1: 1;
      89             : 
      90           7 :   globaldata.eps = eps;
      91           7 :   PetscCall(STGetMatrix(eps->st,0,&A));
      92           7 :   PetscCall(MatCreateVecsEmpty(A,&globaldata.x,&globaldata.y));
      93             : 
      94           7 :   ipar[0]  = 0;            /* stat: error flag */
      95           7 :   ipar[1]  = lohi;         /* smallest (lohi<0) or largest eigenvalues (lohi>0) */
      96           7 :   PetscCall(PetscBLASIntCast(eps->nev,&ipar[2])); /* number of desired eigenpairs */
      97           7 :   ipar[3]  = 0;            /* number of eigenpairs already converged */
      98           7 :   ipar[4]  = tr->maxlan;   /* maximum Lanczos basis size */
      99           7 :   ipar[5]  = tr->restart;  /* restarting scheme */
     100           7 :   PetscCall(PetscBLASIntCast(eps->max_it,&ipar[6])); /* maximum number of MATVECs */
     101             : #if !defined(PETSC_HAVE_MPIUNI)
     102           7 :   fcomm    = MPI_Comm_c2f(PetscObjectComm((PetscObject)eps));
     103           7 :   ipar[7]  = fcomm;
     104             : #endif
     105           7 :   ipar[8]  = 0;            /* verboseness */
     106           7 :   ipar[9]  = 99;           /* Fortran IO unit number used to write log messages */
     107           7 :   ipar[10] = 1;            /* use supplied starting vector */
     108           7 :   ipar[11] = 0;            /* checkpointing flag */
     109           7 :   ipar[12] = 98;           /* Fortran IO unit number used to write checkpoint files */
     110           7 :   ipar[13] = 0;            /* number of flops per matvec per PE (not used) */
     111           7 :   tr->work[0] = eps->tol;  /* relative tolerance on residual norms */
     112             : 
     113          63 :   for (i=0;i<eps->ncv;i++) eps->eigr[i]=0.0;
     114           7 :   PetscCall(EPSGetStartVector(eps,0,NULL));
     115           7 :   PetscCall(BVSetActiveColumns(eps->V,0,0));  /* just for deflation space */
     116           7 :   PetscCall(BVGetColumn(eps->V,0,&v0));
     117           7 :   PetscCall(VecGetArray(v0,&pV));
     118             : 
     119           7 :   PetscStackCallExternalVoid("TRLan",TRLan_(MatMult_TRLAN,ipar,&n,&ncv,eps->eigr,pV,&n,tr->work,&tr->lwork));
     120             : 
     121           7 :   PetscCall(VecRestoreArray(v0,&pV));
     122           7 :   PetscCall(BVRestoreColumn(eps->V,0,&v0));
     123             : 
     124           7 :   stat        = ipar[0];
     125           7 :   eps->nconv  = ipar[3];
     126           7 :   eps->its    = ipar[25];
     127           7 :   eps->reason = EPS_CONVERGED_TOL;
     128             : 
     129           7 :   PetscCall(VecDestroy(&globaldata.x));
     130           7 :   PetscCall(VecDestroy(&globaldata.y));
     131           7 :   PetscCheck(stat==0,PetscObjectComm((PetscObject)eps),PETSC_ERR_LIB,"Error in TRLAN (code=%" PetscBLASInt_FMT ")",stat);
     132           7 :   PetscFunctionReturn(PETSC_SUCCESS);
     133             : }
     134             : 
     135           5 : static PetscErrorCode EPSReset_TRLAN(EPS eps)
     136             : {
     137           5 :   EPS_TRLAN      *tr = (EPS_TRLAN*)eps->data;
     138             : 
     139           5 :   PetscFunctionBegin;
     140           5 :   PetscCall(PetscFree(tr->work));
     141           5 :   PetscFunctionReturn(PETSC_SUCCESS);
     142             : }
     143             : 
     144           5 : static PetscErrorCode EPSDestroy_TRLAN(EPS eps)
     145             : {
     146           5 :   PetscFunctionBegin;
     147           5 :   PetscCall(PetscFree(eps->data));
     148           5 :   PetscFunctionReturn(PETSC_SUCCESS);
     149             : }
     150             : 
     151           5 : SLEPC_EXTERN PetscErrorCode EPSCreate_TRLAN(EPS eps)
     152             : {
     153           5 :   EPS_TRLAN      *ctx;
     154             : 
     155           5 :   PetscFunctionBegin;
     156           5 :   PetscCall(PetscNew(&ctx));
     157           5 :   eps->data = (void*)ctx;
     158             : 
     159           5 :   eps->ops->solve          = EPSSolve_TRLAN;
     160           5 :   eps->ops->setup          = EPSSetUp_TRLAN;
     161           5 :   eps->ops->setupsort      = EPSSetUpSort_Basic;
     162           5 :   eps->ops->destroy        = EPSDestroy_TRLAN;
     163           5 :   eps->ops->reset          = EPSReset_TRLAN;
     164           5 :   eps->ops->backtransform  = EPSBackTransform_Default;
     165           5 :   PetscFunctionReturn(PETSC_SUCCESS);
     166             : }

Generated by: LCOV version 1.14