Actual source code: slp.c
slepc-3.18.1 2022-11-02
1: /*
2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3: SLEPc - Scalable Library for Eigenvalue Problem Computations
4: Copyright (c) 2002-, 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: SLEPc nonlinear eigensolver: "slp"
13: Method: Successive linear problems
15: Algorithm:
17: Newton-type iteration based on first order Taylor approximation.
19: References:
21: [1] A. Ruhe, "Algorithms for the nonlinear eigenvalue problem", SIAM J.
22: Numer. Anal. 10(4):674-689, 1973.
23: */
25: #include <slepc/private/nepimpl.h>
26: #include <../src/nep/impls/nepdefl.h>
27: #include "slp.h"
29: typedef struct {
30: NEP_EXT_OP extop;
31: Vec w;
32: } NEP_SLP_MATSHELL;
34: PetscErrorCode NEPSetUp_SLP(NEP nep)
35: {
36: NEP_SLP *ctx = (NEP_SLP*)nep->data;
37: PetscBool flg;
38: ST st;
40: if (nep->ncv!=PETSC_DEFAULT) PetscInfo(nep,"Setting ncv = nev, ignoring user-provided value\n");
41: nep->ncv = nep->nev;
42: if (nep->mpd!=PETSC_DEFAULT) PetscInfo(nep,"Setting mpd = nev, ignoring user-provided value\n");
43: nep->mpd = nep->nev;
45: if (nep->max_it==PETSC_DEFAULT) nep->max_it = PetscMax(5000,2*nep->n/nep->ncv);
46: if (!nep->which) nep->which = NEP_TARGET_MAGNITUDE;
48: NEPCheckUnsupported(nep,NEP_FEATURE_REGION);
50: if (!ctx->eps) NEPSLPGetEPS(nep,&ctx->eps);
51: EPSGetST(ctx->eps,&st);
52: PetscObjectTypeCompareAny((PetscObject)st,&flg,STSINVERT,STCAYLEY,"");
54: EPSSetDimensions(ctx->eps,1,PETSC_DECIDE,PETSC_DECIDE);
55: EPSSetWhichEigenpairs(ctx->eps,EPS_LARGEST_MAGNITUDE);
56: EPSSetTolerances(ctx->eps,SlepcDefaultTol(nep->tol)/10.0,nep->max_it);
57: if (nep->tol==PETSC_DEFAULT) nep->tol = SLEPC_DEFAULT_TOL;
58: if (ctx->deftol==PETSC_DEFAULT) ctx->deftol = nep->tol;
60: if (nep->twosided) {
61: nep->ops->solve = NEPSolve_SLP_Twosided;
62: nep->ops->computevectors = NULL;
63: if (!ctx->epsts) NEPSLPGetEPSLeft(nep,&ctx->epsts);
64: EPSGetST(ctx->epsts,&st);
65: PetscObjectTypeCompareAny((PetscObject)st,&flg,STSINVERT,STCAYLEY,"");
67: EPSSetDimensions(ctx->epsts,1,PETSC_DECIDE,PETSC_DECIDE);
68: EPSSetWhichEigenpairs(ctx->epsts,EPS_LARGEST_MAGNITUDE);
69: EPSSetTolerances(ctx->epsts,SlepcDefaultTol(nep->tol)/10.0,nep->max_it);
70: } else {
71: nep->ops->solve = NEPSolve_SLP;
72: nep->ops->computevectors = NEPComputeVectors_Schur;
73: }
74: NEPAllocateSolution(nep,0);
75: return 0;
76: }
78: static PetscErrorCode MatMult_SLP(Mat M,Vec x,Vec y)
79: {
80: NEP_SLP_MATSHELL *ctx;
82: MatShellGetContext(M,&ctx);
83: MatMult(ctx->extop->MJ,x,ctx->w);
84: NEPDeflationFunctionSolve(ctx->extop,ctx->w,y);
85: return 0;
86: }
88: static PetscErrorCode MatDestroy_SLP(Mat M)
89: {
90: NEP_SLP_MATSHELL *ctx;
92: MatShellGetContext(M,&ctx);
93: VecDestroy(&ctx->w);
94: PetscFree(ctx);
95: return 0;
96: }
98: #if defined(PETSC_HAVE_CUDA)
99: static PetscErrorCode MatCreateVecs_SLP(Mat M,Vec *left,Vec *right)
100: {
101: NEP_SLP_MATSHELL *ctx;
103: MatShellGetContext(M,&ctx);
104: if (right) VecDuplicate(ctx->w,right);
105: if (left) VecDuplicate(ctx->w,left);
106: return 0;
107: }
108: #endif
110: static PetscErrorCode NEPSLPSetUpLinearEP(NEP nep,NEP_EXT_OP extop,PetscScalar lambda,Vec u,PetscBool ini)
111: {
112: NEP_SLP *slpctx = (NEP_SLP*)nep->data;
113: Mat Mshell;
114: PetscInt nloc,mloc;
115: NEP_SLP_MATSHELL *shellctx;
117: if (ini) {
118: /* Create mat shell */
119: PetscNew(&shellctx);
120: shellctx->extop = extop;
121: NEPDeflationCreateVec(extop,&shellctx->w);
122: MatGetLocalSize(nep->function,&mloc,&nloc);
123: nloc += extop->szd; mloc += extop->szd;
124: MatCreateShell(PetscObjectComm((PetscObject)nep),nloc,mloc,PETSC_DETERMINE,PETSC_DETERMINE,shellctx,&Mshell);
125: MatShellSetOperation(Mshell,MATOP_MULT,(void(*)(void))MatMult_SLP);
126: MatShellSetOperation(Mshell,MATOP_DESTROY,(void(*)(void))MatDestroy_SLP);
127: #if defined(PETSC_HAVE_CUDA)
128: MatShellSetOperation(Mshell,MATOP_CREATE_VECS,(void(*)(void))MatCreateVecs_SLP);
129: #endif
130: EPSSetOperators(slpctx->eps,Mshell,NULL);
131: MatDestroy(&Mshell);
132: }
133: NEPDeflationSolveSetUp(extop,lambda);
134: NEPDeflationComputeJacobian(extop,lambda,NULL);
135: EPSSetInitialSpace(slpctx->eps,1,&u);
136: return 0;
137: }
139: PetscErrorCode NEPSolve_SLP(NEP nep)
140: {
141: NEP_SLP *ctx = (NEP_SLP*)nep->data;
142: Mat F,H,A;
143: Vec uu,u,r;
144: PetscScalar sigma,lambda,mu,im;
145: PetscReal resnorm;
146: PetscInt nconv;
147: PetscBool skip=PETSC_FALSE,lock=PETSC_FALSE;
148: NEP_EXT_OP extop=NULL; /* Extended operator for deflation */
150: /* get initial approximation of eigenvalue and eigenvector */
151: NEPGetDefaultShift(nep,&sigma);
152: if (!nep->nini) BVSetRandomColumn(nep->V,0);
153: lambda = sigma;
154: if (!ctx->ksp) NEPSLPGetKSP(nep,&ctx->ksp);
155: NEPDeflationInitialize(nep,nep->V,ctx->ksp,PETSC_TRUE,nep->nev,&extop);
156: NEPDeflationCreateVec(extop,&u);
157: VecDuplicate(u,&r);
158: BVGetColumn(nep->V,0,&uu);
159: NEPDeflationCopyToExtendedVec(extop,uu,NULL,u,PETSC_FALSE);
160: BVRestoreColumn(nep->V,0,&uu);
162: /* Restart loop */
163: while (nep->reason == NEP_CONVERGED_ITERATING) {
164: nep->its++;
166: /* form residual, r = T(lambda)*u (used in convergence test only) */
167: NEPDeflationComputeFunction(extop,lambda,&F);
168: MatMult(F,u,r);
170: /* convergence test */
171: VecNorm(r,NORM_2,&resnorm);
172: (*nep->converged)(nep,lambda,0,resnorm,&nep->errest[nep->nconv],nep->convergedctx);
173: nep->eigr[nep->nconv] = lambda;
174: if (nep->errest[nep->nconv]<=nep->tol || nep->errest[nep->nconv]<=ctx->deftol) {
175: if (nep->errest[nep->nconv]<=ctx->deftol && !extop->ref && nep->nconv) {
176: NEPDeflationExtractEigenpair(extop,nep->nconv,u,lambda,nep->ds);
177: NEPDeflationSetRefine(extop,PETSC_TRUE);
178: MatMult(F,u,r);
179: VecNorm(r,NORM_2,&resnorm);
180: (*nep->converged)(nep,lambda,0,resnorm,&nep->errest[nep->nconv],nep->convergedctx);
181: if (nep->errest[nep->nconv]<=nep->tol) lock = PETSC_TRUE;
182: } else if (nep->errest[nep->nconv]<=nep->tol) lock = PETSC_TRUE;
183: }
185: if (lock) {
186: NEPDeflationSetRefine(extop,PETSC_FALSE);
187: nep->nconv = nep->nconv + 1;
188: skip = PETSC_TRUE;
189: lock = PETSC_FALSE;
190: NEPDeflationLocking(extop,u,lambda);
191: }
192: (*nep->stopping)(nep,nep->its,nep->max_it,nep->nconv,nep->nev,&nep->reason,nep->stoppingctx);
193: if (!skip || nep->reason>0) NEPMonitor(nep,nep->its,nep->nconv,nep->eigr,nep->eigi,nep->errest,(nep->reason>0)?nep->nconv:nep->nconv+1);
195: if (nep->reason == NEP_CONVERGED_ITERATING) {
196: if (!skip) {
197: /* evaluate T(lambda) and T'(lambda) */
198: NEPSLPSetUpLinearEP(nep,extop,lambda,u,nep->its==1?PETSC_TRUE:PETSC_FALSE);
199: /* compute new eigenvalue correction mu and eigenvector approximation u */
200: EPSSolve(ctx->eps);
201: EPSGetConverged(ctx->eps,&nconv);
202: if (!nconv) {
203: PetscInfo(nep,"iter=%" PetscInt_FMT ", inner iteration failed, stopping solve\n",nep->its);
204: nep->reason = NEP_DIVERGED_LINEAR_SOLVE;
205: break;
206: }
207: EPSGetEigenpair(ctx->eps,0,&mu,&im,u,NULL);
208: mu = 1.0/mu;
210: } else {
211: nep->its--; /* do not count this as a full iteration */
212: /* use second eigenpair computed in previous iteration */
213: EPSGetConverged(ctx->eps,&nconv);
214: if (nconv>=2) {
215: EPSGetEigenpair(ctx->eps,1,&mu,&im,u,NULL);
216: mu = 1.0/mu;
217: } else {
218: NEPDeflationSetRandomVec(extop,u);
219: mu = lambda-sigma;
220: }
221: skip = PETSC_FALSE;
222: }
223: /* correct eigenvalue */
224: lambda = lambda - mu;
225: }
226: }
227: NEPDeflationGetInvariantPair(extop,NULL,&H);
228: DSSetType(nep->ds,DSNHEP);
229: DSAllocate(nep->ds,PetscMax(nep->nconv,1));
230: DSSetDimensions(nep->ds,nep->nconv,0,nep->nconv);
231: DSGetMat(nep->ds,DS_MAT_A,&A);
232: MatCopy(H,A,SAME_NONZERO_PATTERN);
233: DSRestoreMat(nep->ds,DS_MAT_A,&A);
234: MatDestroy(&H);
235: DSSolve(nep->ds,nep->eigr,nep->eigi);
236: NEPDeflationReset(extop);
237: VecDestroy(&u);
238: VecDestroy(&r);
239: return 0;
240: }
242: PetscErrorCode NEPSetFromOptions_SLP(NEP nep,PetscOptionItems *PetscOptionsObject)
243: {
244: NEP_SLP *ctx = (NEP_SLP*)nep->data;
245: PetscBool flg;
246: PetscReal r;
248: PetscOptionsHeadBegin(PetscOptionsObject,"NEP SLP Options");
250: r = 0.0;
251: PetscOptionsReal("-nep_slp_deflation_threshold","Tolerance used as a threshold for including deflated eigenpairs","NEPSLPSetDeflationThreshold",ctx->deftol,&r,&flg);
252: if (flg) NEPSLPSetDeflationThreshold(nep,r);
254: PetscOptionsHeadEnd();
256: if (!ctx->eps) NEPSLPGetEPS(nep,&ctx->eps);
257: EPSSetFromOptions(ctx->eps);
258: if (nep->twosided) {
259: if (!ctx->epsts) NEPSLPGetEPSLeft(nep,&ctx->epsts);
260: EPSSetFromOptions(ctx->epsts);
261: }
262: if (!ctx->ksp) NEPSLPGetKSP(nep,&ctx->ksp);
263: KSPSetFromOptions(ctx->ksp);
264: return 0;
265: }
267: static PetscErrorCode NEPSLPSetDeflationThreshold_SLP(NEP nep,PetscReal deftol)
268: {
269: NEP_SLP *ctx = (NEP_SLP*)nep->data;
271: if (deftol == PETSC_DEFAULT) {
272: ctx->deftol = PETSC_DEFAULT;
273: nep->state = NEP_STATE_INITIAL;
274: } else {
276: ctx->deftol = deftol;
277: }
278: return 0;
279: }
281: /*@
282: NEPSLPSetDeflationThreshold - Sets the threshold value used to switch between
283: deflated and non-deflated iteration.
285: Logically Collective on nep
287: Input Parameters:
288: + nep - nonlinear eigenvalue solver
289: - deftol - the threshold value
291: Options Database Keys:
292: . -nep_slp_deflation_threshold <deftol> - set the threshold
294: Notes:
295: Normally, the solver iterates on the extended problem in order to deflate
296: previously converged eigenpairs. If this threshold is set to a nonzero value,
297: then once the residual error is below this threshold the solver will
298: continue the iteration without deflation. The intention is to be able to
299: improve the current eigenpair further, despite having previous eigenpairs
300: with somewhat bad precision.
302: Level: advanced
304: .seealso: NEPSLPGetDeflationThreshold()
305: @*/
306: PetscErrorCode NEPSLPSetDeflationThreshold(NEP nep,PetscReal deftol)
307: {
310: PetscTryMethod(nep,"NEPSLPSetDeflationThreshold_C",(NEP,PetscReal),(nep,deftol));
311: return 0;
312: }
314: static PetscErrorCode NEPSLPGetDeflationThreshold_SLP(NEP nep,PetscReal *deftol)
315: {
316: NEP_SLP *ctx = (NEP_SLP*)nep->data;
318: *deftol = ctx->deftol;
319: return 0;
320: }
322: /*@
323: NEPSLPGetDeflationThreshold - Returns the threshold value that controls deflation.
325: Not Collective
327: Input Parameter:
328: . nep - nonlinear eigenvalue solver
330: Output Parameter:
331: . deftol - the threshold
333: Level: advanced
335: .seealso: NEPSLPSetDeflationThreshold()
336: @*/
337: PetscErrorCode NEPSLPGetDeflationThreshold(NEP nep,PetscReal *deftol)
338: {
341: PetscUseMethod(nep,"NEPSLPGetDeflationThreshold_C",(NEP,PetscReal*),(nep,deftol));
342: return 0;
343: }
345: static PetscErrorCode NEPSLPSetEPS_SLP(NEP nep,EPS eps)
346: {
347: NEP_SLP *ctx = (NEP_SLP*)nep->data;
349: PetscObjectReference((PetscObject)eps);
350: EPSDestroy(&ctx->eps);
351: ctx->eps = eps;
352: nep->state = NEP_STATE_INITIAL;
353: return 0;
354: }
356: /*@
357: NEPSLPSetEPS - Associate a linear eigensolver object (EPS) to the
358: nonlinear eigenvalue solver.
360: Collective on nep
362: Input Parameters:
363: + nep - nonlinear eigenvalue solver
364: - eps - the eigensolver object
366: Level: advanced
368: .seealso: NEPSLPGetEPS()
369: @*/
370: PetscErrorCode NEPSLPSetEPS(NEP nep,EPS eps)
371: {
375: PetscTryMethod(nep,"NEPSLPSetEPS_C",(NEP,EPS),(nep,eps));
376: return 0;
377: }
379: static PetscErrorCode NEPSLPGetEPS_SLP(NEP nep,EPS *eps)
380: {
381: NEP_SLP *ctx = (NEP_SLP*)nep->data;
383: if (!ctx->eps) {
384: EPSCreate(PetscObjectComm((PetscObject)nep),&ctx->eps);
385: PetscObjectIncrementTabLevel((PetscObject)ctx->eps,(PetscObject)nep,1);
386: EPSSetOptionsPrefix(ctx->eps,((PetscObject)nep)->prefix);
387: EPSAppendOptionsPrefix(ctx->eps,"nep_slp_");
388: PetscObjectSetOptions((PetscObject)ctx->eps,((PetscObject)nep)->options);
389: }
390: *eps = ctx->eps;
391: return 0;
392: }
394: /*@
395: NEPSLPGetEPS - Retrieve the linear eigensolver object (EPS) associated
396: to the nonlinear eigenvalue solver.
398: Not Collective
400: Input Parameter:
401: . nep - nonlinear eigenvalue solver
403: Output Parameter:
404: . eps - the eigensolver object
406: Level: advanced
408: .seealso: NEPSLPSetEPS()
409: @*/
410: PetscErrorCode NEPSLPGetEPS(NEP nep,EPS *eps)
411: {
414: PetscUseMethod(nep,"NEPSLPGetEPS_C",(NEP,EPS*),(nep,eps));
415: return 0;
416: }
418: static PetscErrorCode NEPSLPSetEPSLeft_SLP(NEP nep,EPS eps)
419: {
420: NEP_SLP *ctx = (NEP_SLP*)nep->data;
422: PetscObjectReference((PetscObject)eps);
423: EPSDestroy(&ctx->epsts);
424: ctx->epsts = eps;
425: nep->state = NEP_STATE_INITIAL;
426: return 0;
427: }
429: /*@
430: NEPSLPSetEPSLeft - Associate a linear eigensolver object (EPS) to the
431: nonlinear eigenvalue solver, used to compute left eigenvectors in the
432: two-sided variant of SLP.
434: Collective on nep
436: Input Parameters:
437: + nep - nonlinear eigenvalue solver
438: - eps - the eigensolver object
440: Level: advanced
442: .seealso: NEPSLPGetEPSLeft(), NEPSetTwoSided()
443: @*/
444: PetscErrorCode NEPSLPSetEPSLeft(NEP nep,EPS eps)
445: {
449: PetscTryMethod(nep,"NEPSLPSetEPSLeft_C",(NEP,EPS),(nep,eps));
450: return 0;
451: }
453: static PetscErrorCode NEPSLPGetEPSLeft_SLP(NEP nep,EPS *eps)
454: {
455: NEP_SLP *ctx = (NEP_SLP*)nep->data;
457: if (!ctx->epsts) {
458: EPSCreate(PetscObjectComm((PetscObject)nep),&ctx->epsts);
459: PetscObjectIncrementTabLevel((PetscObject)ctx->epsts,(PetscObject)nep,1);
460: EPSSetOptionsPrefix(ctx->epsts,((PetscObject)nep)->prefix);
461: EPSAppendOptionsPrefix(ctx->epsts,"nep_slp_left_");
462: PetscObjectSetOptions((PetscObject)ctx->epsts,((PetscObject)nep)->options);
463: }
464: *eps = ctx->epsts;
465: return 0;
466: }
468: /*@
469: NEPSLPGetEPSLeft - Retrieve the linear eigensolver object (EPS) associated
470: to the nonlinear eigenvalue solver, used to compute left eigenvectors in the
471: two-sided variant of SLP.
473: Not Collective
475: Input Parameter:
476: . nep - nonlinear eigenvalue solver
478: Output Parameter:
479: . eps - the eigensolver object
481: Level: advanced
483: .seealso: NEPSLPSetEPSLeft(), NEPSetTwoSided()
484: @*/
485: PetscErrorCode NEPSLPGetEPSLeft(NEP nep,EPS *eps)
486: {
489: PetscUseMethod(nep,"NEPSLPGetEPSLeft_C",(NEP,EPS*),(nep,eps));
490: return 0;
491: }
493: static PetscErrorCode NEPSLPSetKSP_SLP(NEP nep,KSP ksp)
494: {
495: NEP_SLP *ctx = (NEP_SLP*)nep->data;
497: PetscObjectReference((PetscObject)ksp);
498: KSPDestroy(&ctx->ksp);
499: ctx->ksp = ksp;
500: nep->state = NEP_STATE_INITIAL;
501: return 0;
502: }
504: /*@
505: NEPSLPSetKSP - Associate a linear solver object (KSP) to the nonlinear
506: eigenvalue solver.
508: Collective on nep
510: Input Parameters:
511: + nep - eigenvalue solver
512: - ksp - the linear solver object
514: Level: advanced
516: .seealso: NEPSLPGetKSP()
517: @*/
518: PetscErrorCode NEPSLPSetKSP(NEP nep,KSP ksp)
519: {
523: PetscTryMethod(nep,"NEPSLPSetKSP_C",(NEP,KSP),(nep,ksp));
524: return 0;
525: }
527: static PetscErrorCode NEPSLPGetKSP_SLP(NEP nep,KSP *ksp)
528: {
529: NEP_SLP *ctx = (NEP_SLP*)nep->data;
531: if (!ctx->ksp) {
532: KSPCreate(PetscObjectComm((PetscObject)nep),&ctx->ksp);
533: PetscObjectIncrementTabLevel((PetscObject)ctx->ksp,(PetscObject)nep,1);
534: KSPSetOptionsPrefix(ctx->ksp,((PetscObject)nep)->prefix);
535: KSPAppendOptionsPrefix(ctx->ksp,"nep_slp_");
536: PetscObjectSetOptions((PetscObject)ctx->ksp,((PetscObject)nep)->options);
537: KSPSetErrorIfNotConverged(ctx->ksp,PETSC_TRUE);
538: KSPSetTolerances(ctx->ksp,SlepcDefaultTol(nep->tol),PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);
539: }
540: *ksp = ctx->ksp;
541: return 0;
542: }
544: /*@
545: NEPSLPGetKSP - Retrieve the linear solver object (KSP) associated with
546: the nonlinear eigenvalue solver.
548: Not Collective
550: Input Parameter:
551: . nep - nonlinear eigenvalue solver
553: Output Parameter:
554: . ksp - the linear solver object
556: Level: advanced
558: .seealso: NEPSLPSetKSP()
559: @*/
560: PetscErrorCode NEPSLPGetKSP(NEP nep,KSP *ksp)
561: {
564: PetscUseMethod(nep,"NEPSLPGetKSP_C",(NEP,KSP*),(nep,ksp));
565: return 0;
566: }
568: PetscErrorCode NEPView_SLP(NEP nep,PetscViewer viewer)
569: {
570: NEP_SLP *ctx = (NEP_SLP*)nep->data;
571: PetscBool isascii;
573: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
574: if (isascii) {
575: if (ctx->deftol) PetscViewerASCIIPrintf(viewer," deflation threshold: %g\n",(double)ctx->deftol);
576: if (!ctx->eps) NEPSLPGetEPS(nep,&ctx->eps);
577: PetscViewerASCIIPushTab(viewer);
578: EPSView(ctx->eps,viewer);
579: if (nep->twosided) {
580: if (!ctx->epsts) NEPSLPGetEPSLeft(nep,&ctx->epsts);
581: EPSView(ctx->epsts,viewer);
582: }
583: if (!ctx->ksp) NEPSLPGetKSP(nep,&ctx->ksp);
584: KSPView(ctx->ksp,viewer);
585: PetscViewerASCIIPopTab(viewer);
586: }
587: return 0;
588: }
590: PetscErrorCode NEPReset_SLP(NEP nep)
591: {
592: NEP_SLP *ctx = (NEP_SLP*)nep->data;
594: EPSReset(ctx->eps);
595: if (nep->twosided) EPSReset(ctx->epsts);
596: KSPReset(ctx->ksp);
597: return 0;
598: }
600: PetscErrorCode NEPDestroy_SLP(NEP nep)
601: {
602: NEP_SLP *ctx = (NEP_SLP*)nep->data;
604: KSPDestroy(&ctx->ksp);
605: EPSDestroy(&ctx->eps);
606: EPSDestroy(&ctx->epsts);
607: PetscFree(nep->data);
608: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPSetDeflationThreshold_C",NULL);
609: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPGetDeflationThreshold_C",NULL);
610: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPSetEPS_C",NULL);
611: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPGetEPS_C",NULL);
612: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPSetEPSLeft_C",NULL);
613: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPGetEPSLeft_C",NULL);
614: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPSetKSP_C",NULL);
615: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPGetKSP_C",NULL);
616: return 0;
617: }
619: SLEPC_EXTERN PetscErrorCode NEPCreate_SLP(NEP nep)
620: {
621: NEP_SLP *ctx;
623: PetscNew(&ctx);
624: nep->data = (void*)ctx;
626: nep->useds = PETSC_TRUE;
627: ctx->deftol = PETSC_DEFAULT;
629: nep->ops->solve = NEPSolve_SLP;
630: nep->ops->setup = NEPSetUp_SLP;
631: nep->ops->setfromoptions = NEPSetFromOptions_SLP;
632: nep->ops->reset = NEPReset_SLP;
633: nep->ops->destroy = NEPDestroy_SLP;
634: nep->ops->view = NEPView_SLP;
635: nep->ops->computevectors = NEPComputeVectors_Schur;
637: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPSetDeflationThreshold_C",NEPSLPSetDeflationThreshold_SLP);
638: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPGetDeflationThreshold_C",NEPSLPGetDeflationThreshold_SLP);
639: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPSetEPS_C",NEPSLPSetEPS_SLP);
640: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPGetEPS_C",NEPSLPGetEPS_SLP);
641: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPSetEPSLeft_C",NEPSLPSetEPSLeft_SLP);
642: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPGetEPSLeft_C",NEPSLPGetEPSLeft_SLP);
643: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPSetKSP_C",NEPSLPSetKSP_SLP);
644: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPGetKSP_C",NEPSLPGetKSP_SLP);
645: return 0;
646: }