Actual source code: jd.c
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 eigensolver: "jd"
13: Method: Jacobi-Davidson
15: Algorithm:
17: Jacobi-Davidson with various subspace extraction and
18: restart techniques.
20: References:
22: [1] G.L.G. Sleijpen and H.A. van der Vorst, "A Jacobi-Davidson
23: iteration method for linear eigenvalue problems", SIAM J.
24: Matrix Anal. Appl. 17(2):401-425, 1996.
26: [2] E. Romero and J.E. Roman, "A parallel implementation of
27: Davidson methods for large-scale eigenvalue problems in
28: SLEPc", ACM Trans. Math. Software 40(2), Article 13, 2014.
29: */
31: #include <slepc/private/epsimpl.h>
32: #include <../src/eps/impls/davidson/davidson.h>
34: static PetscErrorCode EPSSetFromOptions_JD(EPS eps,PetscOptionItems PetscOptionsObject)
35: {
36: PetscBool flg,flg2,op,orth;
37: PetscInt opi,opi0;
38: PetscReal opf;
40: PetscFunctionBegin;
41: PetscOptionsHeadBegin(PetscOptionsObject,"EPS Jacobi-Davidson (JD) Options");
43: PetscCall(EPSJDGetKrylovStart(eps,&op));
44: PetscCall(PetscOptionsBool("-eps_jd_krylov_start","Start the search subspace with a Krylov basis","EPSJDSetKrylovStart",op,&op,&flg));
45: if (flg) PetscCall(EPSJDSetKrylovStart(eps,op));
47: PetscCall(EPSJDGetBOrth(eps,&orth));
48: PetscCall(PetscOptionsBool("-eps_jd_borth","Use B-orthogonalization in the search subspace","EPSJDSetBOrth",op,&op,&flg));
49: if (flg) PetscCall(EPSJDSetBOrth(eps,op));
51: PetscCall(EPSJDGetBlockSize(eps,&opi));
52: PetscCall(PetscOptionsInt("-eps_jd_blocksize","Number of vectors to add to the search subspace","EPSJDSetBlockSize",opi,&opi,&flg));
53: if (flg) PetscCall(EPSJDSetBlockSize(eps,opi));
55: PetscCall(EPSJDGetRestart(eps,&opi,&opi0));
56: PetscCall(PetscOptionsInt("-eps_jd_minv","Size of the search subspace after restarting","EPSJDSetRestart",opi,&opi,&flg));
57: PetscCall(PetscOptionsInt("-eps_jd_plusk","Number of eigenvectors saved from the previous iteration when restarting","EPSJDSetRestart",opi0,&opi0,&flg2));
58: if (flg || flg2) PetscCall(EPSJDSetRestart(eps,opi,opi0));
60: PetscCall(EPSJDGetInitialSize(eps,&opi));
61: PetscCall(PetscOptionsInt("-eps_jd_initial_size","Initial size of the search subspace","EPSJDSetInitialSize",opi,&opi,&flg));
62: if (flg) PetscCall(EPSJDSetInitialSize(eps,opi));
64: PetscCall(EPSJDGetFix(eps,&opf));
65: PetscCall(PetscOptionsReal("-eps_jd_fix","Tolerance for changing the target in the correction equation","EPSJDSetFix",opf,&opf,&flg));
66: if (flg) PetscCall(EPSJDSetFix(eps,opf));
68: PetscCall(EPSJDGetConstCorrectionTol(eps,&op));
69: PetscCall(PetscOptionsBool("-eps_jd_const_correction_tol","Disable the dynamic stopping criterion when solving the correction equation","EPSJDSetConstCorrectionTol",op,&op,&flg));
70: if (flg) PetscCall(EPSJDSetConstCorrectionTol(eps,op));
72: PetscOptionsHeadEnd();
73: PetscFunctionReturn(PETSC_SUCCESS);
74: }
76: static PetscErrorCode EPSSetDefaultST_JD(EPS eps)
77: {
78: KSP ksp;
80: PetscFunctionBegin;
81: if (!((PetscObject)eps->st)->type_name) {
82: PetscCall(STSetType(eps->st,STPRECOND));
83: PetscCall(STPrecondSetKSPHasMat(eps->st,PETSC_TRUE));
84: }
85: PetscCall(STGetKSP(eps->st,&ksp));
86: if (!((PetscObject)ksp)->type_name) {
87: PetscCall(KSPSetType(ksp,KSPBCGSL));
88: PetscCall(KSPSetTolerances(ksp,1e-4,PETSC_CURRENT,PETSC_CURRENT,90));
89: }
90: PetscFunctionReturn(PETSC_SUCCESS);
91: }
93: static PetscErrorCode EPSSetUp_JD(EPS eps)
94: {
95: PetscBool t;
96: KSP ksp;
98: PetscFunctionBegin;
99: /* Setup common for all davidson solvers */
100: PetscCall(EPSSetUp_XD(eps));
102: /* Check some constraints */
103: PetscCall(STGetKSP(eps->st,&ksp));
104: PetscCall(PetscObjectTypeCompare((PetscObject)ksp,KSPPREONLY,&t));
105: PetscCheck(!t,PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"EPSJD does not work with KSPPREONLY");
106: PetscFunctionReturn(PETSC_SUCCESS);
107: }
109: static PetscErrorCode EPSView_JD(EPS eps,PetscViewer viewer)
110: {
111: PetscBool isascii,opb;
112: PetscReal opf;
113: PetscInt opi,opi0;
115: PetscFunctionBegin;
116: PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
117: if (isascii) {
118: PetscCall(EPSXDGetBOrth_XD(eps,&opb));
119: if (opb) PetscCall(PetscViewerASCIIPrintf(viewer," search subspace is B-orthogonalized\n"));
120: else PetscCall(PetscViewerASCIIPrintf(viewer," search subspace is orthogonalized\n"));
121: PetscCall(EPSXDGetBlockSize_XD(eps,&opi));
122: PetscCall(PetscViewerASCIIPrintf(viewer," block size=%" PetscInt_FMT "\n",opi));
123: PetscCall(EPSXDGetKrylovStart_XD(eps,&opb));
124: if (!opb) PetscCall(PetscViewerASCIIPrintf(viewer," type of the initial subspace: non-Krylov\n"));
125: else PetscCall(PetscViewerASCIIPrintf(viewer," type of the initial subspace: Krylov\n"));
126: PetscCall(EPSXDGetRestart_XD(eps,&opi,&opi0));
127: PetscCall(PetscViewerASCIIPrintf(viewer," size of the subspace after restarting: %" PetscInt_FMT "\n",opi));
128: PetscCall(PetscViewerASCIIPrintf(viewer," number of vectors after restarting from the previous iteration: %" PetscInt_FMT "\n",opi0));
130: PetscCall(EPSJDGetFix_JD(eps,&opf));
131: PetscCall(PetscViewerASCIIPrintf(viewer," threshold for changing the target in the correction equation (fix): %g\n",(double)opf));
133: PetscCall(EPSJDGetConstCorrectionTol_JD(eps,&opb));
134: if (!opb) PetscCall(PetscViewerASCIIPrintf(viewer," using dynamic tolerance for the correction equation\n"));
135: }
136: PetscFunctionReturn(PETSC_SUCCESS);
137: }
139: static PetscErrorCode EPSDestroy_JD(EPS eps)
140: {
141: PetscFunctionBegin;
142: PetscCall(PetscFree(eps->data));
143: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDSetKrylovStart_C",NULL));
144: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDGetKrylovStart_C",NULL));
145: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDSetBlockSize_C",NULL));
146: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDGetBlockSize_C",NULL));
147: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDSetRestart_C",NULL));
148: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDGetRestart_C",NULL));
149: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDSetInitialSize_C",NULL));
150: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDGetInitialSize_C",NULL));
151: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDSetFix_C",NULL));
152: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDGetFix_C",NULL));
153: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDSetConstCorrectionTol_C",NULL));
154: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDGetConstCorrectionTol_C",NULL));
155: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDSetBOrth_C",NULL));
156: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDGetBOrth_C",NULL));
157: PetscFunctionReturn(PETSC_SUCCESS);
158: }
160: /*@
161: EPSJDSetKrylovStart - Activates or deactivates starting the searching
162: subspace with a Krylov basis.
164: Logically Collective
166: Input Parameters:
167: + eps - the linear eigensolver context
168: - krylovstart - boolean flag
170: Options Database Key:
171: . -eps_jd_krylov_start - activate starting the searching subspace with a Krylov basis
173: Note:
174: See discussion at `EPSJDSetInitialSize()`.
176: Level: advanced
178: .seealso: [](ch:eps), `EPSJD`, `EPSJDGetKrylovStart()`
179: @*/
180: PetscErrorCode EPSJDSetKrylovStart(EPS eps,PetscBool krylovstart)
181: {
182: PetscFunctionBegin;
185: PetscTryMethod(eps,"EPSJDSetKrylovStart_C",(EPS,PetscBool),(eps,krylovstart));
186: PetscFunctionReturn(PETSC_SUCCESS);
187: }
189: /*@
190: EPSJDGetKrylovStart - Returns a flag indicating if the searching subspace is started with a
191: Krylov basis.
193: Not Collective
195: Input Parameter:
196: . eps - the linear eigensolver context
198: Output Parameter:
199: . krylovstart - boolean flag indicating if the searching subspace is started with a Krylov basis
201: Level: advanced
203: .seealso: [](ch:eps), `EPSJD`, `EPSJDSetKrylovStart()`
204: @*/
205: PetscErrorCode EPSJDGetKrylovStart(EPS eps,PetscBool *krylovstart)
206: {
207: PetscFunctionBegin;
209: PetscAssertPointer(krylovstart,2);
210: PetscUseMethod(eps,"EPSJDGetKrylovStart_C",(EPS,PetscBool*),(eps,krylovstart));
211: PetscFunctionReturn(PETSC_SUCCESS);
212: }
214: /*@
215: EPSJDSetBlockSize - Sets the number of vectors to be added to the searching space
216: in every iteration.
218: Logically Collective
220: Input Parameters:
221: + eps - the linear eigensolver context
222: - blocksize - number of vectors added to the search space in every iteration
224: Options Database Key:
225: . -eps_jd_blocksize \<blocksize\> - number of vectors added to the search space in every iteration
227: Note:
228: Detailed information can be found at {cite:p}`Rom14`.
230: Level: advanced
232: .seealso: [](ch:eps), `EPSJD`, `EPSJDSetKrylovStart()`
233: @*/
234: PetscErrorCode EPSJDSetBlockSize(EPS eps,PetscInt blocksize)
235: {
236: PetscFunctionBegin;
239: PetscTryMethod(eps,"EPSJDSetBlockSize_C",(EPS,PetscInt),(eps,blocksize));
240: PetscFunctionReturn(PETSC_SUCCESS);
241: }
243: /*@
244: EPSJDGetBlockSize - Returns the number of vectors to be added to the searching space
245: in every iteration.
247: Not Collective
249: Input Parameter:
250: . eps - the linear eigensolver context
252: Output Parameter:
253: . blocksize - number of vectors added to the search space in every iteration
255: Level: advanced
257: .seealso: [](ch:eps), `EPSJD`, `EPSJDSetBlockSize()`
258: @*/
259: PetscErrorCode EPSJDGetBlockSize(EPS eps,PetscInt *blocksize)
260: {
261: PetscFunctionBegin;
263: PetscAssertPointer(blocksize,2);
264: PetscUseMethod(eps,"EPSJDGetBlockSize_C",(EPS,PetscInt*),(eps,blocksize));
265: PetscFunctionReturn(PETSC_SUCCESS);
266: }
268: /*@
269: EPSJDSetRestart - Sets the number of vectors of the searching space after
270: restarting and the number of vectors saved from the previous iteration.
272: Logically Collective
274: Input Parameters:
275: + eps - the linear eigensolver context
276: . minv - number of vectors of the searching subspace after restarting
277: - plusk - number of vectors saved from the previous iteration
279: Options Database Keys:
280: + -eps_jd_minv \<minv\> - number of vectors of the searching subspace after restarting
281: - -eps_jd_plusk \<plusk\> - number of vectors saved from the previous iteration
283: Notes:
284: `PETSC_CURRENT` can be used to preserve the current value of any of the
285: arguments, and `PETSC_DETERMINE` to set them to a default value.
287: Detailed information can be found at {cite:p}`Rom14`.
289: Level: advanced
291: .seealso: [](ch:eps), `EPSJD`, `EPSJDGetRestart()`
292: @*/
293: PetscErrorCode EPSJDSetRestart(EPS eps,PetscInt minv,PetscInt plusk)
294: {
295: PetscFunctionBegin;
299: PetscTryMethod(eps,"EPSJDSetRestart_C",(EPS,PetscInt,PetscInt),(eps,minv,plusk));
300: PetscFunctionReturn(PETSC_SUCCESS);
301: }
303: /*@
304: EPSJDGetRestart - Gets the number of vectors of the searching space after
305: restarting and the number of vectors saved from the previous iteration.
307: Not Collective
309: Input Parameter:
310: . eps - the linear eigensolver context
312: Output Parameters:
313: + minv - number of vectors of the searching subspace after restarting
314: - plusk - number of vectors saved from the previous iteration
316: Level: advanced
318: .seealso: [](ch:eps), `EPSJD`, `EPSJDSetRestart()`
319: @*/
320: PetscErrorCode EPSJDGetRestart(EPS eps,PetscInt *minv,PetscInt *plusk)
321: {
322: PetscFunctionBegin;
324: PetscUseMethod(eps,"EPSJDGetRestart_C",(EPS,PetscInt*,PetscInt*),(eps,minv,plusk));
325: PetscFunctionReturn(PETSC_SUCCESS);
326: }
328: /*@
329: EPSJDSetInitialSize - Sets the initial size of the searching space.
331: Logically Collective
333: Input Parameters:
334: + eps - the linear eigensolver context
335: - initialsize - number of vectors of the initial searching subspace
337: Options Database Key:
338: . -eps_jd_initial_size \<initialsize\> - number of vectors of the initial searching subspace
340: Notes:
341: If the flag in `EPSJDSetKrylovStart()` is set to `PETSC_FALSE` and the user
342: provides vectors with `EPSSetInitialSpace()`, up to `initialsize` vectors will be used;
343: and if the provided vectors are not enough, the solver completes the subspace with
344: random vectors. In case the `EPSJDSetKrylovStart()` flag is `PETSC_TRUE`, the solver
345: gets the first vector provided by the user or, if not available, a random vector,
346: and expands the Krylov basis up to `initialsize` vectors.
348: Detailed information can be found at {cite:p}`Rom14`.
350: Level: advanced
352: .seealso: [](ch:eps), `EPSJD`, `EPSJDGetInitialSize()`, `EPSJDGetKrylovStart()`
353: @*/
354: PetscErrorCode EPSJDSetInitialSize(EPS eps,PetscInt initialsize)
355: {
356: PetscFunctionBegin;
359: PetscTryMethod(eps,"EPSJDSetInitialSize_C",(EPS,PetscInt),(eps,initialsize));
360: PetscFunctionReturn(PETSC_SUCCESS);
361: }
363: /*@
364: EPSJDGetInitialSize - Returns the initial size of the searching space.
366: Not Collective
368: Input Parameter:
369: . eps - the linear eigensolver context
371: Output Parameter:
372: . initialsize - number of vectors of the initial searching subspace
374: Level: advanced
376: .seealso: [](ch:eps), `EPSJD`, `EPSJDSetInitialSize()`, `EPSJDGetKrylovStart()`
377: @*/
378: PetscErrorCode EPSJDGetInitialSize(EPS eps,PetscInt *initialsize)
379: {
380: PetscFunctionBegin;
382: PetscAssertPointer(initialsize,2);
383: PetscUseMethod(eps,"EPSJDGetInitialSize_C",(EPS,PetscInt*),(eps,initialsize));
384: PetscFunctionReturn(PETSC_SUCCESS);
385: }
387: static PetscErrorCode EPSJDSetFix_JD(EPS eps,PetscReal fix)
388: {
389: EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
391: PetscFunctionBegin;
392: if (fix == (PetscReal)PETSC_DEFAULT || fix == (PetscReal)PETSC_DECIDE) fix = 0.01;
393: PetscCheck(fix>0.0,PetscObjectComm((PetscObject)eps),PETSC_ERR_ARG_OUTOFRANGE,"Invalid fix value, must be >0");
394: data->fix = fix;
395: PetscFunctionReturn(PETSC_SUCCESS);
396: }
398: /*@
399: EPSJDSetFix - Sets the threshold for changing the target in the correction
400: equation.
402: Logically Collective
404: Input Parameters:
405: + eps - the linear eigensolver context
406: - fix - threshold for changing the target
408: Options Database Key:
409: . -eps_jd_fix \<fix\> - the fix value
411: Notes:
412: The target in the correction equation is fixed at the first iterations.
413: When the norm of the residual vector is lower than the `fix` value,
414: the target is set to the corresponding eigenvalue.
416: Detailed information can be found at {cite:p}`Rom14`.
418: Level: advanced
420: .seealso: [](ch:eps), `EPSJD`, `EPSJDGetFix()`
421: @*/
422: PetscErrorCode EPSJDSetFix(EPS eps,PetscReal fix)
423: {
424: PetscFunctionBegin;
427: PetscTryMethod(eps,"EPSJDSetFix_C",(EPS,PetscReal),(eps,fix));
428: PetscFunctionReturn(PETSC_SUCCESS);
429: }
431: PetscErrorCode EPSJDGetFix_JD(EPS eps,PetscReal *fix)
432: {
433: EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
435: PetscFunctionBegin;
436: *fix = data->fix;
437: PetscFunctionReturn(PETSC_SUCCESS);
438: }
440: /*@
441: EPSJDGetFix - Returns the threshold for changing the target in the correction
442: equation.
444: Not Collective
446: Input Parameter:
447: . eps - the linear eigensolver context
449: Output Parameter:
450: . fix - threshold for changing the target
452: Level: advanced
454: .seealso: [](ch:eps), `EPSJD`, `EPSJDSetFix()`
455: @*/
456: PetscErrorCode EPSJDGetFix(EPS eps,PetscReal *fix)
457: {
458: PetscFunctionBegin;
460: PetscAssertPointer(fix,2);
461: PetscUseMethod(eps,"EPSJDGetFix_C",(EPS,PetscReal*),(eps,fix));
462: PetscFunctionReturn(PETSC_SUCCESS);
463: }
465: static PetscErrorCode EPSJDSetConstCorrectionTol_JD(EPS eps,PetscBool constant)
466: {
467: EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
469: PetscFunctionBegin;
470: data->dynamic = PetscNot(constant);
471: PetscFunctionReturn(PETSC_SUCCESS);
472: }
474: /*@
475: EPSJDSetConstCorrectionTol - Deactivate the dynamic stopping criterion
476: (also called Newton).
478: Logically Collective
480: Input Parameters:
481: + eps - the linear eigensolver context
482: - constant - if `PETSC_FALSE`, the `KSP` relative tolerance is set to $2^{-i}$
484: Options Database Key:
485: . -eps_jd_const_correction_tol - set a constant or dynamic stopping criterion
487: Notes:
488: If this flag is set to `PETSC_FALSE`, then the `KSP` relative tolerance is
489: dynamically set to $2^{-i}$, where $i$ is the number of `EPS` iterations
490: since the last converged eigenvalue. By the default, a constant tolerance is used.
492: Detailed information can be found at {cite:p}`Rom14`.
494: Level: advanced
496: .seealso: [](ch:eps), `EPSJD`, `EPSJDGetConstCorrectionTol()`
497: @*/
498: PetscErrorCode EPSJDSetConstCorrectionTol(EPS eps,PetscBool constant)
499: {
500: PetscFunctionBegin;
503: PetscTryMethod(eps,"EPSJDSetConstCorrectionTol_C",(EPS,PetscBool),(eps,constant));
504: PetscFunctionReturn(PETSC_SUCCESS);
505: }
507: PetscErrorCode EPSJDGetConstCorrectionTol_JD(EPS eps,PetscBool *constant)
508: {
509: EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
511: PetscFunctionBegin;
512: *constant = PetscNot(data->dynamic);
513: PetscFunctionReturn(PETSC_SUCCESS);
514: }
516: /*@
517: EPSJDGetConstCorrectionTol - Returns a flag indicating if a constant
518: of dynamic stopping is being used for solving the correction equation.
520: Not Collective
522: Input Parameter:
523: . eps - the linear eigensolver context
525: Output Parameter:
526: . constant - boolean flag indicating if a constant or dynamic stopping criterion is used
528: Level: advanced
530: .seealso: [](ch:eps), `EPSJD`, `EPSJDSetConstCorrectionTol()`
531: @*/
532: PetscErrorCode EPSJDGetConstCorrectionTol(EPS eps,PetscBool *constant)
533: {
534: PetscFunctionBegin;
536: PetscAssertPointer(constant,2);
537: PetscUseMethod(eps,"EPSJDGetConstCorrectionTol_C",(EPS,PetscBool*),(eps,constant));
538: PetscFunctionReturn(PETSC_SUCCESS);
539: }
541: /*@
542: EPSJDSetBOrth - Selects the orthogonalization that will be used in the search
543: subspace in case of generalized Hermitian problems.
545: Logically Collective
547: Input Parameters:
548: + eps - the linear eigensolver context
549: - borth - whether to $B$-orthogonalize the search subspace
551: Options Database Key:
552: . -eps_jd_borth - toggle the $B$-orthogonalization
554: Note:
555: Detailed information can be found at {cite:p}`Rom14`.
557: Level: advanced
559: .seealso: [](ch:eps), `EPSJD`, `EPSJDGetBOrth()`
560: @*/
561: PetscErrorCode EPSJDSetBOrth(EPS eps,PetscBool borth)
562: {
563: PetscFunctionBegin;
566: PetscTryMethod(eps,"EPSJDSetBOrth_C",(EPS,PetscBool),(eps,borth));
567: PetscFunctionReturn(PETSC_SUCCESS);
568: }
570: /*@
571: EPSJDGetBOrth - Returns the orthogonalization used in the search
572: subspace in case of generalized Hermitian problems.
574: Not Collective
576: Input Parameter:
577: . eps - the linear eigensolver context
579: Output Parameter:
580: . borth - whether to $B$-orthogonalize the search subspace
582: Level: advanced
584: .seealso: [](ch:eps), `EPSJD`, `EPSJDSetBOrth()`
585: @*/
586: PetscErrorCode EPSJDGetBOrth(EPS eps,PetscBool *borth)
587: {
588: PetscFunctionBegin;
590: PetscAssertPointer(borth,2);
591: PetscUseMethod(eps,"EPSJDGetBOrth_C",(EPS,PetscBool*),(eps,borth));
592: PetscFunctionReturn(PETSC_SUCCESS);
593: }
595: /*MC
596: EPSJD - EPSJD = "jd" - The Jacobi-Davidson method.
598: Notes:
599: This is a preconditioned eigensolver, that is, it may be competitive
600: when computing interior eigenvalues in case the shift-and-invert spectral
601: transformation is too costly and a good preconditioner is available.
603: The implemented method is Jacobi-Davidson {cite:p}`Sle00`, which may
604: be preferred to Generalized Davidson in difficult problems.
606: The preconditioner is specified via the internal `ST` object and its
607: associated `KSP`.
609: Details of the implementation are described in {cite:p}`Rom14`.
611: Level: beginner
613: .seealso: [](ch:eps), `EPS`, `EPSType`, `EPSSetType()`, `EPSGetST()`
614: M*/
615: SLEPC_EXTERN PetscErrorCode EPSCreate_JD(EPS eps)
616: {
617: EPS_DAVIDSON *data;
619: PetscFunctionBegin;
620: PetscCall(PetscNew(&data));
621: eps->data = (void*)data;
623: data->blocksize = 1;
624: data->initialsize = 0;
625: data->minv = 0;
626: data->plusk = PETSC_DETERMINE;
627: data->ipB = PETSC_TRUE;
628: data->fix = 0.01;
629: data->krylovstart = PETSC_FALSE;
630: data->dynamic = PETSC_FALSE;
632: eps->useds = PETSC_TRUE;
633: eps->categ = EPS_CATEGORY_PRECOND;
635: eps->ops->solve = EPSSolve_XD;
636: eps->ops->setup = EPSSetUp_JD;
637: eps->ops->setupsort = EPSSetUpSort_Default;
638: eps->ops->setfromoptions = EPSSetFromOptions_JD;
639: eps->ops->destroy = EPSDestroy_JD;
640: eps->ops->reset = EPSReset_XD;
641: eps->ops->view = EPSView_JD;
642: eps->ops->backtransform = EPSBackTransform_Default;
643: eps->ops->computevectors = EPSComputeVectors_XD;
644: eps->ops->setdefaultst = EPSSetDefaultST_JD;
646: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDSetKrylovStart_C",EPSXDSetKrylovStart_XD));
647: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDGetKrylovStart_C",EPSXDGetKrylovStart_XD));
648: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDSetBlockSize_C",EPSXDSetBlockSize_XD));
649: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDGetBlockSize_C",EPSXDGetBlockSize_XD));
650: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDSetRestart_C",EPSXDSetRestart_XD));
651: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDGetRestart_C",EPSXDGetRestart_XD));
652: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDSetInitialSize_C",EPSXDSetInitialSize_XD));
653: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDGetInitialSize_C",EPSXDGetInitialSize_XD));
654: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDSetFix_C",EPSJDSetFix_JD));
655: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDGetFix_C",EPSJDGetFix_JD));
656: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDSetConstCorrectionTol_C",EPSJDSetConstCorrectionTol_JD));
657: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDGetConstCorrectionTol_C",EPSJDGetConstCorrectionTol_JD));
658: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDSetBOrth_C",EPSXDSetBOrth_XD));
659: PetscCall(PetscObjectComposeFunction((PetscObject)eps,"EPSJDGetBOrth_C",EPSXDGetBOrth_XD));
660: PetscFunctionReturn(PETSC_SUCCESS);
661: }