Actual source code: slp.c
slepc-3.17.2 2022-08-09
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: PetscFunctionReturn(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: PetscFunctionReturn(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: PetscFunctionReturn(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: PetscFunctionReturn(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: PetscFunctionReturn(0);
137: }
139: PetscErrorCode NEPSolve_SLP(NEP nep)
140: {
141: NEP_SLP *ctx = (NEP_SLP*)nep->data;
142: Mat F,H;
143: Vec uu,u,r;
144: PetscScalar sigma,lambda,mu,im,*Ap;
145: const PetscScalar *Hp;
146: PetscReal resnorm;
147: PetscInt nconv,ldh,ldds,i,j;
148: PetscBool skip=PETSC_FALSE,lock=PETSC_FALSE;
149: NEP_EXT_OP extop=NULL; /* Extended operator for deflation */
151: /* get initial approximation of eigenvalue and eigenvector */
152: NEPGetDefaultShift(nep,&sigma);
153: if (!nep->nini) BVSetRandomColumn(nep->V,0);
154: lambda = sigma;
155: if (!ctx->ksp) NEPSLPGetKSP(nep,&ctx->ksp);
156: NEPDeflationInitialize(nep,nep->V,ctx->ksp,PETSC_TRUE,nep->nev,&extop);
157: NEPDeflationCreateVec(extop,&u);
158: VecDuplicate(u,&r);
159: BVGetColumn(nep->V,0,&uu);
160: NEPDeflationCopyToExtendedVec(extop,uu,NULL,u,PETSC_FALSE);
161: BVRestoreColumn(nep->V,0,&uu);
163: /* Restart loop */
164: while (nep->reason == NEP_CONVERGED_ITERATING) {
165: nep->its++;
167: /* form residual, r = T(lambda)*u (used in convergence test only) */
168: NEPDeflationComputeFunction(extop,lambda,&F);
169: MatMult(F,u,r);
171: /* convergence test */
172: VecNorm(r,NORM_2,&resnorm);
173: (*nep->converged)(nep,lambda,0,resnorm,&nep->errest[nep->nconv],nep->convergedctx);
174: nep->eigr[nep->nconv] = lambda;
175: if (nep->errest[nep->nconv]<=nep->tol || nep->errest[nep->nconv]<=ctx->deftol) {
176: if (nep->errest[nep->nconv]<=ctx->deftol && !extop->ref && nep->nconv) {
177: NEPDeflationExtractEigenpair(extop,nep->nconv,u,lambda,nep->ds);
178: NEPDeflationSetRefine(extop,PETSC_TRUE);
179: MatMult(F,u,r);
180: VecNorm(r,NORM_2,&resnorm);
181: (*nep->converged)(nep,lambda,0,resnorm,&nep->errest[nep->nconv],nep->convergedctx);
182: if (nep->errest[nep->nconv]<=nep->tol) lock = PETSC_TRUE;
183: } else if (nep->errest[nep->nconv]<=nep->tol) lock = PETSC_TRUE;
184: }
186: if (lock) {
187: NEPDeflationSetRefine(extop,PETSC_FALSE);
188: nep->nconv = nep->nconv + 1;
189: skip = PETSC_TRUE;
190: lock = PETSC_FALSE;
191: NEPDeflationLocking(extop,u,lambda);
192: }
193: (*nep->stopping)(nep,nep->its,nep->max_it,nep->nconv,nep->nev,&nep->reason,nep->stoppingctx);
194: 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);
196: if (nep->reason == NEP_CONVERGED_ITERATING) {
197: if (!skip) {
198: /* evaluate T(lambda) and T'(lambda) */
199: NEPSLPSetUpLinearEP(nep,extop,lambda,u,nep->its==1?PETSC_TRUE:PETSC_FALSE);
200: /* compute new eigenvalue correction mu and eigenvector approximation u */
201: EPSSolve(ctx->eps);
202: EPSGetConverged(ctx->eps,&nconv);
203: if (!nconv) {
204: PetscInfo(nep,"iter=%" PetscInt_FMT ", inner iteration failed, stopping solve\n",nep->its);
205: nep->reason = NEP_DIVERGED_LINEAR_SOLVE;
206: break;
207: }
208: EPSGetEigenpair(ctx->eps,0,&mu,&im,u,NULL);
209: mu = 1.0/mu;
211: } else {
212: nep->its--; /* do not count this as a full iteration */
213: /* use second eigenpair computed in previous iteration */
214: EPSGetConverged(ctx->eps,&nconv);
215: if (nconv>=2) {
216: EPSGetEigenpair(ctx->eps,1,&mu,&im,u,NULL);
217: mu = 1.0/mu;
218: } else {
219: NEPDeflationSetRandomVec(extop,u);
220: mu = lambda-sigma;
221: }
222: skip = PETSC_FALSE;
223: }
224: /* correct eigenvalue */
225: lambda = lambda - mu;
226: }
227: }
228: NEPDeflationGetInvariantPair(extop,NULL,&H);
229: MatGetSize(H,NULL,&ldh);
230: DSReset(nep->ds);
231: DSSetType(nep->ds,DSNHEP);
232: DSAllocate(nep->ds,PetscMax(nep->nconv,1));
233: DSGetLeadingDimension(nep->ds,&ldds);
234: MatDenseGetArrayRead(H,&Hp);
235: DSGetArray(nep->ds,DS_MAT_A,&Ap);
236: for (j=0;j<nep->nconv;j++)
237: for (i=0;i<nep->nconv;i++) Ap[j*ldds+i] = Hp[j*ldh+i];
238: DSRestoreArray(nep->ds,DS_MAT_A,&Ap);
239: MatDenseRestoreArrayRead(H,&Hp);
240: MatDestroy(&H);
241: DSSetDimensions(nep->ds,nep->nconv,0,nep->nconv);
242: DSSolve(nep->ds,nep->eigr,nep->eigi);
243: NEPDeflationReset(extop);
244: VecDestroy(&u);
245: VecDestroy(&r);
246: PetscFunctionReturn(0);
247: }
249: PetscErrorCode NEPSetFromOptions_SLP(PetscOptionItems *PetscOptionsObject,NEP nep)
250: {
251: NEP_SLP *ctx = (NEP_SLP*)nep->data;
252: PetscBool flg;
253: PetscReal r;
255: PetscOptionsHead(PetscOptionsObject,"NEP SLP Options");
257: r = 0.0;
258: PetscOptionsReal("-nep_slp_deflation_threshold","Tolerance used as a threshold for including deflated eigenpairs","NEPSLPSetDeflationThreshold",ctx->deftol,&r,&flg);
259: if (flg) NEPSLPSetDeflationThreshold(nep,r);
261: PetscOptionsTail();
263: if (!ctx->eps) NEPSLPGetEPS(nep,&ctx->eps);
264: EPSSetFromOptions(ctx->eps);
265: if (nep->twosided) {
266: if (!ctx->epsts) NEPSLPGetEPSLeft(nep,&ctx->epsts);
267: EPSSetFromOptions(ctx->epsts);
268: }
269: if (!ctx->ksp) NEPSLPGetKSP(nep,&ctx->ksp);
270: KSPSetFromOptions(ctx->ksp);
271: PetscFunctionReturn(0);
272: }
274: static PetscErrorCode NEPSLPSetDeflationThreshold_SLP(NEP nep,PetscReal deftol)
275: {
276: NEP_SLP *ctx = (NEP_SLP*)nep->data;
278: if (deftol == PETSC_DEFAULT) {
279: ctx->deftol = PETSC_DEFAULT;
280: nep->state = NEP_STATE_INITIAL;
281: } else {
283: ctx->deftol = deftol;
284: }
285: PetscFunctionReturn(0);
286: }
288: /*@
289: NEPSLPSetDeflationThreshold - Sets the threshold value used to switch between
290: deflated and non-deflated iteration.
292: Logically Collective on nep
294: Input Parameters:
295: + nep - nonlinear eigenvalue solver
296: - deftol - the threshold value
298: Options Database Keys:
299: . -nep_slp_deflation_threshold <deftol> - set the threshold
301: Notes:
302: Normally, the solver iterates on the extended problem in order to deflate
303: previously converged eigenpairs. If this threshold is set to a nonzero value,
304: then once the residual error is below this threshold the solver will
305: continue the iteration without deflation. The intention is to be able to
306: improve the current eigenpair further, despite having previous eigenpairs
307: with somewhat bad precision.
309: Level: advanced
311: .seealso: NEPSLPGetDeflationThreshold()
312: @*/
313: PetscErrorCode NEPSLPSetDeflationThreshold(NEP nep,PetscReal deftol)
314: {
317: PetscTryMethod(nep,"NEPSLPSetDeflationThreshold_C",(NEP,PetscReal),(nep,deftol));
318: PetscFunctionReturn(0);
319: }
321: static PetscErrorCode NEPSLPGetDeflationThreshold_SLP(NEP nep,PetscReal *deftol)
322: {
323: NEP_SLP *ctx = (NEP_SLP*)nep->data;
325: *deftol = ctx->deftol;
326: PetscFunctionReturn(0);
327: }
329: /*@
330: NEPSLPGetDeflationThreshold - Returns the threshold value that controls deflation.
332: Not Collective
334: Input Parameter:
335: . nep - nonlinear eigenvalue solver
337: Output Parameter:
338: . deftol - the threshold
340: Level: advanced
342: .seealso: NEPSLPSetDeflationThreshold()
343: @*/
344: PetscErrorCode NEPSLPGetDeflationThreshold(NEP nep,PetscReal *deftol)
345: {
348: PetscUseMethod(nep,"NEPSLPGetDeflationThreshold_C",(NEP,PetscReal*),(nep,deftol));
349: PetscFunctionReturn(0);
350: }
352: static PetscErrorCode NEPSLPSetEPS_SLP(NEP nep,EPS eps)
353: {
354: NEP_SLP *ctx = (NEP_SLP*)nep->data;
356: PetscObjectReference((PetscObject)eps);
357: EPSDestroy(&ctx->eps);
358: ctx->eps = eps;
359: PetscLogObjectParent((PetscObject)nep,(PetscObject)ctx->eps);
360: nep->state = NEP_STATE_INITIAL;
361: PetscFunctionReturn(0);
362: }
364: /*@
365: NEPSLPSetEPS - Associate a linear eigensolver object (EPS) to the
366: nonlinear eigenvalue solver.
368: Collective on nep
370: Input Parameters:
371: + nep - nonlinear eigenvalue solver
372: - eps - the eigensolver object
374: Level: advanced
376: .seealso: NEPSLPGetEPS()
377: @*/
378: PetscErrorCode NEPSLPSetEPS(NEP nep,EPS eps)
379: {
383: PetscTryMethod(nep,"NEPSLPSetEPS_C",(NEP,EPS),(nep,eps));
384: PetscFunctionReturn(0);
385: }
387: static PetscErrorCode NEPSLPGetEPS_SLP(NEP nep,EPS *eps)
388: {
389: NEP_SLP *ctx = (NEP_SLP*)nep->data;
391: if (!ctx->eps) {
392: EPSCreate(PetscObjectComm((PetscObject)nep),&ctx->eps);
393: PetscObjectIncrementTabLevel((PetscObject)ctx->eps,(PetscObject)nep,1);
394: EPSSetOptionsPrefix(ctx->eps,((PetscObject)nep)->prefix);
395: EPSAppendOptionsPrefix(ctx->eps,"nep_slp_");
396: PetscLogObjectParent((PetscObject)nep,(PetscObject)ctx->eps);
397: PetscObjectSetOptions((PetscObject)ctx->eps,((PetscObject)nep)->options);
398: }
399: *eps = ctx->eps;
400: PetscFunctionReturn(0);
401: }
403: /*@
404: NEPSLPGetEPS - Retrieve the linear eigensolver object (EPS) associated
405: to the nonlinear eigenvalue solver.
407: Not Collective
409: Input Parameter:
410: . nep - nonlinear eigenvalue solver
412: Output Parameter:
413: . eps - the eigensolver object
415: Level: advanced
417: .seealso: NEPSLPSetEPS()
418: @*/
419: PetscErrorCode NEPSLPGetEPS(NEP nep,EPS *eps)
420: {
423: PetscUseMethod(nep,"NEPSLPGetEPS_C",(NEP,EPS*),(nep,eps));
424: PetscFunctionReturn(0);
425: }
427: static PetscErrorCode NEPSLPSetEPSLeft_SLP(NEP nep,EPS eps)
428: {
429: NEP_SLP *ctx = (NEP_SLP*)nep->data;
431: PetscObjectReference((PetscObject)eps);
432: EPSDestroy(&ctx->epsts);
433: ctx->epsts = eps;
434: PetscLogObjectParent((PetscObject)nep,(PetscObject)ctx->epsts);
435: nep->state = NEP_STATE_INITIAL;
436: PetscFunctionReturn(0);
437: }
439: /*@
440: NEPSLPSetEPSLeft - Associate a linear eigensolver object (EPS) to the
441: nonlinear eigenvalue solver, used to compute left eigenvectors in the
442: two-sided variant of SLP.
444: Collective on nep
446: Input Parameters:
447: + nep - nonlinear eigenvalue solver
448: - eps - the eigensolver object
450: Level: advanced
452: .seealso: NEPSLPGetEPSLeft(), NEPSetTwoSided()
453: @*/
454: PetscErrorCode NEPSLPSetEPSLeft(NEP nep,EPS eps)
455: {
459: PetscTryMethod(nep,"NEPSLPSetEPSLeft_C",(NEP,EPS),(nep,eps));
460: PetscFunctionReturn(0);
461: }
463: static PetscErrorCode NEPSLPGetEPSLeft_SLP(NEP nep,EPS *eps)
464: {
465: NEP_SLP *ctx = (NEP_SLP*)nep->data;
467: if (!ctx->epsts) {
468: EPSCreate(PetscObjectComm((PetscObject)nep),&ctx->epsts);
469: PetscObjectIncrementTabLevel((PetscObject)ctx->epsts,(PetscObject)nep,1);
470: EPSSetOptionsPrefix(ctx->epsts,((PetscObject)nep)->prefix);
471: EPSAppendOptionsPrefix(ctx->epsts,"nep_slp_left_");
472: PetscLogObjectParent((PetscObject)nep,(PetscObject)ctx->epsts);
473: PetscObjectSetOptions((PetscObject)ctx->epsts,((PetscObject)nep)->options);
474: }
475: *eps = ctx->epsts;
476: PetscFunctionReturn(0);
477: }
479: /*@
480: NEPSLPGetEPSLeft - Retrieve the linear eigensolver object (EPS) associated
481: to the nonlinear eigenvalue solver, used to compute left eigenvectors in the
482: two-sided variant of SLP.
484: Not Collective
486: Input Parameter:
487: . nep - nonlinear eigenvalue solver
489: Output Parameter:
490: . eps - the eigensolver object
492: Level: advanced
494: .seealso: NEPSLPSetEPSLeft(), NEPSetTwoSided()
495: @*/
496: PetscErrorCode NEPSLPGetEPSLeft(NEP nep,EPS *eps)
497: {
500: PetscUseMethod(nep,"NEPSLPGetEPSLeft_C",(NEP,EPS*),(nep,eps));
501: PetscFunctionReturn(0);
502: }
504: static PetscErrorCode NEPSLPSetKSP_SLP(NEP nep,KSP ksp)
505: {
506: NEP_SLP *ctx = (NEP_SLP*)nep->data;
508: PetscObjectReference((PetscObject)ksp);
509: KSPDestroy(&ctx->ksp);
510: ctx->ksp = ksp;
511: PetscLogObjectParent((PetscObject)nep,(PetscObject)ctx->ksp);
512: nep->state = NEP_STATE_INITIAL;
513: PetscFunctionReturn(0);
514: }
516: /*@
517: NEPSLPSetKSP - Associate a linear solver object (KSP) to the nonlinear
518: eigenvalue solver.
520: Collective on nep
522: Input Parameters:
523: + nep - eigenvalue solver
524: - ksp - the linear solver object
526: Level: advanced
528: .seealso: NEPSLPGetKSP()
529: @*/
530: PetscErrorCode NEPSLPSetKSP(NEP nep,KSP ksp)
531: {
535: PetscTryMethod(nep,"NEPSLPSetKSP_C",(NEP,KSP),(nep,ksp));
536: PetscFunctionReturn(0);
537: }
539: static PetscErrorCode NEPSLPGetKSP_SLP(NEP nep,KSP *ksp)
540: {
541: NEP_SLP *ctx = (NEP_SLP*)nep->data;
543: if (!ctx->ksp) {
544: KSPCreate(PetscObjectComm((PetscObject)nep),&ctx->ksp);
545: PetscObjectIncrementTabLevel((PetscObject)ctx->ksp,(PetscObject)nep,1);
546: KSPSetOptionsPrefix(ctx->ksp,((PetscObject)nep)->prefix);
547: KSPAppendOptionsPrefix(ctx->ksp,"nep_slp_");
548: PetscLogObjectParent((PetscObject)nep,(PetscObject)ctx->ksp);
549: PetscObjectSetOptions((PetscObject)ctx->ksp,((PetscObject)nep)->options);
550: KSPSetErrorIfNotConverged(ctx->ksp,PETSC_TRUE);
551: KSPSetTolerances(ctx->ksp,SlepcDefaultTol(nep->tol),PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);
552: }
553: *ksp = ctx->ksp;
554: PetscFunctionReturn(0);
555: }
557: /*@
558: NEPSLPGetKSP - Retrieve the linear solver object (KSP) associated with
559: the nonlinear eigenvalue solver.
561: Not Collective
563: Input Parameter:
564: . nep - nonlinear eigenvalue solver
566: Output Parameter:
567: . ksp - the linear solver object
569: Level: advanced
571: .seealso: NEPSLPSetKSP()
572: @*/
573: PetscErrorCode NEPSLPGetKSP(NEP nep,KSP *ksp)
574: {
577: PetscUseMethod(nep,"NEPSLPGetKSP_C",(NEP,KSP*),(nep,ksp));
578: PetscFunctionReturn(0);
579: }
581: PetscErrorCode NEPView_SLP(NEP nep,PetscViewer viewer)
582: {
583: NEP_SLP *ctx = (NEP_SLP*)nep->data;
584: PetscBool isascii;
586: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
587: if (isascii) {
588: if (ctx->deftol) PetscViewerASCIIPrintf(viewer," deflation threshold: %g\n",(double)ctx->deftol);
589: if (!ctx->eps) NEPSLPGetEPS(nep,&ctx->eps);
590: PetscViewerASCIIPushTab(viewer);
591: EPSView(ctx->eps,viewer);
592: if (nep->twosided) {
593: if (!ctx->epsts) NEPSLPGetEPSLeft(nep,&ctx->epsts);
594: EPSView(ctx->epsts,viewer);
595: }
596: if (!ctx->ksp) NEPSLPGetKSP(nep,&ctx->ksp);
597: KSPView(ctx->ksp,viewer);
598: PetscViewerASCIIPopTab(viewer);
599: }
600: PetscFunctionReturn(0);
601: }
603: PetscErrorCode NEPReset_SLP(NEP nep)
604: {
605: NEP_SLP *ctx = (NEP_SLP*)nep->data;
607: EPSReset(ctx->eps);
608: if (nep->twosided) EPSReset(ctx->epsts);
609: KSPReset(ctx->ksp);
610: PetscFunctionReturn(0);
611: }
613: PetscErrorCode NEPDestroy_SLP(NEP nep)
614: {
615: NEP_SLP *ctx = (NEP_SLP*)nep->data;
617: KSPDestroy(&ctx->ksp);
618: EPSDestroy(&ctx->eps);
619: EPSDestroy(&ctx->epsts);
620: PetscFree(nep->data);
621: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPSetDeflationThreshold_C",NULL);
622: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPGetDeflationThreshold_C",NULL);
623: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPSetEPS_C",NULL);
624: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPGetEPS_C",NULL);
625: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPSetEPSLeft_C",NULL);
626: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPGetEPSLeft_C",NULL);
627: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPSetKSP_C",NULL);
628: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPGetKSP_C",NULL);
629: PetscFunctionReturn(0);
630: }
632: SLEPC_EXTERN PetscErrorCode NEPCreate_SLP(NEP nep)
633: {
634: NEP_SLP *ctx;
636: PetscNewLog(nep,&ctx);
637: nep->data = (void*)ctx;
639: nep->useds = PETSC_TRUE;
640: ctx->deftol = PETSC_DEFAULT;
642: nep->ops->solve = NEPSolve_SLP;
643: nep->ops->setup = NEPSetUp_SLP;
644: nep->ops->setfromoptions = NEPSetFromOptions_SLP;
645: nep->ops->reset = NEPReset_SLP;
646: nep->ops->destroy = NEPDestroy_SLP;
647: nep->ops->view = NEPView_SLP;
648: nep->ops->computevectors = NEPComputeVectors_Schur;
650: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPSetDeflationThreshold_C",NEPSLPSetDeflationThreshold_SLP);
651: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPGetDeflationThreshold_C",NEPSLPGetDeflationThreshold_SLP);
652: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPSetEPS_C",NEPSLPSetEPS_SLP);
653: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPGetEPS_C",NEPSLPGetEPS_SLP);
654: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPSetEPSLeft_C",NEPSLPSetEPSLeft_SLP);
655: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPGetEPSLeft_C",NEPSLPGetEPSLeft_SLP);
656: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPSetKSP_C",NEPSLPSetKSP_SLP);
657: PetscObjectComposeFunction((PetscObject)nep,"NEPSLPGetKSP_C",NEPSLPGetKSP_SLP);
658: PetscFunctionReturn(0);
659: }