Actual source code: gd.c
1: /*
3: SLEPc eigensolver: "gd"
5: Method: Generalized Davidson
7: Algorithm:
9: Generalized Davidson with various subspace extraction and
10: restart techniques.
12: References:
14: [1] E.R. Davidson, "Super-matrix methods", Comput. Phys. Commun.
15: 53(2):49-60, 1989.
17: [2] E. Romero and J.E. Roman, "A parallel implementation of
18: Davidson methods for large-scale eigenvalue problems in
19: SLEPc", submitted, 2013.
21: Last update: Jul 2012
23: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
24: SLEPc - Scalable Library for Eigenvalue Problem Computations
25: Copyright (c) 2002-2013, Universitat Politecnica de Valencia, Spain
27: This file is part of SLEPc.
29: SLEPc is free software: you can redistribute it and/or modify it under the
30: terms of version 3 of the GNU Lesser General Public License as published by
31: the Free Software Foundation.
33: SLEPc is distributed in the hope that it will be useful, but WITHOUT ANY
34: WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
35: FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
36: more details.
38: You should have received a copy of the GNU Lesser General Public License
39: along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
40: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
41: */
43: #include <slepc-private/epsimpl.h> /*I "slepceps.h" I*/
44: #include <../src/eps/impls/davidson/common/davidson.h>
48: PetscErrorCode EPSSetFromOptions_GD(EPS eps)
49: {
51: PetscBool flg,op;
52: PetscInt opi,opi0;
53: KSP ksp;
54: EPSOrthType orth;
55: const char *orth_list[3] = {"I","B","B_opt"};
58: PetscOptionsHead("EPS Generalized Davidson (GD) Options");
60: EPSGDGetKrylovStart(eps,&op);
61: PetscOptionsBool("-eps_gd_krylov_start","Start the searching subspace with a krylov basis","EPSGDSetKrylovStart",op,&op,&flg);
62: if (flg) { EPSGDSetKrylovStart(eps,op); }
64: EPSGDGetBOrth(eps,&orth);
65: PetscOptionsEList("-eps_gd_borth","orthogonalization used in the search subspace","EPSGDSetBOrth",orth_list,3,orth_list[orth-1],&opi,&flg);
66: if (flg) { EPSGDSetBOrth(eps,(EPSOrthType)(opi+1)); }
68: EPSGDGetBlockSize(eps,&opi);
69: PetscOptionsInt("-eps_gd_blocksize","Number vectors add to the searching subspace","EPSGDSetBlockSize",opi,&opi,&flg);
70: if (flg) { EPSGDSetBlockSize(eps,opi); }
72: EPSGDGetRestart(eps,&opi,&opi0);
73: PetscOptionsInt("-eps_gd_minv","Set the size of the searching subspace after restarting","EPSGDSetRestart",opi,&opi,&flg);
74: if (flg) { EPSGDSetRestart(eps,opi,opi0); }
76: PetscOptionsInt("-eps_gd_plusk","Set the number of saved eigenvectors from the previous iteration when restarting","EPSGDSetRestart",opi0,&opi0,&flg);
77: if (flg) { EPSGDSetRestart(eps,opi,opi0); }
79: EPSGDGetInitialSize(eps,&opi);
80: PetscOptionsInt("-eps_gd_initial_size","Set the initial size of the searching subspace","EPSGDSetInitialSize",opi,&opi,&flg);
81: if (flg) { EPSGDSetInitialSize(eps,opi); }
83: EPSGDGetWindowSizes(eps,&opi,&opi0);
84: PetscOptionsInt("-eps_gd_pwindow","(Experimental!) Set the number of converged vectors in the projector","EPSGDSetWindowSizes",opi,&opi,&flg);
85: if (flg) { EPSGDSetWindowSizes(eps,opi,opi0); }
87: PetscOptionsInt("-eps_gd_qwindow","(Experimental!) Set the number of converged vectors in the projected problem","EPSGDSetWindowSizes",opi0,&opi0,&flg);
88: if (flg) { EPSGDSetWindowSizes(eps,opi,opi0); }
90: PetscOptionsBool("-eps_gd_double_expansion","use the doble-expansion variant of GD","EPSGDSetDoubleExpansion",PETSC_FALSE,&op,&flg);
91: if (flg) { EPSGDSetDoubleExpansion(eps,op); }
93: /* Set STPrecond as the default ST */
94: if (!((PetscObject)eps->st)->type_name) {
95: STSetType(eps->st,STPRECOND);
96: }
97: STPrecondSetKSPHasMat(eps->st,PETSC_FALSE);
99: /* Set the default options of the KSP */
100: STGetKSP(eps->st,&ksp);
101: if (!((PetscObject)ksp)->type_name) {
102: KSPSetType(ksp,KSPPREONLY);
103: }
104: PetscOptionsTail();
105: return(0);
106: }
110: PetscErrorCode EPSSetUp_GD(EPS eps)
111: {
113: PetscBool t;
114: KSP ksp;
117: /* Set KSPPREONLY as default */
118: STGetKSP(eps->st,&ksp);
119: if (!((PetscObject)ksp)->type_name) {
120: KSPSetType(ksp,KSPPREONLY);
121: }
123: /* Setup common for all davidson solvers */
124: EPSSetUp_XD(eps);
126: /* Check some constraints */
127: PetscObjectTypeCompare((PetscObject)ksp,KSPPREONLY,&t);
128: if (!t) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"EPSGD only works with KSPPREONLY");
129: return(0);
130: }
134: PetscErrorCode EPSDestroy_GD(EPS eps)
135: {
136: PetscErrorCode ierr;
139: PetscFree(eps->data);
140: PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetKrylovStart_C",NULL);
141: PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetKrylovStart_C",NULL);
142: PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetBOrth_C",NULL);
143: PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetBOrth_C",NULL);
144: PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetBlockSize_C",NULL);
145: PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetBlockSize_C",NULL);
146: PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetRestart_C",NULL);
147: PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetRestart_C",NULL);
148: PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetInitialSize_C",NULL);
149: PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetInitialSize_C",NULL);
150: PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetWindowSizes_C",NULL);
151: PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetWindowSizes_C",NULL);
152: PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetDoubleExpansion_C",NULL);
153: PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetDoubleExpansion_C",NULL);
154: return(0);
155: }
159: /*@
160: EPSGDSetKrylovStart - Activates or deactivates starting the searching
161: subspace with a Krylov basis.
163: Logically Collective on EPS
165: Input Parameters:
166: + eps - the eigenproblem solver context
167: - krylovstart - boolean flag
169: Options Database Key:
170: . -eps_gd_krylov_start - Activates starting the searching subspace with a
171: Krylov basis
173: Level: advanced
175: .seealso: EPSGDGetKrylovStart()
176: @*/
177: PetscErrorCode EPSGDSetKrylovStart(EPS eps,PetscBool krylovstart)
178: {
184: PetscTryMethod(eps,"EPSGDSetKrylovStart_C",(EPS,PetscBool),(eps,krylovstart));
185: return(0);
186: }
190: /*@
191: EPSGDGetKrylovStart - Returns a flag indicating if the search subspace is started with a
192: Krylov basis.
194: Not Collective
196: Input Parameter:
197: . eps - the eigenproblem solver context
199: Output Parameters:
200: . krylovstart - boolean flag indicating if the search subspace is started
201: with a Krylov basis
203: Level: advanced
205: .seealso: EPSGDGetKrylovStart()
206: @*/
207: PetscErrorCode EPSGDGetKrylovStart(EPS eps,PetscBool *krylovstart)
208: {
214: PetscTryMethod(eps,"EPSGDGetKrylovStart_C",(EPS,PetscBool*),(eps,krylovstart));
215: return(0);
216: }
220: /*@
221: EPSGDSetBlockSize - Sets the number of vectors to be added to the searching space
222: in every iteration.
224: Logically Collective on EPS
226: Input Parameters:
227: + eps - the eigenproblem solver context
228: - blocksize - number of vectors added to the search space in every iteration
230: Options Database Key:
231: . -eps_gd_blocksize - number of vectors added to the search space in every iteration
233: Level: advanced
235: .seealso: EPSGDSetKrylovStart()
236: @*/
237: PetscErrorCode EPSGDSetBlockSize(EPS eps,PetscInt blocksize)
238: {
244: PetscTryMethod(eps,"EPSGDSetBlockSize_C",(EPS,PetscInt),(eps,blocksize));
245: return(0);
246: }
250: /*@
251: EPSGDGetBlockSize - Returns the number of vectors to be added to the searching space
252: in every iteration.
254: Not Collective
256: Input Parameter:
257: . eps - the eigenproblem solver context
259: Output Parameter:
260: . blocksize - number of vectors added to the search space in every iteration
262: Level: advanced
264: .seealso: EPSGDSetBlockSize()
265: @*/
266: PetscErrorCode EPSGDGetBlockSize(EPS eps,PetscInt *blocksize)
267: {
273: PetscTryMethod(eps,"EPSGDGetBlockSize_C",(EPS,PetscInt*),(eps,blocksize));
274: return(0);
275: }
279: /*@
280: EPSGDGetRestart - Gets the number of vectors of the searching space after
281: restarting and the number of vectors saved from the previous iteration.
283: Not Collective
285: Input Parameter:
286: . eps - the eigenproblem solver context
288: Output Parameter:
289: + minv - number of vectors of the searching subspace after restarting
290: - plusk - number of vectors saved from the previous iteration
292: Level: advanced
294: .seealso: EPSGDSetRestart()
295: @*/
296: PetscErrorCode EPSGDGetRestart(EPS eps,PetscInt *minv,PetscInt *plusk)
297: {
302: PetscTryMethod(eps,"EPSGDGetRestart_C",(EPS,PetscInt*,PetscInt*),(eps,minv,plusk));
303: return(0);
304: }
308: /*@
309: EPSGDSetRestart - Sets the number of vectors of the searching space after
310: restarting and the number of vectors saved from the previous iteration.
312: Logically Collective on EPS
314: Input Parameters:
315: + eps - the eigenproblem solver context
316: . minv - number of vectors of the searching subspace after restarting
317: - plusk - number of vectors saved from the previous iteration
319: Options Database Keys:
320: + -eps_gd_minv - number of vectors of the searching subspace after restarting
321: - -eps_gd_plusk - number of vectors saved from the previous iteration
323: Level: advanced
325: .seealso: EPSGDSetRestart()
326: @*/
327: PetscErrorCode EPSGDSetRestart(EPS eps,PetscInt minv,PetscInt plusk)
328: {
335: PetscTryMethod(eps,"EPSGDSetRestart_C",(EPS,PetscInt,PetscInt),(eps,minv,plusk));
336: return(0);
337: }
341: /*@
342: EPSGDGetInitialSize - Returns the initial size of the searching space.
344: Not Collective
346: Input Parameter:
347: . eps - the eigenproblem solver context
349: Output Parameter:
350: . initialsize - number of vectors of the initial searching subspace
352: Notes:
353: If EPSGDGetKrylovStart() is PETSC_FALSE and the user provides vectors with
354: EPSSetInitialSpace(), up to initialsize vectors will be used; and if the
355: provided vectors are not enough, the solver completes the subspace with
356: random vectors. In the case of EPSGDGetKrylovStart() being PETSC_TRUE, the solver
357: gets the first vector provided by the user or, if not available, a random vector,
358: and expands the Krylov basis up to initialsize vectors.
360: Level: advanced
362: .seealso: EPSGDSetInitialSize(), EPSGDGetKrylovStart()
363: @*/
364: PetscErrorCode EPSGDGetInitialSize(EPS eps,PetscInt *initialsize)
365: {
371: PetscTryMethod(eps,"EPSGDGetInitialSize_C",(EPS,PetscInt*),(eps,initialsize));
372: return(0);
373: }
377: /*@
378: EPSGDSetInitialSize - Sets the initial size of the searching space.
380: Logically Collective on EPS
382: Input Parameters:
383: + eps - the eigenproblem solver context
384: - initialsize - number of vectors of the initial searching subspace
386: Options Database Key:
387: . -eps_gd_initial_size - number of vectors of the initial searching subspace
389: Notes:
390: If EPSGDGetKrylovStart() is PETSC_FALSE and the user provides vectors with
391: EPSSetInitialSpace(), up to initialsize vectors will be used; and if the
392: provided vectors are not enough, the solver completes the subspace with
393: random vectors. In the case of EPSGDGetKrylovStart() being PETSC_TRUE, the solver
394: gets the first vector provided by the user or, if not available, a random vector,
395: and expands the Krylov basis up to initialsize vectors.
397: Level: advanced
399: .seealso: EPSGDGetInitialSize(), EPSGDGetKrylovStart()
400: @*/
401: PetscErrorCode EPSGDSetInitialSize(EPS eps,PetscInt initialsize)
402: {
408: PetscTryMethod(eps,"EPSGDSetInitialSize_C",(EPS,PetscInt),(eps,initialsize));
409: return(0);
410: }
414: /*@
415: EPSGDSetBOrth - Selects the orthogonalization that will be used in the search
416: subspace in case of generalized Hermitian problems.
418: Logically Collective on EPS
420: Input Parameters:
421: + eps - the eigenproblem solver context
422: - borth - the kind of orthogonalization
424: Possible values:
425: The parameter 'borth' can have one of these values
427: + EPS_ORTH_I - orthogonalization of the search subspace
428: . EPS_ORTH_B - B-orthogonalization of the search subspace
429: - EPS_ORTH_BOPT - B-orthogonalization of the search subspace with an alternative method
431: Options Database Key:
432: . -eps_gd_borth - Set the orthogonalization used in the search subspace
434: Notes:
435: If borth is EPS_ORTH_B, the solver uses a variant of Gram-Schmidt (selected in
436: IP associated to the EPS) with the inner product defined by the matrix problem B.
437: If borth is EPS_ORTH_BOPT, it uses another variant of Gram-Schmidt that only performs
438: one matrix-vector product although more than one reorthogonalization would be done.
440: Level: advanced
442: .seealso: EPSGDGetBOrth()
443: @*/
444: PetscErrorCode EPSGDSetBOrth(EPS eps,EPSOrthType borth)
445: {
451: PetscTryMethod(eps,"EPSGDSetBOrth_C",(EPS,EPSOrthType),(eps,borth));
452: return(0);
453: }
457: /*@
458: EPSGDGetBOrth - Returns the orthogonalization used in the search
459: subspace in case of generalized Hermitian problems.
461: Not Collective
463: Input Parameter:
464: . eps - the eigenproblem solver context
466: Output Parameters:
467: . borth - the kind of orthogonalization
469: Notes:
470: See EPSGDSetBOrth() for possible values of 'borth'.
472: Level: advanced
474: .seealso: EPSGDSetBOrth(), EPSOrthType
475: @*/
476: PetscErrorCode EPSGDGetBOrth(EPS eps,EPSOrthType *borth)
477: {
483: PetscTryMethod(eps,"EPSGDGetBOrth_C",(EPS,EPSOrthType*),(eps,borth));
484: return(0);
485: }
489: /*@
490: EPSGDGetWindowSizes - Gets the number of converged vectors in the projected
491: problem (or Rayleigh quotient) and in the projector employed in the correction
492: equation.
494: Not Collective
496: Input Parameter:
497: . eps - the eigenproblem solver context
499: Output Parameter:
500: + pwindow - number of converged vectors in the projector
501: - qwindow - number of converged vectors in the projected problem
503: Level: advanced
505: .seealso: EPSGDSetWindowSizes()
506: @*/
507: PetscErrorCode EPSGDGetWindowSizes(EPS eps,PetscInt *pwindow,PetscInt *qwindow)
508: {
513: PetscTryMethod(eps,"EPSGDGetWindowSizes_C",(EPS,PetscInt*,PetscInt*),(eps,pwindow,qwindow));
514: return(0);
515: }
519: /*@
520: EPSGDSetWindowSizes - Sets the number of converged vectors in the projected
521: problem (or Rayleigh quotient) and in the projector employed in the correction
522: equation.
524: Logically Collective on EPS
526: Input Parameters:
527: + eps - the eigenproblem solver context
528: . pwindow - number of converged vectors in the projector
529: - qwindow - number of converged vectors in the projected problem
531: Options Database Keys:
532: + -eps_gd_pwindow - set the number of converged vectors in the projector
533: - -eps_gd_qwindow - set the number of converged vectors in the projected problem
535: Level: advanced
537: .seealso: EPSGDGetWindowSizes()
538: @*/
539: PetscErrorCode EPSGDSetWindowSizes(EPS eps,PetscInt pwindow,PetscInt qwindow)
540: {
547: PetscTryMethod(eps,"EPSGDSetWindowSizes_C",(EPS,PetscInt,PetscInt),(eps,pwindow,qwindow));
548: return(0);
549: }
553: static PetscErrorCode EPSGDSetDoubleExpansion_GD(EPS eps,PetscBool use_gd2)
554: {
558: EPSXDSetMethod(eps,use_gd2?DVD_METH_GD2:DVD_METH_GD);
559: return(0);
560: }
564: static PetscErrorCode EPSGDGetDoubleExpansion_GD(EPS eps,PetscBool *flg)
565: {
566: Method_t meth;
570: EPSXDGetMethod_XD(eps,&meth);
571: if (meth==DVD_METH_GD2) *flg = PETSC_TRUE;
572: else *flg = PETSC_FALSE;
573: return(0);
574: }
578: /*@
579: EPSGDGetDoubleExpansion - Gets a flag indicating whether the double
580: expansion variant has been activated or not.
582: Not Collective
584: Input Parameter:
585: . eps - the eigenproblem solver context
587: Output Parameter:
588: . flg - the flag
590: Level: advanced
592: .seealso: EPSGDSetDoubleExpansion()
593: @*/
594: PetscErrorCode EPSGDGetDoubleExpansion(EPS eps,PetscBool *flg)
595: {
601: PetscTryMethod(eps,"EPSGDGetDoubleExpansion_C",(EPS,PetscBool*),(eps,flg));
602: return(0);
603: }
607: /*@
608: EPSGDSetDoubleExpansion - Activate a variant where the search subspace is
609: expanded with K*[A*x B*x] (double expansion) instead of the classic K*r,
610: where K is the preconditioner, x the selected approximate eigenvector and
611: r its associated residual vector.
613: Logically Collective on EPS
615: Input Parameters:
616: + eps - the eigenproblem solver context
617: - use_gd2 - the boolean flag
619: Options Database Keys:
620: . -eps_gd_double_expansion - activate the double-expansion variant of GD
622: Level: advanced
623: @*/
624: PetscErrorCode EPSGDSetDoubleExpansion(EPS eps,PetscBool use_gd2)
625: {
631: PetscTryMethod(eps,"EPSGDSetDoubleExpansion_C",(EPS,PetscBool),(eps,use_gd2));
632: return(0);
633: }
637: PETSC_EXTERN PetscErrorCode EPSCreate_GD(EPS eps)
638: {
639: PetscErrorCode ierr;
642: /* Load the Davidson solver */
643: EPSCreate_XD(eps);
644: EPSJDSetFix_JD(eps,0.0);
645: EPSXDSetMethod(eps,DVD_METH_GD);
647: /* Overload the GD properties */
648: eps->ops->setfromoptions = EPSSetFromOptions_GD;
649: eps->ops->setup = EPSSetUp_GD;
650: eps->ops->destroy = EPSDestroy_GD;
652: PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetKrylovStart_C",EPSXDSetKrylovStart_XD);
653: PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetKrylovStart_C",EPSXDGetKrylovStart_XD);
654: PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetBOrth_C",EPSXDSetBOrth_XD);
655: PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetBOrth_C",EPSXDGetBOrth_XD);
656: PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetBlockSize_C",EPSXDSetBlockSize_XD);
657: PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetBlockSize_C",EPSXDGetBlockSize_XD);
658: PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetRestart_C",EPSXDSetRestart_XD);
659: PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetRestart_C",EPSXDGetRestart_XD);
660: PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetInitialSize_C",EPSXDSetInitialSize_XD);
661: PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetInitialSize_C",EPSXDGetInitialSize_XD);
662: PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetWindowSizes_C",EPSXDSetWindowSizes_XD);
663: PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetWindowSizes_C",EPSXDGetWindowSizes_XD);
664: PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetDoubleExpansion_C",EPSGDSetDoubleExpansion_GD);
665: PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetDoubleExpansion_C",EPSGDGetDoubleExpansion_GD);
666: return(0);
667: }