Actual source code: nleigs-fullb.c
slepc-main 2024-11-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: Full basis for the linearization of the rational approximation of non-linear eigenproblems
12: */
14: #include <slepc/private/nepimpl.h>
15: #include "nleigs.h"
17: static PetscErrorCode MatMult_FullBasis_Sinvert(Mat M,Vec x,Vec y)
18: {
19: NEP_NLEIGS *ctx;
20: NEP nep;
21: const PetscScalar *px;
22: PetscScalar *beta,*s,*xi,*t,*py,sigma;
23: PetscInt nmat,d,i,k,m;
24: Vec xx,xxx,yy,yyy,w,ww,www;
26: PetscFunctionBegin;
27: PetscCall(MatShellGetContext(M,&nep));
28: ctx = (NEP_NLEIGS*)nep->data;
29: beta = ctx->beta; s = ctx->s; xi = ctx->xi;
30: sigma = ctx->shifts[0];
31: nmat = ctx->nmat;
32: d = nmat-1;
33: m = nep->nloc;
34: PetscCall(PetscMalloc1(ctx->nmat,&t));
35: xx = ctx->w[0]; xxx = ctx->w[1]; yy = ctx->w[2]; yyy=ctx->w[3];
36: w = nep->work[0]; ww = nep->work[1]; www = nep->work[2];
37: PetscCall(VecGetArrayRead(x,&px));
38: PetscCall(VecGetArray(y,&py));
39: PetscCall(VecPlaceArray(xx,px+(d-1)*m));
40: PetscCall(VecPlaceArray(xxx,px+(d-2)*m));
41: PetscCall(VecPlaceArray(yy,py+(d-2)*m));
42: PetscCall(VecCopy(xxx,yy));
43: PetscCall(VecAXPY(yy,beta[d-1]/xi[d-2],xx));
44: PetscCall(VecScale(yy,1.0/(s[d-2]-sigma)));
45: PetscCall(VecResetArray(xx));
46: PetscCall(VecResetArray(xxx));
47: PetscCall(VecResetArray(yy));
48: for (i=d-3;i>=0;i--) {
49: PetscCall(VecPlaceArray(xx,px+(i+1)*m));
50: PetscCall(VecPlaceArray(xxx,px+i*m));
51: PetscCall(VecPlaceArray(yy,py+i*m));
52: PetscCall(VecPlaceArray(yyy,py+(i+1)*m));
53: PetscCall(VecCopy(xxx,yy));
54: PetscCall(VecAXPY(yy,beta[i+1]/xi[i],xx));
55: PetscCall(VecAXPY(yy,-beta[i+1]*(1.0-sigma/xi[i]),yyy));
56: PetscCall(VecScale(yy,1.0/(s[i]-sigma)));
57: PetscCall(VecResetArray(xx));
58: PetscCall(VecResetArray(xxx));
59: PetscCall(VecResetArray(yy));
60: PetscCall(VecResetArray(yyy));
61: }
62: if (nep->fui==NEP_USER_INTERFACE_SPLIT) {
63: PetscCall(VecZeroEntries(w));
64: for (k=0;k<nep->nt;k++) {
65: PetscCall(VecZeroEntries(ww));
66: PetscCall(VecPlaceArray(xx,px+(d-1)*m));
67: PetscCall(VecAXPY(ww,-ctx->coeffD[k+nep->nt*d]/beta[d],xx));
68: PetscCall(VecResetArray(xx));
69: for (i=0;i<d-1;i++) {
70: PetscCall(VecPlaceArray(yy,py+i*m));
71: PetscCall(VecAXPY(ww,-ctx->coeffD[nep->nt*i+k],yy));
72: PetscCall(VecResetArray(yy));
73: }
74: PetscCall(MatMult(nep->A[k],ww,www));
75: PetscCall(VecAXPY(w,1.0,www));
76: }
77: } else {
78: PetscCall(VecPlaceArray(xx,px+(d-1)*m));
79: PetscCall(MatMult(ctx->D[d],xx,w));
80: PetscCall(VecScale(w,-1.0/beta[d]));
81: PetscCall(VecResetArray(xx));
82: for (i=0;i<d-1;i++) {
83: PetscCall(VecPlaceArray(yy,py+i*m));
84: PetscCall(MatMult(ctx->D[i],yy,ww));
85: PetscCall(VecResetArray(yy));
86: PetscCall(VecAXPY(w,-1.0,ww));
87: }
88: }
89: PetscCall(VecPlaceArray(yy,py+(d-1)*m));
90: PetscCall(KSPSolve(ctx->ksp[0],w,yy));
91: PetscCall(NEPNLEIGSEvalNRTFunct(nep,d-1,sigma,t));
92: for (i=0;i<d-1;i++) {
93: PetscCall(VecPlaceArray(yyy,py+i*m));
94: PetscCall(VecAXPY(yyy,t[i],yy));
95: PetscCall(VecResetArray(yyy));
96: }
97: PetscCall(VecScale(yy,t[d-1]));
98: PetscCall(VecResetArray(yy));
99: PetscCall(VecRestoreArrayRead(x,&px));
100: PetscCall(VecRestoreArray(y,&py));
101: PetscCall(PetscFree(t));
102: PetscFunctionReturn(PETSC_SUCCESS);
103: }
105: static PetscErrorCode MatMultTranspose_FullBasis_Sinvert(Mat M,Vec x,Vec y)
106: {
107: NEP_NLEIGS *ctx;
108: NEP nep;
109: const PetscScalar *px;
110: PetscScalar *beta,*s,*xi,*t,*py,sigma;
111: PetscInt nmat,d,i,k,m;
112: Vec xx,yy,yyy,w,z0;
114: PetscFunctionBegin;
115: PetscCall(MatShellGetContext(M,&nep));
116: ctx = (NEP_NLEIGS*)nep->data;
117: beta = ctx->beta; s = ctx->s; xi = ctx->xi;
118: sigma = ctx->shifts[0];
119: nmat = ctx->nmat;
120: d = nmat-1;
121: m = nep->nloc;
122: PetscCall(PetscMalloc1(ctx->nmat,&t));
123: xx = ctx->w[0]; yy = ctx->w[1]; yyy=ctx->w[2];
124: w = nep->work[0]; z0 = nep->work[1];
125: PetscCall(VecGetArrayRead(x,&px));
126: PetscCall(VecGetArray(y,&py));
127: PetscCall(NEPNLEIGSEvalNRTFunct(nep,d,sigma,t));
128: PetscCall(VecPlaceArray(xx,px+(d-1)*m));
129: PetscCall(VecCopy(xx,w));
130: PetscCall(VecScale(w,t[d-1]));
131: PetscCall(VecResetArray(xx));
132: for (i=0;i<d-1;i++) {
133: PetscCall(VecPlaceArray(xx,px+i*m));
134: PetscCall(VecAXPY(w,t[i],xx));
135: PetscCall(VecResetArray(xx));
136: }
137: PetscCall(KSPSolveTranspose(ctx->ksp[0],w,z0));
139: PetscCall(VecPlaceArray(yy,py));
140: if (nep->fui==NEP_USER_INTERFACE_SPLIT) {
141: PetscCall(VecZeroEntries(yy));
142: for (k=0;k<nep->nt;k++) {
143: PetscCall(MatMult(nep->A[k],z0,w));
144: PetscCall(VecAXPY(yy,ctx->coeffD[k],w));
145: }
146: } else PetscCall(MatMultTranspose(ctx->D[0],z0,yy));
147: PetscCall(VecPlaceArray(xx,px));
148: PetscCall(VecAXPY(yy,-1.0,xx));
149: PetscCall(VecResetArray(xx));
150: PetscCall(VecScale(yy,-1.0/(s[0]-sigma)));
151: PetscCall(VecResetArray(yy));
152: for (i=2;i<d;i++) {
153: PetscCall(VecPlaceArray(yy,py+(i-1)*m));
154: if (nep->fui==NEP_USER_INTERFACE_SPLIT) {
155: PetscCall(VecZeroEntries(yy));
156: for (k=0;k<nep->nt;k++) {
157: PetscCall(MatMult(nep->A[k],z0,w));
158: PetscCall(VecAXPY(yy,ctx->coeffD[k+(i-1)*nep->nt],w));
159: }
160: } else PetscCall(MatMultTranspose(ctx->D[i-1],z0,yy));
161: PetscCall(VecPlaceArray(yyy,py+(i-2)*m));
162: PetscCall(VecAXPY(yy,beta[i-1]*(1.0-sigma/xi[i-2]),yyy));
163: PetscCall(VecResetArray(yyy));
164: PetscCall(VecPlaceArray(xx,px+(i-1)*m));
165: PetscCall(VecAXPY(yy,-1.0,xx));
166: PetscCall(VecResetArray(xx));
167: PetscCall(VecScale(yy,-1.0/(s[i-1]-sigma)));
168: PetscCall(VecResetArray(yy));
169: }
170: PetscCall(VecPlaceArray(yy,py+(d-1)*m));
171: if (nep->fui==NEP_USER_INTERFACE_SPLIT) {
172: PetscCall(VecZeroEntries(yy));
173: for (k=0;k<nep->nt;k++) {
174: PetscCall(MatMult(nep->A[k],z0,w));
175: PetscCall(VecAXPY(yy,ctx->coeffD[k+d*nep->nt],w));
176: }
177: } else PetscCall(MatMultTranspose(ctx->D[d],z0,yy));
178: PetscCall(VecScale(yy,-1.0/beta[d]));
179: PetscCall(VecPlaceArray(yyy,py+(d-2)*m));
180: PetscCall(VecAXPY(yy,beta[d-1]/xi[d-2],yyy));
181: PetscCall(VecResetArray(yyy));
182: PetscCall(VecResetArray(yy));
184: for (i=d-2;i>0;i--) {
185: PetscCall(VecPlaceArray(yyy,py+(i-1)*m));
186: PetscCall(VecPlaceArray(yy,py+i*m));
187: PetscCall(VecAXPY(yy,beta[i]/xi[i-1],yyy));
188: PetscCall(VecResetArray(yyy));
189: PetscCall(VecResetArray(yy));
190: }
192: PetscCall(VecRestoreArrayRead(x,&px));
193: PetscCall(VecRestoreArray(y,&py));
194: PetscCall(PetscFree(t));
195: PetscFunctionReturn(PETSC_SUCCESS);
196: }
198: static PetscErrorCode BackTransform_FullBasis(ST st,PetscInt n,PetscScalar *eigr,PetscScalar *eigi)
199: {
200: NEP nep;
202: PetscFunctionBegin;
203: PetscCall(STShellGetContext(st,&nep));
204: PetscCall(NEPNLEIGSBackTransform((PetscObject)nep,n,eigr,eigi));
205: PetscFunctionReturn(PETSC_SUCCESS);
206: }
208: static PetscErrorCode Apply_FullBasis(ST st,Vec x,Vec y)
209: {
210: NEP nep;
211: NEP_NLEIGS *ctx;
213: PetscFunctionBegin;
214: PetscCall(STShellGetContext(st,&nep));
215: ctx = (NEP_NLEIGS*)nep->data;
216: PetscCall(MatMult(ctx->A,x,y));
217: PetscFunctionReturn(PETSC_SUCCESS);
218: }
220: static PetscErrorCode ApplyTranspose_FullBasis(ST st,Vec x,Vec y)
221: {
222: NEP nep;
223: NEP_NLEIGS *ctx;
225: PetscFunctionBegin;
226: PetscCall(STShellGetContext(st,&nep));
227: ctx = (NEP_NLEIGS*)nep->data;
228: PetscCall(MatMultTranspose(ctx->A,x,y));
229: PetscFunctionReturn(PETSC_SUCCESS);
230: }
232: PetscErrorCode NEPSetUp_NLEIGS_FullBasis(NEP nep)
233: {
234: NEP_NLEIGS *ctx=(NEP_NLEIGS*)nep->data;
235: ST st;
236: Mat Q;
237: PetscInt i=0,deg=ctx->nmat-1;
238: PetscBool trackall,istrivial,ks;
239: PetscScalar *epsarray,*neparray;
240: Vec veps,w=NULL;
241: EPSWhich which;
243: PetscFunctionBegin;
244: PetscCheck(ctx->nshifts==0,PetscObjectComm((PetscObject)nep),PETSC_ERR_SUP,"The full-basis option is not supported with rational Krylov");
245: if (!ctx->eps) PetscCall(NEPNLEIGSGetEPS(nep,&ctx->eps));
246: PetscCall(EPSGetST(ctx->eps,&st));
247: PetscCall(EPSSetTarget(ctx->eps,nep->target));
248: PetscCall(STSetDefaultShift(st,nep->target));
249: if (!((PetscObject)ctx->eps)->type_name) PetscCall(EPSSetType(ctx->eps,EPSKRYLOVSCHUR));
250: else {
251: PetscCall(PetscObjectTypeCompare((PetscObject)ctx->eps,EPSKRYLOVSCHUR,&ks));
252: PetscCheck(ks,PetscObjectComm((PetscObject)nep),PETSC_ERR_SUP,"Full-basis option only implemented for Krylov-Schur");
253: }
254: PetscCall(STSetType(st,STSHELL));
255: PetscCall(STShellSetContext(st,nep));
256: PetscCall(STShellSetBackTransform(st,BackTransform_FullBasis));
257: PetscCall(KSPGetOperators(ctx->ksp[0],&Q,NULL));
258: PetscCall(MatCreateVecsEmpty(Q,&ctx->w[0],&ctx->w[1]));
259: PetscCall(MatCreateVecsEmpty(Q,&ctx->w[2],&ctx->w[3]));
260: PetscCall(MatCreateShell(PetscObjectComm((PetscObject)nep),deg*nep->nloc,deg*nep->nloc,deg*nep->n,deg*nep->n,nep,&ctx->A));
261: PetscCall(MatShellSetOperation(ctx->A,MATOP_MULT,(void(*)(void))MatMult_FullBasis_Sinvert));
262: PetscCall(MatShellSetOperation(ctx->A,MATOP_MULT_TRANSPOSE,(void(*)(void))MatMultTranspose_FullBasis_Sinvert));
263: PetscCall(STShellSetApply(st,Apply_FullBasis));
264: PetscCall(STShellSetApplyTranspose(st,ApplyTranspose_FullBasis));
265: PetscCall(EPSSetOperators(ctx->eps,ctx->A,NULL));
266: PetscCall(EPSSetProblemType(ctx->eps,EPS_NHEP));
267: switch (nep->which) {
268: case NEP_TARGET_MAGNITUDE: which = EPS_TARGET_MAGNITUDE; break;
269: case NEP_TARGET_REAL: which = EPS_TARGET_REAL; break;
270: case NEP_TARGET_IMAGINARY: which = EPS_TARGET_IMAGINARY; break;
271: case NEP_WHICH_USER: which = EPS_WHICH_USER;
272: PetscCall(EPSSetEigenvalueComparison(ctx->eps,nep->sc->comparison,nep->sc->comparisonctx));
273: break;
274: default: SETERRQ(PetscObjectComm((PetscObject)nep),PETSC_ERR_SUP,"Should set a target selection in NEPSetWhichEigenpairs()");
275: }
276: PetscCall(EPSSetWhichEigenpairs(ctx->eps,which));
277: PetscCall(RGIsTrivial(nep->rg,&istrivial));
278: if (!istrivial) PetscCall(EPSSetRG(ctx->eps,nep->rg));
279: PetscCall(EPSSetDimensions(ctx->eps,nep->nev,nep->ncv,nep->mpd));
280: PetscCall(EPSSetTolerances(ctx->eps,SlepcDefaultTol(nep->tol),nep->max_it));
281: PetscCall(EPSSetTwoSided(ctx->eps,nep->twosided));
282: /* Transfer the trackall option from pep to eps */
283: PetscCall(NEPGetTrackAll(nep,&trackall));
284: PetscCall(EPSSetTrackAll(ctx->eps,trackall));
286: /* process initial vector */
287: if (nep->nini<0) {
288: PetscCall(VecCreateMPI(PetscObjectComm((PetscObject)ctx->eps),deg*nep->nloc,deg*nep->n,&veps));
289: PetscCall(VecGetArray(veps,&epsarray));
290: for (i=0;i<deg;i++) {
291: if (i<-nep->nini) {
292: PetscCall(VecGetArray(nep->IS[i],&neparray));
293: PetscCall(PetscArraycpy(epsarray+i*nep->nloc,neparray,nep->nloc));
294: PetscCall(VecRestoreArray(nep->IS[i],&neparray));
295: } else {
296: if (!w) PetscCall(VecDuplicate(nep->IS[0],&w));
297: PetscCall(VecSetRandom(w,NULL));
298: PetscCall(VecGetArray(w,&neparray));
299: PetscCall(PetscArraycpy(epsarray+i*nep->nloc,neparray,nep->nloc));
300: PetscCall(VecRestoreArray(w,&neparray));
301: }
302: }
303: PetscCall(VecRestoreArray(veps,&epsarray));
304: PetscCall(EPSSetInitialSpace(ctx->eps,1,&veps));
305: PetscCall(VecDestroy(&veps));
306: PetscCall(VecDestroy(&w));
307: PetscCall(SlepcBasisDestroy_Private(&nep->nini,&nep->IS));
308: }
310: PetscCall(EPSSetUp(ctx->eps));
311: PetscCall(EPSGetDimensions(ctx->eps,NULL,&nep->ncv,&nep->mpd));
312: PetscCall(EPSGetTolerances(ctx->eps,NULL,&nep->max_it));
313: PetscCall(NEPAllocateSolution(nep,0));
314: PetscFunctionReturn(PETSC_SUCCESS);
315: }
317: /*
318: NEPNLEIGSExtract_None - Extracts the first block of the basis
319: and normalizes the columns.
320: */
321: static PetscErrorCode NEPNLEIGSExtract_None(NEP nep,EPS eps)
322: {
323: PetscInt i,k,m,d;
324: const PetscScalar *px;
325: PetscScalar sigma=nep->target,*b;
326: Mat A;
327: Vec xxr,xxi=NULL,w,t,xx;
328: PetscReal norm;
329: NEP_NLEIGS *ctx=(NEP_NLEIGS*)nep->data;
331: PetscFunctionBegin;
332: d = ctx->nmat-1;
333: PetscCall(EPSGetOperators(eps,&A,NULL));
334: PetscCall(MatCreateVecs(A,&xxr,NULL));
335: #if !defined(PETSC_USE_COMPLEX)
336: PetscCall(VecDuplicate(xxr,&xxi));
337: #endif
338: w = nep->work[0];
339: for (i=0;i<nep->nconv;i++) {
340: PetscCall(EPSGetEigenvector(eps,i,xxr,xxi));
341: PetscCall(VecGetArrayRead(xxr,&px));
342: PetscCall(VecPlaceArray(w,px));
343: PetscCall(BVInsertVec(nep->V,i,w));
344: PetscCall(BVNormColumn(nep->V,i,NORM_2,&norm));
345: PetscCall(BVScaleColumn(nep->V,i,1.0/norm));
346: PetscCall(VecResetArray(w));
347: PetscCall(VecRestoreArrayRead(xxr,&px));
348: }
349: if (nep->twosided) {
350: PetscCall(PetscMalloc1(ctx->nmat,&b));
351: PetscCall(NEPNLEIGSEvalNRTFunct(nep,d,sigma,b));
352: m = nep->nloc;
353: xx = ctx->w[0];
354: w = nep->work[0]; t = nep->work[1];
355: for (k=0;k<nep->nconv;k++) {
356: PetscCall(EPSGetLeftEigenvector(eps,k,xxr,xxi));
357: PetscCall(VecGetArrayRead(xxr,&px));
358: PetscCall(VecPlaceArray(xx,px+(d-1)*m));
359: PetscCall(VecCopy(xx,w));
360: PetscCall(VecScale(w,PetscConj(b[d-1])));
361: PetscCall(VecResetArray(xx));
362: for (i=0;i<d-1;i++) {
363: PetscCall(VecPlaceArray(xx,px+i*m));
364: PetscCall(VecAXPY(w,PetscConj(b[i]),xx));
365: PetscCall(VecResetArray(xx));
366: }
367: PetscCall(VecConjugate(w));
368: PetscCall(KSPSolveTranspose(ctx->ksp[0],w,t));
369: PetscCall(VecConjugate(t));
370: PetscCall(BVInsertVec(nep->W,k,t));
371: PetscCall(BVNormColumn(nep->W,k,NORM_2,&norm));
372: PetscCall(BVScaleColumn(nep->W,k,1.0/norm));
373: PetscCall(VecRestoreArrayRead(xxr,&px));
374: }
375: PetscCall(PetscFree(b));
376: }
377: PetscCall(VecDestroy(&xxr));
378: #if !defined(PETSC_USE_COMPLEX)
379: PetscCall(VecDestroy(&xxi));
380: #endif
381: PetscFunctionReturn(PETSC_SUCCESS);
382: }
384: PetscErrorCode NEPSolve_NLEIGS_FullBasis(NEP nep)
385: {
386: NEP_NLEIGS *ctx = (NEP_NLEIGS*)nep->data;
387: PetscInt i;
388: PetscScalar eigi=0.0;
390: PetscFunctionBegin;
391: PetscCall(EPSSolve(ctx->eps));
392: PetscCall(EPSGetConverged(ctx->eps,&nep->nconv));
393: PetscCall(EPSGetIterationNumber(ctx->eps,&nep->its));
394: PetscCall(EPSGetConvergedReason(ctx->eps,(EPSConvergedReason*)&nep->reason));
396: /* recover eigenvalues */
397: for (i=0;i<nep->nconv;i++) {
398: PetscCall(EPSGetEigenpair(ctx->eps,i,&nep->eigr[i],&eigi,NULL,NULL));
399: #if !defined(PETSC_USE_COMPLEX)
400: PetscCheck(eigi==0.0,PetscObjectComm((PetscObject)nep),PETSC_ERR_SUP,"Complex value requires complex arithmetic");
401: #endif
402: }
403: PetscCall(NEPNLEIGSExtract_None(nep,ctx->eps));
404: PetscFunctionReturn(PETSC_SUCCESS);
405: }
407: PetscErrorCode NEPNLEIGSSetEPS_NLEIGS(NEP nep,EPS eps)
408: {
409: NEP_NLEIGS *ctx=(NEP_NLEIGS*)nep->data;
411: PetscFunctionBegin;
412: PetscCall(PetscObjectReference((PetscObject)eps));
413: PetscCall(EPSDestroy(&ctx->eps));
414: ctx->eps = eps;
415: nep->state = NEP_STATE_INITIAL;
416: PetscFunctionReturn(PETSC_SUCCESS);
417: }
419: /*@
420: NEPNLEIGSSetEPS - Associate an eigensolver object (EPS) to the NLEIGS solver.
422: Collective
424: Input Parameters:
425: + nep - nonlinear eigenvalue solver
426: - eps - the eigensolver object
428: Level: advanced
430: .seealso: NEPNLEIGSGetEPS()
431: @*/
432: PetscErrorCode NEPNLEIGSSetEPS(NEP nep,EPS eps)
433: {
434: PetscFunctionBegin;
437: PetscCheckSameComm(nep,1,eps,2);
438: PetscTryMethod(nep,"NEPNLEIGSSetEPS_C",(NEP,EPS),(nep,eps));
439: PetscFunctionReturn(PETSC_SUCCESS);
440: }
442: static PetscErrorCode EPSMonitor_NLEIGS(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *ctx)
443: {
444: NEP nep = (NEP)ctx;
445: PetscInt i,nv = PetscMin(nest,nep->ncv);
447: PetscFunctionBegin;
448: for (i=0;i<nv;i++) {
449: nep->eigr[i] = eigr[i];
450: nep->eigi[i] = eigi[i];
451: nep->errest[i] = errest[i];
452: }
453: PetscCall(NEPNLEIGSBackTransform((PetscObject)nep,nv,nep->eigr,nep->eigi));
454: PetscCall(NEPMonitor(nep,its,nconv,nep->eigr,nep->eigi,nep->errest,nest));
455: PetscFunctionReturn(PETSC_SUCCESS);
456: }
458: PetscErrorCode NEPNLEIGSGetEPS_NLEIGS(NEP nep,EPS *eps)
459: {
460: NEP_NLEIGS *ctx=(NEP_NLEIGS*)nep->data;
462: PetscFunctionBegin;
463: if (!ctx->eps) {
464: PetscCall(EPSCreate(PetscObjectComm((PetscObject)nep),&ctx->eps));
465: PetscCall(PetscObjectIncrementTabLevel((PetscObject)ctx->eps,(PetscObject)nep,1));
466: PetscCall(EPSSetOptionsPrefix(ctx->eps,((PetscObject)nep)->prefix));
467: PetscCall(EPSAppendOptionsPrefix(ctx->eps,"nep_nleigs_"));
468: PetscCall(PetscObjectSetOptions((PetscObject)ctx->eps,((PetscObject)nep)->options));
469: PetscCall(EPSMonitorSet(ctx->eps,EPSMonitor_NLEIGS,nep,NULL));
470: }
471: *eps = ctx->eps;
472: PetscFunctionReturn(PETSC_SUCCESS);
473: }
475: /*@
476: NEPNLEIGSGetEPS - Retrieve the eigensolver object (EPS) associated
477: to the nonlinear eigenvalue solver.
479: Collective
481: Input Parameter:
482: . nep - nonlinear eigenvalue solver
484: Output Parameter:
485: . eps - the eigensolver object
487: Level: advanced
489: .seealso: NEPNLEIGSSetEPS()
490: @*/
491: PetscErrorCode NEPNLEIGSGetEPS(NEP nep,EPS *eps)
492: {
493: PetscFunctionBegin;
495: PetscAssertPointer(eps,2);
496: PetscUseMethod(nep,"NEPNLEIGSGetEPS_C",(NEP,EPS*),(nep,eps));
497: PetscFunctionReturn(PETSC_SUCCESS);
498: }