Date: 2021-02-01T14:41:54+00:00

Actual source code: epssetup.c
slepc-3.14.2 2021-02-01
Report Typos and Errors

      1: /*
      2:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      3:    SLEPc - Scalable Library for Eigenvalue Problem Computations
      4:    Copyright (c) 2002-2020, 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:    EPS routines related to problem setup
     12: */

     14: #include <slepc/private/epsimpl.h>

     16: /*
     17:    Let the solver choose the ST type that should be used by default,
     18:    otherwise set it to SHIFT.
     19:    This is called at EPSSetFromOptions (before STSetFromOptions)
     20:    and also at EPSSetUp (in case EPSSetFromOptions was not called).
     21: */
     22: PetscErrorCode EPSSetDefaultST(EPS eps)
     23: {

     27:   if (eps->ops->setdefaultst) { (*eps->ops->setdefaultst)(eps); }
     28:   if (!((PetscObject)eps->st)->type_name) {
     29:     STSetType(eps->st,STSHIFT);
     30:   }
     31:   return(0);
     32: }

     34: /*
     35:    This is done by preconditioned eigensolvers that use the PC only.
     36:    It sets STPRECOND with KSPPREONLY.
     37: */
     38: PetscErrorCode EPSSetDefaultST_Precond(EPS eps)
     39: {
     41:   KSP            ksp;

     44:   if (!((PetscObject)eps->st)->type_name) {
     45:     STSetType(eps->st,STPRECOND);
     46:   }
     47:   STGetKSP(eps->st,&ksp);
     48:   if (!((PetscObject)ksp)->type_name) {
     49:     KSPSetType(ksp,KSPPREONLY);
     50:   }
     51:   return(0);
     52: }

     54: /*
     55:    This is done by preconditioned eigensolvers that can also use the KSP.
     56:    It sets STPRECOND with the default KSP (GMRES) and maxit=5.
     57: */
     58: PetscErrorCode EPSSetDefaultST_GMRES(EPS eps)
     59: {
     61:   KSP            ksp;

     64:   if (!((PetscObject)eps->st)->type_name) {
     65:     STSetType(eps->st,STPRECOND);
     66:   }
     67:   STPrecondSetKSPHasMat(eps->st,PETSC_TRUE);
     68:   STGetKSP(eps->st,&ksp);
     69:   if (!((PetscObject)ksp)->type_name) {
     70:     KSPSetType(ksp,KSPGMRES);
     71:     KSPSetTolerances(ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,5);
     72:   }
     73:   return(0);
     74: }

     76: /*
     77:    This is for direct eigensolvers that work with A and B directly, so
     78:    no need to factorize B.
     79: */
     80: PetscErrorCode EPSSetDefaultST_NoFactor(EPS eps)
     81: {
     83:   KSP            ksp;
     84:   PC             pc;

     87:   if (!((PetscObject)eps->st)->type_name) {
     88:     STSetType(eps->st,STSHIFT);
     89:   }
     90:   STGetKSP(eps->st,&ksp);
     91:   if (!((PetscObject)ksp)->type_name) {
     92:     KSPSetType(ksp,KSPPREONLY);
     93:   }
     94:   KSPGetPC(ksp,&pc);
     95:   if (!((PetscObject)pc)->type_name) {
     96:     PCSetType(pc,PCNONE);
     97:   }
     98:   return(0);
     99: }

    101: /*
    102:    Check that the ST selected by the user is compatible with the EPS solver and options
    103: */
    104: PetscErrorCode EPSCheckCompatibleST(EPS eps)
    105: {
    107:   PetscBool      precond,shift,sinvert,cayley,lyapii;
    108: #if defined(PETSC_USE_COMPLEX)
    109:   PetscScalar    sigma;
    110: #endif

    113:   PetscObjectTypeCompare((PetscObject)eps->st,STPRECOND,&precond);
    114:   PetscObjectTypeCompare((PetscObject)eps->st,STSHIFT,&shift);
    115:   PetscObjectTypeCompare((PetscObject)eps->st,STSINVERT,&sinvert);
    116:   PetscObjectTypeCompare((PetscObject)eps->st,STCAYLEY,&cayley);

    118:   /* preconditioned eigensolvers */
    119:   if (eps->categ==EPS_CATEGORY_PRECOND && !precond) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"This solver requires ST=PRECOND");
    120:   if (eps->categ!=EPS_CATEGORY_PRECOND && precond) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"STPRECOND is intended for preconditioned eigensolvers only");

    122:   /* harmonic extraction */
    123:   if (!(precond || shift) && eps->extraction && eps->extraction!=EPS_RITZ) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Cannot use a spectral transformation combined with harmonic extraction");

    125:   /* real shifts in Hermitian problems */
    126: #if defined(PETSC_USE_COMPLEX)
    127:   STGetShift(eps->st,&sigma);
    128:   if (eps->ishermitian && PetscImaginaryPart(sigma) != 0.0) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Hermitian problems are not compatible with complex shifts");
    129: #endif

    131:   /* Cayley with PGNHEP */
    132:   if (cayley && eps->problem_type == EPS_PGNHEP) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Cayley spectral transformation is not compatible with PGNHEP");

    134:   /* make sure that the user does not specify smallest magnitude with shift-and-invert */
    135:   if ((cayley || sinvert) && (eps->categ==EPS_CATEGORY_KRYLOV || eps->categ==EPS_CATEGORY_OTHER)) {
    136:     PetscObjectTypeCompare((PetscObject)eps,EPSLYAPII,&lyapii);
    137:     if (!lyapii && eps->which!=EPS_TARGET_MAGNITUDE && eps->which!=EPS_TARGET_REAL && eps->which!=EPS_TARGET_IMAGINARY && eps->which!=EPS_ALL && eps->which!=EPS_WHICH_USER) SETERRQ(PetscObjectComm((PetscObject)eps),1,"Shift-and-invert requires a target 'which' (see EPSSetWhichEigenpairs), for instance -st_type sinvert -eps_target 0 -eps_target_magnitude");
    138:   }
    139:   return(0);
    140: }

    142: /*
    143:    EPSSetUpSort_Basic: configure the EPS sorting criterion according to 'which'
    144: */
    145: PetscErrorCode EPSSetUpSort_Basic(EPS eps)
    146: {
    148:   switch (eps->which) {
    149:     case EPS_LARGEST_MAGNITUDE:
    150:       eps->sc->comparison    = SlepcCompareLargestMagnitude;
    151:       eps->sc->comparisonctx = NULL;
    152:       break;
    153:     case EPS_SMALLEST_MAGNITUDE:
    154:       eps->sc->comparison    = SlepcCompareSmallestMagnitude;
    155:       eps->sc->comparisonctx = NULL;
    156:       break;
    157:     case EPS_LARGEST_REAL:
    158:       eps->sc->comparison    = SlepcCompareLargestReal;
    159:       eps->sc->comparisonctx = NULL;
    160:       break;
    161:     case EPS_SMALLEST_REAL:
    162:       eps->sc->comparison    = SlepcCompareSmallestReal;
    163:       eps->sc->comparisonctx = NULL;
    164:       break;
    165:     case EPS_LARGEST_IMAGINARY:
    166:       eps->sc->comparison    = SlepcCompareLargestImaginary;
    167:       eps->sc->comparisonctx = NULL;
    168:       break;
    169:     case EPS_SMALLEST_IMAGINARY:
    170:       eps->sc->comparison    = SlepcCompareSmallestImaginary;
    171:       eps->sc->comparisonctx = NULL;
    172:       break;
    173:     case EPS_TARGET_MAGNITUDE:
    174:       eps->sc->comparison    = SlepcCompareTargetMagnitude;
    175:       eps->sc->comparisonctx = &eps->target;
    176:       break;
    177:     case EPS_TARGET_REAL:
    178:       eps->sc->comparison    = SlepcCompareTargetReal;
    179:       eps->sc->comparisonctx = &eps->target;
    180:       break;
    181:     case EPS_TARGET_IMAGINARY:
    182: #if defined(PETSC_USE_COMPLEX)
    183:       eps->sc->comparison    = SlepcCompareTargetImaginary;
    184:       eps->sc->comparisonctx = &eps->target;
    185: #endif
    186:       break;
    187:     case EPS_ALL:
    188:       eps->sc->comparison    = SlepcCompareSmallestReal;
    189:       eps->sc->comparisonctx = NULL;
    190:       break;
    191:     case EPS_WHICH_USER:
    192:       break;
    193:   }
    194:   eps->sc->map    = NULL;
    195:   eps->sc->mapobj = NULL;
    196:   return(0);
    197: }

    199: /*
    200:    EPSSetUpSort_Default: configure both EPS and DS sorting criterion
    201: */
    202: PetscErrorCode EPSSetUpSort_Default(EPS eps)
    203: {
    205:   SlepcSC        sc;
    206:   PetscBool      istrivial;

    209:   /* fill sorting criterion context */
    210:   EPSSetUpSort_Basic(eps);
    211:   /* fill sorting criterion for DS */
    212:   DSGetSlepcSC(eps->ds,&sc);
    213:   RGIsTrivial(eps->rg,&istrivial);
    214:   sc->rg            = istrivial? NULL: eps->rg;
    215:   sc->comparison    = eps->sc->comparison;
    216:   sc->comparisonctx = eps->sc->comparisonctx;
    217:   sc->map           = SlepcMap_ST;
    218:   sc->mapobj        = (PetscObject)eps->st;
    219:   if (eps->twosided) {
    220:     DSSetSlepcSC(eps->dsts,sc);
    221:   }
    222:   return(0);
    223: }

    225: /*@
    226:    EPSSetUp - Sets up all the internal data structures necessary for the
    227:    execution of the eigensolver. Then calls STSetUp() for any set-up
    228:    operations associated to the ST object.

    230:    Collective on eps

    232:    Input Parameter:
    233: .  eps   - eigenproblem solver context

    235:    Notes:
    236:    This function need not be called explicitly in most cases, since EPSSolve()
    237:    calls it. It can be useful when one wants to measure the set-up time
    238:    separately from the solve time.

    240:    Level: developer

    242: .seealso: EPSCreate(), EPSSolve(), EPSDestroy(), STSetUp(), EPSSetInitialSpace()
    243: @*/
    244: PetscErrorCode EPSSetUp(EPS eps)
    245: {
    247:   Mat            A,B;
    248:   PetscInt       k,nmat;
    249:   PetscBool      flg;

    253:   if (eps->state) return(0);
    254:   PetscLogEventBegin(EPS_SetUp,eps,0,0,0);

    256:   /* reset the convergence flag from the previous solves */
    257:   eps->reason = EPS_CONVERGED_ITERATING;

    259:   /* Set default solver type (EPSSetFromOptions was not called) */
    260:   if (!((PetscObject)eps)->type_name) {
    261:     EPSSetType(eps,EPSKRYLOVSCHUR);
    262:   }
    263:   if (!eps->st) { EPSGetST(eps,&eps->st); }
    264:   EPSSetDefaultST(eps);

    266:   STSetTransform(eps->st,PETSC_TRUE);
    267:   if (eps->useds && !eps->ds) { EPSGetDS(eps,&eps->ds); }
    268:   if (eps->twosided) {
    269:     if (eps->ishermitian && (!eps->isgeneralized || eps->ispositive)) SETERRQ1(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Two-sided methods are not intended for %s problems",SLEPC_STRING_HERMITIAN);
    270:     if (!eps->dsts) { DSDuplicate(eps->ds,&eps->dsts); }
    271:   }
    272:   if (!eps->rg) { EPSGetRG(eps,&eps->rg); }
    273:   if (!((PetscObject)eps->rg)->type_name) {
    274:     RGSetType(eps->rg,RGINTERVAL);
    275:   }

    277:   /* Set problem dimensions */
    278:   STGetNumMatrices(eps->st,&nmat);
    279:   if (!nmat) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_WRONGSTATE,"EPSSetOperators must be called first");
    280:   STMatGetSize(eps->st,&eps->n,NULL);
    281:   STMatGetLocalSize(eps->st,&eps->nloc,NULL);

    283:   /* Set default problem type */
    284:   if (!eps->problem_type) {
    285:     if (nmat==1) {
    286:       EPSSetProblemType(eps,EPS_NHEP);
    287:     } else {
    288:       EPSSetProblemType(eps,EPS_GNHEP);
    289:     }
    290:   } else if (nmat==1 && eps->isgeneralized) {
    291:     PetscInfo(eps,"Eigenproblem set as generalized but no matrix B was provided; reverting to a standard eigenproblem\n");
    292:     eps->isgeneralized = PETSC_FALSE;
    293:     eps->problem_type = eps->ishermitian? EPS_HEP: EPS_NHEP;
    294:   } else if (nmat>1 && !eps->isgeneralized) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_INCOMP,"Inconsistent EPS state: the problem type does not match the number of matrices");

    296:   if (eps->nev > eps->n) eps->nev = eps->n;
    297:   if (eps->ncv > eps->n) eps->ncv = eps->n;

    299:   /* check some combinations of eps->which */
    300:   if (eps->ishermitian && (!eps->isgeneralized || eps->ispositive) && (eps->which==EPS_LARGEST_IMAGINARY || eps->which==EPS_SMALLEST_IMAGINARY || eps->which==EPS_TARGET_IMAGINARY)) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"Sorting the eigenvalues along the imaginary axis is not allowed when all eigenvalues are real");

    302:   /* initialization of matrix norms */
    303:   if (eps->conv==EPS_CONV_NORM) {
    304:     if (!eps->nrma) {
    305:       STGetMatrix(eps->st,0,&A);
    306:       MatNorm(A,NORM_INFINITY,&eps->nrma);
    307:     }
    308:     if (nmat>1 && !eps->nrmb) {
    309:       STGetMatrix(eps->st,1,&B);
    310:       MatNorm(B,NORM_INFINITY,&eps->nrmb);
    311:     }
    312:   }

    314:   /* call specific solver setup */
    315:   (*eps->ops->setup)(eps);

    317:   /* if purification is set, check that it really makes sense */
    318:   if (eps->purify) {
    319:     if (eps->categ==EPS_CATEGORY_PRECOND || eps->categ==EPS_CATEGORY_CONTOUR) eps->purify = PETSC_FALSE;
    320:     else {
    321:       if (!eps->isgeneralized) eps->purify = PETSC_FALSE;
    322:       else if (!eps->ishermitian && !eps->ispositive) eps->purify = PETSC_FALSE;
    323:       else {
    324:         PetscObjectTypeCompare((PetscObject)eps->st,STCAYLEY,&flg);
    325:         if (flg) eps->purify = PETSC_FALSE;
    326:       }
    327:     }
    328:   }

    330:   /* set tolerance if not yet set */
    331:   if (eps->tol==PETSC_DEFAULT) eps->tol = SLEPC_DEFAULT_TOL;

    333:   /* set up sorting criterion */
    334:   if (eps->ops->setupsort) {
    335:     (*eps->ops->setupsort)(eps);
    336:   }

    338:   /* Build balancing matrix if required */
    339:   if (eps->balance!=EPS_BALANCE_USER) {
    340:     STSetBalanceMatrix(eps->st,NULL);
    341:     if (!eps->ishermitian && (eps->balance==EPS_BALANCE_ONESIDE || eps->balance==EPS_BALANCE_TWOSIDE)) {
    342:       if (!eps->D) {
    343:         BVCreateVec(eps->V,&eps->D);
    344:         PetscLogObjectParent((PetscObject)eps,(PetscObject)eps->D);
    345:       }
    346:       EPSBuildBalance_Krylov(eps);
    347:       STSetBalanceMatrix(eps->st,eps->D);
    348:     }
    349:   }

    351:   /* Setup ST */
    352:   STSetUp(eps->st);
    353:   EPSCheckCompatibleST(eps);

    355:   /* process deflation and initial vectors */
    356:   if (eps->nds<0) {
    357:     k = -eps->nds;
    358:     BVInsertConstraints(eps->V,&k,eps->defl);
    359:     SlepcBasisDestroy_Private(&eps->nds,&eps->defl);
    360:     eps->nds = k;
    361:     STCheckNullSpace(eps->st,eps->V);
    362:   }
    363:   if (eps->nini<0) {
    364:     k = -eps->nini;
    365:     if (k>eps->ncv) SETERRQ(PetscObjectComm((PetscObject)eps),1,"The number of initial vectors is larger than ncv");
    366:     BVInsertVecs(eps->V,0,&k,eps->IS,PETSC_TRUE);
    367:     SlepcBasisDestroy_Private(&eps->nini,&eps->IS);
    368:     eps->nini = k;
    369:   }
    370:   if (eps->twosided && eps->ninil<0) {
    371:     k = -eps->ninil;
    372:     if (k>eps->ncv) SETERRQ(PetscObjectComm((PetscObject)eps),1,"The number of left initial vectors is larger than ncv");
    373:     BVInsertVecs(eps->W,0,&k,eps->ISL,PETSC_TRUE);
    374:     SlepcBasisDestroy_Private(&eps->ninil,&eps->ISL);
    375:     eps->ninil = k;
    376:   }

    378:   PetscLogEventEnd(EPS_SetUp,eps,0,0,0);
    379:   eps->state = EPS_STATE_SETUP;
    380:   return(0);
    381: }

    383: /*@
    384:    EPSSetOperators - Sets the matrices associated with the eigenvalue problem.

    386:    Collective on eps

    388:    Input Parameters:
    389: +  eps - the eigenproblem solver context
    390: .  A  - the matrix associated with the eigensystem
    391: -  B  - the second matrix in the case of generalized eigenproblems

    393:    Notes:
    394:    To specify a standard eigenproblem, use NULL for parameter B.

    396:    It must be called before EPSSetUp(). If it is called again after EPSSetUp() and
    397:    the matrix sizes have changed then the EPS object is reset.

    399:    Level: beginner

    401: .seealso: EPSSolve(), EPSSetUp(), EPSReset(), EPSGetST(), STGetMatrix()
    402: @*/
    403: PetscErrorCode EPSSetOperators(EPS eps,Mat A,Mat B)
    404: {
    406:   PetscInt       m,n,m0,mloc,nloc,mloc0,nmat;
    407:   Mat            mat[2];

    416:   /* Check matrix sizes */
    417:   MatGetSize(A,&m,&n);
    418:   MatGetLocalSize(A,&mloc,&nloc);
    419:   if (m!=n) SETERRQ2(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_WRONG,"A is a non-square matrix (%D rows, %D cols)",m,n);
    420:   if (mloc!=nloc) SETERRQ2(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_WRONG,"A does not have equal row and column sizes (%D, %D)",mloc,nloc);
    421:   if (B) {
    422:     MatGetSize(B,&m0,&n);
    423:     MatGetLocalSize(B,&mloc0,&nloc);
    424:     if (m0!=n) SETERRQ2(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_WRONG,"B is a non-square matrix (%D rows, %D cols)",m0,n);
    425:     if (mloc0!=nloc) SETERRQ2(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_WRONG,"B does not have equal row and column local sizes (%D, %D)",mloc0,nloc);
    426:     if (m!=m0) SETERRQ2(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_INCOMP,"Dimensions of A and B do not match (%D, %D)",m,m0);
    427:     if (mloc!=mloc0) SETERRQ2(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_INCOMP,"Local dimensions of A and B do not match (%D, %D)",mloc,mloc0);
    428:   }
    429:   if (eps->state && (n!=eps->n || nloc!=eps->nloc)) { EPSReset(eps); }
    430:   eps->nrma = 0.0;
    431:   eps->nrmb = 0.0;
    432:   if (!eps->st) { EPSGetST(eps,&eps->st); }
    433:   mat[0] = A;
    434:   if (B) {
    435:     mat[1] = B;
    436:     nmat = 2;
    437:   } else nmat = 1;
    438:   STSetMatrices(eps->st,nmat,mat);
    439:   eps->state = EPS_STATE_INITIAL;
    440:   return(0);
    441: }

    443: /*@
    444:    EPSGetOperators - Gets the matrices associated with the eigensystem.

    446:    Collective on eps

    448:    Input Parameter:
    449: .  eps - the EPS context

    451:    Output Parameters:
    452: +  A  - the matrix associated with the eigensystem
    453: -  B  - the second matrix in the case of generalized eigenproblems

    455:    Level: intermediate

    457: .seealso: EPSSolve(), EPSGetST(), STGetMatrix(), STSetMatrices()
    458: @*/
    459: PetscErrorCode EPSGetOperators(EPS eps,Mat *A,Mat *B)
    460: {
    462:   ST             st;
    463:   PetscInt       k;

    467:   EPSGetST(eps,&st);
    468:   if (A) { STGetMatrix(st,0,A); }
    469:   if (B) {
    470:     STGetNumMatrices(st,&k);
    471:     if (k==1) B = NULL;
    472:     else {
    473:       STGetMatrix(st,1,B);
    474:     }
    475:   }
    476:   return(0);
    477: }

    479: /*@C
    480:    EPSSetDeflationSpace - Specify a basis of vectors that constitute the deflation
    481:    space.

    483:    Collective on eps

    485:    Input Parameter:
    486: +  eps - the eigenproblem solver context
    487: .  n   - number of vectors
    488: -  v   - set of basis vectors of the deflation space

    490:    Notes:
    491:    When a deflation space is given, the eigensolver seeks the eigensolution
    492:    in the restriction of the problem to the orthogonal complement of this
    493:    space. This can be used for instance in the case that an invariant
    494:    subspace is known beforehand (such as the nullspace of the matrix).

    496:    These vectors do not persist from one EPSSolve() call to the other, so the
    497:    deflation space should be set every time.

    499:    The vectors do not need to be mutually orthonormal, since they are explicitly
    500:    orthonormalized internally.

    502:    Level: intermediate

    504: .seealso: EPSSetInitialSpace()
    505: @*/
    506: PetscErrorCode EPSSetDeflationSpace(EPS eps,PetscInt n,Vec v[])
    507: {

    513:   if (n<0) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Argument n out of range");
    514:   if (n>0) {
    517:   }
    518:   SlepcBasisReference_Private(n,v,&eps->nds,&eps->defl);
    519:   if (n>0) eps->state = EPS_STATE_INITIAL;
    520:   return(0);
    521: }

    523: /*@C
    524:    EPSSetInitialSpace - Specify a basis of vectors that constitute the initial
    525:    space, that is, the subspace from which the solver starts to iterate.

    527:    Collective on eps

    529:    Input Parameter:
    530: +  eps - the eigenproblem solver context
    531: .  n   - number of vectors
    532: -  is  - set of basis vectors of the initial space

    534:    Notes:
    535:    Some solvers start to iterate on a single vector (initial vector). In that case,
    536:    the other vectors are ignored.

    538:    These vectors do not persist from one EPSSolve() call to the other, so the
    539:    initial space should be set every time.

    541:    The vectors do not need to be mutually orthonormal, since they are explicitly
    542:    orthonormalized internally.

    544:    Common usage of this function is when the user can provide a rough approximation
    545:    of the wanted eigenspace. Then, convergence may be faster.

    547:    Level: intermediate

    549: .seealso: EPSSetLeftInitialSpace(), EPSSetDeflationSpace()
    550: @*/
    551: PetscErrorCode EPSSetInitialSpace(EPS eps,PetscInt n,Vec is[])
    552: {

    558:   if (n<0) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Argument n cannot be negative");
    559:   if (n>0) {
    562:   }
    563:   SlepcBasisReference_Private(n,is,&eps->nini,&eps->IS);
    564:   if (n>0) eps->state = EPS_STATE_INITIAL;
    565:   return(0);
    566: }

    568: /*@C
    569:    EPSSetLeftInitialSpace - Specify a basis of vectors that constitute the left
    570:    initial space, used by two-sided solvers to start the left subspace.

    572:    Collective on eps

    574:    Input Parameter:
    575: +  eps - the eigenproblem solver context
    576: .  n   - number of vectors
    577: -  isl - set of basis vectors of the left initial space

    579:    Notes:
    580:    Left initial vectors are used to initiate the left search space in two-sided
    581:    eigensolvers. Users should pass here an approximation of the left eigenspace,
    582:    if available.

    584:    The same comments in EPSSetInitialSpace() are applicable here.

    586:    Level: intermediate

    588: .seealso: EPSSetInitialSpace(), EPSSetTwoSided()
    589: @*/
    590: PetscErrorCode EPSSetLeftInitialSpace(EPS eps,PetscInt n,Vec isl[])
    591: {

    597:   if (n<0) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Argument n cannot be negative");
    598:   if (n>0) {
    601:   }
    602:   SlepcBasisReference_Private(n,isl,&eps->ninil,&eps->ISL);
    603:   if (n>0) eps->state = EPS_STATE_INITIAL;
    604:   return(0);
    605: }

    607: /*
    608:   EPSSetDimensions_Default - Set reasonable values for ncv, mpd if not set
    609:   by the user. This is called at setup.
    610:  */
    611: PetscErrorCode EPSSetDimensions_Default(EPS eps,PetscInt nev,PetscInt *ncv,PetscInt *mpd)
    612: {
    614:   PetscBool      krylov;

    617:   if (*ncv!=PETSC_DEFAULT) { /* ncv set */
    618:     PetscObjectTypeCompareAny((PetscObject)eps,&krylov,EPSKRYLOVSCHUR,EPSARNOLDI,EPSLANCZOS,"");
    619:     if (krylov) {
    620:       if (*ncv<nev+1 && !(*ncv==nev && *ncv==eps->n)) SETERRQ(PetscObjectComm((PetscObject)eps),1,"The value of ncv must be at least nev+1");
    621:     } else {
    622:       if (*ncv<nev) SETERRQ(PetscObjectComm((PetscObject)eps),1,"The value of ncv must be at least nev");
    623:     }
    624:   } else if (*mpd!=PETSC_DEFAULT) { /* mpd set */
    625:     *ncv = PetscMin(eps->n,nev+(*mpd));
    626:   } else { /* neither set: defaults depend on nev being small or large */
    627:     if (nev<500) *ncv = PetscMin(eps->n,PetscMax(2*nev,nev+15));
    628:     else {
    629:       *mpd = 500;
    630:       *ncv = PetscMin(eps->n,nev+(*mpd));
    631:     }
    632:   }
    633:   if (*mpd==PETSC_DEFAULT) *mpd = *ncv;
    634:   return(0);
    635: }

    637: /*@
    638:    EPSAllocateSolution - Allocate memory storage for common variables such
    639:    as eigenvalues and eigenvectors.

    641:    Collective on eps

    643:    Input Parameters:
    644: +  eps   - eigensolver context
    645: -  extra - number of additional positions, used for methods that require a
    646:            working basis slightly larger than ncv

    648:    Developers Note:
    649:    This is SLEPC_EXTERN because it may be required by user plugin EPS
    650:    implementations.

    652:    Level: developer
    653: @*/
    654: PetscErrorCode EPSAllocateSolution(EPS eps,PetscInt extra)
    655: {
    657:   PetscInt       oldsize,newc,requested;
    658:   PetscLogDouble cnt;
    659:   Vec            t;

    662:   requested = eps->ncv + extra;

    664:   /* oldsize is zero if this is the first time setup is called */
    665:   BVGetSizes(eps->V,NULL,NULL,&oldsize);
    666:   newc = PetscMax(0,requested-oldsize);

    668:   /* allocate space for eigenvalues and friends */
    669:   if (requested != oldsize || !eps->eigr) {
    670:     PetscFree4(eps->eigr,eps->eigi,eps->errest,eps->perm);
    671:     PetscMalloc4(requested,&eps->eigr,requested,&eps->eigi,requested,&eps->errest,requested,&eps->perm);
    672:     cnt = 2*newc*sizeof(PetscScalar) + 2*newc*sizeof(PetscReal) + newc*sizeof(PetscInt);
    673:     PetscLogObjectMemory((PetscObject)eps,cnt);
    674:   }

    676:   /* workspace for the case of arbitrary selection */
    677:   if (eps->arbitrary) {
    678:     if (eps->rr) {
    679:       PetscFree2(eps->rr,eps->ri);
    680:     }
    681:     PetscMalloc2(requested,&eps->rr,requested,&eps->ri);
    682:     PetscLogObjectMemory((PetscObject)eps,2*newc*sizeof(PetscScalar));
    683:   }

    685:   /* allocate V */
    686:   if (!eps->V) { EPSGetBV(eps,&eps->V); }
    687:   if (!oldsize) {
    688:     if (!((PetscObject)(eps->V))->type_name) {
    689:       BVSetType(eps->V,BVSVEC);
    690:     }
    691:     STMatCreateVecsEmpty(eps->st,&t,NULL);
    692:     BVSetSizesFromVec(eps->V,t,requested);
    693:     VecDestroy(&t);
    694:   } else {
    695:     BVResize(eps->V,requested,PETSC_FALSE);
    696:   }

    698:   /* allocate W */
    699:   if (eps->twosided) {
    700:     BVDestroy(&eps->W);
    701:     BVDuplicate(eps->V,&eps->W);
    702:   }
    703:   return(0);
    704: }