LCOV - code coverage report
Current view: top level - nep/impls/nleigs - nleigs-fullb.c (source / functions) Hit Total Coverage
Test: SLEPc Lines: 336 356 94.4 %
Date: 2024-11-23 00:34:26 Functions: 11 13 84.6 %
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             :    Full basis for the linearization of the rational approximation of non-linear eigenproblems
      12             : */
      13             : 
      14             : #include <slepc/private/nepimpl.h>         /*I "slepcnep.h" I*/
      15             : #include "nleigs.h"
      16             : 
      17          84 : static PetscErrorCode MatMult_FullBasis_Sinvert(Mat M,Vec x,Vec y)
      18             : {
      19          84 :   NEP_NLEIGS        *ctx;
      20          84 :   NEP               nep;
      21          84 :   const PetscScalar *px;
      22          84 :   PetscScalar       *beta,*s,*xi,*t,*py,sigma;
      23          84 :   PetscInt          nmat,d,i,k,m;
      24          84 :   Vec               xx,xxx,yy,yyy,w,ww,www;
      25             : 
      26          84 :   PetscFunctionBegin;
      27          84 :   PetscCall(MatShellGetContext(M,&nep));
      28          84 :   ctx = (NEP_NLEIGS*)nep->data;
      29          84 :   beta = ctx->beta; s = ctx->s; xi = ctx->xi;
      30          84 :   sigma = ctx->shifts[0];
      31          84 :   nmat = ctx->nmat;
      32          84 :   d = nmat-1;
      33          84 :   m = nep->nloc;
      34          84 :   PetscCall(PetscMalloc1(ctx->nmat,&t));
      35          84 :   xx = ctx->w[0]; xxx = ctx->w[1]; yy = ctx->w[2]; yyy=ctx->w[3];
      36          84 :   w = nep->work[0]; ww = nep->work[1]; www = nep->work[2];
      37          84 :   PetscCall(VecGetArrayRead(x,&px));
      38          84 :   PetscCall(VecGetArray(y,&py));
      39          84 :   PetscCall(VecPlaceArray(xx,px+(d-1)*m));
      40          84 :   PetscCall(VecPlaceArray(xxx,px+(d-2)*m));
      41          84 :   PetscCall(VecPlaceArray(yy,py+(d-2)*m));
      42          84 :   PetscCall(VecCopy(xxx,yy));
      43          84 :   PetscCall(VecAXPY(yy,beta[d-1]/xi[d-2],xx));
      44          84 :   PetscCall(VecScale(yy,1.0/(s[d-2]-sigma)));
      45          84 :   PetscCall(VecResetArray(xx));
      46          84 :   PetscCall(VecResetArray(xxx));
      47          84 :   PetscCall(VecResetArray(yy));
      48         168 :   for (i=d-3;i>=0;i--) {
      49          84 :     PetscCall(VecPlaceArray(xx,px+(i+1)*m));
      50          84 :     PetscCall(VecPlaceArray(xxx,px+i*m));
      51          84 :     PetscCall(VecPlaceArray(yy,py+i*m));
      52          84 :     PetscCall(VecPlaceArray(yyy,py+(i+1)*m));
      53          84 :     PetscCall(VecCopy(xxx,yy));
      54          84 :     PetscCall(VecAXPY(yy,beta[i+1]/xi[i],xx));
      55          84 :     PetscCall(VecAXPY(yy,-beta[i+1]*(1.0-sigma/xi[i]),yyy));
      56          84 :     PetscCall(VecScale(yy,1.0/(s[i]-sigma)));
      57          84 :     PetscCall(VecResetArray(xx));
      58          84 :     PetscCall(VecResetArray(xxx));
      59          84 :     PetscCall(VecResetArray(yy));
      60          84 :     PetscCall(VecResetArray(yyy));
      61             :   }
      62          84 :   if (nep->fui==NEP_USER_INTERFACE_SPLIT) {
      63          40 :     PetscCall(VecZeroEntries(w));
      64         160 :     for (k=0;k<nep->nt;k++) {
      65         120 :       PetscCall(VecZeroEntries(ww));
      66         120 :       PetscCall(VecPlaceArray(xx,px+(d-1)*m));
      67         120 :       PetscCall(VecAXPY(ww,-ctx->coeffD[k+nep->nt*d]/beta[d],xx));
      68         120 :       PetscCall(VecResetArray(xx));
      69         360 :       for (i=0;i<d-1;i++) {
      70         240 :         PetscCall(VecPlaceArray(yy,py+i*m));
      71         240 :         PetscCall(VecAXPY(ww,-ctx->coeffD[nep->nt*i+k],yy));
      72         240 :         PetscCall(VecResetArray(yy));
      73             :       }
      74         120 :       PetscCall(MatMult(nep->A[k],ww,www));
      75         120 :       PetscCall(VecAXPY(w,1.0,www));
      76             :     }
      77             :   } else {
      78          44 :     PetscCall(VecPlaceArray(xx,px+(d-1)*m));
      79          44 :     PetscCall(MatMult(ctx->D[d],xx,w));
      80          44 :     PetscCall(VecScale(w,-1.0/beta[d]));
      81          44 :     PetscCall(VecResetArray(xx));
      82         132 :     for (i=0;i<d-1;i++) {
      83          88 :       PetscCall(VecPlaceArray(yy,py+i*m));
      84          88 :       PetscCall(MatMult(ctx->D[i],yy,ww));
      85          88 :       PetscCall(VecResetArray(yy));
      86          88 :       PetscCall(VecAXPY(w,-1.0,ww));
      87             :     }
      88             :   }
      89          84 :   PetscCall(VecPlaceArray(yy,py+(d-1)*m));
      90          84 :   PetscCall(KSPSolve(ctx->ksp[0],w,yy));
      91          84 :   PetscCall(NEPNLEIGSEvalNRTFunct(nep,d-1,sigma,t));
      92         252 :   for (i=0;i<d-1;i++) {
      93         168 :     PetscCall(VecPlaceArray(yyy,py+i*m));
      94         168 :     PetscCall(VecAXPY(yyy,t[i],yy));
      95         168 :     PetscCall(VecResetArray(yyy));
      96             :   }
      97          84 :   PetscCall(VecScale(yy,t[d-1]));
      98          84 :   PetscCall(VecResetArray(yy));
      99          84 :   PetscCall(VecRestoreArrayRead(x,&px));
     100          84 :   PetscCall(VecRestoreArray(y,&py));
     101          84 :   PetscCall(PetscFree(t));
     102          84 :   PetscFunctionReturn(PETSC_SUCCESS);
     103             : }
     104             : 
     105          66 : static PetscErrorCode MatMultTranspose_FullBasis_Sinvert(Mat M,Vec x,Vec y)
     106             : {
     107          66 :   NEP_NLEIGS        *ctx;
     108          66 :   NEP               nep;
     109          66 :   const PetscScalar *px;
     110          66 :   PetscScalar       *beta,*s,*xi,*t,*py,sigma;
     111          66 :   PetscInt          nmat,d,i,k,m;
     112          66 :   Vec               xx,yy,yyy,w,z0;
     113             : 
     114          66 :   PetscFunctionBegin;
     115          66 :   PetscCall(MatShellGetContext(M,&nep));
     116          66 :   ctx = (NEP_NLEIGS*)nep->data;
     117          66 :   beta = ctx->beta; s = ctx->s; xi = ctx->xi;
     118          66 :   sigma = ctx->shifts[0];
     119          66 :   nmat = ctx->nmat;
     120          66 :   d = nmat-1;
     121          66 :   m = nep->nloc;
     122          66 :   PetscCall(PetscMalloc1(ctx->nmat,&t));
     123          66 :   xx = ctx->w[0]; yy = ctx->w[1]; yyy=ctx->w[2];
     124          66 :   w = nep->work[0]; z0 = nep->work[1];
     125          66 :   PetscCall(VecGetArrayRead(x,&px));
     126          66 :   PetscCall(VecGetArray(y,&py));
     127          66 :   PetscCall(NEPNLEIGSEvalNRTFunct(nep,d,sigma,t));
     128          66 :   PetscCall(VecPlaceArray(xx,px+(d-1)*m));
     129          66 :   PetscCall(VecCopy(xx,w));
     130          66 :   PetscCall(VecScale(w,t[d-1]));
     131          66 :   PetscCall(VecResetArray(xx));
     132         198 :   for (i=0;i<d-1;i++) {
     133         132 :     PetscCall(VecPlaceArray(xx,px+i*m));
     134         132 :     PetscCall(VecAXPY(w,t[i],xx));
     135         132 :     PetscCall(VecResetArray(xx));
     136             :   }
     137          66 :   PetscCall(KSPSolveTranspose(ctx->ksp[0],w,z0));
     138             : 
     139          66 :   PetscCall(VecPlaceArray(yy,py));
     140          66 :   if (nep->fui==NEP_USER_INTERFACE_SPLIT) {
     141          40 :     PetscCall(VecZeroEntries(yy));
     142         160 :     for (k=0;k<nep->nt;k++) {
     143         120 :       PetscCall(MatMult(nep->A[k],z0,w));
     144         120 :       PetscCall(VecAXPY(yy,ctx->coeffD[k],w));
     145             :     }
     146          26 :   } else PetscCall(MatMultTranspose(ctx->D[0],z0,yy));
     147          66 :   PetscCall(VecPlaceArray(xx,px));
     148          66 :   PetscCall(VecAXPY(yy,-1.0,xx));
     149          66 :   PetscCall(VecResetArray(xx));
     150          66 :   PetscCall(VecScale(yy,-1.0/(s[0]-sigma)));
     151          66 :   PetscCall(VecResetArray(yy));
     152         132 :   for (i=2;i<d;i++) {
     153          66 :     PetscCall(VecPlaceArray(yy,py+(i-1)*m));
     154          66 :     if (nep->fui==NEP_USER_INTERFACE_SPLIT) {
     155          40 :       PetscCall(VecZeroEntries(yy));
     156         160 :       for (k=0;k<nep->nt;k++) {
     157         120 :         PetscCall(MatMult(nep->A[k],z0,w));
     158         120 :         PetscCall(VecAXPY(yy,ctx->coeffD[k+(i-1)*nep->nt],w));
     159             :       }
     160          26 :     } else PetscCall(MatMultTranspose(ctx->D[i-1],z0,yy));
     161          66 :     PetscCall(VecPlaceArray(yyy,py+(i-2)*m));
     162          66 :     PetscCall(VecAXPY(yy,beta[i-1]*(1.0-sigma/xi[i-2]),yyy));
     163          66 :     PetscCall(VecResetArray(yyy));
     164          66 :     PetscCall(VecPlaceArray(xx,px+(i-1)*m));
     165          66 :     PetscCall(VecAXPY(yy,-1.0,xx));
     166          66 :     PetscCall(VecResetArray(xx));
     167          66 :     PetscCall(VecScale(yy,-1.0/(s[i-1]-sigma)));
     168          66 :     PetscCall(VecResetArray(yy));
     169             :   }
     170          66 :   PetscCall(VecPlaceArray(yy,py+(d-1)*m));
     171          66 :   if (nep->fui==NEP_USER_INTERFACE_SPLIT) {
     172          40 :     PetscCall(VecZeroEntries(yy));
     173         160 :     for (k=0;k<nep->nt;k++) {
     174         120 :       PetscCall(MatMult(nep->A[k],z0,w));
     175         120 :       PetscCall(VecAXPY(yy,ctx->coeffD[k+d*nep->nt],w));
     176             :     }
     177          26 :   } else PetscCall(MatMultTranspose(ctx->D[d],z0,yy));
     178          66 :   PetscCall(VecScale(yy,-1.0/beta[d]));
     179          66 :   PetscCall(VecPlaceArray(yyy,py+(d-2)*m));
     180          66 :   PetscCall(VecAXPY(yy,beta[d-1]/xi[d-2],yyy));
     181          66 :   PetscCall(VecResetArray(yyy));
     182          66 :   PetscCall(VecResetArray(yy));
     183             : 
     184         132 :   for (i=d-2;i>0;i--) {
     185          66 :     PetscCall(VecPlaceArray(yyy,py+(i-1)*m));
     186          66 :     PetscCall(VecPlaceArray(yy,py+i*m));
     187          66 :     PetscCall(VecAXPY(yy,beta[i]/xi[i-1],yyy));
     188          66 :     PetscCall(VecResetArray(yyy));
     189          66 :     PetscCall(VecResetArray(yy));
     190             :   }
     191             : 
     192          66 :   PetscCall(VecRestoreArrayRead(x,&px));
     193          66 :   PetscCall(VecRestoreArray(y,&py));
     194          66 :   PetscCall(PetscFree(t));
     195          66 :   PetscFunctionReturn(PETSC_SUCCESS);
     196             : }
     197             : 
     198        1436 : static PetscErrorCode BackTransform_FullBasis(ST st,PetscInt n,PetscScalar *eigr,PetscScalar *eigi)
     199             : {
     200        1436 :   NEP            nep;
     201             : 
     202        1436 :   PetscFunctionBegin;
     203        1436 :   PetscCall(STShellGetContext(st,&nep));
     204        1436 :   PetscCall(NEPNLEIGSBackTransform((PetscObject)nep,n,eigr,eigi));
     205        1436 :   PetscFunctionReturn(PETSC_SUCCESS);
     206             : }
     207             : 
     208          84 : static PetscErrorCode Apply_FullBasis(ST st,Vec x,Vec y)
     209             : {
     210          84 :   NEP            nep;
     211          84 :   NEP_NLEIGS     *ctx;
     212             : 
     213          84 :   PetscFunctionBegin;
     214          84 :   PetscCall(STShellGetContext(st,&nep));
     215          84 :   ctx = (NEP_NLEIGS*)nep->data;
     216          84 :   PetscCall(MatMult(ctx->A,x,y));
     217          84 :   PetscFunctionReturn(PETSC_SUCCESS);
     218             : }
     219             : 
     220          66 : static PetscErrorCode ApplyTranspose_FullBasis(ST st,Vec x,Vec y)
     221             : {
     222          66 :   NEP            nep;
     223          66 :   NEP_NLEIGS     *ctx;
     224             : 
     225          66 :   PetscFunctionBegin;
     226          66 :   PetscCall(STShellGetContext(st,&nep));
     227          66 :   ctx = (NEP_NLEIGS*)nep->data;
     228          66 :   PetscCall(MatMultTranspose(ctx->A,x,y));
     229          66 :   PetscFunctionReturn(PETSC_SUCCESS);
     230             : }
     231             : 
     232           3 : PetscErrorCode NEPSetUp_NLEIGS_FullBasis(NEP nep)
     233             : {
     234           3 :   NEP_NLEIGS     *ctx=(NEP_NLEIGS*)nep->data;
     235           3 :   ST             st;
     236           3 :   Mat            Q;
     237           3 :   PetscInt       i=0,deg=ctx->nmat-1;
     238           3 :   PetscBool      trackall,istrivial,ks;
     239           3 :   PetscScalar    *epsarray,*neparray;
     240           3 :   Vec            veps,w=NULL;
     241           3 :   EPSWhich       which;
     242             : 
     243           3 :   PetscFunctionBegin;
     244           3 :   PetscCheck(ctx->nshifts==0,PetscObjectComm((PetscObject)nep),PETSC_ERR_SUP,"The full-basis option is not supported with rational Krylov");
     245           3 :   if (!ctx->eps) PetscCall(NEPNLEIGSGetEPS(nep,&ctx->eps));
     246           3 :   PetscCall(EPSGetST(ctx->eps,&st));
     247           3 :   PetscCall(EPSSetTarget(ctx->eps,nep->target));
     248           3 :   PetscCall(STSetDefaultShift(st,nep->target));
     249           3 :   if (!((PetscObject)ctx->eps)->type_name) PetscCall(EPSSetType(ctx->eps,EPSKRYLOVSCHUR));
     250             :   else {
     251           3 :     PetscCall(PetscObjectTypeCompare((PetscObject)ctx->eps,EPSKRYLOVSCHUR,&ks));
     252           3 :     PetscCheck(ks,PetscObjectComm((PetscObject)nep),PETSC_ERR_SUP,"Full-basis option only implemented for Krylov-Schur");
     253             :   }
     254           3 :   PetscCall(STSetType(st,STSHELL));
     255           3 :   PetscCall(STShellSetContext(st,nep));
     256           3 :   PetscCall(STShellSetBackTransform(st,BackTransform_FullBasis));
     257           3 :   PetscCall(KSPGetOperators(ctx->ksp[0],&Q,NULL));
     258           3 :   PetscCall(MatCreateVecsEmpty(Q,&ctx->w[0],&ctx->w[1]));
     259           3 :   PetscCall(MatCreateVecsEmpty(Q,&ctx->w[2],&ctx->w[3]));
     260           3 :   PetscCall(MatCreateShell(PetscObjectComm((PetscObject)nep),deg*nep->nloc,deg*nep->nloc,deg*nep->n,deg*nep->n,nep,&ctx->A));
     261           3 :   PetscCall(MatShellSetOperation(ctx->A,MATOP_MULT,(void(*)(void))MatMult_FullBasis_Sinvert));
     262           3 :   PetscCall(MatShellSetOperation(ctx->A,MATOP_MULT_TRANSPOSE,(void(*)(void))MatMultTranspose_FullBasis_Sinvert));
     263           3 :   PetscCall(STShellSetApply(st,Apply_FullBasis));
     264           3 :   PetscCall(STShellSetApplyTranspose(st,ApplyTranspose_FullBasis));
     265           3 :   PetscCall(EPSSetOperators(ctx->eps,ctx->A,NULL));
     266           3 :   PetscCall(EPSSetProblemType(ctx->eps,EPS_NHEP));
     267           3 :   switch (nep->which) {
     268             :     case NEP_TARGET_MAGNITUDE:   which = EPS_TARGET_MAGNITUDE; break;
     269           0 :     case NEP_TARGET_REAL:        which = EPS_TARGET_REAL; break;
     270           0 :     case NEP_TARGET_IMAGINARY:   which = EPS_TARGET_IMAGINARY; break;
     271           0 :     case NEP_WHICH_USER:         which = EPS_WHICH_USER;
     272           0 :       PetscCall(EPSSetEigenvalueComparison(ctx->eps,nep->sc->comparison,nep->sc->comparisonctx));
     273             :       break;
     274           0 :     default: SETERRQ(PetscObjectComm((PetscObject)nep),PETSC_ERR_SUP,"Should set a target selection in NEPSetWhichEigenpairs()");
     275             :   }
     276           3 :   PetscCall(EPSSetWhichEigenpairs(ctx->eps,which));
     277           3 :   PetscCall(RGIsTrivial(nep->rg,&istrivial));
     278           3 :   if (!istrivial) PetscCall(EPSSetRG(ctx->eps,nep->rg));
     279           3 :   PetscCall(EPSSetDimensions(ctx->eps,nep->nev,nep->ncv,nep->mpd));
     280           3 :   PetscCall(EPSSetTolerances(ctx->eps,SlepcDefaultTol(nep->tol),nep->max_it));
     281           3 :   PetscCall(EPSSetTwoSided(ctx->eps,nep->twosided));
     282             :   /* Transfer the trackall option from pep to eps */
     283           3 :   PetscCall(NEPGetTrackAll(nep,&trackall));
     284           3 :   PetscCall(EPSSetTrackAll(ctx->eps,trackall));
     285             : 
     286             :   /* process initial vector */
     287           3 :   if (nep->nini<0) {
     288           2 :     PetscCall(VecCreateMPI(PetscObjectComm((PetscObject)ctx->eps),deg*nep->nloc,deg*nep->n,&veps));
     289           2 :     PetscCall(VecGetArray(veps,&epsarray));
     290           8 :     for (i=0;i<deg;i++) {
     291           6 :       if (i<-nep->nini) {
     292           2 :         PetscCall(VecGetArray(nep->IS[i],&neparray));
     293           2 :         PetscCall(PetscArraycpy(epsarray+i*nep->nloc,neparray,nep->nloc));
     294           2 :         PetscCall(VecRestoreArray(nep->IS[i],&neparray));
     295             :       } else {
     296           4 :         if (!w) PetscCall(VecDuplicate(nep->IS[0],&w));
     297           4 :         PetscCall(VecSetRandom(w,NULL));
     298           4 :         PetscCall(VecGetArray(w,&neparray));
     299           4 :         PetscCall(PetscArraycpy(epsarray+i*nep->nloc,neparray,nep->nloc));
     300           6 :         PetscCall(VecRestoreArray(w,&neparray));
     301             :       }
     302             :     }
     303           2 :     PetscCall(VecRestoreArray(veps,&epsarray));
     304           2 :     PetscCall(EPSSetInitialSpace(ctx->eps,1,&veps));
     305           2 :     PetscCall(VecDestroy(&veps));
     306           2 :     PetscCall(VecDestroy(&w));
     307           2 :     PetscCall(SlepcBasisDestroy_Private(&nep->nini,&nep->IS));
     308             :   }
     309             : 
     310           3 :   PetscCall(EPSSetUp(ctx->eps));
     311           3 :   PetscCall(EPSGetDimensions(ctx->eps,NULL,&nep->ncv,&nep->mpd));
     312           3 :   PetscCall(EPSGetTolerances(ctx->eps,NULL,&nep->max_it));
     313           3 :   PetscCall(NEPAllocateSolution(nep,0));
     314           3 :   PetscFunctionReturn(PETSC_SUCCESS);
     315             : }
     316             : 
     317             : /*
     318             :    NEPNLEIGSExtract_None - Extracts the first block of the basis
     319             :    and normalizes the columns.
     320             : */
     321           3 : static PetscErrorCode NEPNLEIGSExtract_None(NEP nep,EPS eps)
     322             : {
     323           3 :   PetscInt          i,k,m,d;
     324           3 :   const PetscScalar *px;
     325           3 :   PetscScalar       sigma=nep->target,*b;
     326           3 :   Mat               A;
     327           3 :   Vec               xxr,xxi=NULL,w,t,xx;
     328           3 :   PetscReal         norm;
     329           3 :   NEP_NLEIGS        *ctx=(NEP_NLEIGS*)nep->data;
     330             : 
     331           3 :   PetscFunctionBegin;
     332           3 :   d = ctx->nmat-1;
     333           3 :   PetscCall(EPSGetOperators(eps,&A,NULL));
     334           3 :   PetscCall(MatCreateVecs(A,&xxr,NULL));
     335             : #if !defined(PETSC_USE_COMPLEX)
     336           3 :   PetscCall(VecDuplicate(xxr,&xxi));
     337             : #endif
     338           3 :   w = nep->work[0];
     339          19 :   for (i=0;i<nep->nconv;i++) {
     340          16 :     PetscCall(EPSGetEigenvector(eps,i,xxr,xxi));
     341          16 :     PetscCall(VecGetArrayRead(xxr,&px));
     342          16 :     PetscCall(VecPlaceArray(w,px));
     343          16 :     PetscCall(BVInsertVec(nep->V,i,w));
     344          16 :     PetscCall(BVNormColumn(nep->V,i,NORM_2,&norm));
     345          16 :     PetscCall(BVScaleColumn(nep->V,i,1.0/norm));
     346          16 :     PetscCall(VecResetArray(w));
     347          16 :     PetscCall(VecRestoreArrayRead(xxr,&px));
     348             :   }
     349           3 :   if (nep->twosided) {
     350           2 :     PetscCall(PetscMalloc1(ctx->nmat,&b));
     351           2 :     PetscCall(NEPNLEIGSEvalNRTFunct(nep,d,sigma,b));
     352           2 :     m = nep->nloc;
     353           2 :     xx = ctx->w[0];
     354           2 :     w = nep->work[0]; t = nep->work[1];
     355          14 :     for (k=0;k<nep->nconv;k++) {
     356          12 :       PetscCall(EPSGetLeftEigenvector(eps,k,xxr,xxi));
     357          12 :       PetscCall(VecGetArrayRead(xxr,&px));
     358          12 :       PetscCall(VecPlaceArray(xx,px+(d-1)*m));
     359          12 :       PetscCall(VecCopy(xx,w));
     360          12 :       PetscCall(VecScale(w,PetscConj(b[d-1])));
     361          12 :       PetscCall(VecResetArray(xx));
     362          36 :       for (i=0;i<d-1;i++) {
     363          24 :         PetscCall(VecPlaceArray(xx,px+i*m));
     364          24 :         PetscCall(VecAXPY(w,PetscConj(b[i]),xx));
     365          24 :         PetscCall(VecResetArray(xx));
     366             :       }
     367          12 :       PetscCall(VecConjugate(w));
     368          12 :       PetscCall(KSPSolveTranspose(ctx->ksp[0],w,t));
     369          12 :       PetscCall(VecConjugate(t));
     370          12 :       PetscCall(BVInsertVec(nep->W,k,t));
     371          12 :       PetscCall(BVNormColumn(nep->W,k,NORM_2,&norm));
     372          12 :       PetscCall(BVScaleColumn(nep->W,k,1.0/norm));
     373          12 :       PetscCall(VecRestoreArrayRead(xxr,&px));
     374             :     }
     375           2 :     PetscCall(PetscFree(b));
     376             :   }
     377           3 :   PetscCall(VecDestroy(&xxr));
     378             : #if !defined(PETSC_USE_COMPLEX)
     379           3 :   PetscCall(VecDestroy(&xxi));
     380             : #endif
     381           3 :   PetscFunctionReturn(PETSC_SUCCESS);
     382             : }
     383             : 
     384           3 : PetscErrorCode NEPSolve_NLEIGS_FullBasis(NEP nep)
     385             : {
     386           3 :   NEP_NLEIGS     *ctx = (NEP_NLEIGS*)nep->data;
     387           3 :   PetscInt       i;
     388           3 :   PetscScalar    eigi=0.0;
     389             : 
     390           3 :   PetscFunctionBegin;
     391           3 :   PetscCall(EPSSolve(ctx->eps));
     392           3 :   PetscCall(EPSGetConverged(ctx->eps,&nep->nconv));
     393           3 :   PetscCall(EPSGetIterationNumber(ctx->eps,&nep->its));
     394           3 :   PetscCall(EPSGetConvergedReason(ctx->eps,(EPSConvergedReason*)&nep->reason));
     395             : 
     396             :   /* recover eigenvalues */
     397          19 :   for (i=0;i<nep->nconv;i++) {
     398          16 :     PetscCall(EPSGetEigenpair(ctx->eps,i,&nep->eigr[i],&eigi,NULL,NULL));
     399             : #if !defined(PETSC_USE_COMPLEX)
     400          16 :     PetscCheck(eigi==0.0,PetscObjectComm((PetscObject)nep),PETSC_ERR_SUP,"Complex value requires complex arithmetic");
     401             : #endif
     402             :   }
     403           3 :   PetscCall(NEPNLEIGSExtract_None(nep,ctx->eps));
     404           3 :   PetscFunctionReturn(PETSC_SUCCESS);
     405             : }
     406             : 
     407           0 : PetscErrorCode NEPNLEIGSSetEPS_NLEIGS(NEP nep,EPS eps)
     408             : {
     409           0 :   NEP_NLEIGS     *ctx=(NEP_NLEIGS*)nep->data;
     410             : 
     411           0 :   PetscFunctionBegin;
     412           0 :   PetscCall(PetscObjectReference((PetscObject)eps));
     413           0 :   PetscCall(EPSDestroy(&ctx->eps));
     414           0 :   ctx->eps = eps;
     415           0 :   nep->state = NEP_STATE_INITIAL;
     416           0 :   PetscFunctionReturn(PETSC_SUCCESS);
     417             : }
     418             : 
     419             : /*@
     420             :    NEPNLEIGSSetEPS - Associate an eigensolver object (EPS) to the NLEIGS solver.
     421             : 
     422             :    Collective
     423             : 
     424             :    Input Parameters:
     425             : +  nep - nonlinear eigenvalue solver
     426             : -  eps - the eigensolver object
     427             : 
     428             :    Level: advanced
     429             : 
     430             : .seealso: NEPNLEIGSGetEPS()
     431             : @*/
     432           0 : PetscErrorCode NEPNLEIGSSetEPS(NEP nep,EPS eps)
     433             : {
     434           0 :   PetscFunctionBegin;
     435           0 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     436           0 :   PetscValidHeaderSpecific(eps,EPS_CLASSID,2);
     437           0 :   PetscCheckSameComm(nep,1,eps,2);
     438           0 :   PetscTryMethod(nep,"NEPNLEIGSSetEPS_C",(NEP,EPS),(nep,eps));
     439           0 :   PetscFunctionReturn(PETSC_SUCCESS);
     440             : }
     441             : 
     442           6 : static PetscErrorCode EPSMonitor_NLEIGS(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *ctx)
     443             : {
     444           6 :   NEP            nep = (NEP)ctx;
     445           6 :   PetscInt       i,nv = PetscMin(nest,nep->ncv);
     446             : 
     447           6 :   PetscFunctionBegin;
     448         129 :   for (i=0;i<nv;i++) {
     449         123 :     nep->eigr[i]   = eigr[i];
     450         123 :     nep->eigi[i]   = eigi[i];
     451         123 :     nep->errest[i] = errest[i];
     452             :   }
     453           6 :   PetscCall(NEPNLEIGSBackTransform((PetscObject)nep,nv,nep->eigr,nep->eigi));
     454           6 :   PetscCall(NEPMonitor(nep,its,nconv,nep->eigr,nep->eigi,nep->errest,nest));
     455           6 :   PetscFunctionReturn(PETSC_SUCCESS);
     456             : }
     457             : 
     458           3 : PetscErrorCode NEPNLEIGSGetEPS_NLEIGS(NEP nep,EPS *eps)
     459             : {
     460           3 :   NEP_NLEIGS     *ctx=(NEP_NLEIGS*)nep->data;
     461             : 
     462           3 :   PetscFunctionBegin;
     463           3 :   if (!ctx->eps) {
     464           3 :     PetscCall(EPSCreate(PetscObjectComm((PetscObject)nep),&ctx->eps));
     465           3 :     PetscCall(PetscObjectIncrementTabLevel((PetscObject)ctx->eps,(PetscObject)nep,1));
     466           3 :     PetscCall(EPSSetOptionsPrefix(ctx->eps,((PetscObject)nep)->prefix));
     467           3 :     PetscCall(EPSAppendOptionsPrefix(ctx->eps,"nep_nleigs_"));
     468           3 :     PetscCall(PetscObjectSetOptions((PetscObject)ctx->eps,((PetscObject)nep)->options));
     469           3 :     PetscCall(EPSMonitorSet(ctx->eps,EPSMonitor_NLEIGS,nep,NULL));
     470             :   }
     471           3 :   *eps = ctx->eps;
     472           3 :   PetscFunctionReturn(PETSC_SUCCESS);
     473             : }
     474             : 
     475             : /*@
     476             :    NEPNLEIGSGetEPS - Retrieve the eigensolver object (EPS) associated
     477             :    to the nonlinear eigenvalue solver.
     478             : 
     479             :    Collective
     480             : 
     481             :    Input Parameter:
     482             : .  nep - nonlinear eigenvalue solver
     483             : 
     484             :    Output Parameter:
     485             : .  eps - the eigensolver object
     486             : 
     487             :    Level: advanced
     488             : 
     489             : .seealso: NEPNLEIGSSetEPS()
     490             : @*/
     491           3 : PetscErrorCode NEPNLEIGSGetEPS(NEP nep,EPS *eps)
     492             : {
     493           3 :   PetscFunctionBegin;
     494           3 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     495           3 :   PetscAssertPointer(eps,2);
     496           3 :   PetscUseMethod(nep,"NEPNLEIGSGetEPS_C",(NEP,EPS*),(nep,eps));
     497           3 :   PetscFunctionReturn(PETSC_SUCCESS);
     498             : }

Generated by: LCOV version 1.14