Line data Source code
1 : /*
2 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3 : SLEPc - Scalable Library for Eigenvalue Problem Computations
4 : Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain
5 :
6 : This file is part of SLEPc.
7 : SLEPc is distributed under a 2-clause BSD license (see LICENSE).
8 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9 : */
10 : /*
11 : This file implements a wrapper to eigensolvers in EVSL.
12 : */
13 :
14 : #include <slepc/private/epsimpl.h> /*I "slepceps.h" I*/
15 : #include <evsl.h>
16 :
17 : #define PetscCallEVSL(func, ...) do { \
18 : PetscStackPushExternal(PetscStringize(func)); \
19 : int evsl_ierr_ = func(__VA_ARGS__); \
20 : PetscStackPop; \
21 : PetscCheck(!evsl_ierr_,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error calling %s: error code %d",PetscStringize(func(__VA_ARGS__)),evsl_ierr_); \
22 : } while (0)
23 :
24 : typedef struct {
25 : PetscBool initialized;
26 : Mat A; /* problem matrix */
27 : Vec x,y; /* auxiliary vectors */
28 : PetscReal *sli; /* slice bounds */
29 : PetscInt nev; /* approximate number of wanted eigenvalues in each slice */
30 : PetscLayout map; /* used to distribute slices among MPI processes */
31 : PetscBool estimrange; /* the filter range was not set by the user */
32 : /* user parameters */
33 : PetscInt nslices; /* number of slices */
34 : PetscReal lmin,lmax; /* numerical range (min and max eigenvalue) */
35 : EPSEVSLDOSMethod dos; /* DOS method, either KPM or Lanczos */
36 : PetscInt nvec; /* number of sample vectors used for DOS */
37 : PetscInt deg; /* polynomial degree used for DOS (KPM only) */
38 : PetscInt steps; /* number of Lanczos steps used for DOS (Lanczos only) */
39 : PetscInt npoints; /* number of sample points used for DOS (Lanczos only) */
40 : PetscInt max_deg; /* maximum degree allowed for the polynomial */
41 : PetscReal thresh; /* threshold for accepting polynomial */
42 : EPSEVSLDamping damping; /* type of damping (for polynomial and for DOS-KPM) */
43 : } EPS_EVSL;
44 :
45 497050 : static void AMatvec_EVSL(double *xa,double *ya,void *data)
46 : {
47 497050 : EPS_EVSL *ctx = (EPS_EVSL*)data;
48 497050 : Vec x = ctx->x,y = ctx->y;
49 497050 : Mat A = ctx->A;
50 :
51 497050 : PetscFunctionBegin;
52 497050 : PetscCallAbort(PetscObjectComm((PetscObject)A),VecPlaceArray(x,(PetscScalar*)xa));
53 497050 : PetscCallAbort(PetscObjectComm((PetscObject)A),VecPlaceArray(y,(PetscScalar*)ya));
54 497050 : PetscCallAbort(PetscObjectComm((PetscObject)A),MatMult(A,x,y));
55 497050 : PetscCallAbort(PetscObjectComm((PetscObject)A),VecResetArray(x));
56 497050 : PetscCallAbort(PetscObjectComm((PetscObject)A),VecResetArray(y));
57 497050 : PetscFunctionReturnVoid();
58 : }
59 :
60 15 : static PetscErrorCode EPSSetUp_EVSL(EPS eps)
61 : {
62 15 : EPS_EVSL *ctx = (EPS_EVSL*)eps->data;
63 15 : PetscMPIInt size,rank;
64 15 : PetscBool isshift;
65 15 : PetscScalar *vinit;
66 15 : PetscReal *mu,ecount,xintv[4],*xdos,*ydos;
67 15 : Vec v0;
68 15 : Mat A;
69 15 : PetscRandom rnd;
70 :
71 15 : PetscFunctionBegin;
72 15 : EPSCheckStandard(eps);
73 15 : EPSCheckHermitian(eps);
74 15 : EPSCheckNotStructured(eps);
75 15 : if (eps->nev==0) eps->nev = 1;
76 15 : PetscCall(PetscObjectTypeCompare((PetscObject)eps->st,STSHIFT,&isshift));
77 15 : PetscCheck(isshift,PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"This solver does not support spectral transformations");
78 :
79 15 : if (ctx->initialized) EVSLFinish();
80 15 : EVSLStart();
81 15 : ctx->initialized=PETSC_TRUE;
82 :
83 : /* get number of slices per process */
84 15 : PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)eps),&size));
85 15 : PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)eps),&rank));
86 15 : if (!ctx->nslices) ctx->nslices = size;
87 15 : PetscCall(PetscLayoutDestroy(&ctx->map));
88 15 : PetscCall(PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)eps),PETSC_DECIDE,ctx->nslices,1,&ctx->map));
89 :
90 : /* get matrix and prepare auxiliary vectors */
91 15 : PetscCall(MatDestroy(&ctx->A));
92 15 : PetscCall(STGetMatrix(eps->st,0,&A));
93 15 : if (size==1) {
94 7 : PetscCall(PetscObjectReference((PetscObject)A));
95 7 : ctx->A = A;
96 8 : } else PetscCall(MatCreateRedundantMatrix(A,0,PETSC_COMM_SELF,MAT_INITIAL_MATRIX,&ctx->A));
97 15 : SetAMatvec(eps->n,&AMatvec_EVSL,(void*)ctx);
98 15 : if (!ctx->x) PetscCall(MatCreateVecsEmpty(ctx->A,&ctx->x,&ctx->y));
99 15 : EPSCheckUnsupported(eps,EPS_FEATURE_ARBITRARY | EPS_FEATURE_REGION | EPS_FEATURE_STOPPING);
100 15 : EPSCheckIgnored(eps,EPS_FEATURE_EXTRACTION | EPS_FEATURE_CONVERGENCE);
101 :
102 15 : if (!eps->which) eps->which=EPS_ALL;
103 15 : PetscCheck(eps->which==EPS_ALL && eps->inta!=eps->intb,PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"This solver requires setting an interval with EPSSetInterval()");
104 :
105 : /* estimate numerical range */
106 15 : if (ctx->estimrange || ctx->lmin == PETSC_MIN_REAL || ctx->lmax == PETSC_MAX_REAL) {
107 14 : PetscCall(MatCreateVecs(ctx->A,&v0,NULL));
108 14 : if (!eps->V) PetscCall(EPSGetBV(eps,&eps->V));
109 14 : PetscCall(BVGetRandomContext(eps->V,&rnd));
110 14 : PetscCall(VecSetRandom(v0,rnd));
111 14 : PetscCall(VecGetArray(v0,&vinit));
112 14 : PetscCallEVSL(LanTrbounds,50,200,eps->tol,vinit,1,&ctx->lmin,&ctx->lmax,NULL);
113 14 : PetscCall(VecRestoreArray(v0,&vinit));
114 14 : PetscCall(VecDestroy(&v0));
115 14 : ctx->estimrange = PETSC_TRUE; /* estimate if called again with another matrix */
116 : }
117 15 : PetscCheck(ctx->lmin<=eps->inta && ctx->lmax>=eps->intb,PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"The requested interval [%g,%g] must be contained in the numerical range [%g,%g]",(double)eps->inta,(double)eps->intb,(double)ctx->lmin,(double)ctx->lmax);
118 15 : xintv[0] = eps->inta;
119 15 : xintv[1] = eps->intb;
120 15 : xintv[2] = ctx->lmin;
121 15 : xintv[3] = ctx->lmax;
122 :
123 : /* estimate number of eigenvalues in the interval */
124 15 : switch (ctx->dos) {
125 9 : case EPS_EVSL_DOS_KPM:
126 9 : PetscCall(PetscMalloc1(ctx->deg+1,&mu));
127 9 : if (!rank) PetscCallEVSL(kpmdos,ctx->deg,(int)ctx->damping,ctx->nvec,xintv,mu,&ecount);
128 18 : PetscCallMPI(MPI_Bcast(mu,ctx->deg+1,MPIU_REAL,0,PetscObjectComm((PetscObject)eps)));
129 : break;
130 6 : case EPS_EVSL_DOS_LANCZOS:
131 6 : PetscCall(PetscMalloc2(ctx->npoints,&xdos,ctx->npoints,&ydos));
132 6 : if (!rank) PetscCallEVSL(LanDos,ctx->nvec,PetscMin(ctx->steps,eps->n/2),ctx->npoints,xdos,ydos,&ecount,xintv);
133 12 : PetscCallMPI(MPI_Bcast(xdos,ctx->npoints,MPIU_REAL,0,PetscObjectComm((PetscObject)eps)));
134 12 : PetscCallMPI(MPI_Bcast(ydos,ctx->npoints,MPIU_REAL,0,PetscObjectComm((PetscObject)eps)));
135 : break;
136 0 : default:
137 0 : SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid DOS method");
138 : }
139 30 : PetscCallMPI(MPI_Bcast(&ecount,1,MPIU_REAL,0,PetscObjectComm((PetscObject)eps)));
140 :
141 15 : PetscCall(PetscInfo(eps,"Estimated eigenvalue count in the interval: %g\n",ecount));
142 15 : eps->ncv = (PetscInt)PetscCeilReal(1.5*ecount);
143 :
144 : /* slice the spectrum */
145 15 : PetscCall(PetscFree(ctx->sli));
146 15 : PetscCall(PetscMalloc1(ctx->nslices+1,&ctx->sli));
147 15 : if (ctx->dos == EPS_EVSL_DOS_KPM) {
148 9 : PetscCallEVSL(spslicer,ctx->sli,mu,ctx->deg,xintv,ctx->nslices,10*(PetscInt)ecount);
149 9 : PetscCall(PetscFree(mu));
150 6 : } else if (ctx->dos == EPS_EVSL_DOS_LANCZOS) {
151 6 : spslicer2(xdos,ydos,ctx->nslices,ctx->npoints,ctx->sli);
152 6 : PetscCall(PetscFree2(xdos,ydos));
153 : }
154 :
155 : /* approximate number of eigenvalues wanted in each slice */
156 15 : ctx->nev = (PetscInt)(1.0 + ecount/(PetscReal)ctx->nslices) + 2;
157 :
158 15 : if (eps->mpd!=PETSC_DETERMINE) PetscCall(PetscInfo(eps,"Warning: parameter mpd ignored\n"));
159 15 : if (eps->max_it==PETSC_DETERMINE) eps->max_it = 1;
160 15 : PetscCall(EPSAllocateSolution(eps,0));
161 15 : PetscFunctionReturn(PETSC_SUCCESS);
162 : }
163 :
164 15 : static PetscErrorCode EPSSolve_EVSL(EPS eps)
165 : {
166 15 : EPS_EVSL *ctx = (EPS_EVSL*)eps->data;
167 15 : PetscInt i,j,k=0,sl,mlan,nevout,*ind,nevmax,rstart,rend,*nevloc,*disp,N;
168 15 : PetscReal *res,xintv[4],*errest;
169 15 : PetscScalar *lam,*X,*Y,*vinit,*eigr;
170 15 : PetscMPIInt size,rank;
171 15 : PetscRandom rnd;
172 15 : Vec v,w,v0,x;
173 15 : VecScatter vs;
174 15 : IS is;
175 15 : polparams pol;
176 :
177 15 : PetscFunctionBegin;
178 15 : PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)eps),&size));
179 15 : PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)eps),&rank));
180 15 : PetscCall(PetscLayoutGetRange(ctx->map,&rstart,&rend));
181 15 : nevmax = (rend-rstart)*ctx->nev;
182 15 : PetscCall(MatCreateVecs(ctx->A,&v0,NULL));
183 15 : PetscCall(BVGetRandomContext(eps->V,&rnd));
184 15 : PetscCall(VecSetRandom(v0,rnd));
185 15 : PetscCall(VecGetArray(v0,&vinit));
186 15 : PetscCall(PetscMalloc5(size,&nevloc,size+1,&disp,nevmax,&eigr,nevmax,&errest,nevmax*eps->n,&X));
187 15 : mlan = PetscMin(PetscMax(5*ctx->nev,300),eps->n);
188 37 : for (sl=rstart; sl<rend; sl++) {
189 22 : xintv[0] = ctx->sli[sl];
190 22 : xintv[1] = ctx->sli[sl+1];
191 22 : xintv[2] = ctx->lmin;
192 22 : xintv[3] = ctx->lmax;
193 22 : PetscCall(PetscInfo(ctx->A,"Subinterval %" PetscInt_FMT ": [%.4e, %.4e]\n",sl+1,xintv[0],xintv[1]));
194 22 : set_pol_def(&pol);
195 22 : pol.max_deg = ctx->max_deg;
196 22 : pol.damping = (int)ctx->damping;
197 22 : pol.thresh_int = ctx->thresh;
198 22 : find_pol(xintv,&pol);
199 22 : PetscCall(PetscInfo(ctx->A,"Polynomial [type = %" PetscInt_FMT "], deg %" PetscInt_FMT ", bar %e gam %e\n",pol.type,pol.deg,pol.bar,pol.gam));
200 22 : PetscCallEVSL(ChebLanNr,xintv,mlan,eps->tol,vinit,&pol,&nevout,&lam,&Y,&res,NULL);
201 22 : PetscCheck(k+nevout<=nevmax,PetscObjectComm((PetscObject)eps),PETSC_ERR_LIB,"Too low estimation of eigenvalue count, try modifying the sampling parameters");
202 22 : free_pol(&pol);
203 22 : PetscCall(PetscInfo(ctx->A,"Computed %" PetscInt_FMT " eigenvalues\n",nevout));
204 22 : PetscCall(PetscMalloc1(nevout,&ind));
205 22 : sort_double(nevout,lam,ind);
206 170 : for (i=0;i<nevout;i++) {
207 126 : eigr[i+k] = lam[i];
208 126 : errest[i+k] = res[ind[i]];
209 126 : PetscCall(PetscArraycpy(X+(i+k)*eps->n,Y+ind[i]*eps->n,eps->n));
210 : }
211 22 : k += nevout;
212 22 : if (lam) evsl_Free(lam);
213 22 : if (Y) evsl_Free_device(Y);
214 22 : if (res) evsl_Free(res);
215 22 : PetscCall(PetscFree(ind));
216 : }
217 15 : PetscCall(VecRestoreArray(v0,&vinit));
218 15 : PetscCall(VecDestroy(&v0));
219 :
220 : /* gather eigenvalues computed by each MPI process */
221 30 : PetscCallMPI(MPI_Allgather(&k,1,MPIU_INT,nevloc,1,MPIU_INT,PetscObjectComm((PetscObject)eps)));
222 15 : eps->nev = nevloc[0];
223 15 : disp[0] = 0;
224 23 : for (i=1;i<size;i++) {
225 8 : eps->nev += nevloc[i];
226 8 : disp[i] = disp[i-1]+nevloc[i-1];
227 : }
228 15 : disp[size] = disp[size-1]+nevloc[size-1];
229 15 : PetscCheck(eps->nev<=eps->ncv,PetscObjectComm((PetscObject)eps),PETSC_ERR_LIB,"Too low estimation of eigenvalue count, try modifying the sampling parameters");
230 30 : PetscCallMPI(MPI_Allgatherv(eigr,k,MPIU_SCALAR,eps->eigr,nevloc,disp,MPIU_SCALAR,PetscObjectComm((PetscObject)eps)));
231 30 : PetscCallMPI(MPI_Allgatherv(errest,k,MPIU_REAL,eps->errest,nevloc,disp,MPIU_REAL,PetscObjectComm((PetscObject)eps)));
232 15 : eps->nconv = eps->nev;
233 15 : eps->its = 1;
234 15 : eps->reason = EPS_CONVERGED_TOL;
235 :
236 : /* scatter computed eigenvectors and store them in eps->V */
237 15 : PetscCall(BVCreateVec(eps->V,&w));
238 38 : for (i=0;i<size;i++) {
239 23 : N = (rank==i)? eps->n: 0;
240 23 : PetscCall(VecCreateSeq(PETSC_COMM_SELF,N,&x));
241 23 : PetscCall(VecSetFromOptions(x));
242 23 : PetscCall(ISCreateStride(PETSC_COMM_SELF,N,0,1,&is));
243 23 : PetscCall(VecScatterCreate(x,is,w,is,&vs));
244 23 : PetscCall(ISDestroy(&is));
245 176 : for (j=disp[i];j<disp[i+1];j++) {
246 153 : PetscCall(BVGetColumn(eps->V,j,&v));
247 153 : if (rank==i) PetscCall(VecPlaceArray(x,X+(j-disp[i])*eps->n));
248 153 : PetscCall(VecScatterBegin(vs,x,v,INSERT_VALUES,SCATTER_FORWARD));
249 153 : PetscCall(VecScatterEnd(vs,x,v,INSERT_VALUES,SCATTER_FORWARD));
250 153 : if (rank==i) PetscCall(VecResetArray(x));
251 153 : PetscCall(BVRestoreColumn(eps->V,j,&v));
252 : }
253 23 : PetscCall(VecScatterDestroy(&vs));
254 23 : PetscCall(VecDestroy(&x));
255 : }
256 15 : PetscCall(VecDestroy(&w));
257 15 : PetscCall(PetscFree5(nevloc,disp,eigr,errest,X));
258 15 : PetscFunctionReturn(PETSC_SUCCESS);
259 : }
260 :
261 2 : static PetscErrorCode EPSEVSLSetSlices_EVSL(EPS eps,PetscInt nslices)
262 : {
263 2 : EPS_EVSL *ctx = (EPS_EVSL*)eps->data;
264 :
265 2 : PetscFunctionBegin;
266 2 : if (nslices == PETSC_DECIDE || nslices == PETSC_DEFAULT) nslices = 0;
267 2 : else PetscCheck(nslices>0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Number of slices must be 1 at least");
268 2 : if (ctx->nslices != nslices) {
269 2 : ctx->nslices = nslices;
270 2 : eps->state = EPS_STATE_INITIAL;
271 : }
272 2 : PetscFunctionReturn(PETSC_SUCCESS);
273 : }
274 :
275 : /*@
276 : EPSEVSLSetSlices - Set the number of slices in which the interval must be
277 : subdivided.
278 :
279 : Logically Collective
280 :
281 : Input Parameters:
282 : + eps - the eigensolver context
283 : - nslices - the number of slices
284 :
285 : Options Database Key:
286 : . -eps_evsl_slices <n> - set the number of slices to n
287 :
288 : Notes:
289 : By default, one slice per MPI process is used. Depending on the number of
290 : eigenvalues, using more slices may be beneficial, but very narrow subintervals
291 : imply higher polynomial degree.
292 :
293 : Level: intermediate
294 :
295 : .seealso: EPSEVSLGetSlices()
296 : @*/
297 2 : PetscErrorCode EPSEVSLSetSlices(EPS eps,PetscInt nslices)
298 : {
299 2 : PetscFunctionBegin;
300 2 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
301 6 : PetscValidLogicalCollectiveInt(eps,nslices,2);
302 2 : PetscTryMethod(eps,"EPSEVSLSetSlices_C",(EPS,PetscInt),(eps,nslices));
303 2 : PetscFunctionReturn(PETSC_SUCCESS);
304 : }
305 :
306 1 : static PetscErrorCode EPSEVSLGetSlices_EVSL(EPS eps,PetscInt *nslices)
307 : {
308 1 : EPS_EVSL *ctx = (EPS_EVSL*)eps->data;
309 :
310 1 : PetscFunctionBegin;
311 1 : *nslices = ctx->nslices;
312 1 : PetscFunctionReturn(PETSC_SUCCESS);
313 : }
314 :
315 : /*@
316 : EPSEVSLGetSlices - Gets the number of slices in which the interval must be
317 : subdivided.
318 :
319 : Not Collective
320 :
321 : Input Parameter:
322 : . eps - the eigensolver context
323 :
324 : Output Parameter:
325 : . nslices - the number of slices
326 :
327 : Level: intermediate
328 :
329 : .seealso: EPSEVSLSetSlices()
330 : @*/
331 1 : PetscErrorCode EPSEVSLGetSlices(EPS eps,PetscInt *nslices)
332 : {
333 1 : PetscFunctionBegin;
334 1 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
335 1 : PetscAssertPointer(nslices,2);
336 1 : PetscUseMethod(eps,"EPSEVSLGetSlices_C",(EPS,PetscInt*),(eps,nslices));
337 1 : PetscFunctionReturn(PETSC_SUCCESS);
338 : }
339 :
340 1 : static PetscErrorCode EPSEVSLSetRange_EVSL(EPS eps,PetscReal lmin,PetscReal lmax)
341 : {
342 1 : EPS_EVSL *ctx = (EPS_EVSL*)eps->data;
343 :
344 1 : PetscFunctionBegin;
345 1 : PetscCheck(lmin<lmax,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_WRONG,"Badly defined interval, must be lmin<lmax");
346 1 : if (ctx->lmin != lmin || ctx->lmax != lmax) {
347 1 : ctx->lmin = lmin;
348 1 : ctx->lmax = lmax;
349 1 : eps->state = EPS_STATE_INITIAL;
350 : }
351 1 : PetscFunctionReturn(PETSC_SUCCESS);
352 : }
353 :
354 : /*@
355 : EPSEVSLSetRange - Defines the numerical range (or field of values) of the problem,
356 : that is, the interval containing all eigenvalues.
357 :
358 : Logically Collective
359 :
360 : Input Parameters:
361 : + eps - the eigensolver context
362 : . lmin - left end of the interval
363 : - lmax - right end of the interval
364 :
365 : Options Database Key:
366 : . -eps_evsl_range <a,b> - set [a,b] as the numerical range
367 :
368 : Notes:
369 : The filter will be most effective if the numerical range is tight, that is, lmin
370 : and lmax are good approximations to the leftmost and rightmost eigenvalues,
371 : respectively. If not set by the user, an approximation is computed internally.
372 :
373 : The wanted computational interval specified via EPSSetInterval() must be
374 : contained in the numerical range.
375 :
376 : Level: intermediate
377 :
378 : .seealso: EPSEVSLGetRange(), EPSSetInterval()
379 : @*/
380 1 : PetscErrorCode EPSEVSLSetRange(EPS eps,PetscReal lmin,PetscReal lmax)
381 : {
382 1 : PetscFunctionBegin;
383 1 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
384 3 : PetscValidLogicalCollectiveReal(eps,lmin,2);
385 3 : PetscValidLogicalCollectiveReal(eps,lmax,3);
386 1 : PetscTryMethod(eps,"EPSEVSLSetRange_C",(EPS,PetscReal,PetscReal),(eps,lmin,lmax));
387 1 : PetscFunctionReturn(PETSC_SUCCESS);
388 : }
389 :
390 1 : static PetscErrorCode EPSEVSLGetRange_EVSL(EPS eps,PetscReal *lmin,PetscReal *lmax)
391 : {
392 1 : EPS_EVSL *ctx = (EPS_EVSL*)eps->data;
393 :
394 1 : PetscFunctionBegin;
395 1 : if (lmin) *lmin = ctx->lmin;
396 1 : if (lmax) *lmax = ctx->lmax;
397 1 : PetscFunctionReturn(PETSC_SUCCESS);
398 : }
399 :
400 : /*@
401 : EPSEVSLGetRange - Gets the interval containing all eigenvalues.
402 :
403 : Not Collective
404 :
405 : Input Parameter:
406 : . eps - the eigensolver context
407 :
408 : Output Parameters:
409 : + lmin - left end of the interval
410 : - lmax - right end of the interval
411 :
412 : Level: intermediate
413 :
414 : .seealso: EPSEVSLSetRange()
415 : @*/
416 1 : PetscErrorCode EPSEVSLGetRange(EPS eps,PetscReal *lmin,PetscReal *lmax)
417 : {
418 1 : PetscFunctionBegin;
419 1 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
420 1 : PetscUseMethod(eps,"EPSEVSLGetRange_C",(EPS,PetscReal*,PetscReal*),(eps,lmin,lmax));
421 1 : PetscFunctionReturn(PETSC_SUCCESS);
422 : }
423 :
424 4 : static PetscErrorCode EPSEVSLSetDOSParameters_EVSL(EPS eps,EPSEVSLDOSMethod dos,PetscInt nvec,PetscInt deg,PetscInt steps,PetscInt npoints)
425 : {
426 4 : EPS_EVSL *ctx = (EPS_EVSL*)eps->data;
427 :
428 4 : PetscFunctionBegin;
429 4 : ctx->dos = dos;
430 4 : if (nvec == PETSC_DETERMINE) ctx->nvec = 80;
431 4 : else if (nvec != PETSC_CURRENT) {
432 4 : PetscCheck(nvec>0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"The nvec argument must be > 0");
433 4 : ctx->nvec = nvec;
434 : }
435 4 : switch (dos) {
436 1 : case EPS_EVSL_DOS_KPM:
437 1 : if (deg == PETSC_DETERMINE) ctx->deg = 300;
438 1 : else if (deg != PETSC_CURRENT) {
439 1 : PetscCheck(deg>0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"The deg argument must be > 0");
440 1 : ctx->deg = deg;
441 : }
442 : break;
443 3 : case EPS_EVSL_DOS_LANCZOS:
444 3 : if (steps == PETSC_DETERMINE) ctx->steps = 40;
445 3 : else if (steps != PETSC_CURRENT) {
446 3 : PetscCheck(steps>0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"The steps argument must be > 0");
447 3 : ctx->steps = steps;
448 : }
449 3 : if (npoints == PETSC_DETERMINE) ctx->npoints = 200;
450 3 : else if (npoints != PETSC_CURRENT) {
451 3 : PetscCheck(npoints>0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"The npoints argument must be > 0");
452 3 : ctx->npoints = npoints;
453 : }
454 : break;
455 : }
456 4 : eps->state = EPS_STATE_INITIAL;
457 4 : PetscFunctionReturn(PETSC_SUCCESS);
458 : }
459 :
460 : /*@
461 : EPSEVSLSetDOSParameters - Defines the parameters used for computing the
462 : density of states (DOS) in the EVSL solver.
463 :
464 : Logically Collective
465 :
466 : Input Parameters:
467 : + eps - the eigensolver context
468 : . dos - DOS method, either KPM or Lanczos
469 : . nvec - number of sample vectors
470 : . deg - polynomial degree (KPM only)
471 : . steps - number of Lanczos steps (Lanczos only)
472 : - npoints - number of sample points (Lanczos only)
473 :
474 : Options Database Keys:
475 : + -eps_evsl_dos_method <dos> - set the DOS method, either kpm or lanczos
476 : . -eps_evsl_dos_nvec <n> - set the number of sample vectors
477 : . -eps_evsl_dos_degree <n> - set the polynomial degree
478 : . -eps_evsl_dos_steps <n> - set the number of Lanczos steps
479 : - -eps_evsl_dos_npoints <n> - set the number of sample points
480 :
481 : Notes:
482 : The density of states (or spectral density) can be approximated with two
483 : methods, kernel polynomial method (KPM) or Lanczos. Some parameters for
484 : these methods can be set by the user with this function, with some of
485 : them being relevant for one of the methods only.
486 :
487 : For the integer argumens, you can use PETSC_CURRENT to keep the current
488 : value, and PETSC_DETERMINE to set them to a reasonable default.
489 :
490 : Level: intermediate
491 :
492 : .seealso: EPSEVSLGetDOSParameters()
493 : @*/
494 4 : PetscErrorCode EPSEVSLSetDOSParameters(EPS eps,EPSEVSLDOSMethod dos,PetscInt nvec,PetscInt deg,PetscInt steps,PetscInt npoints)
495 : {
496 4 : PetscFunctionBegin;
497 4 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
498 12 : PetscValidLogicalCollectiveEnum(eps,dos,2);
499 12 : PetscValidLogicalCollectiveInt(eps,nvec,3);
500 12 : PetscValidLogicalCollectiveInt(eps,deg,4);
501 12 : PetscValidLogicalCollectiveInt(eps,steps,5);
502 12 : PetscValidLogicalCollectiveInt(eps,npoints,6);
503 4 : PetscTryMethod(eps,"EPSEVSLSetDOSParameters_C",(EPS,EPSEVSLDOSMethod,PetscInt,PetscInt,PetscInt,PetscInt),(eps,dos,nvec,deg,steps,npoints));
504 4 : PetscFunctionReturn(PETSC_SUCCESS);
505 : }
506 :
507 9 : static PetscErrorCode EPSEVSLGetDOSParameters_EVSL(EPS eps,EPSEVSLDOSMethod *dos,PetscInt *nvec,PetscInt *deg,PetscInt *steps,PetscInt *npoints)
508 : {
509 9 : EPS_EVSL *ctx = (EPS_EVSL*)eps->data;
510 :
511 9 : PetscFunctionBegin;
512 9 : if (dos) *dos = ctx->dos;
513 9 : if (nvec) *nvec = ctx->nvec;
514 9 : if (deg) *deg = ctx->deg;
515 9 : if (steps) *steps = ctx->steps;
516 9 : if (npoints) *npoints = ctx->npoints;
517 9 : PetscFunctionReturn(PETSC_SUCCESS);
518 : }
519 :
520 : /*@
521 : EPSEVSLGetDOSParameters - Gets the parameters used for computing the
522 : density of states (DOS) in the EVSL solver.
523 :
524 : Not Collective
525 :
526 : Input Parameter:
527 : . eps - the eigensolver context
528 :
529 : Output Parameters:
530 : + dos - DOS method, either KPM or Lanczos
531 : . nvec - number of sample vectors
532 : . deg - polynomial degree (KPM only)
533 : . steps - number of Lanczos steps (Lanczos only)
534 : - npoints - number of sample points (Lanczos only)
535 :
536 : Level: intermediate
537 :
538 : .seealso: EPSEVSLSetDOSParameters()
539 : @*/
540 9 : PetscErrorCode EPSEVSLGetDOSParameters(EPS eps,EPSEVSLDOSMethod *dos,PetscInt *nvec,PetscInt *deg,PetscInt *steps,PetscInt *npoints)
541 : {
542 9 : PetscFunctionBegin;
543 9 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
544 9 : PetscUseMethod(eps,"EPSEVSLGetDOSParameters_C",(EPS,EPSEVSLDOSMethod*,PetscInt*,PetscInt*,PetscInt*,PetscInt*),(eps,dos,nvec,deg,steps,npoints));
545 9 : PetscFunctionReturn(PETSC_SUCCESS);
546 : }
547 :
548 1 : static PetscErrorCode EPSEVSLSetPolParameters_EVSL(EPS eps,PetscInt max_deg,PetscReal thresh)
549 : {
550 1 : EPS_EVSL *ctx = (EPS_EVSL*)eps->data;
551 :
552 1 : PetscFunctionBegin;
553 1 : if (max_deg == PETSC_DETERMINE) ctx->max_deg = 10000;
554 1 : else if (max_deg != PETSC_CURRENT) {
555 1 : PetscCheck(max_deg>2,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"The max_deg argument must be > 2");
556 1 : ctx->max_deg = max_deg;
557 : }
558 1 : if (thresh == (PetscReal)PETSC_DETERMINE) ctx->thresh = 0.8;
559 1 : else if (thresh != (PetscReal)PETSC_CURRENT) {
560 1 : PetscCheck(thresh>0.0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"The thresh argument must be > 0.0");
561 1 : ctx->thresh = thresh;
562 : }
563 1 : eps->state = EPS_STATE_INITIAL;
564 1 : PetscFunctionReturn(PETSC_SUCCESS);
565 : }
566 :
567 : /*@
568 : EPSEVSLSetPolParameters - Defines the parameters used for building the
569 : building the polynomial in the EVSL solver.
570 :
571 : Logically Collective
572 :
573 : Input Parameters:
574 : + eps - the eigensolver context
575 : . max_deg - maximum degree allowed for the polynomial
576 : - thresh - threshold for accepting polynomial
577 :
578 : Options Database Keys:
579 : + -eps_evsl_pol_max_deg <d> - set maximum polynomial degree
580 : - -eps_evsl_pol_thresh <t> - set the threshold
581 :
582 : Note:
583 : PETSC_CURRENT can be used to preserve the current value of any of the
584 : arguments, and PETSC_DETERMINE to set them to a default value.
585 :
586 : Level: intermediate
587 :
588 : .seealso: EPSEVSLGetPolParameters()
589 : @*/
590 1 : PetscErrorCode EPSEVSLSetPolParameters(EPS eps,PetscInt max_deg,PetscReal thresh)
591 : {
592 1 : PetscFunctionBegin;
593 1 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
594 3 : PetscValidLogicalCollectiveInt(eps,max_deg,2);
595 3 : PetscValidLogicalCollectiveReal(eps,thresh,3);
596 1 : PetscTryMethod(eps,"EPSEVSLSetPolParameters_C",(EPS,PetscInt,PetscReal),(eps,max_deg,thresh));
597 1 : PetscFunctionReturn(PETSC_SUCCESS);
598 : }
599 :
600 9 : static PetscErrorCode EPSEVSLGetPolParameters_EVSL(EPS eps,PetscInt *max_deg,PetscReal *thresh)
601 : {
602 9 : EPS_EVSL *ctx = (EPS_EVSL*)eps->data;
603 :
604 9 : PetscFunctionBegin;
605 9 : if (max_deg) *max_deg = ctx->max_deg;
606 9 : if (thresh) *thresh = ctx->thresh;
607 9 : PetscFunctionReturn(PETSC_SUCCESS);
608 : }
609 :
610 : /*@
611 : EPSEVSLGetPolParameters - Gets the parameters used for building the
612 : polynomial in the EVSL solver.
613 :
614 : Not Collective
615 :
616 : Input Parameter:
617 : . eps - the eigensolver context
618 :
619 : Output Parameters:
620 : + max_deg - the maximum degree of the polynomial
621 : - thresh - the threshold
622 :
623 : Level: intermediate
624 :
625 : .seealso: EPSEVSLSetPolParameters()
626 : @*/
627 9 : PetscErrorCode EPSEVSLGetPolParameters(EPS eps,PetscInt *max_deg,PetscReal *thresh)
628 : {
629 9 : PetscFunctionBegin;
630 9 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
631 9 : PetscUseMethod(eps,"EPSEVSLGetPolParameters_C",(EPS,PetscInt*,PetscReal*),(eps,max_deg,thresh));
632 9 : PetscFunctionReturn(PETSC_SUCCESS);
633 : }
634 :
635 2 : static PetscErrorCode EPSEVSLSetDamping_EVSL(EPS eps,EPSEVSLDamping damping)
636 : {
637 2 : EPS_EVSL *ctx = (EPS_EVSL*)eps->data;
638 :
639 2 : PetscFunctionBegin;
640 2 : if (ctx->damping != damping) {
641 1 : ctx->damping = damping;
642 1 : eps->state = EPS_STATE_INITIAL;
643 : }
644 2 : PetscFunctionReturn(PETSC_SUCCESS);
645 : }
646 :
647 : /*@
648 : EPSEVSLSetDamping - Set the type of damping to be used in EVSL.
649 :
650 : Logically Collective
651 :
652 : Input Parameters:
653 : + eps - the eigensolver context
654 : - damping - the type of damping
655 :
656 : Options Database Key:
657 : . -eps_evsl_damping <n> - set the type of damping
658 :
659 : Notes:
660 : Damping is applied when building the polynomial to be used when solving the
661 : eigenproblem, and also during estimation of DOS with the KPM method.
662 :
663 : Level: intermediate
664 :
665 : .seealso: EPSEVSLGetDamping(), EPSEVSLSetDOSParameters()
666 : @*/
667 2 : PetscErrorCode EPSEVSLSetDamping(EPS eps,EPSEVSLDamping damping)
668 : {
669 2 : PetscFunctionBegin;
670 2 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
671 6 : PetscValidLogicalCollectiveEnum(eps,damping,2);
672 2 : PetscTryMethod(eps,"EPSEVSLSetDamping_C",(EPS,EPSEVSLDamping),(eps,damping));
673 2 : PetscFunctionReturn(PETSC_SUCCESS);
674 : }
675 :
676 1 : static PetscErrorCode EPSEVSLGetDamping_EVSL(EPS eps,EPSEVSLDamping *damping)
677 : {
678 1 : EPS_EVSL *ctx = (EPS_EVSL*)eps->data;
679 :
680 1 : PetscFunctionBegin;
681 1 : *damping = ctx->damping;
682 1 : PetscFunctionReturn(PETSC_SUCCESS);
683 : }
684 :
685 : /*@
686 : EPSEVSLGetDamping - Gets the type of damping.
687 :
688 : Not Collective
689 :
690 : Input Parameter:
691 : . eps - the eigensolver context
692 :
693 : Output Parameter:
694 : . damping - the type of damping
695 :
696 : Level: intermediate
697 :
698 : .seealso: EPSEVSLSetDamping()
699 : @*/
700 1 : PetscErrorCode EPSEVSLGetDamping(EPS eps,EPSEVSLDamping *damping)
701 : {
702 1 : PetscFunctionBegin;
703 1 : PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
704 1 : PetscAssertPointer(damping,2);
705 1 : PetscUseMethod(eps,"EPSEVSLGetDamping_C",(EPS,EPSEVSLDamping*),(eps,damping));
706 1 : PetscFunctionReturn(PETSC_SUCCESS);
707 : }
708 :
709 1 : static PetscErrorCode EPSView_EVSL(EPS eps,PetscViewer viewer)
710 : {
711 1 : PetscBool isascii;
712 1 : EPS_EVSL *ctx = (EPS_EVSL*)eps->data;
713 :
714 1 : PetscFunctionBegin;
715 1 : PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
716 1 : if (isascii) {
717 1 : PetscCall(PetscViewerASCIIPrintf(viewer," numerical range = [%g,%g]\n",(double)ctx->lmin,(double)ctx->lmax));
718 1 : PetscCall(PetscViewerASCIIPrintf(viewer," number of slices = %" PetscInt_FMT "\n",ctx->nslices));
719 1 : PetscCall(PetscViewerASCIIPrintf(viewer," type of damping = %s\n",EPSEVSLDampings[ctx->damping]));
720 1 : PetscCall(PetscViewerASCIIPrintf(viewer," computing DOS with %s: nvec=%" PetscInt_FMT ", ",EPSEVSLDOSMethods[ctx->dos],ctx->nvec));
721 1 : PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
722 1 : switch (ctx->dos) {
723 1 : case EPS_EVSL_DOS_KPM:
724 1 : PetscCall(PetscViewerASCIIPrintf(viewer,"degree=%" PetscInt_FMT "\n",ctx->deg));
725 : break;
726 0 : case EPS_EVSL_DOS_LANCZOS:
727 0 : PetscCall(PetscViewerASCIIPrintf(viewer,"steps=%" PetscInt_FMT ", npoints=%" PetscInt_FMT "\n",ctx->steps,ctx->npoints));
728 : break;
729 : }
730 1 : PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
731 1 : PetscCall(PetscViewerASCIIPrintf(viewer," polynomial parameters: max degree = %" PetscInt_FMT ", threshold = %g\n",ctx->max_deg,(double)ctx->thresh));
732 : }
733 1 : PetscFunctionReturn(PETSC_SUCCESS);
734 : }
735 :
736 9 : static PetscErrorCode EPSSetFromOptions_EVSL(EPS eps,PetscOptionItems *PetscOptionsObject)
737 : {
738 9 : PetscReal array[2]={0,0},th;
739 9 : PetscInt k,i1,i2,i3,i4;
740 9 : PetscBool flg,flg1;
741 9 : EPSEVSLDOSMethod dos;
742 9 : EPSEVSLDamping damping;
743 9 : EPS_EVSL *ctx = (EPS_EVSL*)eps->data;
744 :
745 9 : PetscFunctionBegin;
746 9 : PetscOptionsHeadBegin(PetscOptionsObject,"EPS EVSL Options");
747 :
748 9 : k = 2;
749 9 : PetscCall(PetscOptionsRealArray("-eps_evsl_range","Interval containing all eigenvalues (two real values separated with a comma without spaces)","EPSEVSLSetRange",array,&k,&flg));
750 9 : if (flg) {
751 0 : PetscCheck(k>1,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_SIZ,"Must pass two values in -eps_evsl_range (comma-separated without spaces)");
752 0 : PetscCall(EPSEVSLSetRange(eps,array[0],array[1]));
753 : }
754 :
755 9 : PetscCall(PetscOptionsInt("-eps_evsl_slices","Number of slices","EPSEVSLSetSlices",ctx->nslices,&i1,&flg));
756 9 : if (flg) PetscCall(EPSEVSLSetSlices(eps,i1));
757 :
758 9 : PetscCall(PetscOptionsEnum("-eps_evsl_damping","Type of damping","EPSEVSLSetDamping",EPSEVSLDampings,(PetscEnum)ctx->damping,(PetscEnum*)&damping,&flg));
759 9 : if (flg) PetscCall(EPSEVSLSetDamping(eps,damping));
760 :
761 9 : PetscCall(EPSEVSLGetDOSParameters(eps,&dos,&i1,&i2,&i3,&i4));
762 9 : PetscCall(PetscOptionsEnum("-eps_evsl_dos_method","Method to compute the DOS","EPSEVSLSetDOSParameters",EPSEVSLDOSMethods,(PetscEnum)ctx->dos,(PetscEnum*)&dos,&flg));
763 9 : PetscCall(PetscOptionsInt("-eps_evsl_dos_nvec","Number of sample vectors for DOS","EPSEVSLSetDOSParameters",i1,&i1,&flg1));
764 9 : if (flg1) flg = PETSC_TRUE;
765 9 : PetscCall(PetscOptionsInt("-eps_evsl_dos_degree","Polynomial degree used for DOS","EPSEVSLSetDOSParameters",i2,&i2,&flg1));
766 9 : if (flg1) flg = PETSC_TRUE;
767 9 : PetscCall(PetscOptionsInt("-eps_evsl_dos_steps","Number of Lanczos steps in DOS","EPSEVSLSetDOSParameters",i3,&i3,&flg1));
768 9 : if (flg1) flg = PETSC_TRUE;
769 9 : PetscCall(PetscOptionsInt("-eps_evsl_dos_npoints","Number of sample points used for DOS","EPSEVSLSetDOSParameters",i4,&i4,&flg1));
770 9 : if (flg || flg1) PetscCall(EPSEVSLSetDOSParameters(eps,dos,i1,i2,i3,i4));
771 :
772 9 : PetscCall(EPSEVSLGetPolParameters(eps,&i1,&th));
773 9 : PetscCall(PetscOptionsInt("-eps_evsl_pol_max_deg","Maximum degree allowed for the polynomial","EPSEVSLSetPolParameters",i1,&i1,&flg));
774 9 : PetscCall(PetscOptionsReal("-eps_evsl_pol_threshold","Threshold for accepting polynomial","EPSEVSLSetPolParameters",th,&th,&flg1));
775 9 : if (flg || flg1) PetscCall(EPSEVSLSetPolParameters(eps,i1,th));
776 :
777 9 : PetscOptionsHeadEnd();
778 9 : PetscFunctionReturn(PETSC_SUCCESS);
779 : }
780 :
781 9 : static PetscErrorCode EPSDestroy_EVSL(EPS eps)
782 : {
783 9 : EPS_EVSL *ctx = (EPS_EVSL*)eps->data;
784 :
785 9 : PetscFunctionBegin;
786 9 : if (ctx->initialized) EVSLFinish();
787 9 : PetscCall(PetscLayoutDestroy(&ctx->map));
788 9 : PetscCall(PetscFree(ctx->sli));
789 9 : PetscCall(PetscFree(eps->data));
790 9 : PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSEVSLSetRange_C",NULL));
791 9 : PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSEVSLGetRange_C",NULL));
792 9 : PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSEVSLSetSlices_C",NULL));
793 9 : PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSEVSLGetSlices_C",NULL));
794 9 : PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSEVSLSetDOSParameters_C",NULL));
795 9 : PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSEVSLGetDOSParameters_C",NULL));
796 9 : PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSEVSLSetPolParameters_C",NULL));
797 9 : PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSEVSLGetPolParameters_C",NULL));
798 9 : PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSEVSLSetDamping_C",NULL));
799 9 : PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSEVSLGetDamping_C",NULL));
800 9 : PetscFunctionReturn(PETSC_SUCCESS);
801 : }
802 :
803 12 : static PetscErrorCode EPSReset_EVSL(EPS eps)
804 : {
805 12 : EPS_EVSL *ctx = (EPS_EVSL*)eps->data;
806 :
807 12 : PetscFunctionBegin;
808 12 : PetscCall(MatDestroy(&ctx->A));
809 12 : PetscCall(VecDestroy(&ctx->x));
810 12 : PetscCall(VecDestroy(&ctx->y));
811 12 : PetscFunctionReturn(PETSC_SUCCESS);
812 : }
813 :
814 9 : SLEPC_EXTERN PetscErrorCode EPSCreate_EVSL(EPS eps)
815 : {
816 9 : EPS_EVSL *ctx;
817 :
818 9 : PetscFunctionBegin;
819 9 : PetscCall(PetscNew(&ctx));
820 9 : eps->data = (void*)ctx;
821 :
822 9 : ctx->nslices = 0;
823 9 : ctx->lmin = PETSC_MIN_REAL;
824 9 : ctx->lmax = PETSC_MAX_REAL;
825 9 : ctx->dos = EPS_EVSL_DOS_KPM;
826 9 : ctx->nvec = 80;
827 9 : ctx->deg = 300;
828 9 : ctx->steps = 40;
829 9 : ctx->npoints = 200;
830 9 : ctx->max_deg = 10000;
831 9 : ctx->thresh = 0.8;
832 9 : ctx->damping = EPS_EVSL_DAMPING_SIGMA;
833 :
834 9 : eps->categ = EPS_CATEGORY_OTHER;
835 :
836 9 : eps->ops->solve = EPSSolve_EVSL;
837 9 : eps->ops->setup = EPSSetUp_EVSL;
838 9 : eps->ops->setupsort = EPSSetUpSort_Basic;
839 9 : eps->ops->setfromoptions = EPSSetFromOptions_EVSL;
840 9 : eps->ops->destroy = EPSDestroy_EVSL;
841 9 : eps->ops->reset = EPSReset_EVSL;
842 9 : eps->ops->view = EPSView_EVSL;
843 9 : eps->ops->backtransform = EPSBackTransform_Default;
844 9 : eps->ops->setdefaultst = EPSSetDefaultST_NoFactor;
845 :
846 9 : PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSEVSLSetRange_C",EPSEVSLSetRange_EVSL));
847 9 : PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSEVSLGetRange_C",EPSEVSLGetRange_EVSL));
848 9 : PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSEVSLSetSlices_C",EPSEVSLSetSlices_EVSL));
849 9 : PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSEVSLGetSlices_C",EPSEVSLGetSlices_EVSL));
850 9 : PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSEVSLSetDOSParameters_C",EPSEVSLSetDOSParameters_EVSL));
851 9 : PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSEVSLGetDOSParameters_C",EPSEVSLGetDOSParameters_EVSL));
852 9 : PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSEVSLSetPolParameters_C",EPSEVSLSetPolParameters_EVSL));
853 9 : PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSEVSLGetPolParameters_C",EPSEVSLGetPolParameters_EVSL));
854 9 : PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSEVSLSetDamping_C",EPSEVSLSetDamping_EVSL));
855 9 : PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSEVSLGetDamping_C",EPSEVSLGetDamping_EVSL));
856 9 : PetscFunctionReturn(PETSC_SUCCESS);
857 : }
|