Actual source code: gd.c
1: /*
2: SLEPc eigensolver: "gd"
4: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5: SLEPc - Scalable Library for Eigenvalue Problem Computations
6: Copyright (c) 2002-2012, Universitat Politecnica de Valencia, Spain
8: This file is part of SLEPc.
9:
10: SLEPc is free software: you can redistribute it and/or modify it under the
11: terms of version 3 of the GNU Lesser General Public License as published by
12: the Free Software Foundation.
14: SLEPc is distributed in the hope that it will be useful, but WITHOUT ANY
15: WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16: FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
17: more details.
19: You should have received a copy of the GNU Lesser General Public License
20: along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
21: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
22: */
24: #include "slepc-private/epsimpl.h" /*I "slepceps.h" I*/
25: #include <../src/eps/impls/davidson/common/davidson.h>
27: PetscErrorCode EPSSetUp_GD(EPS eps);
28: PetscErrorCode EPSDestroy_GD(EPS eps);
30: EXTERN_C_BEGIN
33: PetscErrorCode EPSSetFromOptions_GD(EPS eps)
34: {
36: PetscBool flg,op;
37: PetscInt opi,opi0;
38: KSP ksp;
39: EPSOrthType orth;
40: const char *orth_list[3] = {"I","B","B_opt"};
43: PetscOptionsHead("EPS Generalized Davidson (GD) Options");
45: EPSGDGetKrylovStart(eps,&op);
46: PetscOptionsBool("-eps_gd_krylov_start","Start the searching subspace with a krylov basis","EPSGDSetKrylovStart",op,&op,&flg);
47: if(flg) { EPSGDSetKrylovStart(eps,op); }
49: EPSGDGetBOrth(eps,&orth);
50: PetscOptionsEList("-eps_gd_borth","orthogonalization used in the search subspace","EPSGDSetBOrth",orth_list,3,orth_list[orth-1],&opi,&flg);
51: if (flg) {EPSGDSetBOrth(eps,(EPSOrthType)(opi+1));}
52:
53: EPSGDGetBlockSize(eps,&opi);
54: PetscOptionsInt("-eps_gd_blocksize","Number vectors add to the searching subspace","EPSGDSetBlockSize",opi,&opi,&flg);
55: if(flg) { EPSGDSetBlockSize(eps,opi); }
57: EPSGDGetRestart(eps,&opi,&opi0);
58: PetscOptionsInt("-eps_gd_minv","Set the size of the searching subspace after restarting","EPSGDSetRestart",opi,&opi,&flg);
59: if(flg) { EPSGDSetRestart(eps,opi,opi0); }
61: PetscOptionsInt("-eps_gd_plusk","Set the number of saved eigenvectors from the previous iteration when restarting","EPSGDSetRestart",opi0,&opi0,&flg);
62: if(flg) { EPSGDSetRestart(eps,opi,opi0); }
64: EPSGDGetInitialSize(eps,&opi);
65: PetscOptionsInt("-eps_gd_initial_size","Set the initial size of the searching subspace","EPSGDSetInitialSize",opi,&opi,&flg);
66: if(flg) { EPSGDSetInitialSize(eps,opi); }
68: EPSGDGetWindowSizes(eps,&opi,&opi0);
69: PetscOptionsInt("-eps_gd_pwindow","(Experimental!) Set the number of converged vectors in the projector","EPSGDSetWindowSizes",opi,&opi,&flg);
70: if(flg) { EPSGDSetWindowSizes(eps,opi,opi0); }
72: PetscOptionsInt("-eps_gd_qwindow","(Experimental!) Set the number of converged vectors in the projected problem","EPSGDSetWindowSizes",opi0,&opi0,&flg);
73: if(flg) { EPSGDSetWindowSizes(eps,opi,opi0); }
75: PetscOptionsBool("-eps_gd_double_expansion","use the doble-expansion variant of GD","EPSGDSetDoubleExpansion",PETSC_FALSE,&op,&flg);
76: if(flg) { EPSGDSetDoubleExpansion(eps,op); }
77: PetscOptionsTail();
79: /* Set STPrecond as the default ST */
80: if (!((PetscObject)eps->OP)->type_name) {
81: STSetType(eps->OP,STPRECOND);
82: }
83: STPrecondSetKSPHasMat(eps->OP,PETSC_FALSE);
85: /* Set the default options of the KSP */
86: STGetKSP(eps->OP,&ksp);
87: if (!((PetscObject)ksp)->type_name) {
88: KSPSetType(ksp,KSPPREONLY);
89: }
90:
91: return(0);
92: }
93: EXTERN_C_END
97: PetscErrorCode EPSSetUp_GD(EPS eps)
98: {
100: PetscBool t;
101: KSP ksp;
104: /* Set KSPPREONLY as default */
105: STGetKSP(eps->OP,&ksp);
106: if (!((PetscObject)ksp)->type_name) {
107: KSPSetType(ksp,KSPPREONLY);
108: }
110: /* Setup common for all davidson solvers */
111: EPSSetUp_Davidson(eps);
113: /* Check some constraints */
114: PetscObjectTypeCompare((PetscObject)ksp,KSPPREONLY,&t);
115: if (!t) SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"EPSGD only works with KSPPREONLY");
116: return(0);
117: }
119: EXTERN_C_BEGIN
122: PetscErrorCode EPSCreate_GD(EPS eps)
123: {
124: PetscErrorCode ierr;
127: /* Load the Davidson solver */
128: EPSCreate_Davidson(eps);
129: EPSDavidsonSetFix_Davidson(eps,0.0);
130: EPSDavidsonSetMethod_Davidson(eps,DVD_METH_GD);
132: /* Overload the GD properties */
133: eps->ops->setfromoptions = EPSSetFromOptions_GD;
134: eps->ops->setup = EPSSetUp_GD;
135: eps->ops->destroy = EPSDestroy_GD;
137: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetKrylovStart_C","EPSDavidsonSetKrylovStart_Davidson",EPSDavidsonSetKrylovStart_Davidson);
138: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetKrylovStart_C","EPSDavidsonGetKrylovStart_Davidson",EPSDavidsonGetKrylovStart_Davidson);
139: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetBOrth_C","EPSDavidsonSetBOrth_Davidson",EPSDavidsonSetBOrth_Davidson);
140: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetBOrth_C","EPSDavidsonGetBOrth_Davidson",EPSDavidsonGetBOrth_Davidson);
141: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetBlockSize_C","EPSDavidsonSetBlockSize_Davidson",EPSDavidsonSetBlockSize_Davidson);
142: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetBlockSize_C","EPSDavidsonGetBlockSize_Davidson",EPSDavidsonGetBlockSize_Davidson);
143: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetRestart_C","EPSDavidsonSetRestart_Davidson",EPSDavidsonSetRestart_Davidson);
144: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetRestart_C","EPSDavidsonGetRestart_Davidson",EPSDavidsonGetRestart_Davidson);
145: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetInitialSize_C","EPSDavidsonSetInitialSize_Davidson",EPSDavidsonSetInitialSize_Davidson);
146: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetInitialSize_C","EPSDavidsonGetInitialSize_Davidson",EPSDavidsonGetInitialSize_Davidson);
147: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetWindowSizes_C","EPSDavidsonSetWindowSizes_Davidson",EPSDavidsonSetWindowSizes_Davidson);
148: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetWindowSizes_C","EPSDavidsonGetWindowSizes_Davidson",EPSDavidsonGetWindowSizes_Davidson);
149: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetDoubleExpansion_C","EPSGDSetDoubleExpansion_GD",EPSGDSetDoubleExpansion_GD);
150: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetDoubleExpansion_C","EPSGDGetDoubleExpansion_GD",EPSGDGetDoubleExpansion_GD);
151: return(0);
152: }
153: EXTERN_C_END
157: PetscErrorCode EPSDestroy_GD(EPS eps)
158: {
159: PetscErrorCode ierr;
162: PetscFree(eps->data);
163: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetKrylovStart_C","",PETSC_NULL);
164: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetKrylovStart_C","",PETSC_NULL);
165: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetBOrth_C","",PETSC_NULL);
166: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetBOrth_C","",PETSC_NULL);
167: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetBlockSize_C","",PETSC_NULL);
168: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetBlockSize_C","",PETSC_NULL);
169: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetRestart_C","",PETSC_NULL);
170: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetRestart_C","",PETSC_NULL);
171: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetInitialSize_C","",PETSC_NULL);
172: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetInitialSize_C","",PETSC_NULL);
173: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetWindowSizes_C","",PETSC_NULL);
174: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetWindowSizes_C","",PETSC_NULL);
175: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetDoubleExpansion_C","",PETSC_NULL);
176: PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetDoubleExpansion_C","",PETSC_NULL);
177: return(0);
178: }
182: /*@
183: EPSGDSetKrylovStart - Activates or deactivates starting the searching
184: subspace with a Krylov basis.
186: Logically Collective on EPS
188: Input Parameters:
189: + eps - the eigenproblem solver context
190: - krylovstart - boolean flag
192: Options Database Key:
193: . -eps_gd_krylov_start - Activates starting the searching subspace with a
194: Krylov basis
195:
196: Level: advanced
198: .seealso: EPSGDGetKrylovStart()
199: @*/
200: PetscErrorCode EPSGDSetKrylovStart(EPS eps,PetscBool krylovstart)
201: {
207: PetscTryMethod(eps,"EPSGDSetKrylovStart_C",(EPS,PetscBool),(eps,krylovstart));
208: return(0);
209: }
213: /*@
214: EPSGDGetKrylovStart - Returns a flag indicating if the search subspace is started with a
215: Krylov basis.
217: Not Collective
219: Input Parameter:
220: . eps - the eigenproblem solver context
222: Output Parameters:
223: . krylovstart - boolean flag indicating if the search subspace is started
224: with a Krylov basis
226: Level: advanced
228: .seealso: EPSGDGetKrylovStart()
229: @*/
230: PetscErrorCode EPSGDGetKrylovStart(EPS eps,PetscBool *krylovstart)
231: {
237: PetscTryMethod(eps,"EPSGDGetKrylovStart_C",(EPS,PetscBool*),(eps,krylovstart));
238: return(0);
239: }
243: /*@
244: EPSGDSetBlockSize - Sets the number of vectors to be added to the searching space
245: in every iteration.
247: Logically Collective on EPS
249: Input Parameters:
250: + eps - the eigenproblem solver context
251: - blocksize - number of vectors added to the search space in every iteration
253: Options Database Key:
254: . -eps_gd_blocksize - number of vectors added to the search space in every iteration
255:
256: Level: advanced
258: .seealso: EPSGDSetKrylovStart()
259: @*/
260: PetscErrorCode EPSGDSetBlockSize(EPS eps,PetscInt blocksize)
261: {
267: PetscTryMethod(eps,"EPSGDSetBlockSize_C",(EPS,PetscInt),(eps,blocksize));
268: return(0);
269: }
273: /*@
274: EPSGDGetBlockSize - Returns the number of vectors to be added to the searching space
275: in every iteration.
277: Not Collective
279: Input Parameter:
280: . eps - the eigenproblem solver context
282: Output Parameter:
283: . blocksize - number of vectors added to the search space in every iteration
285: Level: advanced
287: .seealso: EPSGDSetBlockSize()
288: @*/
289: PetscErrorCode EPSGDGetBlockSize(EPS eps,PetscInt *blocksize)
290: {
296: PetscTryMethod(eps,"EPSGDGetBlockSize_C",(EPS,PetscInt*),(eps,blocksize));
297: return(0);
298: }
302: /*@
303: EPSGDGetRestart - Gets the number of vectors of the searching space after
304: restarting and the number of vectors saved from the previous iteration.
306: Not Collective
308: Input Parameter:
309: . eps - the eigenproblem solver context
311: Output Parameter:
312: + minv - number of vectors of the searching subspace after restarting
313: - plusk - number of vectors saved from the previous iteration
315: Level: advanced
317: .seealso: EPSGDSetRestart()
318: @*/
319: PetscErrorCode EPSGDGetRestart(EPS eps,PetscInt *minv,PetscInt *plusk)
320: {
325: PetscTryMethod(eps,"EPSGDGetRestart_C",(EPS,PetscInt*,PetscInt*),(eps,minv,plusk));
326: return(0);
327: }
331: /*@
332: EPSGDSetRestart - Sets the number of vectors of the searching space after
333: restarting and the number of vectors saved from the previous iteration.
335: Logically Collective on EPS
337: Input Parameters:
338: + eps - the eigenproblem solver context
339: . minv - number of vectors of the searching subspace after restarting
340: - plusk - number of vectors saved from the previous iteration
342: Options Database Keys:
343: + -eps_gd_minv - number of vectors of the searching subspace after restarting
344: - -eps_gd_plusk - number of vectors saved from the previous iteration
345:
346: Level: advanced
348: .seealso: EPSGDSetRestart()
349: @*/
350: PetscErrorCode EPSGDSetRestart(EPS eps,PetscInt minv,PetscInt plusk)
351: {
358: PetscTryMethod(eps,"EPSGDSetRestart_C",(EPS,PetscInt,PetscInt),(eps,minv,plusk));
359: return(0);
360: }
364: /*@
365: EPSGDGetInitialSize - Returns the initial size of the searching space.
367: Not Collective
369: Input Parameter:
370: . eps - the eigenproblem solver context
372: Output Parameter:
373: . initialsize - number of vectors of the initial searching subspace
375: Notes:
376: If EPSGDGetKrylovStart() is PETSC_FALSE and the user provides vectors with
377: EPSSetInitialSpace(), up to initialsize vectors will be used; and if the
378: provided vectors are not enough, the solver completes the subspace with
379: random vectors. In the case of EPSGDGetKrylovStart() being PETSC_TRUE, the solver
380: gets the first vector provided by the user or, if not available, a random vector,
381: and expands the Krylov basis up to initialsize vectors.
383: Level: advanced
385: .seealso: EPSGDSetInitialSize(), EPSGDGetKrylovStart()
386: @*/
387: PetscErrorCode EPSGDGetInitialSize(EPS eps,PetscInt *initialsize)
388: {
394: PetscTryMethod(eps,"EPSGDGetInitialSize_C",(EPS,PetscInt*),(eps,initialsize));
395: return(0);
396: }
400: /*@
401: EPSGDSetInitialSize - Sets the initial size of the searching space.
403: Logically Collective on EPS
405: Input Parameters:
406: + eps - the eigenproblem solver context
407: - initialsize - number of vectors of the initial searching subspace
409: Options Database Key:
410: . -eps_gd_initial_size - number of vectors of the initial searching subspace
411:
412: Notes:
413: If EPSGDGetKrylovStart() is PETSC_FALSE and the user provides vectors with
414: EPSSetInitialSpace(), up to initialsize vectors will be used; and if the
415: provided vectors are not enough, the solver completes the subspace with
416: random vectors. In the case of EPSGDGetKrylovStart() being PETSC_TRUE, the solver
417: gets the first vector provided by the user or, if not available, a random vector,
418: and expands the Krylov basis up to initialsize vectors.
420: Level: advanced
422: .seealso: EPSGDGetInitialSize(), EPSGDGetKrylovStart()
423: @*/
424: PetscErrorCode EPSGDSetInitialSize(EPS eps,PetscInt initialsize)
425: {
431: PetscTryMethod(eps,"EPSGDSetInitialSize_C",(EPS,PetscInt),(eps,initialsize));
432: return(0);
433: }
437: /*@
438: EPSGDSetBOrth - Selects the orthogonalization that will be used in the search
439: subspace in case of generalized Hermitian problems.
441: Logically Collective on EPS
443: Input Parameters:
444: + eps - the eigenproblem solver context
445: - borth - the kind of orthogonalization
447: Possible values:
448: The parameter 'borth' can have one of these values
450: + EPS_ORTH_I - orthogonalization of the search subspace
451: . EPS_ORTH_B - B-orthogonalization of the search subspace
452: - EPS_ORTH_BOPT - B-orthogonalization of the search subspace with an alternative method
454: Options Database Key:
455: . -eps_gd_borth - Set the orthogonalization used in the search subspace
457: Notes:
458: If borth is EPS_ORTH_B, the solver uses a variant of Gram-Schmidt (selected in
459: IP associated to the EPS) with the inner product defined by the matrix problem B.
460: If borth is EPS_ORTH_BOPT, it uses another variant of Gram-Schmidt that only performs
461: one matrix-vector product although more than one reorthogonalization would be done.
462:
463: Level: advanced
465: .seealso: EPSGDGetBOrth()
466: @*/
467: PetscErrorCode EPSGDSetBOrth(EPS eps,EPSOrthType borth)
468: {
474: PetscTryMethod(eps,"EPSGDSetBOrth_C",(EPS,EPSOrthType),(eps,borth));
475: return(0);
476: }
480: /*@
481: EPSGDGetBOrth - Returns the orthogonalization used in the search
482: subspace in case of generalized Hermitian problems.
484: Not Collective
486: Input Parameter:
487: . eps - the eigenproblem solver context
489: Output Parameters:
490: . borth - the kind of orthogonalization
492: Notes:
493: See EPSGDSetBOrth() for possible values of 'borth'.
495: Level: advanced
497: .seealso: EPSGDSetBOrth(), EPSOrthType
498: @*/
499: PetscErrorCode EPSGDGetBOrth(EPS eps,EPSOrthType *borth)
500: {
506: PetscTryMethod(eps,"EPSGDGetBOrth_C",(EPS,EPSOrthType*),(eps,borth));
507: return(0);
508: }
512: /*@
513: EPSGDGetWindowSizes - Gets the number of converged vectors in the projected
514: problem (or Rayleigh quotient) and in the projector employed in the correction
515: equation.
517: Not Collective
519: Input Parameter:
520: . eps - the eigenproblem solver context
522: Output Parameter:
523: + pwindow - number of converged vectors in the projector
524: - qwindow - number of converged vectors in the projected problem
526: Level: advanced
528: .seealso: EPSGDSetWindowSizes()
529: @*/
530: PetscErrorCode EPSGDGetWindowSizes(EPS eps,PetscInt *pwindow,PetscInt *qwindow)
531: {
536: PetscTryMethod(eps,"EPSGDGetWindowSizes_C",(EPS,PetscInt*,PetscInt*),(eps,pwindow,qwindow));
537: return(0);
538: }
542: /*@
543: EPSGDSetWindowSizes - Sets the number of converged vectors in the projected
544: problem (or Rayleigh quotient) and in the projector employed in the correction
545: equation.
547: Logically Collective on EPS
549: Input Parameters:
550: + eps - the eigenproblem solver context
551: . pwindow - number of converged vectors in the projector
552: - qwindow - number of converged vectors in the projected problem
554: Options Database Keys:
555: + -eps_gd_pwindow - set the number of converged vectors in the projector
556: - -eps_gd_qwindow - set the number of converged vectors in the projected problem
557:
558: Level: advanced
560: .seealso: EPSGDGetWindowSizes()
561: @*/
562: PetscErrorCode EPSGDSetWindowSizes(EPS eps,PetscInt pwindow,PetscInt qwindow)
563: {
570: PetscTryMethod(eps,"EPSGDSetWindowSizes_C",(EPS,PetscInt,PetscInt),(eps,pwindow,qwindow));
571: return(0);
572: }
576: PetscErrorCode EPSGDSetDoubleExpansion_GD(EPS eps,PetscBool use_gd2)
577: {
581: EPSDavidsonSetMethod_Davidson(eps,use_gd2?DVD_METH_GD2:DVD_METH_GD);
582: return(0);
583: }
587: PetscErrorCode EPSGDGetDoubleExpansion_GD(EPS eps,PetscBool *flg)
588: {
589: Method_t meth;
593: EPSDavidsonGetMethod_Davidson(eps,&meth);
594: if (meth==DVD_METH_GD2) *flg = PETSC_TRUE;
595: else *flg = PETSC_FALSE;
596: return(0);
597: }
601: /*@
602: EPSGDGetDoubleExpansion - Gets a flag indicating whether the double
603: expansion variant has been activated or not.
605: Not Collective
607: Input Parameter:
608: . eps - the eigenproblem solver context
610: Output Parameter:
611: . flg - the flag
613: Level: advanced
615: .seealso: EPSGDSetDoubleExpansion()
616: @*/
617: PetscErrorCode EPSGDGetDoubleExpansion(EPS eps,PetscBool *flg)
618: {
624: PetscTryMethod(eps,"EPSGDGetDoubleExpansion_C",(EPS,PetscBool*),(eps,flg));
625: return(0);
626: }
630: /*@
631: EPSGDSetDoubleExpansion - Activate a variant where the search subspace is
632: expanded with K*[A*x B*x] (double expansion) instead of the classic K*r,
633: where K is the preconditioner, x the selected approximate eigenvector and
634: r its associated residual vector.
636: Logically Collective on EPS
638: Input Parameters:
639: + eps - the eigenproblem solver context
640: - use_gd2 - the boolean flag
642: Options Database Keys:
643: . -eps_gd_double_expansion - activate the double-expansion variant of GD
644:
645: Level: advanced
646: @*/
647: PetscErrorCode EPSGDSetDoubleExpansion(EPS eps,PetscBool use_gd2)
648: {
654: PetscTryMethod(eps,"EPSGDSetDoubleExpansion_C",(EPS,PetscBool),(eps,use_gd2));
655: return(0);
656: }