Date: 2013-09-02T10:02:38+00:00

Actual source code: basic.c

      1: /*
      2:      The basic EPS routines, Create, View, etc. are here.

      4:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      5:    SLEPc - Scalable Library for Eigenvalue Problem Computations
      6:    Copyright (c) 2002-2013, Universitat Politecnica de Valencia, Spain

      8:    This file is part of SLEPc.

     10:    SLEPc is free software: you can redistribute it and/or modify it under  the
     11:    terms of version 3 of the GNU Lesser General Public License as published by
     12:    the Free Software Foundation.

     14:    SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
     15:    WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
     16:    FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
     17:    more details.

     19:    You  should have received a copy of the GNU Lesser General  Public  License
     20:    along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
     21:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     22: */

     24: #include <slepc-private/epsimpl.h>      /*I "slepceps.h" I*/

     26: PetscFunctionList EPSList = 0;
     27: PetscBool         EPSRegisterAllCalled = PETSC_FALSE;
     28: PetscClassId      EPS_CLASSID = 0;
     29: PetscLogEvent     EPS_SetUp = 0,EPS_Solve = 0;
     30: static PetscBool  EPSPackageInitialized = PETSC_FALSE;

     32: const char *EPSPowerShiftTypes[] = {"CONSTANT","RAYLEIGH","WILKINSON","EPSPowerShiftType","EPS_POWER_SHIFT_",0};
     33: const char *EPSLanczosReorthogTypes[] = {"LOCAL","FULL","SELECTIVE","PERIODIC","PARTIAL","DELAYED","EPSLanczosReorthogType","EPS_LANCZOS_REORTHOG_",0};
     34: const char *EPSPRIMMEMethods[] = {"DYNAMIC","DEFAULT_MIN_TIME","DEFAULT_MIN_MATVECS","ARNOLDI","GD","GD_PLUSK","GD_OLSEN_PLUSK","JD_OLSEN_PLUSK","RQI","JDQR","JDQMR","JDQMR_ETOL","SUBSPACE_ITERATION","LOBPCG_ORTHOBASIS","LOBPCG_ORTHOBASISW","EPSPRIMMEMethod","EPS_PRIMME_",0};

     38: /*@C
     39:   EPSFinalizePackage - This function destroys everything in the SLEPc interface
     40:   to the EPS package. It is called from SlepcFinalize().

     42:   Level: developer

     44: .seealso: SlepcFinalize()
     45: @*/
     46: PetscErrorCode EPSFinalizePackage(void)
     47: {

     51:   PetscFunctionListDestroy(&EPSList);
     52:   EPSPackageInitialized = PETSC_FALSE;
     53:   EPSRegisterAllCalled  = PETSC_FALSE;
     54:   return(0);
     55: }

     59: /*@C
     60:   EPSInitializePackage - This function initializes everything in the EPS package.
     61:   It is called from PetscDLLibraryRegister() when using dynamic libraries, and
     62:   on the first call to EPSCreate() when using static libraries.

     64:   Level: developer

     66: .seealso: SlepcInitialize()
     67: @*/
     68: PetscErrorCode EPSInitializePackage()
     69: {
     70:   char           logList[256];
     71:   char           *className;
     72:   PetscBool      opt;

     76:   if (EPSPackageInitialized) return(0);
     77:   EPSPackageInitialized = PETSC_TRUE;
     78:   /* Register Classes */
     79:   PetscClassIdRegister("Eigenvalue Problem Solver",&EPS_CLASSID);
     80:   /* Register Constructors */
     81:   EPSRegisterAll();
     82:   /* Register Events */
     83:   PetscLogEventRegister("EPSSetUp",EPS_CLASSID,&EPS_SetUp);
     84:   PetscLogEventRegister("EPSSolve",EPS_CLASSID,&EPS_Solve);
     85:   /* Process info exclusions */
     86:   PetscOptionsGetString(NULL,"-info_exclude",logList,256,&opt);
     87:   if (opt) {
     88:     PetscStrstr(logList,"eps",&className);
     89:     if (className) {
     90:       PetscInfoDeactivateClass(EPS_CLASSID);
     91:     }
     92:   }
     93:   /* Process summary exclusions */
     94:   PetscOptionsGetString(NULL,"-log_summary_exclude",logList,256,&opt);
     95:   if (opt) {
     96:     PetscStrstr(logList,"eps",&className);
     97:     if (className) {
     98:       PetscLogEventDeactivateClass(EPS_CLASSID);
     99:     }
    100:   }
    101:   PetscRegisterFinalize(EPSFinalizePackage);
    102:   return(0);
    103: }

    107: /*@C
    108:    EPSView - Prints the EPS data structure.

    110:    Collective on EPS

    112:    Input Parameters:
    113: +  eps - the eigenproblem solver context
    114: -  viewer - optional visualization context

    116:    Options Database Key:
    117: .  -eps_view -  Calls EPSView() at end of EPSSolve()

    119:    Note:
    120:    The available visualization contexts include
    121: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
    122: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
    123:          output where only the first processor opens
    124:          the file.  All other processors send their
    125:          data to the first processor to print.

    127:    The user can open an alternative visualization context with
    128:    PetscViewerASCIIOpen() - output to a specified file.

    130:    Level: beginner

    132: .seealso: STView(), PetscViewerASCIIOpen()
    133: @*/
    134: PetscErrorCode EPSView(EPS eps,PetscViewer viewer)
    135: {
    137:   const char     *type,*extr,*bal;
    138:   char           str[50];
    139:   PetscBool      isascii,ispower,isexternal;

    143:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)eps));

    147: #if defined(PETSC_USE_COMPLEX)
    148: #define HERM "hermitian"
    149: #else
    150: #define HERM "symmetric"
    151: #endif
    152:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    153:   if (isascii) {
    154:     PetscObjectPrintClassNamePrefixType((PetscObject)eps,viewer,"EPS Object");
    155:     if (eps->ops->view) {
    156:       PetscViewerASCIIPushTab(viewer);
    157:       (*eps->ops->view)(eps,viewer);
    158:       PetscViewerASCIIPopTab(viewer);
    159:     }
    160:     if (eps->problem_type) {
    161:       switch (eps->problem_type) {
    162:         case EPS_HEP:   type = HERM " eigenvalue problem"; break;
    163:         case EPS_GHEP:  type = "generalized " HERM " eigenvalue problem"; break;
    164:         case EPS_NHEP:  type = "non-" HERM " eigenvalue problem"; break;
    165:         case EPS_GNHEP: type = "generalized non-" HERM " eigenvalue problem"; break;
    166:         case EPS_PGNHEP: type = "generalized non-" HERM " eigenvalue problem with " HERM " positive definite B"; break;
    167:         case EPS_GHIEP: type = "generalized " HERM "-indefinite eigenvalue problem"; break;
    168:         default: SETERRQ(PetscObjectComm((PetscObject)eps),1,"Wrong value of eps->problem_type");
    169:       }
    170:     } else type = "not yet set";
    171:     PetscViewerASCIIPrintf(viewer,"  problem type: %s\n",type);
    172:     if (eps->extraction) {
    173:       switch (eps->extraction) {
    174:         case EPS_RITZ:             extr = "Rayleigh-Ritz"; break;
    175:         case EPS_HARMONIC:         extr = "harmonic Ritz"; break;
    176:         case EPS_HARMONIC_RELATIVE:extr = "relative harmonic Ritz"; break;
    177:         case EPS_HARMONIC_RIGHT:   extr = "right harmonic Ritz"; break;
    178:         case EPS_HARMONIC_LARGEST: extr = "largest harmonic Ritz"; break;
    179:         case EPS_REFINED:          extr = "refined Ritz"; break;
    180:         case EPS_REFINED_HARMONIC: extr = "refined harmonic Ritz"; break;
    181:         default: SETERRQ(PetscObjectComm((PetscObject)eps),1,"Wrong value of eps->extraction");
    182:       }
    183:       PetscViewerASCIIPrintf(viewer,"  extraction type: %s\n",extr);
    184:     }
    185:     if (eps->balance && !eps->ishermitian && eps->balance!=EPS_BALANCE_NONE) {
    186:       switch (eps->balance) {
    187:         case EPS_BALANCE_ONESIDE:   bal = "one-sided Krylov"; break;
    188:         case EPS_BALANCE_TWOSIDE:   bal = "two-sided Krylov"; break;
    189:         case EPS_BALANCE_USER:      bal = "user-defined matrix"; break;
    190:         default: SETERRQ(PetscObjectComm((PetscObject)eps),1,"Wrong value of eps->balance");
    191:       }
    192:       PetscViewerASCIIPrintf(viewer,"  balancing enabled: %s",bal);
    193:       if (eps->balance==EPS_BALANCE_ONESIDE || eps->balance==EPS_BALANCE_TWOSIDE) {
    194:         PetscViewerASCIIPrintf(viewer,", with its=%D",eps->balance_its);
    195:       }
    196:       if (eps->balance==EPS_BALANCE_TWOSIDE && eps->balance_cutoff!=0.0) {
    197:         PetscViewerASCIIPrintf(viewer," and cutoff=%G",eps->balance_cutoff);
    198:       }
    199:       PetscViewerASCIIPrintf(viewer,"\n");
    200:     }
    201:     PetscViewerASCIIPrintf(viewer,"  selected portion of the spectrum: ");
    202:     SlepcSNPrintfScalar(str,50,eps->target,PETSC_FALSE);
    203:     if (!eps->which) {
    204:       PetscViewerASCIIPrintf(viewer,"not yet set\n");
    205:     } else switch (eps->which) {
    206:       case EPS_WHICH_USER:
    207:         PetscViewerASCIIPrintf(viewer,"user defined\n");
    208:         break;
    209:       case EPS_TARGET_MAGNITUDE:
    210:         PetscViewerASCIIPrintf(viewer,"closest to target: %s (in magnitude)\n",str);
    211:         break;
    212:       case EPS_TARGET_REAL:
    213:         PetscViewerASCIIPrintf(viewer,"closest to target: %s (along the real axis)\n",str);
    214:         break;
    215:       case EPS_TARGET_IMAGINARY:
    216:         PetscViewerASCIIPrintf(viewer,"closest to target: %s (along the imaginary axis)\n",str);
    217:         break;
    218:       case EPS_LARGEST_MAGNITUDE:
    219:         PetscViewerASCIIPrintf(viewer,"largest eigenvalues in magnitude\n");
    220:         break;
    221:       case EPS_SMALLEST_MAGNITUDE:
    222:         PetscViewerASCIIPrintf(viewer,"smallest eigenvalues in magnitude\n");
    223:         break;
    224:       case EPS_LARGEST_REAL:
    225:         PetscViewerASCIIPrintf(viewer,"largest real parts\n");
    226:         break;
    227:       case EPS_SMALLEST_REAL:
    228:         PetscViewerASCIIPrintf(viewer,"smallest real parts\n");
    229:         break;
    230:       case EPS_LARGEST_IMAGINARY:
    231:         PetscViewerASCIIPrintf(viewer,"largest imaginary parts\n");
    232:         break;
    233:       case EPS_SMALLEST_IMAGINARY:
    234:         PetscViewerASCIIPrintf(viewer,"smallest imaginary parts\n");
    235:         break;
    236:       case EPS_ALL:
    237:         PetscViewerASCIIPrintf(viewer,"all eigenvalues in interval [%G,%G]\n",eps->inta,eps->intb);
    238:         break;
    239:       default: SETERRQ(PetscObjectComm((PetscObject)eps),1,"Wrong value of eps->which");
    240:     }
    241:     if (eps->leftvecs) {
    242:       PetscViewerASCIIPrintf(viewer,"  computing left eigenvectors also\n");
    243:     }
    244:     if (eps->trueres) {
    245:       PetscViewerASCIIPrintf(viewer,"  computing true residuals explicitly\n");
    246:     }
    247:     if (eps->trackall) {
    248:       PetscViewerASCIIPrintf(viewer,"  computing all residuals (for tracking convergence)\n");
    249:     }
    250:     PetscViewerASCIIPrintf(viewer,"  number of eigenvalues (nev): %D\n",eps->nev);
    251:     PetscViewerASCIIPrintf(viewer,"  number of column vectors (ncv): %D\n",eps->ncv);
    252:     PetscViewerASCIIPrintf(viewer,"  maximum dimension of projected problem (mpd): %D\n",eps->mpd);
    253:     PetscViewerASCIIPrintf(viewer,"  maximum number of iterations: %D\n",eps->max_it);
    254:     PetscViewerASCIIPrintf(viewer,"  tolerance: %G\n",eps->tol);
    255:     PetscViewerASCIIPrintf(viewer,"  convergence test: ");
    256:     switch (eps->conv) {
    257:     case EPS_CONV_ABS:
    258:       PetscViewerASCIIPrintf(viewer,"absolute\n");break;
    259:     case EPS_CONV_EIG:
    260:       PetscViewerASCIIPrintf(viewer,"relative to the eigenvalue\n");break;
    261:     case EPS_CONV_NORM:
    262:       PetscViewerASCIIPrintf(viewer,"relative to the eigenvalue and matrix norms\n");break;
    263:     default:
    264:       PetscViewerASCIIPrintf(viewer,"user-defined\n");break;
    265:     }
    266:     if (eps->nini) {
    267:       PetscViewerASCIIPrintf(viewer,"  dimension of user-provided initial space: %D\n",PetscAbs(eps->nini));
    268:     }
    269:     if (eps->ninil) {
    270:       PetscViewerASCIIPrintf(viewer,"  dimension of user-provided initial left space: %D\n",PetscAbs(eps->ninil));
    271:     }
    272:     if (eps->nds>0) {
    273:       PetscViewerASCIIPrintf(viewer,"  dimension of user-provided deflation space: %D\n",eps->nds);
    274:     }
    275:     PetscViewerASCIIPrintf(viewer,"  estimates of matrix norms (%s): norm(A)=%G",eps->adaptive?"adaptive":"constant",eps->nrma);
    276:     if (eps->isgeneralized) {
    277:       PetscViewerASCIIPrintf(viewer,", norm(B)=%G",eps->nrmb);
    278:     }
    279:     PetscViewerASCIIPrintf(viewer,"\n");
    280:   } else {
    281:     if (eps->ops->view) {
    282:       (*eps->ops->view)(eps,viewer);
    283:     }
    284:   }
    285:   PetscObjectTypeCompareAny((PetscObject)eps,&isexternal,EPSARPACK,EPSBLZPACK,EPSTRLAN,EPSBLOPEX,EPSPRIMME,"");
    286:   if (!isexternal) {
    287:     if (!eps->ip) { EPSGetIP(eps,&eps->ip); }
    288:     IPView(eps->ip,viewer);
    289:     PetscObjectTypeCompare((PetscObject)eps,EPSPOWER,&ispower);
    290:     if (!ispower) {
    291:       if (!eps->ds) { EPSGetDS(eps,&eps->ds); }
    292:       PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
    293:       DSView(eps->ds,viewer);
    294:       PetscViewerPopFormat(viewer);
    295:     }
    296:   }
    297:   if (!eps->st) { EPSGetST(eps,&eps->st); }
    298:   STView(eps->st,viewer);
    299:   return(0);
    300: }

    304: /*@
    305:    EPSPrintSolution - Prints the computed eigenvalues.

    307:    Collective on EPS

    309:    Input Parameters:
    310: +  eps - the eigensolver context
    311: -  viewer - optional visualization context

    313:    Options Database Key:
    314: .  -eps_terse - print only minimal information

    316:    Note:
    317:    By default, this function prints a table with eigenvalues and associated
    318:    relative errors. With -eps_terse only the eigenvalues are printed.

    320:    Level: intermediate

    322: .seealso: PetscViewerASCIIOpen()
    323: @*/
    324: PetscErrorCode EPSPrintSolution(EPS eps,PetscViewer viewer)
    325: {
    326:   PetscBool      terse,errok,isascii;
    327:   PetscReal      error,re,im;
    328:   PetscScalar    kr,ki;
    329:   PetscInt       i,j;

    334:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)eps));
    337:   if (!eps->eigr || !eps->eigi || !eps->V) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_WRONGSTATE,"EPSSolve must be called first");
    338:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    339:   if (!isascii) return(0);

    341:   PetscOptionsHasName(NULL,"-eps_terse",&terse);
    342:   if (terse) {
    343:     if (eps->nconv<eps->nev) {
    344:       PetscViewerASCIIPrintf(viewer," Problem: less than %D eigenvalues converged\n\n",eps->nev);
    345:     } else {
    346:       errok = PETSC_TRUE;
    347:       for (i=0;i<eps->nev;i++) {
    348:         EPSComputeRelativeError(eps,i,&error);
    349:         errok = (errok && error<eps->tol)? PETSC_TRUE: PETSC_FALSE;
    350:       }
    351:       if (errok) {
    352:         PetscViewerASCIIPrintf(viewer," All requested eigenvalues computed up to the required tolerance:");
    353:         for (i=0;i<=(eps->nev-1)/8;i++) {
    354:           PetscViewerASCIIPrintf(viewer,"\n     ");
    355:           for (j=0;j<PetscMin(8,eps->nev-8*i);j++) {
    356:             EPSGetEigenpair(eps,8*i+j,&kr,&ki,NULL,NULL);
    357: #if defined(PETSC_USE_COMPLEX)
    358:             re = PetscRealPart(kr);
    359:             im = PetscImaginaryPart(kr);
    360: #else
    361:             re = kr;
    362:             im = ki;
    363: #endif
    364:             if (PetscAbs(re)/PetscAbs(im)<PETSC_SMALL) re = 0.0;
    365:             if (PetscAbs(im)/PetscAbs(re)<PETSC_SMALL) im = 0.0;
    366:             if (im!=0.0) {
    367:               PetscViewerASCIIPrintf(viewer,"%.5F%+.5Fi",re,im);
    368:             } else {
    369:               PetscViewerASCIIPrintf(viewer,"%.5F",re);
    370:             }
    371:             if (8*i+j+1<eps->nev) { PetscViewerASCIIPrintf(viewer,", "); }
    372:           }
    373:         }
    374:         PetscViewerASCIIPrintf(viewer,"\n\n");
    375:       } else {
    376:         PetscViewerASCIIPrintf(viewer," Problem: some of the first %D relative errors are higher than the tolerance\n\n",eps->nev);
    377:       }
    378:     }
    379:   } else {
    380:     PetscViewerASCIIPrintf(viewer," Number of converged approximate eigenpairs: %D\n\n",eps->nconv);
    381:     if (eps->nconv>0) {
    382:       PetscViewerASCIIPrintf(viewer,
    383:            "           k          ||Ax-k%sx||/||kx||\n"
    384:            "   ----------------- ------------------\n",eps->isgeneralized?"B":"");
    385:       for (i=0;i<eps->nconv;i++) {
    386:         EPSGetEigenpair(eps,i,&kr,&ki,NULL,NULL);
    387:         EPSComputeRelativeError(eps,i,&error);
    388: #if defined(PETSC_USE_COMPLEX)
    389:         re = PetscRealPart(kr);
    390:         im = PetscImaginaryPart(kr);
    391: #else
    392:         re = kr;
    393:         im = ki;
    394: #endif
    395:         if (im!=0.0) {
    396:           PetscViewerASCIIPrintf(viewer," % 9F%+9F i %12G\n",re,im,error);
    397:         } else {
    398:           PetscViewerASCIIPrintf(viewer,"   % 12F       %12G\n",re,error);
    399:         }
    400:       }
    401:       PetscViewerASCIIPrintf(viewer,"\n");
    402:     }
    403:   }
    404:   return(0);
    405: }

    409: /*@C
    410:    EPSCreate - Creates the default EPS context.

    412:    Collective on MPI_Comm

    414:    Input Parameter:
    415: .  comm - MPI communicator

    417:    Output Parameter:
    418: .  eps - location to put the EPS context

    420:    Note:
    421:    The default EPS type is EPSKRYLOVSCHUR

    423:    Level: beginner

    425: .seealso: EPSSetUp(), EPSSolve(), EPSDestroy(), EPS
    426: @*/
    427: PetscErrorCode EPSCreate(MPI_Comm comm,EPS *outeps)
    428: {
    430:   EPS            eps;

    434:   *outeps = 0;
    435: #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
    436:   EPSInitializePackage();
    437: #endif

    439:   SlepcHeaderCreate(eps,_p_EPS,struct _EPSOps,EPS_CLASSID,"EPS","Eigenvalue Problem Solver","EPS",comm,EPSDestroy,EPSView);

    441:   eps->max_it          = 0;
    442:   eps->nev             = 1;
    443:   eps->ncv             = 0;
    444:   eps->mpd             = 0;
    445:   eps->allocated_ncv   = 0;
    446:   eps->nini            = 0;
    447:   eps->ninil           = 0;
    448:   eps->nds             = 0;
    449:   eps->tol             = PETSC_DEFAULT;
    450:   eps->conv            = EPS_CONV_EIG;
    451:   eps->converged       = EPSConvergedEigRelative;
    452:   eps->convergedctx    = NULL;
    453:   eps->which           = (EPSWhich)0;
    454:   eps->comparison      = NULL;
    455:   eps->comparisonctx   = NULL;
    456:   eps->arbitrary       = NULL;
    457:   eps->arbitraryctx    = NULL;
    458:   eps->leftvecs        = PETSC_FALSE;
    459:   eps->trueres         = PETSC_FALSE;
    460:   eps->trackall        = PETSC_FALSE;
    461:   eps->target          = 0.0;
    462:   eps->inta            = 0.0;
    463:   eps->intb            = 0.0;
    464:   eps->evecsavailable  = PETSC_FALSE;
    465:   eps->problem_type    = (EPSProblemType)0;
    466:   eps->extraction      = (EPSExtraction)0;
    467:   eps->balance         = (EPSBalance)0;
    468:   eps->balance_its     = 5;
    469:   eps->balance_cutoff  = 1e-8;
    470:   eps->nrma            = 1.0;
    471:   eps->nrmb            = 1.0;
    472:   eps->adaptive        = PETSC_FALSE;

    474:   eps->V               = 0;
    475:   eps->W               = 0;
    476:   eps->D               = 0;
    477:   eps->defl            = 0;
    478:   eps->IS              = 0;
    479:   eps->ISL             = 0;
    480:   eps->t               = 0;
    481:   eps->ds_ortho        = PETSC_FALSE;
    482:   eps->eigr            = 0;
    483:   eps->eigi            = 0;
    484:   eps->errest          = 0;
    485:   eps->errest_left     = 0;
    486:   eps->st              = 0;
    487:   eps->ip              = 0;
    488:   eps->ds              = 0;
    489:   eps->rand            = 0;
    490:   eps->data            = 0;
    491:   eps->nconv           = 0;
    492:   eps->its             = 0;
    493:   eps->perm            = NULL;

    495:   eps->nwork           = 0;
    496:   eps->work            = 0;
    497:   eps->isgeneralized   = PETSC_FALSE;
    498:   eps->ishermitian     = PETSC_FALSE;
    499:   eps->ispositive      = PETSC_FALSE;
    500:   eps->setupcalled     = 0;
    501:   eps->reason          = EPS_CONVERGED_ITERATING;
    502:   eps->numbermonitors  = 0;

    504:   PetscRandomCreate(comm,&eps->rand);
    505:   PetscRandomSetSeed(eps->rand,0x12345678);
    506:   PetscLogObjectParent(eps,eps->rand);
    507:   *outeps = eps;
    508:   return(0);
    509: }

    513: /*@C
    514:    EPSSetType - Selects the particular solver to be used in the EPS object.

    516:    Logically Collective on EPS

    518:    Input Parameters:
    519: +  eps  - the eigensolver context
    520: -  type - a known method

    522:    Options Database Key:
    523: .  -eps_type <method> - Sets the method; use -help for a list
    524:     of available methods

    526:    Notes:
    527:    See "slepc/include/slepceps.h" for available methods. The default
    528:    is EPSKRYLOVSCHUR.

    530:    Normally, it is best to use the EPSSetFromOptions() command and
    531:    then set the EPS type from the options database rather than by using
    532:    this routine.  Using the options database provides the user with
    533:    maximum flexibility in evaluating the different available methods.
    534:    The EPSSetType() routine is provided for those situations where it
    535:    is necessary to set the iterative solver independently of the command
    536:    line or options database.

    538:    Level: intermediate

    540: .seealso: STSetType(), EPSType
    541: @*/
    542: PetscErrorCode EPSSetType(EPS eps,EPSType type)
    543: {
    544:   PetscErrorCode ierr,(*r)(EPS);
    545:   PetscBool      match;

    551:   PetscObjectTypeCompare((PetscObject)eps,type,&match);
    552:   if (match) return(0);

    554:   PetscFunctionListFind(EPSList,type,&r);
    555:   if (!r) SETERRQ1(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown EPS type given: %s",type);

    557:   if (eps->ops->destroy) { (*eps->ops->destroy)(eps); }
    558:   PetscMemzero(eps->ops,sizeof(struct _EPSOps));

    560:   eps->setupcalled = 0;
    561:   PetscObjectChangeTypeName((PetscObject)eps,type);
    562:   (*r)(eps);
    563:   return(0);
    564: }

    568: /*@C
    569:    EPSGetType - Gets the EPS type as a string from the EPS object.

    571:    Not Collective

    573:    Input Parameter:
    574: .  eps - the eigensolver context

    576:    Output Parameter:
    577: .  name - name of EPS method

    579:    Level: intermediate

    581: .seealso: EPSSetType()
    582: @*/
    583: PetscErrorCode EPSGetType(EPS eps,EPSType *type)
    584: {
    588:   *type = ((PetscObject)eps)->type_name;
    589:   return(0);
    590: }

    594: /*@C
    595:    EPSRegister - Adds a method to the eigenproblem solver package.

    597:    Not Collective

    599:    Input Parameters:
    600: +  name - name of a new user-defined solver
    601: -  function - routine to create the solver context

    603:    Notes:
    604:    EPSRegister() may be called multiple times to add several user-defined solvers.

    606:    Sample usage:
    607: .vb
    608:    EPSRegister("my_solver",MySolverCreate);
    609: .ve

    611:    Then, your solver can be chosen with the procedural interface via
    612: $     EPSSetType(eps,"my_solver")
    613:    or at runtime via the option
    614: $     -eps_type my_solver

    616:    Level: advanced

    618: .seealso: EPSRegisterAll()
    619: @*/
    620: PetscErrorCode EPSRegister(const char *name,PetscErrorCode (*function)(EPS))
    621: {

    625:   PetscFunctionListAdd(&EPSList,name,function);
    626:   return(0);
    627: }

    631: /*@
    632:    EPSReset - Resets the EPS context to the setupcalled=0 state and removes any
    633:    allocated objects.

    635:    Collective on EPS

    637:    Input Parameter:
    638: .  eps - eigensolver context obtained from EPSCreate()

    640:    Level: advanced

    642: .seealso: EPSDestroy()
    643: @*/
    644: PetscErrorCode EPSReset(EPS eps)
    645: {

    650:   if (eps->ops->reset) { (eps->ops->reset)(eps); }
    651:   if (eps->st) { STReset(eps->st); }
    652:   if (eps->ip) { IPReset(eps->ip); }
    653:   if (eps->ds) { DSReset(eps->ds); }
    654:   VecDestroy(&eps->t);
    655:   VecDestroy(&eps->D);
    656:   eps->setupcalled = 0;
    657:   return(0);
    658: }

    662: /*@C
    663:    EPSDestroy - Destroys the EPS context.

    665:    Collective on EPS

    667:    Input Parameter:
    668: .  eps - eigensolver context obtained from EPSCreate()

    670:    Level: beginner

    672: .seealso: EPSCreate(), EPSSetUp(), EPSSolve()
    673: @*/
    674: PetscErrorCode EPSDestroy(EPS *eps)
    675: {

    679:   if (!*eps) return(0);
    681:   if (--((PetscObject)(*eps))->refct > 0) { *eps = 0; return(0); }
    682:   EPSReset(*eps);
    683:   if ((*eps)->ops->destroy) { (*(*eps)->ops->destroy)(*eps); }
    684:   STDestroy(&(*eps)->st);
    685:   IPDestroy(&(*eps)->ip);
    686:   DSDestroy(&(*eps)->ds);
    687:   PetscRandomDestroy(&(*eps)->rand);
    688:   /* just in case the initial vectors have not been used */
    689:   SlepcBasisDestroy_Private(&(*eps)->nini,&(*eps)->IS);
    690:   SlepcBasisDestroy_Private(&(*eps)->ninil,&(*eps)->ISL);
    691:   EPSRemoveDeflationSpace(*eps);
    692:   EPSMonitorCancel(*eps);
    693:   PetscHeaderDestroy(eps);
    694:   return(0);
    695: }

    699: /*@
    700:    EPSSetTarget - Sets the value of the target.

    702:    Logically Collective on EPS

    704:    Input Parameters:
    705: +  eps    - eigensolver context
    706: -  target - the value of the target

    708:    Notes:
    709:    The target is a scalar value used to determine the portion of the spectrum
    710:    of interest. It is used in combination with EPSSetWhichEigenpairs().

    712:    Level: beginner

    714: .seealso: EPSGetTarget(), EPSSetWhichEigenpairs()
    715: @*/
    716: PetscErrorCode EPSSetTarget(EPS eps,PetscScalar target)
    717: {

    723:   eps->target = target;
    724:   if (!eps->st) { EPSGetST(eps,&eps->st); }
    725:   STSetDefaultShift(eps->st,target);
    726:   return(0);
    727: }

    731: /*@
    732:    EPSGetTarget - Gets the value of the target.

    734:    Not Collective

    736:    Input Parameter:
    737: .  eps - eigensolver context

    739:    Output Parameter:
    740: .  target - the value of the target

    742:    Level: beginner

    744:    Note:
    745:    If the target was not set by the user, then zero is returned.

    747: .seealso: EPSSetTarget()
    748: @*/
    749: PetscErrorCode EPSGetTarget(EPS eps,PetscScalar* target)
    750: {
    754:   *target = eps->target;
    755:   return(0);
    756: }

    760: /*@
    761:    EPSSetInterval - Defines the computational interval for spectrum slicing.

    763:    Logically Collective on EPS

    765:    Input Parameters:
    766: +  eps  - eigensolver context
    767: .  inta - left end of the interval
    768: -  intb - right end of the interval

    770:    Options Database Key:
    771: .  -eps_interval <a,b> - set [a,b] as the interval of interest

    773:    Notes:
    774:    Spectrum slicing is a technique employed for computing all eigenvalues of
    775:    symmetric eigenproblems in a given interval. This function provides the
    776:    interval to be considered. It must be used in combination with EPS_ALL, see
    777:    EPSSetWhichEigenpairs().

    779:    In the command-line option, two values must be provided. For an open interval,
    780:    one can give an infinite, e.g., -eps_interval 1.0,inf or -eps_interval -inf,1.0.
    781:    An open interval in the programmatic interface can be specified with
    782:    PETSC_MAX_REAL and -PETSC_MAX_REAL.

    784:    Level: intermediate

    786: .seealso: EPSGetInterval(), EPSSetWhichEigenpairs()
    787: @*/
    788: PetscErrorCode EPSSetInterval(EPS eps,PetscReal inta,PetscReal intb)
    789: {
    794:   if (inta>=intb) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_WRONG,"Badly defined interval, must be inta<intb");
    795:   eps->inta = inta;
    796:   eps->intb = intb;
    797:   return(0);
    798: }

    802: /*@
    803:    EPSGetInterval - Gets the computational interval for spectrum slicing.

    805:    Not Collective

    807:    Input Parameter:
    808: .  eps - eigensolver context

    810:    Output Parameters:
    811: +  inta - left end of the interval
    812: -  intb - right end of the interval

    814:    Level: intermediate

    816:    Note:
    817:    If the interval was not set by the user, then zeros are returned.

    819: .seealso: EPSSetInterval()
    820: @*/
    821: PetscErrorCode EPSGetInterval(EPS eps,PetscReal* inta,PetscReal* intb)
    822: {
    827:   if (inta) *inta = eps->inta;
    828:   if (intb) *intb = eps->intb;
    829:   return(0);
    830: }

    834: /*@
    835:    EPSSetST - Associates a spectral transformation object to the eigensolver.

    837:    Collective on EPS

    839:    Input Parameters:
    840: +  eps - eigensolver context obtained from EPSCreate()
    841: -  st   - the spectral transformation object

    843:    Note:
    844:    Use EPSGetST() to retrieve the spectral transformation context (for example,
    845:    to free it at the end of the computations).

    847:    Level: developer

    849: .seealso: EPSGetST()
    850: @*/
    851: PetscErrorCode EPSSetST(EPS eps,ST st)
    852: {

    859:   PetscObjectReference((PetscObject)st);
    860:   STDestroy(&eps->st);
    861:   eps->st = st;
    862:   PetscLogObjectParent(eps,eps->st);
    863:   return(0);
    864: }

    868: /*@C
    869:    EPSGetST - Obtain the spectral transformation (ST) object associated
    870:    to the eigensolver object.

    872:    Not Collective

    874:    Input Parameters:
    875: .  eps - eigensolver context obtained from EPSCreate()

    877:    Output Parameter:
    878: .  st - spectral transformation context

    880:    Level: beginner

    882: .seealso: EPSSetST()
    883: @*/
    884: PetscErrorCode EPSGetST(EPS eps,ST *st)
    885: {

    891:   if (!eps->st) {
    892:     STCreate(PetscObjectComm((PetscObject)eps),&eps->st);
    893:     PetscLogObjectParent(eps,eps->st);
    894:   }
    895:   *st = eps->st;
    896:   return(0);
    897: }

    901: /*@
    902:    EPSSetIP - Associates an inner product object to the eigensolver.

    904:    Collective on EPS

    906:    Input Parameters:
    907: +  eps - eigensolver context obtained from EPSCreate()
    908: -  ip  - the inner product object

    910:    Note:
    911:    Use EPSGetIP() to retrieve the inner product context (for example,
    912:    to free it at the end of the computations).

    914:    Level: advanced

    916: .seealso: EPSGetIP()
    917: @*/
    918: PetscErrorCode EPSSetIP(EPS eps,IP ip)
    919: {

    926:   PetscObjectReference((PetscObject)ip);
    927:   IPDestroy(&eps->ip);
    928:   eps->ip = ip;
    929:   PetscLogObjectParent(eps,eps->ip);
    930:   return(0);
    931: }

    935: /*@C
    936:    EPSGetIP - Obtain the inner product object associated to the eigensolver object.

    938:    Not Collective

    940:    Input Parameters:
    941: .  eps - eigensolver context obtained from EPSCreate()

    943:    Output Parameter:
    944: .  ip - inner product context

    946:    Level: advanced

    948: .seealso: EPSSetIP()
    949: @*/
    950: PetscErrorCode EPSGetIP(EPS eps,IP *ip)
    951: {

    957:   if (!eps->ip) {
    958:     IPCreate(PetscObjectComm((PetscObject)eps),&eps->ip);
    959:     PetscLogObjectParent(eps,eps->ip);
    960:   }
    961:   *ip = eps->ip;
    962:   return(0);
    963: }

    967: /*@
    968:    EPSSetDS - Associates a direct solver object to the eigensolver.

    970:    Collective on EPS

    972:    Input Parameters:
    973: +  eps - eigensolver context obtained from EPSCreate()
    974: -  ds  - the direct solver object

    976:    Note:
    977:    Use EPSGetDS() to retrieve the direct solver context (for example,
    978:    to free it at the end of the computations).

    980:    Level: advanced

    982: .seealso: EPSGetDS()
    983: @*/
    984: PetscErrorCode EPSSetDS(EPS eps,DS ds)
    985: {

    992:   PetscObjectReference((PetscObject)ds);
    993:   DSDestroy(&eps->ds);
    994:   eps->ds = ds;
    995:   PetscLogObjectParent(eps,eps->ds);
    996:   return(0);
    997: }

    1001: /*@C
    1002:    EPSGetDS - Obtain the direct solver object associated to the eigensolver object.

    1004:    Not Collective

    1006:    Input Parameters:
    1007: .  eps - eigensolver context obtained from EPSCreate()

    1009:    Output Parameter:
    1010: .  ds - direct solver context

    1012:    Level: advanced

    1014: .seealso: EPSSetDS()
    1015: @*/
    1016: PetscErrorCode EPSGetDS(EPS eps,DS *ds)
    1017: {

    1023:   if (!eps->ds) {
    1024:     DSCreate(PetscObjectComm((PetscObject)eps),&eps->ds);
    1025:     PetscLogObjectParent(eps,eps->ds);
    1026:   }
    1027:   *ds = eps->ds;
    1028:   return(0);
    1029: }

    1033: /*@
    1034:    EPSIsGeneralized - Ask if the EPS object corresponds to a generalized
    1035:    eigenvalue problem.

    1037:    Not collective

    1039:    Input Parameter:
    1040: .  eps - the eigenproblem solver context

    1042:    Output Parameter:
    1043: .  is - the answer

    1045:    Level: intermediate

    1047: .seealso: EPSIsHermitian(), EPSIsPositive()
    1048: @*/
    1049: PetscErrorCode EPSIsGeneralized(EPS eps,PetscBool* is)
    1050: {
    1054:   *is = eps->isgeneralized;
    1055:   return(0);
    1056: }

    1060: /*@
    1061:    EPSIsHermitian - Ask if the EPS object corresponds to a Hermitian
    1062:    eigenvalue problem.

    1064:    Not collective

    1066:    Input Parameter:
    1067: .  eps - the eigenproblem solver context

    1069:    Output Parameter:
    1070: .  is - the answer

    1072:    Level: intermediate

    1074: .seealso: EPSIsGeneralized(), EPSIsPositive()
    1075: @*/
    1076: PetscErrorCode EPSIsHermitian(EPS eps,PetscBool* is)
    1077: {
    1081:   *is = eps->ishermitian;
    1082:   return(0);
    1083: }

    1087: /*@
    1088:    EPSIsPositive - Ask if the EPS object corresponds to an eigenvalue
    1089:    problem type that requires a positive (semi-) definite matrix B.

    1091:    Not collective

    1093:    Input Parameter:
    1094: .  eps - the eigenproblem solver context

    1096:    Output Parameter:
    1097: .  is - the answer

    1099:    Level: intermediate

    1101: .seealso: EPSIsGeneralized(), EPSIsHermitian()
    1102: @*/
    1103: PetscErrorCode EPSIsPositive(EPS eps,PetscBool* is)
    1104: {
    1108:   *is = eps->ispositive;
    1109:   return(0);
    1110: }