Actual source code: linear.c
slepc-3.10.1 2018-10-23
Report Typos and Errors

      1: /*
      2:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      3:    SLEPc - Scalable Library for Eigenvalue Problem Computations
      4:    Copyright (c) 2002-2018, Universitat Politecnica de Valencia, Spain

      6:    This file is part of SLEPc.
      7:    SLEPc is distributed under a 2-clause BSD license (see LICENSE).
      8:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      9: */
     10: /*
     11:    Explicit linearization for polynomial eigenproblems
     12: */

     14: #include <slepc/private/pepimpl.h>         /*I "slepcpep.h" I*/
     15: #include "linearp.h"

     17: static PetscErrorCode MatMult_Linear_Shift(Mat M,Vec x,Vec y)
     18: {
     19:   PetscErrorCode    ierr;
     20:   PEP_LINEAR        *ctx;
     21:   PEP               pep;
     22:   const PetscScalar *px;
     23:   PetscScalar       *py,a,sigma=0.0;
     24:   PetscInt          nmat,deg,i,m;
     25:   Vec               x1,x2,x3,y1,aux;
     26:   PetscReal         *ca,*cb,*cg;
     27:   PetscBool         flg;

     30:   MatShellGetContext(M,(void**)&ctx);
     31:   pep = ctx->pep;
     32:   STGetTransform(pep->st,&flg);
     33:   if (!flg) {
     34:     STGetShift(pep->st,&sigma);
     35:   }
     36:   nmat = pep->nmat;
     37:   deg = nmat-1;
     38:   m = pep->nloc;
     39:   ca = pep->pbc;
     40:   cb = pep->pbc+nmat;
     41:   cg = pep->pbc+2*nmat;
     42:   x1=ctx->w[0];x2=ctx->w[1];x3=ctx->w[2];y1=ctx->w[3];aux=ctx->w[4];

     44:   VecSet(y,0.0);
     45:   VecGetArrayRead(x,&px);
     46:   VecGetArray(y,&py);
     47:   a = 1.0;

     49:   /* first block */
     50:   VecPlaceArray(x2,px);
     51:   VecPlaceArray(x3,px+m);
     52:   VecPlaceArray(y1,py);
     53:   VecAXPY(y1,cb[0]-sigma,x2);
     54:   VecAXPY(y1,ca[0],x3);
     55:   VecResetArray(x2);
     56:   VecResetArray(x3);
     57:   VecResetArray(y1);

     59:   /* inner blocks */
     60:   for (i=1;i<deg-1;i++) {
     61:     VecPlaceArray(x1,px+(i-1)*m);
     62:     VecPlaceArray(x2,px+i*m);
     63:     VecPlaceArray(x3,px+(i+1)*m);
     64:     VecPlaceArray(y1,py+i*m);
     65:     VecAXPY(y1,cg[i],x1);
     66:     VecAXPY(y1,cb[i]-sigma,x2);
     67:     VecAXPY(y1,ca[i],x3);
     68:     VecResetArray(x1);
     69:     VecResetArray(x2);
     70:     VecResetArray(x3);
     71:     VecResetArray(y1);
     72:   }

     74:   /* last block */
     75:   VecPlaceArray(y1,py+(deg-1)*m);
     76:   for (i=0;i<deg;i++) {
     77:     VecPlaceArray(x1,px+i*m);
     78:     STMatMult(pep->st,i,x1,aux);
     79:     VecAXPY(y1,a,aux);
     80:     VecResetArray(x1);
     81:     a *= pep->sfactor;
     82:   }
     83:   VecCopy(y1,aux);
     84:   STMatSolve(pep->st,aux,y1);
     85:   VecScale(y1,-ca[deg-1]/a);
     86:   VecPlaceArray(x1,px+(deg-2)*m);
     87:   VecPlaceArray(x2,px+(deg-1)*m);
     88:   VecAXPY(y1,cg[deg-1],x1);
     89:   VecAXPY(y1,cb[deg-1]-sigma,x2);
     90:   VecResetArray(x1);
     91:   VecResetArray(x2);
     92:   VecResetArray(y1);

     94:   VecRestoreArrayRead(x,&px);
     95:   VecRestoreArray(y,&py);
     96:   return(0);
     97: }

     99: static PetscErrorCode MatMult_Linear_Sinvert(Mat M,Vec x,Vec y)
    100: {
    101:   PetscErrorCode    ierr;
    102:   PEP_LINEAR        *ctx;
    103:   PEP               pep;
    104:   const PetscScalar *px;
    105:   PetscScalar       *py,a,sigma,t=1.0,tp=0.0,tt;
    106:   PetscInt          nmat,deg,i,m;
    107:   Vec               x1,y1,y2,y3,aux,aux2;
    108:   PetscReal         *ca,*cb,*cg;

    111:   MatShellGetContext(M,(void**)&ctx);
    112:   pep = ctx->pep;
    113:   nmat = pep->nmat;
    114:   deg = nmat-1;
    115:   m = pep->nloc;
    116:   ca = pep->pbc;
    117:   cb = pep->pbc+nmat;
    118:   cg = pep->pbc+2*nmat;
    119:   x1=ctx->w[0];y1=ctx->w[1];y2=ctx->w[2];y3=ctx->w[3];aux=ctx->w[4];aux2=ctx->w[5];
    120:   EPSGetTarget(ctx->eps,&sigma);
    121:   VecSet(y,0.0);
    122:   VecGetArrayRead(x,&px);
    123:   VecGetArray(y,&py);
    124:   a = pep->sfactor;

    126:   /* first block */
    127:   VecPlaceArray(x1,px);
    128:   VecPlaceArray(y1,py+m);
    129:   VecCopy(x1,y1);
    130:   VecScale(y1,1.0/ca[0]);
    131:   VecResetArray(x1);
    132:   VecResetArray(y1);

    134:   /* second block */
    135:   if (deg>2) {
    136:     VecPlaceArray(x1,px+m);
    137:     VecPlaceArray(y1,py+m);
    138:     VecPlaceArray(y2,py+2*m);
    139:     VecCopy(x1,y2);
    140:     VecAXPY(y2,sigma-cb[1],y1);
    141:     VecScale(y2,1.0/ca[1]);
    142:     VecResetArray(x1);
    143:     VecResetArray(y1);
    144:     VecResetArray(y2);
    145:   }

    147:   /* inner blocks */
    148:   for (i=2;i<deg-1;i++) {
    149:     VecPlaceArray(x1,px+i*m);
    150:     VecPlaceArray(y1,py+(i-1)*m);
    151:     VecPlaceArray(y2,py+i*m);
    152:     VecPlaceArray(y3,py+(i+1)*m);
    153:     VecCopy(x1,y3);
    154:     VecAXPY(y3,sigma-cb[i],y2);
    155:     VecAXPY(y3,-cg[i],y1);
    156:     VecScale(y3,1.0/ca[i]);
    157:     VecResetArray(x1);
    158:     VecResetArray(y1);
    159:     VecResetArray(y2);
    160:     VecResetArray(y3);
    161:   }

    163:   /* last block */
    164:   VecPlaceArray(y1,py);
    165:   for (i=0;i<deg-2;i++) {
    166:     VecPlaceArray(y2,py+(i+1)*m);
    167:     STMatMult(pep->st,i+1,y2,aux);
    168:     VecAXPY(y1,a,aux);
    169:     VecResetArray(y2);
    170:     a *= pep->sfactor;
    171:   }
    172:   i = deg-2;
    173:   VecPlaceArray(y2,py+(i+1)*m);
    174:   VecPlaceArray(y3,py+i*m);
    175:   VecCopy(y2,aux2);
    176:   VecAXPY(aux2,cg[i+1]/ca[i+1],y3);
    177:   STMatMult(pep->st,i+1,aux2,aux);
    178:   VecAXPY(y1,a,aux);
    179:   VecResetArray(y2);
    180:   VecResetArray(y3);
    181:   a *= pep->sfactor;
    182:   i = deg-1;
    183:   VecPlaceArray(x1,px+i*m);
    184:   VecPlaceArray(y3,py+i*m);
    185:   VecCopy(x1,aux2);
    186:   VecAXPY(aux2,sigma-cb[i],y3);
    187:   VecScale(aux2,1.0/ca[i]);
    188:   STMatMult(pep->st,i+1,aux2,aux);
    189:   VecAXPY(y1,a,aux);
    190:   VecResetArray(x1);
    191:   VecResetArray(y3);

    193:   VecCopy(y1,aux);
    194:   STMatSolve(pep->st,aux,y1);
    195:   VecScale(y1,-1.0);

    197:   /* final update */
    198:   for (i=1;i<deg;i++) {
    199:     VecPlaceArray(y2,py+i*m);
    200:     tt = t;
    201:     t = ((sigma-cb[i-1])*t-cg[i-1]*tp)/ca[i-1]; /* i-th basis polynomial */
    202:     tp = tt;
    203:     VecAXPY(y2,t,y1);
    204:     VecResetArray(y2);
    205:   }
    206:   VecResetArray(y1);

    208:   VecRestoreArrayRead(x,&px);
    209:   VecRestoreArray(y,&py);
    210:   return(0);
    211: }

    213: static PetscErrorCode BackTransform_Linear(ST st,PetscInt n,PetscScalar *eigr,PetscScalar *eigi)
    214: {
    216:   PEP_LINEAR     *ctx;
    217:   ST             stctx;

    220:   STShellGetContext(st,(void**)&ctx);
    221:   PEPGetST(ctx->pep,&stctx);
    222:   STBackTransform(stctx,n,eigr,eigi);
    223:   return(0);
    224: }

    226: /*
    227:    Dummy backtransform operation
    228:  */
    229: static PetscErrorCode BackTransform_Skip(ST st,PetscInt n,PetscScalar *eigr,PetscScalar *eigi)
    230: {
    232:   return(0);
    233: }

    235: static PetscErrorCode Apply_Linear(ST st,Vec x,Vec y)
    236: {
    238:   PEP_LINEAR     *ctx;

    241:   STShellGetContext(st,(void**)&ctx);
    242:   MatMult(ctx->A,x,y);
    243:   return(0);
    244: }

    246: PetscErrorCode PEPSetUp_Linear(PEP pep)
    247: {
    249:   PEP_LINEAR     *ctx = (PEP_LINEAR*)pep->data;
    250:   ST             st;
    251:   PetscInt       i=0,deg=pep->nmat-1;
    252:   EPSWhich       which = EPS_LARGEST_MAGNITUDE;
    253:   EPSProblemType ptype;
    254:   PetscBool      trackall,istrivial,transf,shift,sinv,ks;
    255:   PetscScalar    sigma,*epsarray,*peparray;
    256:   Vec            veps,w=NULL;
    257:   /* function tables */
    258:   PetscErrorCode (*fcreate[][2])(MPI_Comm,PEP_LINEAR*,Mat*) = {
    259:     { MatCreateExplicit_Linear_NA, MatCreateExplicit_Linear_NB },
    260:     { MatCreateExplicit_Linear_SA, MatCreateExplicit_Linear_SB },
    261:     { MatCreateExplicit_Linear_HA, MatCreateExplicit_Linear_HB },
    262:   };

    265:   if (pep->stopping!=PEPStoppingBasic) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"User-defined stopping test not supported");
    266:   pep->lineariz = PETSC_TRUE;
    267:   STGetTransform(pep->st,&transf);
    268:   PetscObjectTypeCompare((PetscObject)pep->st,STSHIFT,&shift);
    269:   PetscObjectTypeCompare((PetscObject)pep->st,STSINVERT,&sinv);
    270:   if (!shift && !sinv) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"Only STSHIFT and STSINVERT spectral transformations can be used");
    271:   if (!pep->which) {
    272:     if (sinv) pep->which = PEP_TARGET_MAGNITUDE;
    273:     else pep->which = PEP_LARGEST_MAGNITUDE;
    274:   }
    275:   if (pep->which==PEP_ALL) SETERRQ(PetscObjectComm((PetscObject)pep),1,"Wrong value of pep->which");
    276:   STSetUp(pep->st);
    277:   if (!ctx->eps) { PEPLinearGetEPS(pep,&ctx->eps); }
    278:   EPSGetST(ctx->eps,&st);
    279:   if (!transf && !ctx->usereps) { EPSSetTarget(ctx->eps,pep->target); }
    280:   if (sinv && !transf && !ctx->usereps) { STSetDefaultShift(st,pep->target); }
    281:   /* compute scale factor if not set by user */
    282:   PEPComputeScaleFactor(pep);

    284:   if (ctx->explicitmatrix) {
    285:     if (transf) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"Explicit matrix option is not implemented with st-transform flag active");
    286:     if (pep->nmat!=3) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"Explicit matrix option only available for quadratic problems");
    287:     if (pep->basis!=PEP_BASIS_MONOMIAL) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"Explicit matrix option not implemented for non-monomial bases");
    288:     if (pep->scale==PEP_SCALE_DIAGONAL || pep->scale==PEP_SCALE_BOTH) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"Diagonal scaling not allowed in PEPLINEAR with explicit matrices");
    289:     if (sinv && !transf) { STSetType(st,STSINVERT); }
    290:     RGPushScale(pep->rg,1.0/pep->sfactor);
    291:     STGetMatrixTransformed(pep->st,0,&ctx->K);
    292:     STGetMatrixTransformed(pep->st,1,&ctx->C);
    293:     STGetMatrixTransformed(pep->st,2,&ctx->M);
    294:     ctx->sfactor = pep->sfactor;
    295:     ctx->dsfactor = pep->dsfactor;

    297:     MatDestroy(&ctx->A);
    298:     MatDestroy(&ctx->B);
    299:     VecDestroy(&ctx->w[0]);
    300:     VecDestroy(&ctx->w[1]);
    301:     VecDestroy(&ctx->w[2]);
    302:     VecDestroy(&ctx->w[3]);

    304:     switch (pep->problem_type) {
    305:       case PEP_GENERAL:    i = 0; break;
    306:       case PEP_HERMITIAN:
    307:       case PEP_HYPERBOLIC: i = 1; break;
    308:       case PEP_GYROSCOPIC: i = 2; break;
    309:     }

    311:     (*fcreate[i][0])(PetscObjectComm((PetscObject)pep),ctx,&ctx->A);
    312:     (*fcreate[i][1])(PetscObjectComm((PetscObject)pep),ctx,&ctx->B);
    313:     PetscLogObjectParent((PetscObject)pep,(PetscObject)ctx->A);
    314:     PetscLogObjectParent((PetscObject)pep,(PetscObject)ctx->B);

    316:   } else {   /* implicit matrix */
    317:     if (pep->problem_type!=PEP_GENERAL) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"Must use the explicit matrix option if problem type is not general");
    318:     if (!((PetscObject)(ctx->eps))->type_name) {
    319:       EPSSetType(ctx->eps,EPSKRYLOVSCHUR);
    320:     } else {
    321:       PetscObjectTypeCompare((PetscObject)ctx->eps,EPSKRYLOVSCHUR,&ks);
    322:       if (!ks) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"Implicit matrix option only implemented for Krylov-Schur");
    323:     }
    324:     if (ctx->alpha!=1.0 || ctx->beta!=0.0) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"Implicit matrix option does not support changing alpha,beta parameters of the linearization");
    325:     STSetType(st,STSHELL);
    326:     STShellSetContext(st,(PetscObject)ctx);
    327:     if (!transf) { STShellSetBackTransform(st,BackTransform_Linear); }
    328:     else { STShellSetBackTransform(st,BackTransform_Skip); }
    329:     MatCreateVecsEmpty(pep->A[0],&ctx->w[0],&ctx->w[1]);
    330:     MatCreateVecsEmpty(pep->A[0],&ctx->w[2],&ctx->w[3]);
    331:     MatCreateVecs(pep->A[0],&ctx->w[4],&ctx->w[5]);
    332:     PetscLogObjectParents(pep,6,ctx->w);
    333:     MatCreateShell(PetscObjectComm((PetscObject)pep),deg*pep->nloc,deg*pep->nloc,deg*pep->n,deg*pep->n,ctx,&ctx->A);
    334:     if (sinv && !transf) {
    335:       MatShellSetOperation(ctx->A,MATOP_MULT,(void(*)(void))MatMult_Linear_Sinvert);
    336:     } else {
    337:       MatShellSetOperation(ctx->A,MATOP_MULT,(void(*)(void))MatMult_Linear_Shift);
    338:     }
    339:     STShellSetApply(st,Apply_Linear);
    340:     PetscLogObjectParent((PetscObject)pep,(PetscObject)ctx->A);
    341:     ctx->pep = pep;

    343:     PEPBasisCoefficients(pep,pep->pbc);
    344:     if (!transf) {
    345:       PetscMalloc1(pep->nmat,&pep->solvematcoeffs);
    346:       PetscLogObjectMemory((PetscObject)pep,pep->nmat*sizeof(PetscScalar));
    347:       if (sinv) {
    348:         PEPEvaluateBasis(pep,pep->target,0,pep->solvematcoeffs,NULL);
    349:       } else {
    350:         for (i=0;i<deg;i++) pep->solvematcoeffs[i] = 0.0;
    351:         pep->solvematcoeffs[deg] = 1.0;
    352:       }
    353:       STScaleShift(pep->st,1.0/pep->sfactor);
    354:       RGPushScale(pep->rg,1.0/pep->sfactor);
    355:     }
    356:     if (pep->sfactor!=1.0) {
    357:       for (i=0;i<pep->nmat;i++) {
    358:         pep->pbc[pep->nmat+i] /= pep->sfactor;
    359:         pep->pbc[2*pep->nmat+i] /= pep->sfactor*pep->sfactor;
    360:       }
    361:     }
    362:   }

    364:   EPSSetOperators(ctx->eps,ctx->A,ctx->B);
    365:   EPSGetProblemType(ctx->eps,&ptype);
    366:   if (!ptype) {
    367:     if (ctx->explicitmatrix) {
    368:       EPSSetProblemType(ctx->eps,EPS_GNHEP);
    369:     } else {
    370:       EPSSetProblemType(ctx->eps,EPS_NHEP);
    371:     }
    372:   }
    373:   if (!ctx->usereps) {
    374:     if (transf) which = EPS_LARGEST_MAGNITUDE;
    375:     else {
    376:       switch (pep->which) {
    377:           case PEP_LARGEST_MAGNITUDE:  which = EPS_LARGEST_MAGNITUDE; break;
    378:           case PEP_SMALLEST_MAGNITUDE: which = EPS_SMALLEST_MAGNITUDE; break;
    379:           case PEP_LARGEST_REAL:       which = EPS_LARGEST_REAL; break;
    380:           case PEP_SMALLEST_REAL:      which = EPS_SMALLEST_REAL; break;
    381:           case PEP_LARGEST_IMAGINARY:  which = EPS_LARGEST_IMAGINARY; break;
    382:           case PEP_SMALLEST_IMAGINARY: which = EPS_SMALLEST_IMAGINARY; break;
    383:           case PEP_TARGET_MAGNITUDE:   which = EPS_TARGET_MAGNITUDE; break;
    384:           case PEP_TARGET_REAL:        which = EPS_TARGET_REAL; break;
    385:           case PEP_TARGET_IMAGINARY:   which = EPS_TARGET_IMAGINARY; break;
    386:           case PEP_ALL:                which = EPS_ALL; break;
    387:           case PEP_WHICH_USER:         which = EPS_WHICH_USER;
    388:             EPSSetEigenvalueComparison(ctx->eps,pep->sc->comparison,pep->sc->comparisonctx);
    389:             break;
    390:       }
    391:     }
    392:     EPSSetWhichEigenpairs(ctx->eps,which);

    394:     EPSSetDimensions(ctx->eps,pep->nev,pep->ncv?pep->ncv:PETSC_DEFAULT,pep->mpd?pep->mpd:PETSC_DEFAULT);
    395:     EPSSetTolerances(ctx->eps,pep->tol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL:pep->tol,pep->max_it?pep->max_it:PETSC_DEFAULT);
    396:   }
    397:   RGIsTrivial(pep->rg,&istrivial);
    398:   if (!istrivial) {
    399:     if (transf) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"PEPLINEAR does not support a nontrivial region with st-transform");
    400:     EPSSetRG(ctx->eps,pep->rg);
    401:   }
    402:   /* Transfer the trackall option from pep to eps */
    403:   PEPGetTrackAll(pep,&trackall);
    404:   EPSSetTrackAll(ctx->eps,trackall);

    406:   /* temporary change of target */
    407:   if (pep->sfactor!=1.0) {
    408:     EPSGetTarget(ctx->eps,&sigma);
    409:     EPSSetTarget(ctx->eps,sigma/pep->sfactor);
    410:   }

    412:   /* process initial vector */
    413:   if (pep->nini<0) {
    414:     VecCreateMPI(PetscObjectComm((PetscObject)ctx->eps),deg*pep->nloc,deg*pep->n,&veps);
    415:     VecGetArray(veps,&epsarray);
    416:     for (i=0;i<deg;i++) {
    417:       if (i<-pep->nini) {
    418:         VecGetArray(pep->IS[i],&peparray);
    419:         PetscMemcpy(epsarray+i*pep->nloc,peparray,pep->nloc*sizeof(PetscScalar));
    420:         VecRestoreArray(pep->IS[i],&peparray);
    421:       } else {
    422:         if (!w) { VecDuplicate(pep->IS[0],&w); }
    423:         VecSetRandom(w,NULL);
    424:         VecGetArray(w,&peparray);
    425:         PetscMemcpy(epsarray+i*pep->nloc,peparray,pep->nloc*sizeof(PetscScalar));
    426:         VecRestoreArray(w,&peparray);
    427:       }
    428:     }
    429:     VecRestoreArray(veps,&epsarray);
    430:     EPSSetInitialSpace(ctx->eps,1,&veps);
    431:     VecDestroy(&veps);
    432:     VecDestroy(&w);
    433:     SlepcBasisDestroy_Private(&pep->nini,&pep->IS);
    434:   }

    436:   EPSSetUp(ctx->eps);
    437:   EPSGetDimensions(ctx->eps,NULL,&pep->ncv,&pep->mpd);
    438:   EPSGetTolerances(ctx->eps,NULL,&pep->max_it);
    439:   PEPAllocateSolution(pep,0);
    440:   return(0);
    441: }

    443: /*
    444:    PEPLinearExtract_Residual - Auxiliary routine that copies the solution of the
    445:    linear eigenproblem to the PEP object. The eigenvector of the generalized
    446:    problem is supposed to be
    447:                                z = [  x  ]
    448:                                    [ l*x ]
    449:    The eigenvector is taken from z(1:n) or z(n+1:2*n) depending on the explicitly
    450:    computed residual norm.
    451:    Finally, x is normalized so that ||x||_2 = 1.
    452: */
    453: static PetscErrorCode PEPLinearExtract_Residual(PEP pep,EPS eps)
    454: {
    455:   PetscErrorCode    ierr;
    456:   PetscInt          i,k;
    457:   const PetscScalar *px;
    458:   PetscScalar       *er=pep->eigr,*ei=pep->eigi;
    459:   PetscReal         rn1,rn2;
    460:   Vec               xr,xi=NULL,wr;
    461:   Mat               A;
    462: #if !defined(PETSC_USE_COMPLEX)
    463:   Vec               wi;
    464:   const PetscScalar *py;
    465: #endif

    468: #if defined(PETSC_USE_COMPLEX)
    469:   PEPSetWorkVecs(pep,2);
    470: #else
    471:   PEPSetWorkVecs(pep,4);
    472: #endif
    473:   EPSGetOperators(eps,&A,NULL);
    474:   MatCreateVecs(A,&xr,NULL);
    475:   MatCreateVecsEmpty(pep->A[0],&wr,NULL);
    476: #if !defined(PETSC_USE_COMPLEX)
    477:   VecDuplicate(xr,&xi);
    478:   VecDuplicateEmpty(wr,&wi);
    479: #endif
    480:   for (i=0;i<pep->nconv;i++) {
    481:     EPSGetEigenpair(eps,i,NULL,NULL,xr,xi);
    482: #if !defined(PETSC_USE_COMPLEX)
    483:     if (ei[i]!=0.0) {   /* complex conjugate pair */
    484:       VecGetArrayRead(xr,&px);
    485:       VecGetArrayRead(xi,&py);
    486:       VecPlaceArray(wr,px);
    487:       VecPlaceArray(wi,py);
    488:       VecNormalizeComplex(wr,wi,PETSC_TRUE,NULL);
    489:       PEPComputeResidualNorm_Private(pep,er[i],ei[i],wr,wi,pep->work,&rn1);
    490:       BVInsertVec(pep->V,i,wr);
    491:       BVInsertVec(pep->V,i+1,wi);
    492:       for (k=1;k<pep->nmat-1;k++) {
    493:         VecResetArray(wr);
    494:         VecResetArray(wi);
    495:         VecPlaceArray(wr,px+k*pep->nloc);
    496:         VecPlaceArray(wi,py+k*pep->nloc);
    497:         VecNormalizeComplex(wr,wi,PETSC_TRUE,NULL);
    498:         PEPComputeResidualNorm_Private(pep,er[i],ei[i],wr,wi,pep->work,&rn2);
    499:         if (rn1>rn2) {
    500:           BVInsertVec(pep->V,i,wr);
    501:           BVInsertVec(pep->V,i+1,wi);
    502:           rn1 = rn2;
    503:         }
    504:       }
    505:       VecResetArray(wr);
    506:       VecResetArray(wi);
    507:       VecRestoreArrayRead(xr,&px);
    508:       VecRestoreArrayRead(xi,&py);
    509:       i++;
    510:     } else   /* real eigenvalue */
    511: #endif
    512:     {
    513:       VecGetArrayRead(xr,&px);
    514:       VecPlaceArray(wr,px);
    515:       VecNormalizeComplex(wr,NULL,PETSC_FALSE,NULL);
    516:       PEPComputeResidualNorm_Private(pep,er[i],ei[i],wr,NULL,pep->work,&rn1);
    517:       BVInsertVec(pep->V,i,wr);
    518:       for (k=1;k<pep->nmat-1;k++) {
    519:         VecResetArray(wr);
    520:         VecPlaceArray(wr,px+k*pep->nloc);
    521:         VecNormalizeComplex(wr,NULL,PETSC_FALSE,NULL);
    522:         PEPComputeResidualNorm_Private(pep,er[i],ei[i],wr,NULL,pep->work,&rn2);
    523:         if (rn1>rn2) {
    524:           BVInsertVec(pep->V,i,wr);
    525:           rn1 = rn2;
    526:         }
    527:       }
    528:       VecResetArray(wr);
    529:       VecRestoreArrayRead(xr,&px);
    530:     }
    531:   }
    532:   VecDestroy(&wr);
    533:   VecDestroy(&xr);
    534: #if !defined(PETSC_USE_COMPLEX)
    535:   VecDestroy(&wi);
    536:   VecDestroy(&xi);
    537: #endif
    538:   return(0);
    539: }

    541: /*
    542:    PEPLinearExtract_None - Same as PEPLinearExtract_Norm but always takes
    543:    the first block.
    544: */
    545: static PetscErrorCode PEPLinearExtract_None(PEP pep,EPS eps)
    546: {
    547:   PetscErrorCode    ierr;
    548:   PetscInt          i;
    549:   const PetscScalar *px;
    550:   Mat               A;
    551:   Vec               xr,xi,w;
    552: #if !defined(PETSC_USE_COMPLEX)
    553:   PetscScalar       *ei=pep->eigi;
    554: #endif

    557:   EPSGetOperators(eps,&A,NULL);
    558:   MatCreateVecs(A,&xr,NULL);
    559:   VecDuplicate(xr,&xi);
    560:   MatCreateVecsEmpty(pep->A[0],&w,NULL);
    561:   for (i=0;i<pep->nconv;i++) {
    562:     EPSGetEigenpair(eps,i,NULL,NULL,xr,xi);
    563: #if !defined(PETSC_USE_COMPLEX)
    564:     if (ei[i]!=0.0) {   /* complex conjugate pair */
    565:       VecGetArrayRead(xr,&px);
    566:       VecPlaceArray(w,px);
    567:       BVInsertVec(pep->V,i,w);
    568:       VecResetArray(w);
    569:       VecRestoreArrayRead(xr,&px);
    570:       VecGetArrayRead(xi,&px);
    571:       VecPlaceArray(w,px);
    572:       BVInsertVec(pep->V,i+1,w);
    573:       VecResetArray(w);
    574:       VecRestoreArrayRead(xi,&px);
    575:       i++;
    576:     } else   /* real eigenvalue */
    577: #endif
    578:     {
    579:       VecGetArrayRead(xr,&px);
    580:       VecPlaceArray(w,px);
    581:       BVInsertVec(pep->V,i,w);
    582:       VecResetArray(w);
    583:       VecRestoreArrayRead(xr,&px);
    584:     }
    585:   }
    586:   VecDestroy(&w);
    587:   VecDestroy(&xr);
    588:   VecDestroy(&xi);
    589:   return(0);
    590: }

    592: /*
    593:    PEPLinearExtract_Norm - Auxiliary routine that copies the solution of the
    594:    linear eigenproblem to the PEP object. The eigenvector of the generalized
    595:    problem is supposed to be
    596:                                z = [  x  ]
    597:                                    [ l*x ]
    598:    If |l|<1.0, the eigenvector is taken from z(1:n), otherwise from z(n+1:2*n).
    599:    Finally, x is normalized so that ||x||_2 = 1.
    600: */
    601: static PetscErrorCode PEPLinearExtract_Norm(PEP pep,EPS eps)
    602: {
    603:   PetscErrorCode    ierr;
    604:   PetscInt          i,offset;
    605:   const PetscScalar *px;
    606:   PetscScalar       *er=pep->eigr;
    607:   Mat               A;
    608:   Vec               xr,xi=NULL,w;
    609: #if !defined(PETSC_USE_COMPLEX)
    610:   PetscScalar       *ei=pep->eigi;
    611: #endif

    614:   EPSGetOperators(eps,&A,NULL);
    615:   MatCreateVecs(A,&xr,NULL);
    616: #if !defined(PETSC_USE_COMPLEX)
    617:   VecDuplicate(xr,&xi);
    618: #endif
    619:   MatCreateVecsEmpty(pep->A[0],&w,NULL);
    620:   for (i=0;i<pep->nconv;i++) {
    621:     EPSGetEigenpair(eps,i,NULL,NULL,xr,xi);
    622:     if (SlepcAbsEigenvalue(er[i],ei[i])>1.0) offset = (pep->nmat-2)*pep->nloc;
    623:     else offset = 0;
    624: #if !defined(PETSC_USE_COMPLEX)
    625:     if (ei[i]!=0.0) {   /* complex conjugate pair */
    626:       VecGetArrayRead(xr,&px);
    627:       VecPlaceArray(w,px+offset);
    628:       BVInsertVec(pep->V,i,w);
    629:       VecResetArray(w);
    630:       VecRestoreArrayRead(xr,&px);
    631:       VecGetArrayRead(xi,&px);
    632:       VecPlaceArray(w,px+offset);
    633:       BVInsertVec(pep->V,i+1,w);
    634:       VecResetArray(w);
    635:       VecRestoreArrayRead(xi,&px);
    636:       i++;
    637:     } else /* real eigenvalue */
    638: #endif
    639:     {
    640:       VecGetArrayRead(xr,&px);
    641:       VecPlaceArray(w,px+offset);
    642:       BVInsertVec(pep->V,i,w);
    643:       VecResetArray(w);
    644:       VecRestoreArrayRead(xr,&px);
    645:     }
    646:   }
    647:   VecDestroy(&w);
    648:   VecDestroy(&xr);
    649: #if !defined(PETSC_USE_COMPLEX)
    650:   VecDestroy(&xi);
    651: #endif
    652:   return(0);
    653: }

    655: PetscErrorCode PEPExtractVectors_Linear(PEP pep)
    656: {
    658:   PEP_LINEAR     *ctx = (PEP_LINEAR*)pep->data;

    661:   switch (pep->extract) {
    662:   case PEP_EXTRACT_NONE:
    663:     PEPLinearExtract_None(pep,ctx->eps);
    664:     break;
    665:   case PEP_EXTRACT_NORM:
    666:     PEPLinearExtract_Norm(pep,ctx->eps);
    667:     break;
    668:   case PEP_EXTRACT_RESIDUAL:
    669:     PEPLinearExtract_Residual(pep,ctx->eps);
    670:     break;
    671:   case PEP_EXTRACT_STRUCTURED:
    672:     SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_SUP,"Extraction not implemented in this solver");
    673:   }
    674:   return(0);
    675: }

    677: PetscErrorCode PEPSolve_Linear(PEP pep)
    678: {
    680:   PEP_LINEAR     *ctx = (PEP_LINEAR*)pep->data;
    681:   PetscScalar    sigma;
    682:   PetscBool      flg;
    683:   PetscInt       i;

    686:   EPSSolve(ctx->eps);
    687:   EPSGetConverged(ctx->eps,&pep->nconv);
    688:   EPSGetIterationNumber(ctx->eps,&pep->its);
    689:   EPSGetConvergedReason(ctx->eps,(EPSConvergedReason*)&pep->reason);

    691:   /* recover eigenvalues */
    692:   for (i=0;i<pep->nconv;i++) {
    693:     EPSGetEigenpair(ctx->eps,i,&pep->eigr[i],&pep->eigi[i],NULL,NULL);
    694:     pep->eigr[i] *= pep->sfactor;
    695:     pep->eigi[i] *= pep->sfactor;
    696:   }

    698:   /* restore target */
    699:   EPSGetTarget(ctx->eps,&sigma);
    700:   EPSSetTarget(ctx->eps,sigma*pep->sfactor);

    702:   STGetTransform(pep->st,&flg);
    703:   if (flg && pep->ops->backtransform) {
    704:     (*pep->ops->backtransform)(pep);
    705:   }
    706:   if (pep->sfactor!=1.0) {
    707:     /* Restore original values */
    708:     for (i=0;i<pep->nmat;i++){
    709:       pep->pbc[pep->nmat+i] *= pep->sfactor;
    710:       pep->pbc[2*pep->nmat+i] *= pep->sfactor*pep->sfactor;
    711:     }
    712:     if (!flg && !ctx->explicitmatrix) {
    713:       STScaleShift(pep->st,pep->sfactor);
    714:     }
    715:   }
    716:   if (ctx->explicitmatrix || !flg) {
    717:     RGPopScale(pep->rg);
    718:   }
    719:   return(0);
    720: }

    722: static PetscErrorCode EPSMonitor_Linear(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *ctx)
    723: {
    724:   PEP            pep = (PEP)ctx;

    728:   PEPMonitor(pep,its,nconv,eigr,eigi,errest,nest);
    729:   return(0);
    730: }

    732: PetscErrorCode PEPSetFromOptions_Linear(PetscOptionItems *PetscOptionsObject,PEP pep)
    733: {
    735:   PetscBool      set,val;
    736:   PetscInt       k;
    737:   PetscReal      array[2]={0,0};
    738:   PetscBool      flg;
    739:   PEP_LINEAR     *ctx = (PEP_LINEAR*)pep->data;

    742:   PetscOptionsHead(PetscOptionsObject,"PEP Linear Options");

    744:     k = 2;
    745:     PetscOptionsRealArray("-pep_linear_linearization","Parameters of the linearization","PEPLinearSetLinearization",array,&k,&flg);
    746:     if (flg) {
    747:       PEPLinearSetLinearization(pep,array[0],array[1]);
    748:     }

    750:     PetscOptionsBool("-pep_linear_explicitmatrix","Use explicit matrix in linearization","PEPLinearSetExplicitMatrix",ctx->explicitmatrix,&val,&set);
    751:     if (set) { PEPLinearSetExplicitMatrix(pep,val); }

    753:   PetscOptionsTail();

    755:   if (!ctx->eps) { PEPLinearGetEPS(pep,&ctx->eps); }
    756:   EPSSetFromOptions(ctx->eps);
    757:   return(0);
    758: }

    760: static PetscErrorCode PEPLinearSetLinearization_Linear(PEP pep,PetscReal alpha,PetscReal beta)
    761: {
    762:   PEP_LINEAR *ctx = (PEP_LINEAR*)pep->data;

    765:   if (beta==0.0 && alpha==0.0) SETERRQ(PetscObjectComm((PetscObject)pep),PETSC_ERR_ARG_WRONG,"Parameters alpha and beta cannot be zero simultaneously");
    766:   ctx->alpha = alpha;
    767:   ctx->beta  = beta;
    768:   return(0);
    769: }

    771: /*@
    772:    PEPLinearSetLinearization - Set the coefficients that define
    773:    the linearization of a quadratic eigenproblem.

    775:    Logically Collective on PEP

    777:    Input Parameters:
    778: +  pep   - polynomial eigenvalue solver
    779: .  alpha - first parameter of the linearization
    780: -  beta  - second parameter of the linearization

    782:    Options Database Key:
    783: .  -pep_linear_linearization <alpha,beta> - Sets the coefficients

    785:    Notes:
    786:    Cannot pass zero for both alpha and beta. The default values are
    787:    alpha=1 and beta=0.

    789:    Level: advanced

    791: .seealso: PEPLinearGetLinearization()
    792: @*/
    793: PetscErrorCode PEPLinearSetLinearization(PEP pep,PetscReal alpha,PetscReal beta)
    794: {

    801:   PetscTryMethod(pep,"PEPLinearSetLinearization_C",(PEP,PetscReal,PetscReal),(pep,alpha,beta));
    802:   return(0);
    803: }

    805: static PetscErrorCode PEPLinearGetLinearization_Linear(PEP pep,PetscReal *alpha,PetscReal *beta)
    806: {
    807:   PEP_LINEAR *ctx = (PEP_LINEAR*)pep->data;

    810:   if (alpha) *alpha = ctx->alpha;
    811:   if (beta)  *beta  = ctx->beta;
    812:   return(0);
    813: }

    815: /*@
    816:    PEPLinearGetLinearization - Returns the coefficients that define
    817:    the linearization of a quadratic eigenproblem.

    819:    Not Collective

    821:    Input Parameter:
    822: .  pep  - polynomial eigenvalue solver

    824:    Output Parameters:
    825: +  alpha - the first parameter of the linearization
    826: -  beta  - the second parameter of the linearization

    828:    Level: advanced

    830: .seealso: PEPLinearSetLinearization()
    831: @*/
    832: PetscErrorCode PEPLinearGetLinearization(PEP pep,PetscReal *alpha,PetscReal *beta)
    833: {

    838:   PetscUseMethod(pep,"PEPLinearGetLinearization_C",(PEP,PetscReal*,PetscReal*),(pep,alpha,beta));
    839:   return(0);
    840: }

    842: static PetscErrorCode PEPLinearSetExplicitMatrix_Linear(PEP pep,PetscBool explicitmatrix)
    843: {
    844:   PEP_LINEAR *ctx = (PEP_LINEAR*)pep->data;

    847:   if (ctx->explicitmatrix != explicitmatrix) {
    848:     ctx->explicitmatrix = explicitmatrix;
    849:     pep->state = PEP_STATE_INITIAL;
    850:   }
    851:   return(0);
    852: }

    854: /*@
    855:    PEPLinearSetExplicitMatrix - Indicate if the matrices A and B for the
    856:    linearization of the problem must be built explicitly.

    858:    Logically Collective on PEP

    860:    Input Parameters:
    861: +  pep      - polynomial eigenvalue solver
    862: -  explicit - boolean flag indicating if the matrices are built explicitly

    864:    Options Database Key:
    865: .  -pep_linear_explicitmatrix <boolean> - Indicates the boolean flag

    867:    Level: advanced

    869: .seealso: PEPLinearGetExplicitMatrix()
    870: @*/
    871: PetscErrorCode PEPLinearSetExplicitMatrix(PEP pep,PetscBool explicitmatrix)
    872: {

    878:   PetscTryMethod(pep,"PEPLinearSetExplicitMatrix_C",(PEP,PetscBool),(pep,explicitmatrix));
    879:   return(0);
    880: }

    882: static PetscErrorCode PEPLinearGetExplicitMatrix_Linear(PEP pep,PetscBool *explicitmatrix)
    883: {
    884:   PEP_LINEAR *ctx = (PEP_LINEAR*)pep->data;

    887:   *explicitmatrix = ctx->explicitmatrix;
    888:   return(0);
    889: }

    891: /*@
    892:    PEPLinearGetExplicitMatrix - Returns the flag indicating if the matrices
    893:    A and B for the linearization are built explicitly.

    895:    Not Collective

    897:    Input Parameter:
    898: .  pep  - polynomial eigenvalue solver

    900:    Output Parameter:
    901: .  explicitmatrix - the mode flag

    903:    Level: advanced

    905: .seealso: PEPLinearSetExplicitMatrix()
    906: @*/
    907: PetscErrorCode PEPLinearGetExplicitMatrix(PEP pep,PetscBool *explicitmatrix)
    908: {

    914:   PetscUseMethod(pep,"PEPLinearGetExplicitMatrix_C",(PEP,PetscBool*),(pep,explicitmatrix));
    915:   return(0);
    916: }

    918: static PetscErrorCode PEPLinearSetEPS_Linear(PEP pep,EPS eps)
    919: {
    921:   PEP_LINEAR     *ctx = (PEP_LINEAR*)pep->data;

    924:   PetscObjectReference((PetscObject)eps);
    925:   EPSDestroy(&ctx->eps);
    926:   ctx->eps = eps;
    927:   ctx->usereps = PETSC_TRUE;
    928:   PetscLogObjectParent((PetscObject)pep,(PetscObject)ctx->eps);
    929:   pep->state = PEP_STATE_INITIAL;
    930:   return(0);
    931: }

    933: /*@
    934:    PEPLinearSetEPS - Associate an eigensolver object (EPS) to the
    935:    polynomial eigenvalue solver.

    937:    Collective on PEP

    939:    Input Parameters:
    940: +  pep - polynomial eigenvalue solver
    941: -  eps - the eigensolver object

    943:    Level: advanced

    945: .seealso: PEPLinearGetEPS()
    946: @*/
    947: PetscErrorCode PEPLinearSetEPS(PEP pep,EPS eps)
    948: {

    955:   PetscTryMethod(pep,"PEPLinearSetEPS_C",(PEP,EPS),(pep,eps));
    956:   return(0);
    957: }

    959: static PetscErrorCode PEPLinearGetEPS_Linear(PEP pep,EPS *eps)
    960: {
    962:   PEP_LINEAR     *ctx = (PEP_LINEAR*)pep->data;

    965:   if (!ctx->eps) {
    966:     EPSCreate(PetscObjectComm((PetscObject)pep),&ctx->eps);
    967:     PetscObjectIncrementTabLevel((PetscObject)ctx->eps,(PetscObject)pep,1);
    968:     EPSSetOptionsPrefix(ctx->eps,((PetscObject)pep)->prefix);
    969:     EPSAppendOptionsPrefix(ctx->eps,"pep_linear_");
    970:     PetscLogObjectParent((PetscObject)pep,(PetscObject)ctx->eps);
    971:     EPSMonitorSet(ctx->eps,EPSMonitor_Linear,pep,NULL);
    972:   }
    973:   *eps = ctx->eps;
    974:   return(0);
    975: }

    977: /*@
    978:    PEPLinearGetEPS - Retrieve the eigensolver object (EPS) associated
    979:    to the polynomial eigenvalue solver.

    981:    Not Collective

    983:    Input Parameter:
    984: .  pep - polynomial eigenvalue solver

    986:    Output Parameter:
    987: .  eps - the eigensolver object

    989:    Level: advanced

    991: .seealso: PEPLinearSetEPS()
    992: @*/
    993: PetscErrorCode PEPLinearGetEPS(PEP pep,EPS *eps)
    994: {

    1000:   PetscUseMethod(pep,"PEPLinearGetEPS_C",(PEP,EPS*),(pep,eps));
    1001:   return(0);
    1002: }

    1004: PetscErrorCode PEPView_Linear(PEP pep,PetscViewer viewer)
    1005: {
    1007:   PEP_LINEAR     *ctx = (PEP_LINEAR*)pep->data;
    1008:   PetscBool      isascii;

    1011:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    1012:   if (isascii) {
    1013:     if (!ctx->eps) { PEPLinearGetEPS(pep,&ctx->eps); }
    1014:     PetscViewerASCIIPrintf(viewer,"  %s matrices\n",ctx->explicitmatrix? "explicit": "implicit");
    1015:     PetscViewerASCIIPrintf(viewer,"  linearization parameters: alpha=%g beta=%g\n",(double)ctx->alpha,(double)ctx->beta);
    1016:     EPSView(ctx->eps,viewer);
    1017:   }
    1018:   return(0);
    1019: }

    1021: PetscErrorCode PEPReset_Linear(PEP pep)
    1022: {
    1024:   PEP_LINEAR     *ctx = (PEP_LINEAR*)pep->data;

    1027:   if (!ctx->eps) { EPSReset(ctx->eps); }
    1028:   MatDestroy(&ctx->A);
    1029:   MatDestroy(&ctx->B);
    1030:   VecDestroy(&ctx->w[0]);
    1031:   VecDestroy(&ctx->w[1]);
    1032:   VecDestroy(&ctx->w[2]);
    1033:   VecDestroy(&ctx->w[3]);
    1034:   VecDestroy(&ctx->w[4]);
    1035:   VecDestroy(&ctx->w[5]);
    1036:   return(0);
    1037: }

    1039: PetscErrorCode PEPDestroy_Linear(PEP pep)
    1040: {
    1042:   PEP_LINEAR     *ctx = (PEP_LINEAR*)pep->data;

    1045:   EPSDestroy(&ctx->eps);
    1046:   PetscFree(pep->data);
    1047:   PetscObjectComposeFunction((PetscObject)pep,"PEPLinearSetLinearization_C",NULL);
    1048:   PetscObjectComposeFunction((PetscObject)pep,"PEPLinearGetLinearization_C",NULL);
    1049:   PetscObjectComposeFunction((PetscObject)pep,"PEPLinearSetEPS_C",NULL);
    1050:   PetscObjectComposeFunction((PetscObject)pep,"PEPLinearGetEPS_C",NULL);
    1051:   PetscObjectComposeFunction((PetscObject)pep,"PEPLinearSetExplicitMatrix_C",NULL);
    1052:   PetscObjectComposeFunction((PetscObject)pep,"PEPLinearGetExplicitMatrix_C",NULL);
    1053:   return(0);
    1054: }

    1056: PETSC_EXTERN PetscErrorCode PEPCreate_Linear(PEP pep)
    1057: {
    1059:   PEP_LINEAR     *ctx;

    1062:   PetscNewLog(pep,&ctx);
    1063:   ctx->explicitmatrix = PETSC_FALSE;
    1064:   pep->data = (void*)ctx;
    1065:   ctx->alpha = 1.0;
    1066:   ctx->beta  = 0.0;

    1068:   pep->ops->solve          = PEPSolve_Linear;
    1069:   pep->ops->setup          = PEPSetUp_Linear;
    1070:   pep->ops->setfromoptions = PEPSetFromOptions_Linear;
    1071:   pep->ops->destroy        = PEPDestroy_Linear;
    1072:   pep->ops->reset          = PEPReset_Linear;
    1073:   pep->ops->view           = PEPView_Linear;
    1074:   pep->ops->backtransform  = PEPBackTransform_Default;
    1075:   pep->ops->computevectors = PEPComputeVectors_Default;
    1076:   pep->ops->extractvectors = PEPExtractVectors_Linear;

    1078:   PetscObjectComposeFunction((PetscObject)pep,"PEPLinearSetLinearization_C",PEPLinearSetLinearization_Linear);
    1079:   PetscObjectComposeFunction((PetscObject)pep,"PEPLinearGetLinearization_C",PEPLinearGetLinearization_Linear);
    1080:   PetscObjectComposeFunction((PetscObject)pep,"PEPLinearSetEPS_C",PEPLinearSetEPS_Linear);
    1081:   PetscObjectComposeFunction((PetscObject)pep,"PEPLinearGetEPS_C",PEPLinearGetEPS_Linear);
    1082:   PetscObjectComposeFunction((PetscObject)pep,"PEPLinearSetExplicitMatrix_C",PEPLinearSetExplicitMatrix_Linear);
    1083:   PetscObjectComposeFunction((PetscObject)pep,"PEPLinearGetExplicitMatrix_C",PEPLinearGetExplicitMatrix_Linear);
    1084:   return(0);
    1085: }