Actual source code: nepbasic.c
slepc-3.13.3 2020-06-14
1: /*
2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3: SLEPc - Scalable Library for Eigenvalue Problem Computations
4: Copyright (c) 2002-2020, 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>
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 = PETSC_DEFAULT;
48: nep->nev = 1;
49: nep->ncv = PETSC_DEFAULT;
50: nep->mpd = PETSC_DEFAULT;
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: }