Date: 2013-09-02T10:07:43+00:00

Actual source code: nepbasic.c

      1: /*
      2:    Basic NEP routines, Create, View, etc.

      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/nepimpl.h>      /*I "slepcnep.h" I*/

     26: PetscFunctionList NEPList = 0;
     27: PetscBool         NEPRegisterAllCalled = PETSC_FALSE;
     28: PetscClassId      NEP_CLASSID = 0;
     29: PetscLogEvent     NEP_SetUp = 0,NEP_Solve = 0,NEP_Dense = 0,NEP_FunctionEval = 0,NEP_JacobianEval = 0;
     30: static PetscBool  NEPPackageInitialized = PETSC_FALSE;

     34: /*@C
     35:    NEPFinalizePackage - This function destroys everything in the Slepc interface
     36:    to the NEP package. It is called from SlepcFinalize().

     38:    Level: developer

     40: .seealso: SlepcFinalize()
     41: @*/
     42: PetscErrorCode NEPFinalizePackage(void)
     43: {

     47:   PetscFunctionListDestroy(&NEPList);
     48:   NEPPackageInitialized = PETSC_FALSE;
     49:   NEPRegisterAllCalled  = PETSC_FALSE;
     50:   return(0);
     51: }

     55: /*@C
     56:    NEPInitializePackage - This function initializes everything in the NEP package. It is called
     57:    from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to NEPCreate()
     58:    when using static libraries.

     60:    Level: developer

     62: .seealso: SlepcInitialize()
     63: @*/
     64: PetscErrorCode NEPInitializePackage(void)
     65: {
     66:   char           logList[256];
     67:   char           *className;
     68:   PetscBool      opt;

     72:   if (NEPPackageInitialized) return(0);
     73:   NEPPackageInitialized = PETSC_TRUE;
     74:   /* Register Classes */
     75:   PetscClassIdRegister("Nonlinear Eigenvalue Problem solver",&NEP_CLASSID);
     76:   /* Register Constructors */
     77:   NEPRegisterAll();
     78:   /* Register Events */
     79:   PetscLogEventRegister("NEPSetUp",NEP_CLASSID,&NEP_SetUp);
     80:   PetscLogEventRegister("NEPSolve",NEP_CLASSID,&NEP_Solve);
     81:   PetscLogEventRegister("NEPDense",NEP_CLASSID,&NEP_Dense);
     82:   PetscLogEventRegister("NEPFunctionEval",NEP_CLASSID,&NEP_FunctionEval);
     83:   PetscLogEventRegister("NEPJacobianEval",NEP_CLASSID,&NEP_JacobianEval);
     84:   /* Process info exclusions */
     85:   PetscOptionsGetString(NULL,"-info_exclude",logList,256,&opt);
     86:   if (opt) {
     87:     PetscStrstr(logList,"nep",&className);
     88:     if (className) {
     89:       PetscInfoDeactivateClass(NEP_CLASSID);
     90:     }
     91:   }
     92:   /* Process summary exclusions */
     93:   PetscOptionsGetString(NULL,"-log_summary_exclude",logList,256,&opt);
     94:   if (opt) {
     95:     PetscStrstr(logList,"nep",&className);
     96:     if (className) {
     97:       PetscLogEventDeactivateClass(NEP_CLASSID);
     98:     }
     99:   }
    100:   PetscRegisterFinalize(NEPFinalizePackage);
    101:   return(0);
    102: }

    106: /*@C
    107:    NEPView - Prints the NEP data structure.

    109:    Collective on NEP

    111:    Input Parameters:
    112: +  nep - the nonlinear eigenproblem solver context
    113: -  viewer - optional visualization context

    115:    Options Database Key:
    116: .  -nep_view -  Calls NEPView() at end of NEPSolve()

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

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

    129:    Level: beginner

    131: .seealso: PetscViewerASCIIOpen()
    132: @*/
    133: PetscErrorCode NEPView(NEP nep,PetscViewer viewer)
    134: {
    136:   char           str[50];
    137:   PetscBool      isascii,isslp;

    141:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)nep));

    145:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    146:   if (isascii) {
    147:     PetscObjectPrintClassNamePrefixType((PetscObject)nep,viewer,"NEP Object");
    148:     if (nep->ops->view) {
    149:       PetscViewerASCIIPushTab(viewer);
    150:       (*nep->ops->view)(nep,viewer);
    151:       PetscViewerASCIIPopTab(viewer);
    152:     }
    153:     if (nep->split) {
    154:       PetscViewerASCIIPrintf(viewer,"  nonlinear operator in split form\n");
    155:     } else {
    156:       PetscViewerASCIIPrintf(viewer,"  nonlinear operator from user callbacks\n");
    157:     }
    158:     PetscViewerASCIIPrintf(viewer,"  selected portion of the spectrum: ");
    159:     SlepcSNPrintfScalar(str,50,nep->target,PETSC_FALSE);
    160:     if (!nep->which) {
    161:       PetscViewerASCIIPrintf(viewer,"not yet set\n");
    162:     } else switch (nep->which) {
    163:       case NEP_TARGET_MAGNITUDE:
    164:         PetscViewerASCIIPrintf(viewer,"closest to target: %s (in magnitude)\n",str);
    165:         break;
    166:       case NEP_TARGET_REAL:
    167:         PetscViewerASCIIPrintf(viewer,"closest to target: %s (along the real axis)\n",str);
    168:         break;
    169:       case NEP_TARGET_IMAGINARY:
    170:         PetscViewerASCIIPrintf(viewer,"closest to target: %s (along the imaginary axis)\n",str);
    171:         break;
    172:       case NEP_LARGEST_MAGNITUDE:
    173:         PetscViewerASCIIPrintf(viewer,"largest eigenvalues in magnitude\n");
    174:         break;
    175:       case NEP_SMALLEST_MAGNITUDE:
    176:         PetscViewerASCIIPrintf(viewer,"smallest eigenvalues in magnitude\n");
    177:         break;
    178:       case NEP_LARGEST_REAL:
    179:         PetscViewerASCIIPrintf(viewer,"largest real parts\n");
    180:         break;
    181:       case NEP_SMALLEST_REAL:
    182:         PetscViewerASCIIPrintf(viewer,"smallest real parts\n");
    183:         break;
    184:       case NEP_LARGEST_IMAGINARY:
    185:         PetscViewerASCIIPrintf(viewer,"largest imaginary parts\n");
    186:         break;
    187:       case NEP_SMALLEST_IMAGINARY:
    188:         PetscViewerASCIIPrintf(viewer,"smallest imaginary parts\n");
    189:         break;
    190:       default: SETERRQ(PetscObjectComm((PetscObject)nep),1,"Wrong value of nep->which");
    191:     }
    192:     PetscViewerASCIIPrintf(viewer,"  number of eigenvalues (nev): %D\n",nep->nev);
    193:     PetscViewerASCIIPrintf(viewer,"  number of column vectors (ncv): %D\n",nep->ncv);
    194:     PetscViewerASCIIPrintf(viewer,"  maximum dimension of projected problem (mpd): %D\n",nep->mpd);
    195:     PetscViewerASCIIPrintf(viewer,"  maximum number of iterations: %D\n",nep->max_it);
    196:     PetscViewerASCIIPrintf(viewer,"  maximum number of function evaluations: %D\n",nep->max_funcs);
    197:     PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",nep->rtol,nep->abstol,nep->stol);
    198:     if (nep->lag) {
    199:       PetscViewerASCIIPrintf(viewer,"  updating the preconditioner every %D iterations\n",nep->lag);
    200:     }
    201:     if (nep->cctol) {
    202:       PetscViewerASCIIPrintf(viewer,"  using a constant tolerance for the linear solver\n");
    203:     }
    204:     if (nep->nini) {
    205:       PetscViewerASCIIPrintf(viewer,"  dimension of user-provided initial space: %D\n",PetscAbs(nep->nini));
    206:     }
    207:   } else {
    208:     if (nep->ops->view) {
    209:       (*nep->ops->view)(nep,viewer);
    210:     }
    211:   }
    212:   if (!nep->ip) { NEPGetIP(nep,&nep->ip); }
    213:   IPView(nep->ip,viewer);
    214:   if (!nep->ds) { NEPGetDS(nep,&nep->ds); }
    215:   PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
    216:   DSView(nep->ds,viewer);
    217:   PetscViewerPopFormat(viewer);
    218:   PetscObjectTypeCompare((PetscObject)nep,NEPSLP,&isslp);
    219:   if (!isslp) {
    220:     if (!nep->ksp) { NEPGetKSP(nep,&nep->ksp); }
    221:     KSPView(nep->ksp,viewer);
    222:   }
    223:   return(0);
    224: }

    228: /*@C
    229:    NEPCreate - Creates the default NEP context.

    231:    Collective on MPI_Comm

    233:    Input Parameter:
    234: .  comm - MPI communicator

    236:    Output Parameter:
    237: .  nep - location to put the NEP context

    239:    Level: beginner

    241: .seealso: NEPSetUp(), NEPSolve(), NEPDestroy(), NEP
    242: @*/
    243: PetscErrorCode NEPCreate(MPI_Comm comm,NEP *outnep)
    244: {
    246:   NEP            nep;

    250:   *outnep = 0;
    251: #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
    252:   NEPInitializePackage();
    253: #endif

    255:   SlepcHeaderCreate(nep,_p_NEP,struct _NEPOps,NEP_CLASSID,"NEP","Nonlinear Eigenvalue Problem","NEP",comm,NEPDestroy,NEPView);

    257:   nep->max_it          = 0;
    258:   nep->max_funcs       = 0;
    259:   nep->nev             = 1;
    260:   nep->ncv             = 0;
    261:   nep->mpd             = 0;
    262:   nep->lag             = 1;
    263:   nep->nini            = 0;
    264:   nep->allocated_ncv   = 0;
    265:   nep->ip              = 0;
    266:   nep->ds              = 0;
    267:   nep->function        = 0;
    268:   nep->function_pre    = 0;
    269:   nep->jacobian        = 0;
    270:   nep->abstol          = PETSC_DEFAULT;
    271:   nep->rtol            = PETSC_DEFAULT;
    272:   nep->stol            = PETSC_DEFAULT;
    273:   nep->ktol            = 0.1;
    274:   nep->cctol           = PETSC_FALSE;
    275:   nep->ttol            = 0.0;
    276:   nep->which           = (NEPWhich)0;
    277:   nep->computefunction = NULL;
    278:   nep->computejacobian = NULL;
    279:   nep->comparison      = NULL;
    280:   nep->converged       = NEPConvergedDefault;
    281:   nep->convergeddestroy= NULL;
    282:   nep->comparisonctx   = NULL;
    283:   nep->convergedctx    = NULL;
    284:   nep->functionctx     = NULL;
    285:   nep->jacobianctx     = NULL;
    286:   nep->V               = NULL;
    287:   nep->IS              = NULL;
    288:   nep->eig             = NULL;
    289:   nep->errest          = NULL;
    290:   nep->data            = NULL;
    291:   nep->t               = NULL;
    292:   nep->split           = PETSC_FALSE;
    293:   nep->nt              = 0;
    294:   nep->mstr            = DIFFERENT_NONZERO_PATTERN;
    295:   nep->A               = NULL;
    296:   nep->f               = NULL;
    297:   nep->nconv           = 0;
    298:   nep->its             = 0;
    299:   nep->perm            = NULL;
    300:   nep->nfuncs          = 0;
    301:   nep->linits          = 0;
    302:   nep->nwork           = 0;
    303:   nep->work            = NULL;
    304:   nep->setupcalled     = 0;
    305:   nep->reason          = NEP_CONVERGED_ITERATING;
    306:   nep->numbermonitors  = 0;
    307:   nep->trackall        = PETSC_FALSE;
    308:   nep->rand            = 0;

    310:   PetscRandomCreate(comm,&nep->rand);
    311:   PetscRandomSetSeed(nep->rand,0x12345678);
    312:   PetscLogObjectParent(nep,nep->rand);
    313:   *outnep = nep;
    314:   return(0);
    315: }

    319: /*@C
    320:    NEPSetType - Selects the particular solver to be used in the NEP object.

    322:    Logically Collective on NEP

    324:    Input Parameters:
    325: +  nep      - the nonlinear eigensolver context
    326: -  type     - a known method

    328:    Options Database Key:
    329: .  -nep_type <method> - Sets the method; use -help for a list
    330:     of available methods

    332:    Notes:
    333:    See "slepc/include/slepcnep.h" for available methods.

    335:    Normally, it is best to use the NEPSetFromOptions() command and
    336:    then set the NEP type from the options database rather than by using
    337:    this routine.  Using the options database provides the user with
    338:    maximum flexibility in evaluating the different available methods.
    339:    The NEPSetType() routine is provided for those situations where it
    340:    is necessary to set the iterative solver independently of the command
    341:    line or options database.

    343:    Level: intermediate

    345: .seealso: NEPType
    346: @*/
    347: PetscErrorCode NEPSetType(NEP nep,NEPType type)
    348: {
    349:   PetscErrorCode ierr,(*r)(NEP);
    350:   PetscBool      match;

    356:   PetscObjectTypeCompare((PetscObject)nep,type,&match);
    357:   if (match) return(0);

    359:   PetscFunctionListFind(NEPList,type,&r);
    360:   if (!r) SETERRQ1(PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown NEP type given: %s",type);

    362:   if (nep->ops->destroy) { (*nep->ops->destroy)(nep); }
    363:   PetscMemzero(nep->ops,sizeof(struct _NEPOps));

    365:   nep->setupcalled = 0;
    366:   PetscObjectChangeTypeName((PetscObject)nep,type);
    367:   (*r)(nep);
    368:   return(0);
    369: }

    373: /*@C
    374:    NEPGetType - Gets the NEP type as a string from the NEP object.

    376:    Not Collective

    378:    Input Parameter:
    379: .  nep - the eigensolver context

    381:    Output Parameter:
    382: .  name - name of NEP method

    384:    Level: intermediate

    386: .seealso: NEPSetType()
    387: @*/
    388: PetscErrorCode NEPGetType(NEP nep,NEPType *type)
    389: {
    393:   *type = ((PetscObject)nep)->type_name;
    394:   return(0);
    395: }

    399: /*@C
    400:    NEPRegister - Adds a method to the quadratic eigenproblem solver package.

    402:    Not Collective

    404:    Input Parameters:
    405: +  name - name of a new user-defined solver
    406: -  function - routine to create the solver context

    408:    Notes:
    409:    NEPRegister() may be called multiple times to add several user-defined solvers.

    411:    Sample usage:
    412: .vb
    413:    NEPRegister("my_solver",MySolverCreate);
    414: .ve

    416:    Then, your solver can be chosen with the procedural interface via
    417: $     NEPSetType(qep,"my_solver")
    418:    or at runtime via the option
    419: $     -qep_type my_solver

    421:    Level: advanced

    423: .seealso: NEPRegisterAll()
    424: @*/
    425: PetscErrorCode NEPRegister(const char *name,PetscErrorCode (*function)(NEP))
    426: {

    430:   PetscFunctionListAdd(&NEPList,name,function);
    431:   return(0);
    432: }

    436: /*@
    437:    NEPReset - Resets the NEP context to the setupcalled=0 state and removes any
    438:    allocated objects.

    440:    Collective on NEP

    442:    Input Parameter:
    443: .  nep - eigensolver context obtained from NEPCreate()

    445:    Level: advanced

    447: .seealso: NEPDestroy()
    448: @*/
    449: PetscErrorCode NEPReset(NEP nep)
    450: {

    455:   if (nep->ops->reset) { (nep->ops->reset)(nep); }
    456:   if (nep->ip) { IPReset(nep->ip); }
    457:   if (nep->ds) { DSReset(nep->ds); }
    458:   VecDestroy(&nep->t);
    459:   NEPFreeSolution(nep);
    460:   nep->nfuncs      = 0;
    461:   nep->linits      = 0;
    462:   nep->setupcalled = 0;
    463:   return(0);
    464: }

    468: /*@C
    469:    NEPDestroy - Destroys the NEP context.

    471:    Collective on NEP

    473:    Input Parameter:
    474: .  nep - eigensolver context obtained from NEPCreate()

    476:    Level: beginner

    478: .seealso: NEPCreate(), NEPSetUp(), NEPSolve()
    479: @*/
    480: PetscErrorCode NEPDestroy(NEP *nep)
    481: {
    483:   PetscInt       i;

    486:   if (!*nep) return(0);
    488:   if (--((PetscObject)(*nep))->refct > 0) { *nep = 0; return(0); }
    489:   NEPReset(*nep);
    490:   if ((*nep)->ops->destroy) { (*(*nep)->ops->destroy)(*nep); }
    491:   KSPDestroy(&(*nep)->ksp);
    492:   IPDestroy(&(*nep)->ip);
    493:   DSDestroy(&(*nep)->ds);
    494:   MatDestroy(&(*nep)->function);
    495:   MatDestroy(&(*nep)->function_pre);
    496:   MatDestroy(&(*nep)->jacobian);
    497:   if ((*nep)->split) {
    498:     MatDestroyMatrices((*nep)->nt,&(*nep)->A);
    499:     for (i=0;i<(*nep)->nt;i++) {
    500:       FNDestroy(&(*nep)->f[i]);
    501:     }
    502:     PetscFree((*nep)->f);
    503:   }
    504:   PetscRandomDestroy(&(*nep)->rand);
    505:   /* just in case the initial vectors have not been used */
    506:   SlepcBasisDestroy_Private(&(*nep)->nini,&(*nep)->IS);
    507:   NEPMonitorCancel(*nep);
    508:   PetscHeaderDestroy(nep);
    509:   return(0);
    510: }

    514: /*@
    515:    NEPSetIP - Associates an inner product object to the nonlinear eigensolver.

    517:    Collective on NEP

    519:    Input Parameters:
    520: +  nep - eigensolver context obtained from NEPCreate()
    521: -  ip  - the inner product object

    523:    Note:
    524:    Use NEPGetIP() to retrieve the inner product context (for example,
    525:    to free it at the end of the computations).

    527:    Level: advanced

    529: .seealso: NEPGetIP()
    530: @*/
    531: PetscErrorCode NEPSetIP(NEP nep,IP ip)
    532: {

    539:   PetscObjectReference((PetscObject)ip);
    540:   IPDestroy(&nep->ip);
    541:   nep->ip = ip;
    542:   PetscLogObjectParent(nep,nep->ip);
    543:   return(0);
    544: }

    548: /*@C
    549:    NEPGetIP - Obtain the inner product object associated
    550:    to the nonlinear eigensolver object.

    552:    Not Collective

    554:    Input Parameters:
    555: .  nep - eigensolver context obtained from NEPCreate()

    557:    Output Parameter:
    558: .  ip - inner product context

    560:    Level: advanced

    562: .seealso: NEPSetIP()
    563: @*/
    564: PetscErrorCode NEPGetIP(NEP nep,IP *ip)
    565: {

    571:   if (!nep->ip) {
    572:     IPCreate(PetscObjectComm((PetscObject)nep),&nep->ip);
    573:     PetscLogObjectParent(nep,nep->ip);
    574:   }
    575:   *ip = nep->ip;
    576:   return(0);
    577: }

    581: /*@
    582:    NEPSetDS - Associates a direct solver object to the nonlinear eigensolver.

    584:    Collective on NEP

    586:    Input Parameters:
    587: +  nep - eigensolver context obtained from NEPCreate()
    588: -  ds  - the direct solver object

    590:    Note:
    591:    Use NEPGetDS() to retrieve the direct solver context (for example,
    592:    to free it at the end of the computations).

    594:    Level: advanced

    596: .seealso: NEPGetDS()
    597: @*/
    598: PetscErrorCode NEPSetDS(NEP nep,DS ds)
    599: {

    606:   PetscObjectReference((PetscObject)ds);
    607:   DSDestroy(&nep->ds);
    608:   nep->ds = ds;
    609:   PetscLogObjectParent(nep,nep->ds);
    610:   return(0);
    611: }

    615: /*@C
    616:    NEPGetDS - Obtain the direct solver object associated to the
    617:    nonlinear eigensolver object.

    619:    Not Collective

    621:    Input Parameters:
    622: .  nep - eigensolver context obtained from NEPCreate()

    624:    Output Parameter:
    625: .  ds - direct solver context

    627:    Level: advanced

    629: .seealso: NEPSetDS()
    630: @*/
    631: PetscErrorCode NEPGetDS(NEP nep,DS *ds)
    632: {

    638:   if (!nep->ds) {
    639:     DSCreate(PetscObjectComm((PetscObject)nep),&nep->ds);
    640:     PetscLogObjectParent(nep,nep->ds);
    641:   }
    642:   *ds = nep->ds;
    643:   return(0);
    644: }

    648: /*@
    649:    NEPSetKSP - Associates a linear solver object to the nonlinear eigensolver.

    651:    Collective on NEP

    653:    Input Parameters:
    654: +  nep - eigensolver context obtained from NEPCreate()
    655: -  ksp - the linear solver object

    657:    Note:
    658:    Use NEPGetKSP() to retrieve the linear solver context (for example,
    659:    to free it at the end of the computations).

    661:    Level: developer

    663: .seealso: NEPGetKSP()
    664: @*/
    665: PetscErrorCode NEPSetKSP(NEP nep,KSP ksp)
    666: {

    673:   PetscObjectReference((PetscObject)ksp);
    674:   KSPDestroy(&nep->ksp);
    675:   nep->ksp = ksp;
    676:   PetscLogObjectParent(nep,nep->ksp);
    677:   return(0);
    678: }

    682: /*@C
    683:    NEPGetKSP - Obtain the linear solver (KSP) object associated
    684:    to the eigensolver object.

    686:    Not Collective

    688:    Input Parameters:
    689: .  nep - eigensolver context obtained from NEPCreate()

    691:    Output Parameter:
    692: .  ksp - linear solver context

    694:    Level: beginner

    696: .seealso: NEPSetKSP()
    697: @*/
    698: PetscErrorCode NEPGetKSP(NEP nep,KSP *ksp)
    699: {

    705:   if (!nep->ksp) {
    706:     KSPCreate(PetscObjectComm((PetscObject)nep),&nep->ksp);
    707:     KSPSetOptionsPrefix(nep->ksp,((PetscObject)nep)->prefix);
    708:     KSPAppendOptionsPrefix(nep->ksp,"nep_");
    709:     PetscObjectIncrementTabLevel((PetscObject)nep->ksp,(PetscObject)nep,1);
    710:     PetscLogObjectParent(nep,nep->ksp);
    711:   }
    712:   *ksp = nep->ksp;
    713:   return(0);
    714: }

    718: /*@
    719:    NEPSetTarget - Sets the value of the target.

    721:    Logically Collective on NEP

    723:    Input Parameters:
    724: +  nep    - eigensolver context
    725: -  target - the value of the target

    727:    Notes:
    728:    The target is a scalar value used to determine the portion of the spectrum
    729:    of interest. It is used in combination with NEPSetWhichEigenpairs().

    731:    Level: beginner

    733: .seealso: NEPGetTarget(), NEPSetWhichEigenpairs()
    734: @*/
    735: PetscErrorCode NEPSetTarget(NEP nep,PetscScalar target)
    736: {
    740:   nep->target = target;
    741:   return(0);
    742: }

    746: /*@
    747:    NEPGetTarget - Gets the value of the target.

    749:    Not Collective

    751:    Input Parameter:
    752: .  nep - eigensolver context

    754:    Output Parameter:
    755: .  target - the value of the target

    757:    Level: beginner

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

    762: .seealso: NEPSetTarget()
    763: @*/
    764: PetscErrorCode NEPGetTarget(NEP nep,PetscScalar* target)
    765: {
    769:   *target = nep->target;
    770:   return(0);
    771: }

    775: /*@C
    776:    NEPSetFunction - Sets the function to compute the nonlinear Function T(lambda)
    777:    as well as the location to store the matrix.

    779:    Logically Collective on NEP and Mat

    781:    Input Parameters:
    782: +  nep - the NEP context
    783: .  A   - Function matrix
    784: .  B   - preconditioner matrix (usually same as the Function)
    785: .  fun - Function evaluation routine (if NULL then NEP retains any
    786:          previously set value)
    787: -  ctx - [optional] user-defined context for private data for the Function
    788:          evaluation routine (may be NULL) (if NULL then NEP retains any
    789:          previously set value)

    791:    Notes:
    792:    The routine fun() takes Mat* as the matrix arguments rather than Mat.
    793:    This allows the Function evaluation routine to replace A and/or B with a
    794:    completely new matrix structure (not just different matrix elements)
    795:    when appropriate, for instance, if the nonzero structure is changing
    796:    throughout the global iterations.

    798:    Level: beginner

    800: .seealso: NEPGetFunction(), NEPSetJacobian()
    801: @*/
    802: PetscErrorCode NEPSetFunction(NEP nep,Mat A,Mat B,PetscErrorCode (*fun)(NEP,PetscScalar,Mat*,Mat*,MatStructure*,void*),void *ctx)
    803: {

    812:   if (fun) nep->computefunction = fun;
    813:   if (ctx) nep->functionctx     = ctx;
    814:   if (A) {
    815:     PetscObjectReference((PetscObject)A);
    816:     MatDestroy(&nep->function);
    817:     nep->function = A;
    818:   }
    819:   if (B) {
    820:     PetscObjectReference((PetscObject)B);
    821:     MatDestroy(&nep->function_pre);
    822:     nep->function_pre = B;
    823:   }
    824:   nep->split = PETSC_FALSE;
    825:   return(0);
    826: }

    830: /*@C
    831:    NEPGetFunction - Returns the Function matrix and optionally the user
    832:    provided context for evaluating the Function.

    834:    Not Collective, but Mat object will be parallel if NEP object is

    836:    Input Parameter:
    837: .  nep - the nonlinear eigensolver context

    839:    Output Parameters:
    840: +  A   - location to stash Function matrix (or NULL)
    841: .  B   - location to stash preconditioner matrix (or NULL)
    842: .  fun - location to put Function function (or NULL)
    843: -  ctx - location to stash Function context (or NULL)

    845:    Level: advanced

    847: .seealso: NEPSetFunction()
    848: @*/
    849: PetscErrorCode NEPGetFunction(NEP nep,Mat *A,Mat *B,PetscErrorCode (**fun)(NEP,PetscScalar,Mat*,Mat*,MatStructure*,void*),void **ctx)
    850: {
    853:   if (A)   *A   = nep->function;
    854:   if (B)   *B   = nep->function_pre;
    855:   if (fun) *fun = nep->computefunction;
    856:   if (ctx) *ctx = nep->functionctx;
    857:   return(0);
    858: }

    862: /*@C
    863:    NEPSetJacobian - Sets the function to compute Jacobian T'(lambda) as well
    864:    as the location to store the matrix.

    866:    Logically Collective on NEP and Mat

    868:    Input Parameters:
    869: +  nep - the NEP context
    870: .  A   - Jacobian matrix
    871: .  jac - Jacobian evaluation routine (if NULL then NEP retains any
    872:          previously set value)
    873: -  ctx - [optional] user-defined context for private data for the Jacobian
    874:          evaluation routine (may be NULL) (if NULL then NEP retains any
    875:          previously set value)

    877:    Notes:
    878:    The routine jac() takes Mat* as the matrix arguments rather than Mat.
    879:    This allows the Jacobian evaluation routine to replace A with a
    880:    completely new matrix structure (not just different matrix elements)
    881:    when appropriate, for instance, if the nonzero structure is changing
    882:    throughout the global iterations.

    884:    Level: beginner

    886: .seealso: NEPSetFunction(), NEPGetJacobian()
    887: @*/
    888: PetscErrorCode NEPSetJacobian(NEP nep,Mat A,PetscErrorCode (*jac)(NEP,PetscScalar,Mat*,MatStructure*,void*),void *ctx)
    889: {

    896:   if (jac) nep->computejacobian = jac;
    897:   if (ctx) nep->jacobianctx     = ctx;
    898:   if (A) {
    899:     PetscObjectReference((PetscObject)A);
    900:     MatDestroy(&nep->jacobian);
    901:     nep->jacobian = A;
    902:   }
    903:   nep->split = PETSC_FALSE;
    904:   return(0);
    905: }

    909: /*@C
    910:    NEPGetJacobian - Returns the Jacobian matrix and optionally the user
    911:    provided context for evaluating the Jacobian.

    913:    Not Collective, but Mat object will be parallel if NEP object is

    915:    Input Parameter:
    916: .  nep - the nonlinear eigensolver context

    918:    Output Parameters:
    919: +  A   - location to stash Jacobian matrix (or NULL)
    920: .  jac - location to put Jacobian function (or NULL)
    921: -  ctx - location to stash Jacobian context (or NULL)

    923:    Level: advanced

    925: .seealso: NEPSetJacobian()
    926: @*/
    927: PetscErrorCode NEPGetJacobian(NEP nep,Mat *A,PetscErrorCode (**jac)(NEP,PetscScalar,Mat*,MatStructure*,void*),void **ctx)
    928: {
    931:   if (A)   *A   = nep->jacobian;
    932:   if (jac) *jac = nep->computejacobian;
    933:   if (ctx) *ctx = nep->jacobianctx;
    934:   return(0);
    935: }

    939: /*@
    940:    NEPSetSplitOperator - Sets the operator of the nonlinear eigenvalue problem
    941:    in split form.

    943:    Collective on NEP, Mat and FN

    945:    Input Parameters:
    946: +  nep - the nonlinear eigensolver context
    947: .  n   - number of terms in the split form
    948: .  A   - array of matrices
    949: .  f   - array of functions
    950: -  str - structure flag for matrices

    952:    Notes:
    953:    The nonlinear operator is written as T(lambda) = sum_i A_i*f_i(lambda),
    954:    for i=1,...,n. The derivative T'(lambda) can be obtained using the
    955:    derivatives of f_i.

    957:    The structure flag provides information about A_i's nonzero pattern
    958:    (see MatStructure enum). If all matrices have the same pattern, then
    959:    use SAME_NONZERO_PATTERN. If the patterns are different but contained
    960:    in the pattern of the first one, then use SUBSET_NONZERO_PATTERN.
    961:    Otherwise use DIFFERENT_NONZERO_PATTERN.

    963:    This function must be called before NEPSetUp(). If it is called again
    964:    after NEPSetUp() then the NEP object is reset.

    966:    Level: intermediate

    968: .seealso: NEPGetSplitOperatorTerm(), NEPGetSplitOperatorInfo()
    969:  @*/
    970: PetscErrorCode NEPSetSplitOperator(NEP nep,PetscInt n,Mat A[],FN f[],MatStructure str)
    971: {
    972:   PetscInt       i;

    978:   if (n <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more terms, you have %D",n);
    983:   if (nep->setupcalled) { NEPReset(nep); }
    984:   /* clean previously stored information */
    985:   MatDestroy(&nep->function);
    986:   MatDestroy(&nep->function_pre);
    987:   MatDestroy(&nep->jacobian);
    988:   if (nep->split) {
    989:     MatDestroyMatrices(nep->nt,&nep->A);
    990:     for (i=0;i<nep->nt;i++) {
    991:       FNDestroy(&nep->f[i]);
    992:     }
    993:     PetscFree(nep->f);
    994:   }
    995:   /* allocate space and copy matrices and functions */
    996:   PetscMalloc(n*sizeof(Mat),&nep->A);
    997:   PetscLogObjectMemory(nep,n*sizeof(Mat));
    998:   for (i=0;i<n;i++) {
    1000:     PetscObjectReference((PetscObject)A[i]);
    1001:     nep->A[i] = A[i];
    1002:   }
    1003:   PetscMalloc(n*sizeof(FN),&nep->f);
    1004:   PetscLogObjectMemory(nep,n*sizeof(FN));
    1005:   for (i=0;i<n;i++) {
    1007:     PetscObjectReference((PetscObject)f[i]);
    1008:     nep->f[i] = f[i];
    1009:   }
    1010:   nep->nt    = n;
    1011:   nep->mstr  = str;
    1012:   nep->split = PETSC_TRUE;
    1013:   return(0);
    1014: }

    1018: /*@
    1019:    NEPGetSplitOperatorTerm - Gets the matrices and functions associated with
    1020:    the nonlinear operator in split form.

    1022:    Not collective, though parallel Mats and FNs are returned if the NEP is parallel

    1024:    Input Parameter:
    1025: +  nep - the nonlinear eigensolver context
    1026: -  k   - the index of the requested term (starting in 0)

    1028:    Output Parameters:
    1029: +  A - the matrix of the requested term
    1030: -  f - the function of the requested term

    1032:    Level: intermediate

    1034: .seealso: NEPSetSplitOperator(), NEPGetSplitOperatorInfo()
    1035: @*/
    1036: PetscErrorCode NEPGetSplitOperatorTerm(NEP nep,PetscInt k,Mat *A,FN *f)
    1037: {
    1040:   if (k<0 || k>=nep->nt) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"k must be between 0 and %d",nep->nt-1);
    1041:   if (A) *A = nep->A[k];
    1042:   if (f) *f = nep->f[k];
    1043:   return(0);
    1044: }

    1048: /*@
    1049:    NEPGetSplitOperatorInfo - Returns the number of terms of the split form of
    1050:    the nonlinear operator, as well as the structure flag for matrices.

    1052:    Not collective

    1054:    Input Parameter:
    1055: .  nep - the nonlinear eigensolver context

    1057:    Output Parameters:
    1058: +  n   - the number of terms passed in NEPSetSplitOperator()
    1059: -  str - the matrix structure flag passed in NEPSetSplitOperator()

    1061:    Level: intermediate

    1063: .seealso: NEPSetSplitOperator(), NEPGetSplitOperatorTerm()
    1064: @*/
    1065: PetscErrorCode NEPGetSplitOperatorInfo(NEP nep,PetscInt *n,MatStructure *str)
    1066: {
    1069:   if (n) *n = nep->nt;
    1070:   if (str) *str = nep->mstr;
    1071:   return(0);
    1072: }