Actual source code: nepbasic.c
 
   slepc-3.12.2 2020-01-13
   
  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: }