Date: 2020-01-13T12:01:40+00:00

Actual source code: nepbasic.c
slepc-3.12.2 2020-01-13
Report Typos and Errors

      1: /*
      2:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      3:    SLEPc - Scalable Library for Eigenvalue Problem Computations
      4:    Copyright (c) 2002-2019, 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:    Basic NEP routines
     12: */

     14: #include <slepc/private/nepimpl.h>      /*I "slepcnep.h" I*/

     16: PetscFunctionList NEPList = 0;
     17: PetscBool         NEPRegisterAllCalled = PETSC_FALSE;
     18: PetscClassId      NEP_CLASSID = 0;
     19: PetscLogEvent     NEP_SetUp = 0,NEP_Solve = 0,NEP_Refine = 0,NEP_FunctionEval = 0,NEP_JacobianEval = 0,NEP_Resolvent = 0;

     21: /*@
     22:    NEPCreate - Creates the default NEP context.

     24:    Collective

     26:    Input Parameter:
     27: .  comm - MPI communicator

     29:    Output Parameter:
     30: .  nep - location to put the NEP context

     32:    Level: beginner

     34: .seealso: NEPSetUp(), NEPSolve(), NEPDestroy(), NEP
     35: @*/
     36: PetscErrorCode NEPCreate(MPI_Comm comm,NEP *outnep)
     37: {
     39:   NEP            nep;

     43:   *outnep = 0;
     44:   NEPInitializePackage();
     45:   SlepcHeaderCreate(nep,NEP_CLASSID,"NEP","Nonlinear Eigenvalue Problem","NEP",comm,NEPDestroy,NEPView);

     47:   nep->max_it          = 0;
     48:   nep->nev             = 1;
     49:   nep->ncv             = 0;
     50:   nep->mpd             = 0;
     51:   nep->nini            = 0;
     52:   nep->target          = 0.0;
     53:   nep->tol             = PETSC_DEFAULT;
     54:   nep->conv            = NEP_CONV_REL;
     55:   nep->stop            = NEP_STOP_BASIC;
     56:   nep->which           = (NEPWhich)0;
     57:   nep->problem_type    = (NEPProblemType)0;
     58:   nep->refine          = NEP_REFINE_NONE;
     59:   nep->npart           = 1;
     60:   nep->rtol            = PETSC_DEFAULT;
     61:   nep->rits            = PETSC_DEFAULT;
     62:   nep->scheme          = (NEPRefineScheme)0;
     63:   nep->trackall        = PETSC_FALSE;
     64:   nep->twosided        = PETSC_FALSE;

     66:   nep->computefunction = NULL;
     67:   nep->computejacobian = NULL;
     68:   nep->functionctx     = NULL;
     69:   nep->jacobianctx     = NULL;
     70:   nep->converged       = NEPConvergedRelative;
     71:   nep->convergeduser   = NULL;
     72:   nep->convergeddestroy= NULL;
     73:   nep->stopping        = NEPStoppingBasic;
     74:   nep->stoppinguser    = NULL;
     75:   nep->stoppingdestroy = NULL;
     76:   nep->convergedctx    = NULL;
     77:   nep->stoppingctx     = NULL;
     78:   nep->numbermonitors  = 0;

     80:   nep->ds              = NULL;
     81:   nep->V               = NULL;
     82:   nep->W               = NULL;
     83:   nep->rg              = NULL;
     84:   nep->function        = NULL;
     85:   nep->function_pre    = NULL;
     86:   nep->jacobian        = NULL;
     87:   nep->A               = NULL;
     88:   nep->f               = NULL;
     89:   nep->nt              = 0;
     90:   nep->mstr            = DIFFERENT_NONZERO_PATTERN;
     91:   nep->IS              = NULL;
     92:   nep->eigr            = NULL;
     93:   nep->eigi            = NULL;
     94:   nep->errest          = NULL;
     95:   nep->perm            = NULL;
     96:   nep->nwork           = 0;
     97:   nep->work            = NULL;
     98:   nep->data            = NULL;

    100:   nep->state           = NEP_STATE_INITIAL;
    101:   nep->nconv           = 0;
    102:   nep->its             = 0;
    103:   nep->n               = 0;
    104:   nep->nloc            = 0;
    105:   nep->nrma            = NULL;
    106:   nep->fui             = (NEPUserInterface)0;
    107:   nep->useds           = PETSC_FALSE;
    108:   nep->hasts           = PETSC_FALSE;
    109:   nep->resolvent       = NULL;
    110:   nep->reason          = NEP_CONVERGED_ITERATING;

    112:   PetscNewLog(nep,&nep->sc);
    113:   *outnep = nep;
    114:   return(0);
    115: }

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

    120:    Logically Collective on nep

    122:    Input Parameters:
    123: +  nep      - the nonlinear eigensolver context
    124: -  type     - a known method

    126:    Options Database Key:
    127: .  -nep_type <method> - Sets the method; use -help for a list
    128:     of available methods

    130:    Notes:
    131:    See "slepc/include/slepcnep.h" for available methods.

    133:    Normally, it is best to use the NEPSetFromOptions() command and
    134:    then set the NEP type from the options database rather than by using
    135:    this routine.  Using the options database provides the user with
    136:    maximum flexibility in evaluating the different available methods.
    137:    The NEPSetType() routine is provided for those situations where it
    138:    is necessary to set the iterative solver independently of the command
    139:    line or options database.

    141:    Level: intermediate

    143: .seealso: NEPType
    144: @*/
    145: PetscErrorCode NEPSetType(NEP nep,NEPType type)
    146: {
    147:   PetscErrorCode ierr,(*r)(NEP);
    148:   PetscBool      match;

    154:   PetscObjectTypeCompare((PetscObject)nep,type,&match);
    155:   if (match) return(0);

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

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

    163:   nep->state = NEP_STATE_INITIAL;
    164:   PetscObjectChangeTypeName((PetscObject)nep,type);
    165:   (*r)(nep);
    166:   return(0);
    167: }

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

    172:    Not Collective

    174:    Input Parameter:
    175: .  nep - the eigensolver context

    177:    Output Parameter:
    178: .  name - name of NEP method

    180:    Level: intermediate

    182: .seealso: NEPSetType()
    183: @*/
    184: PetscErrorCode NEPGetType(NEP nep,NEPType *type)
    185: {
    189:   *type = ((PetscObject)nep)->type_name;
    190:   return(0);
    191: }

    193: /*@C
    194:    NEPRegister - Adds a method to the nonlinear eigenproblem solver package.

    196:    Not Collective

    198:    Input Parameters:
    199: +  name - name of a new user-defined solver
    200: -  function - routine to create the solver context

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

    205:    Sample usage:
    206: .vb
    207:     NEPRegister("my_solver",MySolverCreate);
    208: .ve

    210:    Then, your solver can be chosen with the procedural interface via
    211: $     NEPSetType(nep,"my_solver")
    212:    or at runtime via the option
    213: $     -nep_type my_solver

    215:    Level: advanced

    217: .seealso: NEPRegisterAll()
    218: @*/
    219: PetscErrorCode NEPRegister(const char *name,PetscErrorCode (*function)(NEP))
    220: {

    224:   NEPInitializePackage();
    225:   PetscFunctionListAdd(&NEPList,name,function);
    226:   return(0);
    227: }

    229: /*
    230:    NEPReset_Problem - Destroys the problem matrices.
    231: @*/
    232: PetscErrorCode NEPReset_Problem(NEP nep)
    233: {
    235:   PetscInt       i;

    239:   MatDestroy(&nep->function);
    240:   MatDestroy(&nep->function_pre);
    241:   MatDestroy(&nep->jacobian);
    242:   if (nep->fui==NEP_USER_INTERFACE_SPLIT) {
    243:     MatDestroyMatrices(nep->nt,&nep->A);
    244:     for (i=0;i<nep->nt;i++) {
    245:       FNDestroy(&nep->f[i]);
    246:     }
    247:     PetscFree(nep->f);
    248:     PetscFree(nep->nrma);
    249:     nep->nt = 0;
    250:   }
    251:   return(0);
    252: }
    253: /*@
    254:    NEPReset - Resets the NEP context to the initial state (prior to setup)
    255:    and destroys any allocated Vecs and Mats.

    257:    Collective on nep

    259:    Input Parameter:
    260: .  nep - eigensolver context obtained from NEPCreate()

    262:    Level: advanced

    264: .seealso: NEPDestroy()
    265: @*/
    266: PetscErrorCode NEPReset(NEP nep)
    267: {

    272:   if (!nep) return(0);
    273:   if (nep->ops->reset) { (nep->ops->reset)(nep); }
    274:   if (nep->refineksp) { KSPReset(nep->refineksp); }
    275:   NEPReset_Problem(nep);
    276:   BVDestroy(&nep->V);
    277:   BVDestroy(&nep->W);
    278:   VecDestroyVecs(nep->nwork,&nep->work);
    279:   MatDestroy(&nep->resolvent);
    280:   nep->nwork = 0;
    281:   nep->state = NEP_STATE_INITIAL;
    282:   return(0);
    283: }

    285: /*@
    286:    NEPDestroy - Destroys the NEP context.

    288:    Collective on nep

    290:    Input Parameter:
    291: .  nep - eigensolver context obtained from NEPCreate()

    293:    Level: beginner

    295: .seealso: NEPCreate(), NEPSetUp(), NEPSolve()
    296: @*/
    297: PetscErrorCode NEPDestroy(NEP *nep)
    298: {

    302:   if (!*nep) return(0);
    304:   if (--((PetscObject)(*nep))->refct > 0) { *nep = 0; return(0); }
    305:   NEPReset(*nep);
    306:   if ((*nep)->ops->destroy) { (*(*nep)->ops->destroy)(*nep); }
    307:   if ((*nep)->eigr) {
    308:     PetscFree4((*nep)->eigr,(*nep)->eigi,(*nep)->errest,(*nep)->perm);
    309:   }
    310:   RGDestroy(&(*nep)->rg);
    311:   DSDestroy(&(*nep)->ds);
    312:   KSPDestroy(&(*nep)->refineksp);
    313:   PetscSubcommDestroy(&(*nep)->refinesubc);
    314:   PetscFree((*nep)->sc);
    315:   /* just in case the initial vectors have not been used */
    316:   SlepcBasisDestroy_Private(&(*nep)->nini,&(*nep)->IS);
    317:   if ((*nep)->convergeddestroy) {
    318:     (*(*nep)->convergeddestroy)((*nep)->convergedctx);
    319:   }
    320:   NEPMonitorCancel(*nep);
    321:   PetscHeaderDestroy(nep);
    322:   return(0);
    323: }

    325: /*@
    326:    NEPSetBV - Associates a basis vectors object to the nonlinear eigensolver.

    328:    Collective on nep

    330:    Input Parameters:
    331: +  nep - eigensolver context obtained from NEPCreate()
    332: -  bv  - the basis vectors object

    334:    Note:
    335:    Use NEPGetBV() to retrieve the basis vectors context (for example,
    336:    to free it at the end of the computations).

    338:    Level: advanced

    340: .seealso: NEPGetBV()
    341: @*/
    342: PetscErrorCode NEPSetBV(NEP nep,BV bv)
    343: {

    350:   PetscObjectReference((PetscObject)bv);
    351:   BVDestroy(&nep->V);
    352:   nep->V = bv;
    353:   PetscLogObjectParent((PetscObject)nep,(PetscObject)nep->V);
    354:   return(0);
    355: }

    357: /*@
    358:    NEPGetBV - Obtain the basis vectors object associated to the nonlinear
    359:    eigensolver object.

    361:    Not Collective

    363:    Input Parameters:
    364: .  nep - eigensolver context obtained from NEPCreate()

    366:    Output Parameter:
    367: .  bv - basis vectors context

    369:    Level: advanced

    371: .seealso: NEPSetBV()
    372: @*/
    373: PetscErrorCode NEPGetBV(NEP nep,BV *bv)
    374: {

    380:   if (!nep->V) {
    381:     BVCreate(PetscObjectComm((PetscObject)nep),&nep->V);
    382:     PetscObjectIncrementTabLevel((PetscObject)nep->V,(PetscObject)nep,0);
    383:     PetscLogObjectParent((PetscObject)nep,(PetscObject)nep->V);
    384:     PetscObjectSetOptions((PetscObject)nep->V,((PetscObject)nep)->options);
    385:   }
    386:   *bv = nep->V;
    387:   return(0);
    388: }

    390: /*@
    391:    NEPSetRG - Associates a region object to the nonlinear eigensolver.

    393:    Collective on nep

    395:    Input Parameters:
    396: +  nep - eigensolver context obtained from NEPCreate()
    397: -  rg  - the region object

    399:    Note:
    400:    Use NEPGetRG() to retrieve the region context (for example,
    401:    to free it at the end of the computations).

    403:    Level: advanced

    405: .seealso: NEPGetRG()
    406: @*/
    407: PetscErrorCode NEPSetRG(NEP nep,RG rg)
    408: {

    415:   PetscObjectReference((PetscObject)rg);
    416:   RGDestroy(&nep->rg);
    417:   nep->rg = rg;
    418:   PetscLogObjectParent((PetscObject)nep,(PetscObject)nep->rg);
    419:   return(0);
    420: }

    422: /*@
    423:    NEPGetRG - Obtain the region object associated to the
    424:    nonlinear eigensolver object.

    426:    Not Collective

    428:    Input Parameters:
    429: .  nep - eigensolver context obtained from NEPCreate()

    431:    Output Parameter:
    432: .  rg - region context

    434:    Level: advanced

    436: .seealso: NEPSetRG()
    437: @*/
    438: PetscErrorCode NEPGetRG(NEP nep,RG *rg)
    439: {

    445:   if (!nep->rg) {
    446:     RGCreate(PetscObjectComm((PetscObject)nep),&nep->rg);
    447:     PetscObjectIncrementTabLevel((PetscObject)nep->rg,(PetscObject)nep,0);
    448:     PetscLogObjectParent((PetscObject)nep,(PetscObject)nep->rg);
    449:     PetscObjectSetOptions((PetscObject)nep->rg,((PetscObject)nep)->options);
    450:   }
    451:   *rg = nep->rg;
    452:   return(0);
    453: }

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

    458:    Collective on nep

    460:    Input Parameters:
    461: +  nep - eigensolver context obtained from NEPCreate()
    462: -  ds  - the direct solver object

    464:    Note:
    465:    Use NEPGetDS() to retrieve the direct solver context (for example,
    466:    to free it at the end of the computations).

    468:    Level: advanced

    470: .seealso: NEPGetDS()
    471: @*/
    472: PetscErrorCode NEPSetDS(NEP nep,DS ds)
    473: {

    480:   PetscObjectReference((PetscObject)ds);
    481:   DSDestroy(&nep->ds);
    482:   nep->ds = ds;
    483:   PetscLogObjectParent((PetscObject)nep,(PetscObject)nep->ds);
    484:   return(0);
    485: }

    487: /*@
    488:    NEPGetDS - Obtain the direct solver object associated to the
    489:    nonlinear eigensolver object.

    491:    Not Collective

    493:    Input Parameters:
    494: .  nep - eigensolver context obtained from NEPCreate()

    496:    Output Parameter:
    497: .  ds - direct solver context

    499:    Level: advanced

    501: .seealso: NEPSetDS()
    502: @*/
    503: PetscErrorCode NEPGetDS(NEP nep,DS *ds)
    504: {

    510:   if (!nep->ds) {
    511:     DSCreate(PetscObjectComm((PetscObject)nep),&nep->ds);
    512:     PetscObjectIncrementTabLevel((PetscObject)nep->ds,(PetscObject)nep,0);
    513:     PetscLogObjectParent((PetscObject)nep,(PetscObject)nep->ds);
    514:     PetscObjectSetOptions((PetscObject)nep->ds,((PetscObject)nep)->options);
    515:   }
    516:   *ds = nep->ds;
    517:   return(0);
    518: }

    520: /*@
    521:    NEPRefineGetKSP - Obtain the ksp object used by the eigensolver
    522:    object in the refinement phase.

    524:    Not Collective

    526:    Input Parameters:
    527: .  nep - eigensolver context obtained from NEPCreate()

    529:    Output Parameter:
    530: .  ksp - ksp context

    532:    Level: advanced

    534: .seealso: NEPSetRefine()
    535: @*/
    536: PetscErrorCode NEPRefineGetKSP(NEP nep,KSP *ksp)
    537: {

    543:   if (!nep->refineksp) {
    544:     if (nep->npart>1) {
    545:       /* Split in subcomunicators */
    546:       PetscSubcommCreate(PetscObjectComm((PetscObject)nep),&nep->refinesubc);
    547:       PetscSubcommSetNumber(nep->refinesubc,nep->npart);
    548:       PetscSubcommSetType(nep->refinesubc,PETSC_SUBCOMM_CONTIGUOUS);
    549:       PetscLogObjectMemory((PetscObject)nep,sizeof(PetscSubcomm));
    550:     }
    551:     KSPCreate((nep->npart==1)?PetscObjectComm((PetscObject)nep):PetscSubcommChild(nep->refinesubc),&nep->refineksp);
    552:     PetscObjectIncrementTabLevel((PetscObject)nep->refineksp,(PetscObject)nep,0);
    553:     PetscLogObjectParent((PetscObject)nep,(PetscObject)nep->refineksp);
    554:     PetscObjectSetOptions((PetscObject)nep->refineksp,((PetscObject)nep)->options);
    555:     KSPSetOptionsPrefix(*ksp,((PetscObject)nep)->prefix);
    556:     KSPAppendOptionsPrefix(*ksp,"nep_refine_");
    557:     KSPSetTolerances(nep->refineksp,SLEPC_DEFAULT_TOL,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);
    558:   }
    559:   *ksp = nep->refineksp;
    560:   return(0);
    561: }

    563: /*@
    564:    NEPSetTarget - Sets the value of the target.

    566:    Logically Collective on nep

    568:    Input Parameters:
    569: +  nep    - eigensolver context
    570: -  target - the value of the target

    572:    Options Database Key:
    573: .  -nep_target <scalar> - the value of the target

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

    579:    In the case of complex scalars, a complex value can be provided in the
    580:    command line with [+/-][realnumber][+/-]realnumberi with no spaces, e.g.
    581:    -nep_target 1.0+2.0i

    583:    Level: intermediate

    585: .seealso: NEPGetTarget(), NEPSetWhichEigenpairs()
    586: @*/
    587: PetscErrorCode NEPSetTarget(NEP nep,PetscScalar target)
    588: {
    592:   nep->target = target;
    593:   return(0);
    594: }

    596: /*@
    597:    NEPGetTarget - Gets the value of the target.

    599:    Not Collective

    601:    Input Parameter:
    602: .  nep - eigensolver context

    604:    Output Parameter:
    605: .  target - the value of the target

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

    610:    Level: intermediate

    612: .seealso: NEPSetTarget()
    613: @*/
    614: PetscErrorCode NEPGetTarget(NEP nep,PetscScalar* target)
    615: {
    619:   *target = nep->target;
    620:   return(0);
    621: }

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

    627:    Logically Collective on nep

    629:    Input Parameters:
    630: +  nep - the NEP context
    631: .  A   - Function matrix
    632: .  B   - preconditioner matrix (usually same as the Function)
    633: .  fun - Function evaluation routine (if NULL then NEP retains any
    634:          previously set value)
    635: -  ctx - [optional] user-defined context for private data for the Function
    636:          evaluation routine (may be NULL) (if NULL then NEP retains any
    637:          previously set value)

    639:    Calling Sequence of fun:
    640: $   fun(NEP nep,PetscScalar lambda,Mat F,Mat P,void *ctx)

    642: +  nep    - the NEP context
    643: .  lambda - the scalar argument where T(.) must be evaluated
    644: .  T      - matrix that will contain T(lambda)
    645: .  P      - (optional) different matrix to build the preconditioner
    646: -  ctx    - (optional) user-defined context, as set by NEPSetFunction()

    648:    Level: beginner

    650: .seealso: NEPGetFunction(), NEPSetJacobian()
    651: @*/
    652: PetscErrorCode NEPSetFunction(NEP nep,Mat A,Mat B,PetscErrorCode (*fun)(NEP,PetscScalar,Mat,Mat,void*),void *ctx)
    653: {

    663:   if (nep->state) { NEPReset(nep); }
    664:   else if (nep->fui && nep->fui!=NEP_USER_INTERFACE_CALLBACK) { NEPReset_Problem(nep); }

    666:   if (fun) nep->computefunction = fun;
    667:   if (ctx) nep->functionctx     = ctx;
    668:   if (A) {
    669:     PetscObjectReference((PetscObject)A);
    670:     MatDestroy(&nep->function);
    671:     nep->function = A;
    672:   }
    673:   if (B) {
    674:     PetscObjectReference((PetscObject)B);
    675:     MatDestroy(&nep->function_pre);
    676:     nep->function_pre = B;
    677:   }
    678:   nep->fui   = NEP_USER_INTERFACE_CALLBACK;
    679:   nep->state = NEP_STATE_INITIAL;
    680:   return(0);
    681: }

    683: /*@C
    684:    NEPGetFunction - Returns the Function matrix and optionally the user
    685:    provided context for evaluating the Function.

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

    689:    Input Parameter:
    690: .  nep - the nonlinear eigensolver context

    692:    Output Parameters:
    693: +  A   - location to stash Function matrix (or NULL)
    694: .  B   - location to stash preconditioner matrix (or NULL)
    695: .  fun - location to put Function function (or NULL)
    696: -  ctx - location to stash Function context (or NULL)

    698:    Level: advanced

    700: .seealso: NEPSetFunction()
    701: @*/
    702: PetscErrorCode NEPGetFunction(NEP nep,Mat *A,Mat *B,PetscErrorCode (**fun)(NEP,PetscScalar,Mat,Mat,void*),void **ctx)
    703: {
    706:   NEPCheckCallback(nep,1);
    707:   if (A)   *A   = nep->function;
    708:   if (B)   *B   = nep->function_pre;
    709:   if (fun) *fun = nep->computefunction;
    710:   if (ctx) *ctx = nep->functionctx;
    711:   return(0);
    712: }

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

    718:    Logically Collective on nep

    720:    Input Parameters:
    721: +  nep - the NEP context
    722: .  A   - Jacobian matrix
    723: .  jac - Jacobian evaluation routine (if NULL then NEP retains any
    724:          previously set value)
    725: -  ctx - [optional] user-defined context for private data for the Jacobian
    726:          evaluation routine (may be NULL) (if NULL then NEP retains any
    727:          previously set value)

    729:    Calling Sequence of jac:
    730: $   jac(NEP nep,PetscScalar lambda,Mat J,void *ctx)

    732: +  nep    - the NEP context
    733: .  lambda - the scalar argument where T'(.) must be evaluated
    734: .  J      - matrix that will contain T'(lambda)
    735: -  ctx    - (optional) user-defined context, as set by NEPSetJacobian()

    737:    Level: beginner

    739: .seealso: NEPSetFunction(), NEPGetJacobian()
    740: @*/
    741: PetscErrorCode NEPSetJacobian(NEP nep,Mat A,PetscErrorCode (*jac)(NEP,PetscScalar,Mat,void*),void *ctx)
    742: {

    750:   if (nep->state) { NEPReset(nep); }
    751:   else if (nep->fui && nep->fui!=NEP_USER_INTERFACE_CALLBACK) { NEPReset_Problem(nep); }

    753:   if (jac) nep->computejacobian = jac;
    754:   if (ctx) nep->jacobianctx     = ctx;
    755:   if (A) {
    756:     PetscObjectReference((PetscObject)A);
    757:     MatDestroy(&nep->jacobian);
    758:     nep->jacobian = A;
    759:   }
    760:   nep->fui   = NEP_USER_INTERFACE_CALLBACK;
    761:   nep->state = NEP_STATE_INITIAL;
    762:   return(0);
    763: }

    765: /*@C
    766:    NEPGetJacobian - Returns the Jacobian matrix and optionally the user
    767:    provided routine and context for evaluating the Jacobian.

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

    771:    Input Parameter:
    772: .  nep - the nonlinear eigensolver context

    774:    Output Parameters:
    775: +  A   - location to stash Jacobian matrix (or NULL)
    776: .  jac - location to put Jacobian function (or NULL)
    777: -  ctx - location to stash Jacobian context (or NULL)

    779:    Level: advanced

    781: .seealso: NEPSetJacobian()
    782: @*/
    783: PetscErrorCode NEPGetJacobian(NEP nep,Mat *A,PetscErrorCode (**jac)(NEP,PetscScalar,Mat,void*),void **ctx)
    784: {
    787:   NEPCheckCallback(nep,1);
    788:   if (A)   *A   = nep->jacobian;
    789:   if (jac) *jac = nep->computejacobian;
    790:   if (ctx) *ctx = nep->jacobianctx;
    791:   return(0);
    792: }

    794: /*@
    795:    NEPSetSplitOperator - Sets the operator of the nonlinear eigenvalue problem
    796:    in split form.

    798:    Collective on nep

    800:    Input Parameters:
    801: +  nep - the nonlinear eigensolver context
    802: .  n   - number of terms in the split form
    803: .  A   - array of matrices
    804: .  f   - array of functions
    805: -  str - structure flag for matrices

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

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

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

    821:    Level: beginner

    823: .seealso: NEPGetSplitOperatorTerm(), NEPGetSplitOperatorInfo()
    824:  @*/
    825: PetscErrorCode NEPSetSplitOperator(NEP nep,PetscInt n,Mat A[],FN f[],MatStructure str)
    826: {
    827:   PetscInt       i;

    833:   if (n <= 0) SETERRQ1(PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more terms, you have %D",n);

    839:   for (i=0;i<n;i++) {
    842:     PetscObjectReference((PetscObject)A[i]);
    843:     PetscObjectReference((PetscObject)f[i]);
    844:   }

    846:   if (nep->state) { NEPReset(nep); }
    847:   else { NEPReset_Problem(nep); }

    849:   /* allocate space and copy matrices and functions */
    850:   PetscMalloc1(n,&nep->A);
    851:   PetscLogObjectMemory((PetscObject)nep,n*sizeof(Mat));
    852:   for (i=0;i<n;i++) nep->A[i] = A[i];
    853:   PetscMalloc1(n,&nep->f);
    854:   PetscLogObjectMemory((PetscObject)nep,n*sizeof(FN));
    855:   for (i=0;i<n;i++) nep->f[i] = f[i];
    856:   PetscCalloc1(n,&nep->nrma);
    857:   PetscLogObjectMemory((PetscObject)nep,n*sizeof(PetscReal));
    858:   nep->nt    = n;
    859:   nep->mstr  = str;
    860:   nep->fui   = NEP_USER_INTERFACE_SPLIT;
    861:   nep->state = NEP_STATE_INITIAL;
    862:   return(0);
    863: }

    865: /*@
    866:    NEPGetSplitOperatorTerm - Gets the matrices and functions associated with
    867:    the nonlinear operator in split form.

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

    871:    Input Parameter:
    872: +  nep - the nonlinear eigensolver context
    873: -  k   - the index of the requested term (starting in 0)

    875:    Output Parameters:
    876: +  A - the matrix of the requested term
    877: -  f - the function of the requested term

    879:    Level: intermediate

    881: .seealso: NEPSetSplitOperator(), NEPGetSplitOperatorInfo()
    882: @*/
    883: PetscErrorCode NEPGetSplitOperatorTerm(NEP nep,PetscInt k,Mat *A,FN *f)
    884: {
    887:   NEPCheckSplit(nep,1);
    888:   if (k<0 || k>=nep->nt) SETERRQ1(PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_OUTOFRANGE,"k must be between 0 and %D",nep->nt-1);
    889:   if (A) *A = nep->A[k];
    890:   if (f) *f = nep->f[k];
    891:   return(0);
    892: }

    894: /*@
    895:    NEPGetSplitOperatorInfo - Returns the number of terms of the split form of
    896:    the nonlinear operator, as well as the structure flag for matrices.

    898:    Not collective

    900:    Input Parameter:
    901: .  nep - the nonlinear eigensolver context

    903:    Output Parameters:
    904: +  n   - the number of terms passed in NEPSetSplitOperator()
    905: -  str - the matrix structure flag passed in NEPSetSplitOperator()

    907:    Level: intermediate

    909: .seealso: NEPSetSplitOperator(), NEPGetSplitOperatorTerm()
    910: @*/
    911: PetscErrorCode NEPGetSplitOperatorInfo(NEP nep,PetscInt *n,MatStructure *str)
    912: {
    915:   NEPCheckSplit(nep,1);
    916:   if (n)   *n = nep->nt;
    917:   if (str) *str = nep->mstr;
    918:   return(0);
    919: }