Date: 2015-09-03T15:05:51+00:00

Actual source code: nepbasic.c
slepc-3.6.1 2015-09-03
Report Typos and Errors

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

      4:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      5:    SLEPc - Scalable Library for Eigenvalue Problem Computations
      6:    Copyright (c) 2002-2015, 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_Refine = 0,NEP_FunctionEval = 0,NEP_JacobianEval = 0;

     33: /*@
     34:    NEPCreate - Creates the default NEP context.

     36:    Collective on MPI_Comm

     38:    Input Parameter:
     39: .  comm - MPI communicator

     41:    Output Parameter:
     42: .  nep - location to put the NEP context

     44:    Level: beginner

     46: .seealso: NEPSetUp(), NEPSolve(), NEPDestroy(), NEP
     47: @*/
     48: PetscErrorCode NEPCreate(MPI_Comm comm,NEP *outnep)
     49: {
     51:   NEP            nep;

     55:   *outnep = 0;
     56:   NEPInitializePackage();
     57:   SlepcHeaderCreate(nep,NEP_CLASSID,"NEP","Nonlinear Eigenvalue Problem","NEP",comm,NEPDestroy,NEPView);

     59:   nep->max_it          = 0;
     60:   nep->max_funcs       = 0;
     61:   nep->nev             = 1;
     62:   nep->ncv             = 0;
     63:   nep->mpd             = 0;
     64:   nep->lag             = 1;
     65:   nep->nini            = 0;
     66:   nep->target          = 0.0;
     67:   nep->abstol          = PETSC_DEFAULT;
     68:   nep->rtol            = PETSC_DEFAULT;
     69:   nep->stol            = PETSC_DEFAULT;
     70:   nep->ktol            = 0.1;
     71:   nep->cctol           = PETSC_FALSE;
     72:   nep->ttol            = 0.0;
     73:   nep->which           = (NEPWhich)0;
     74:   nep->refine          = NEP_REFINE_NONE;
     75:   nep->npart           = 1;
     76:   nep->reftol          = PETSC_DEFAULT;
     77:   nep->rits            = PETSC_DEFAULT;
     78:   nep->trackall        = PETSC_FALSE;

     80:   nep->computefunction = NULL;
     81:   nep->computejacobian = NULL;
     82:   nep->functionctx     = NULL;
     83:   nep->jacobianctx     = NULL;
     84:   nep->converged       = NEPConvergedDefault;
     85:   nep->convergeddestroy= NULL;
     86:   nep->convergedctx    = NULL;
     87:   nep->numbermonitors  = 0;

     89:   nep->ds              = NULL;
     90:   nep->V               = NULL;
     91:   nep->rg              = NULL;
     92:   nep->rand            = NULL;
     93:   nep->ksp             = NULL;
     94:   nep->function        = NULL;
     95:   nep->function_pre    = NULL;
     96:   nep->jacobian        = NULL;
     97:   nep->A               = NULL;
     98:   nep->f               = NULL;
     99:   nep->nt              = 0;
    100:   nep->mstr            = DIFFERENT_NONZERO_PATTERN;
    101:   nep->IS              = NULL;
    102:   nep->eigr            = NULL;
    103:   nep->eigi            = NULL;
    104:   nep->errest          = NULL;
    105:   nep->perm            = NULL;
    106:   nep->nwork           = 0;
    107:   nep->work            = NULL;
    108:   nep->data            = NULL;

    110:   nep->state           = NEP_STATE_INITIAL;
    111:   nep->nconv           = 0;
    112:   nep->its             = 0;
    113:   nep->n               = 0;
    114:   nep->nloc            = 0;
    115:   nep->nfuncs          = 0;
    116:   nep->split           = PETSC_FALSE;
    117:   nep->reason          = NEP_CONVERGED_ITERATING;

    119:   PetscNewLog(nep,&nep->sc);
    120:   PetscRandomCreate(comm,&nep->rand);
    121:   PetscRandomSetSeed(nep->rand,0x12345678);
    122:   PetscLogObjectParent((PetscObject)nep,(PetscObject)nep->rand);
    123:   *outnep = nep;
    124:   return(0);
    125: }

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

    132:    Logically Collective on NEP

    134:    Input Parameters:
    135: +  nep      - the nonlinear eigensolver context
    136: -  type     - a known method

    138:    Options Database Key:
    139: .  -nep_type <method> - Sets the method; use -help for a list
    140:     of available methods

    142:    Notes:
    143:    See "slepc/include/slepcnep.h" for available methods.

    145:    Normally, it is best to use the NEPSetFromOptions() command and
    146:    then set the NEP type from the options database rather than by using
    147:    this routine.  Using the options database provides the user with
    148:    maximum flexibility in evaluating the different available methods.
    149:    The NEPSetType() routine is provided for those situations where it
    150:    is necessary to set the iterative solver independently of the command
    151:    line or options database.

    153:    Level: intermediate

    155: .seealso: NEPType
    156: @*/
    157: PetscErrorCode NEPSetType(NEP nep,NEPType type)
    158: {
    159:   PetscErrorCode ierr,(*r)(NEP);
    160:   PetscBool      match;

    166:   PetscObjectTypeCompare((PetscObject)nep,type,&match);
    167:   if (match) return(0);

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

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

    175:   nep->state = NEP_STATE_INITIAL;
    176:   PetscObjectChangeTypeName((PetscObject)nep,type);
    177:   (*r)(nep);
    178:   return(0);
    179: }

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

    186:    Not Collective

    188:    Input Parameter:
    189: .  nep - the eigensolver context

    191:    Output Parameter:
    192: .  name - name of NEP method

    194:    Level: intermediate

    196: .seealso: NEPSetType()
    197: @*/
    198: PetscErrorCode NEPGetType(NEP nep,NEPType *type)
    199: {
    203:   *type = ((PetscObject)nep)->type_name;
    204:   return(0);
    205: }

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

    212:    Not Collective

    214:    Input Parameters:
    215: +  name - name of a new user-defined solver
    216: -  function - routine to create the solver context

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

    221:    Sample usage:
    222: .vb
    223:    NEPRegister("my_solver",MySolverCreate);
    224: .ve

    226:    Then, your solver can be chosen with the procedural interface via
    227: $     NEPSetType(nep,"my_solver")
    228:    or at runtime via the option
    229: $     -nep_type my_solver

    231:    Level: advanced

    233: .seealso: NEPRegisterAll()
    234: @*/
    235: PetscErrorCode NEPRegister(const char *name,PetscErrorCode (*function)(NEP))
    236: {

    240:   PetscFunctionListAdd(&NEPList,name,function);
    241:   return(0);
    242: }

    246: /*@
    247:    NEPReset - Resets the NEP context to the initial state and removes any
    248:    allocated objects.

    250:    Collective on NEP

    252:    Input Parameter:
    253: .  nep - eigensolver context obtained from NEPCreate()

    255:    Level: advanced

    257: .seealso: NEPDestroy()
    258: @*/
    259: PetscErrorCode NEPReset(NEP nep)
    260: {
    262:   PetscInt       i,ncols;

    266:   if (nep->ops->reset) { (nep->ops->reset)(nep); }
    267:   if (nep->ds) { DSReset(nep->ds); }
    268:   MatDestroy(&nep->function);
    269:   MatDestroy(&nep->function_pre);
    270:   MatDestroy(&nep->jacobian);
    271:   if (nep->split) {
    272:     MatDestroyMatrices(nep->nt,&nep->A);
    273:     for (i=0;i<nep->nt;i++) {
    274:       FNDestroy(&nep->f[i]);
    275:     }
    276:     PetscFree(nep->f);
    277:   }
    278:   BVGetSizes(nep->V,NULL,NULL,&ncols);
    279:   if (ncols) {
    280:     PetscFree4(nep->eigr,nep->eigi,nep->errest,nep->perm);
    281:   }
    282:   BVDestroy(&nep->V);
    283:   VecDestroyVecs(nep->nwork,&nep->work);
    284:   nep->nwork  = 0;
    285:   nep->nfuncs = 0;
    286:   nep->state  = NEP_STATE_INITIAL;
    287:   return(0);
    288: }

    292: /*@
    293:    NEPDestroy - Destroys the NEP context.

    295:    Collective on NEP

    297:    Input Parameter:
    298: .  nep - eigensolver context obtained from NEPCreate()

    300:    Level: beginner

    302: .seealso: NEPCreate(), NEPSetUp(), NEPSolve()
    303: @*/
    304: PetscErrorCode NEPDestroy(NEP *nep)
    305: {

    309:   if (!*nep) return(0);
    311:   if (--((PetscObject)(*nep))->refct > 0) { *nep = 0; return(0); }
    312:   NEPReset(*nep);
    313:   if ((*nep)->ops->destroy) { (*(*nep)->ops->destroy)(*nep); }
    314:   KSPDestroy(&(*nep)->ksp);
    315:   RGDestroy(&(*nep)->rg);
    316:   DSDestroy(&(*nep)->ds);
    317:   PetscRandomDestroy(&(*nep)->rand);
    318:   PetscFree((*nep)->sc);
    319:   /* just in case the initial vectors have not been used */
    320:   SlepcBasisDestroy_Private(&(*nep)->nini,&(*nep)->IS);
    321:   if ((*nep)->convergeddestroy) {
    322:     (*(*nep)->convergeddestroy)((*nep)->convergedctx);
    323:   }
    324:   NEPMonitorCancel(*nep);
    325:   PetscHeaderDestroy(nep);
    326:   return(0);
    327: }

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

    334:    Collective on NEP

    336:    Input Parameters:
    337: +  nep - eigensolver context obtained from NEPCreate()
    338: -  bv  - the basis vectors object

    340:    Note:
    341:    Use NEPGetBV() to retrieve the basis vectors context (for example,
    342:    to free it at the end of the computations).

    344:    Level: advanced

    346: .seealso: NEPGetBV()
    347: @*/
    348: PetscErrorCode NEPSetBV(NEP nep,BV bv)
    349: {

    356:   PetscObjectReference((PetscObject)bv);
    357:   BVDestroy(&nep->V);
    358:   nep->V = bv;
    359:   PetscLogObjectParent((PetscObject)nep,(PetscObject)nep->V);
    360:   return(0);
    361: }

    365: /*@
    366:    NEPGetBV - Obtain the basis vectors object associated to the nonlinear
    367:    eigensolver object.

    369:    Not Collective

    371:    Input Parameters:
    372: .  nep - eigensolver context obtained from NEPCreate()

    374:    Output Parameter:
    375: .  bv - basis vectors context

    377:    Level: advanced

    379: .seealso: NEPSetBV()
    380: @*/
    381: PetscErrorCode NEPGetBV(NEP nep,BV *bv)
    382: {

    388:   if (!nep->V) {
    389:     BVCreate(PetscObjectComm((PetscObject)nep),&nep->V);
    390:     PetscLogObjectParent((PetscObject)nep,(PetscObject)nep->V);
    391:   }
    392:   *bv = nep->V;
    393:   return(0);
    394: }

    398: /*@
    399:    NEPSetRG - Associates a region object to the nonlinear eigensolver.

    401:    Collective on NEP

    403:    Input Parameters:
    404: +  nep - eigensolver context obtained from NEPCreate()
    405: -  rg  - the region object

    407:    Note:
    408:    Use NEPGetRG() to retrieve the region context (for example,
    409:    to free it at the end of the computations).

    411:    Level: advanced

    413: .seealso: NEPGetRG()
    414: @*/
    415: PetscErrorCode NEPSetRG(NEP nep,RG rg)
    416: {

    423:   PetscObjectReference((PetscObject)rg);
    424:   RGDestroy(&nep->rg);
    425:   nep->rg = rg;
    426:   PetscLogObjectParent((PetscObject)nep,(PetscObject)nep->rg);
    427:   return(0);
    428: }

    432: /*@
    433:    NEPGetRG - Obtain the region object associated to the
    434:    nonlinear eigensolver object.

    436:    Not Collective

    438:    Input Parameters:
    439: .  nep - eigensolver context obtained from NEPCreate()

    441:    Output Parameter:
    442: .  rg - region context

    444:    Level: advanced

    446: .seealso: NEPSetRG()
    447: @*/
    448: PetscErrorCode NEPGetRG(NEP nep,RG *rg)
    449: {

    455:   if (!nep->rg) {
    456:     RGCreate(PetscObjectComm((PetscObject)nep),&nep->rg);
    457:     PetscLogObjectParent((PetscObject)nep,(PetscObject)nep->rg);
    458:   }
    459:   *rg = nep->rg;
    460:   return(0);
    461: }

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

    468:    Collective on NEP

    470:    Input Parameters:
    471: +  nep - eigensolver context obtained from NEPCreate()
    472: -  ds  - the direct solver object

    474:    Note:
    475:    Use NEPGetDS() to retrieve the direct solver context (for example,
    476:    to free it at the end of the computations).

    478:    Level: advanced

    480: .seealso: NEPGetDS()
    481: @*/
    482: PetscErrorCode NEPSetDS(NEP nep,DS ds)
    483: {

    490:   PetscObjectReference((PetscObject)ds);
    491:   DSDestroy(&nep->ds);
    492:   nep->ds = ds;
    493:   PetscLogObjectParent((PetscObject)nep,(PetscObject)nep->ds);
    494:   return(0);
    495: }

    499: /*@
    500:    NEPGetDS - Obtain the direct solver object associated to the
    501:    nonlinear eigensolver object.

    503:    Not Collective

    505:    Input Parameters:
    506: .  nep - eigensolver context obtained from NEPCreate()

    508:    Output Parameter:
    509: .  ds - direct solver context

    511:    Level: advanced

    513: .seealso: NEPSetDS()
    514: @*/
    515: PetscErrorCode NEPGetDS(NEP nep,DS *ds)
    516: {

    522:   if (!nep->ds) {
    523:     DSCreate(PetscObjectComm((PetscObject)nep),&nep->ds);
    524:     PetscLogObjectParent((PetscObject)nep,(PetscObject)nep->ds);
    525:   }
    526:   *ds = nep->ds;
    527:   return(0);
    528: }

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

    535:    Collective on NEP

    537:    Input Parameters:
    538: +  nep - eigensolver context obtained from NEPCreate()
    539: -  ksp - the linear solver object

    541:    Note:
    542:    Use NEPGetKSP() to retrieve the linear solver context (for example,
    543:    to free it at the end of the computations).

    545:    Level: advanced

    547: .seealso: NEPGetKSP()
    548: @*/
    549: PetscErrorCode NEPSetKSP(NEP nep,KSP ksp)
    550: {

    557:   PetscObjectReference((PetscObject)ksp);
    558:   KSPDestroy(&nep->ksp);
    559:   nep->ksp = ksp;
    560:   PetscLogObjectParent((PetscObject)nep,(PetscObject)nep->ksp);
    561:   return(0);
    562: }

    566: /*@
    567:    NEPGetKSP - Obtain the linear solver (KSP) object associated
    568:    to the eigensolver object.

    570:    Not Collective

    572:    Input Parameters:
    573: .  nep - eigensolver context obtained from NEPCreate()

    575:    Output Parameter:
    576: .  ksp - linear solver context

    578:    Level: advanced

    580: .seealso: NEPSetKSP()
    581: @*/
    582: PetscErrorCode NEPGetKSP(NEP nep,KSP *ksp)
    583: {

    589:   if (!nep->ksp) {
    590:     KSPCreate(PetscObjectComm((PetscObject)nep),&nep->ksp);
    591:     KSPSetOptionsPrefix(nep->ksp,((PetscObject)nep)->prefix);
    592:     KSPAppendOptionsPrefix(nep->ksp,"nep_");
    593:     PetscObjectIncrementTabLevel((PetscObject)nep->ksp,(PetscObject)nep,1);
    594:     PetscLogObjectParent((PetscObject)nep,(PetscObject)nep->ksp);
    595:     KSPSetErrorIfNotConverged(nep->ksp,PETSC_TRUE);
    596:   }
    597:   *ksp = nep->ksp;
    598:   return(0);
    599: }

    603: /*@
    604:    NEPSetTarget - Sets the value of the target.

    606:    Logically Collective on NEP

    608:    Input Parameters:
    609: +  nep    - eigensolver context
    610: -  target - the value of the target

    612:    Options Database Key:
    613: .  -nep_target <scalar> - the value of the target

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

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

    623:    Level: intermediate

    625: .seealso: NEPGetTarget(), NEPSetWhichEigenpairs()
    626: @*/
    627: PetscErrorCode NEPSetTarget(NEP nep,PetscScalar target)
    628: {
    632:   nep->target = target;
    633:   return(0);
    634: }

    638: /*@
    639:    NEPGetTarget - Gets the value of the target.

    641:    Not Collective

    643:    Input Parameter:
    644: .  nep - eigensolver context

    646:    Output Parameter:
    647: .  target - the value of the target

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

    652:    Level: intermediate

    654: .seealso: NEPSetTarget()
    655: @*/
    656: PetscErrorCode NEPGetTarget(NEP nep,PetscScalar* target)
    657: {
    661:   *target = nep->target;
    662:   return(0);
    663: }

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

    671:    Logically Collective on NEP and Mat

    673:    Input Parameters:
    674: +  nep - the NEP context
    675: .  A   - Function matrix
    676: .  B   - preconditioner matrix (usually same as the Function)
    677: .  fun - Function evaluation routine (if NULL then NEP retains any
    678:          previously set value)
    679: -  ctx - [optional] user-defined context for private data for the Function
    680:          evaluation routine (may be NULL) (if NULL then NEP retains any
    681:          previously set value)

    683:    Level: beginner

    685: .seealso: NEPGetFunction(), NEPSetJacobian()
    686: @*/
    687: PetscErrorCode NEPSetFunction(NEP nep,Mat A,Mat B,PetscErrorCode (*fun)(NEP,PetscScalar,Mat,Mat,void*),void *ctx)
    688: {

    697:   if (fun) nep->computefunction = fun;
    698:   if (ctx) nep->functionctx     = ctx;
    699:   if (A) {
    700:     PetscObjectReference((PetscObject)A);
    701:     MatDestroy(&nep->function);
    702:     nep->function = A;
    703:   }
    704:   if (B) {
    705:     PetscObjectReference((PetscObject)B);
    706:     MatDestroy(&nep->function_pre);
    707:     nep->function_pre = B;
    708:   }
    709:   nep->split = PETSC_FALSE;
    710:   return(0);
    711: }

    715: /*@C
    716:    NEPGetFunction - Returns the Function matrix and optionally the user
    717:    provided context for evaluating the Function.

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

    721:    Input Parameter:
    722: .  nep - the nonlinear eigensolver context

    724:    Output Parameters:
    725: +  A   - location to stash Function matrix (or NULL)
    726: .  B   - location to stash preconditioner matrix (or NULL)
    727: .  fun - location to put Function function (or NULL)
    728: -  ctx - location to stash Function context (or NULL)

    730:    Level: advanced

    732: .seealso: NEPSetFunction()
    733: @*/
    734: PetscErrorCode NEPGetFunction(NEP nep,Mat *A,Mat *B,PetscErrorCode (**fun)(NEP,PetscScalar,Mat,Mat,void*),void **ctx)
    735: {
    738:   if (A)   *A   = nep->function;
    739:   if (B)   *B   = nep->function_pre;
    740:   if (fun) *fun = nep->computefunction;
    741:   if (ctx) *ctx = nep->functionctx;
    742:   return(0);
    743: }

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

    751:    Logically Collective on NEP and Mat

    753:    Input Parameters:
    754: +  nep - the NEP context
    755: .  A   - Jacobian matrix
    756: .  jac - Jacobian evaluation routine (if NULL then NEP retains any
    757:          previously set value)
    758: -  ctx - [optional] user-defined context for private data for the Jacobian
    759:          evaluation routine (may be NULL) (if NULL then NEP retains any
    760:          previously set value)

    762:    Level: beginner

    764: .seealso: NEPSetFunction(), NEPGetJacobian()
    765: @*/
    766: PetscErrorCode NEPSetJacobian(NEP nep,Mat A,PetscErrorCode (*jac)(NEP,PetscScalar,Mat,void*),void *ctx)
    767: {

    774:   if (jac) nep->computejacobian = jac;
    775:   if (ctx) nep->jacobianctx     = ctx;
    776:   if (A) {
    777:     PetscObjectReference((PetscObject)A);
    778:     MatDestroy(&nep->jacobian);
    779:     nep->jacobian = A;
    780:   }
    781:   nep->split = PETSC_FALSE;
    782:   return(0);
    783: }

    787: /*@C
    788:    NEPGetJacobian - Returns the Jacobian matrix and optionally the user
    789:    provided context for evaluating the Jacobian.

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

    793:    Input Parameter:
    794: .  nep - the nonlinear eigensolver context

    796:    Output Parameters:
    797: +  A   - location to stash Jacobian matrix (or NULL)
    798: .  jac - location to put Jacobian function (or NULL)
    799: -  ctx - location to stash Jacobian context (or NULL)

    801:    Level: advanced

    803: .seealso: NEPSetJacobian()
    804: @*/
    805: PetscErrorCode NEPGetJacobian(NEP nep,Mat *A,PetscErrorCode (**jac)(NEP,PetscScalar,Mat,void*),void **ctx)
    806: {
    809:   if (A)   *A   = nep->jacobian;
    810:   if (jac) *jac = nep->computejacobian;
    811:   if (ctx) *ctx = nep->jacobianctx;
    812:   return(0);
    813: }

    817: /*@
    818:    NEPSetSplitOperator - Sets the operator of the nonlinear eigenvalue problem
    819:    in split form.

    821:    Collective on NEP, Mat and FN

    823:    Input Parameters:
    824: +  nep - the nonlinear eigensolver context
    825: .  n   - number of terms in the split form
    826: .  A   - array of matrices
    827: .  f   - array of functions
    828: -  str - structure flag for matrices

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

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

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

    844:    Level: beginner

    846: .seealso: NEPGetSplitOperatorTerm(), NEPGetSplitOperatorInfo()
    847:  @*/
    848: PetscErrorCode NEPSetSplitOperator(NEP nep,PetscInt n,Mat A[],FN f[],MatStructure str)
    849: {
    850:   PetscInt       i;

    856:   if (n <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more terms, you have %D",n);
    861:   if (nep->state) { NEPReset(nep); }
    862:   /* clean previously stored information */
    863:   MatDestroy(&nep->function);
    864:   MatDestroy(&nep->function_pre);
    865:   MatDestroy(&nep->jacobian);
    866:   if (nep->split) {
    867:     MatDestroyMatrices(nep->nt,&nep->A);
    868:     for (i=0;i<nep->nt;i++) {
    869:       FNDestroy(&nep->f[i]);
    870:     }
    871:     PetscFree(nep->f);
    872:   }
    873:   /* allocate space and copy matrices and functions */
    874:   PetscMalloc1(n,&nep->A);
    875:   PetscLogObjectMemory((PetscObject)nep,n*sizeof(Mat));
    876:   for (i=0;i<n;i++) {
    878:     PetscObjectReference((PetscObject)A[i]);
    879:     nep->A[i] = A[i];
    880:   }
    881:   PetscMalloc1(n,&nep->f);
    882:   PetscLogObjectMemory((PetscObject)nep,n*sizeof(FN));
    883:   for (i=0;i<n;i++) {
    885:     PetscObjectReference((PetscObject)f[i]);
    886:     nep->f[i] = f[i];
    887:   }
    888:   nep->nt    = n;
    889:   nep->mstr  = str;
    890:   nep->split = PETSC_TRUE;
    891:   return(0);
    892: }

    896: /*@
    897:    NEPGetSplitOperatorTerm - Gets the matrices and functions associated with
    898:    the nonlinear operator in split form.

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

    902:    Input Parameter:
    903: +  nep - the nonlinear eigensolver context
    904: -  k   - the index of the requested term (starting in 0)

    906:    Output Parameters:
    907: +  A - the matrix of the requested term
    908: -  f - the function of the requested term

    910:    Level: intermediate

    912: .seealso: NEPSetSplitOperator(), NEPGetSplitOperatorInfo()
    913: @*/
    914: PetscErrorCode NEPGetSplitOperatorTerm(NEP nep,PetscInt k,Mat *A,FN *f)
    915: {
    918:   if (k<0 || k>=nep->nt) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"k must be between 0 and %d",nep->nt-1);
    919:   if (A) *A = nep->A[k];
    920:   if (f) *f = nep->f[k];
    921:   return(0);
    922: }

    926: /*@
    927:    NEPGetSplitOperatorInfo - Returns the number of terms of the split form of
    928:    the nonlinear operator, as well as the structure flag for matrices.

    930:    Not collective

    932:    Input Parameter:
    933: .  nep - the nonlinear eigensolver context

    935:    Output Parameters:
    936: +  n   - the number of terms passed in NEPSetSplitOperator()
    937: -  str - the matrix structure flag passed in NEPSetSplitOperator()

    939:    Level: intermediate

    941: .seealso: NEPSetSplitOperator(), NEPGetSplitOperatorTerm()
    942: @*/
    943: PetscErrorCode NEPGetSplitOperatorInfo(NEP nep,PetscInt *n,MatStructure *str)
    944: {
    947:   if (n) *n = nep->nt;
    948:   if (str) *str = nep->mstr;
    949:   return(0);
    950: }