Actual source code: gd.c

slepc-3.6.1 2015-09-03
Report Typos and Errors
  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", ACM Trans. Math. Software 40(2), Article 13, 2014.

 21:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 22:    SLEPc - Scalable Library for Eigenvalue Problem Computations
 23:    Copyright (c) 2002-2015, Universitat Politecnica de Valencia, Spain

 25:    This file is part of SLEPc.

 27:    SLEPc is free software: you can redistribute it and/or modify it under  the
 28:    terms of version 3 of the GNU Lesser General Public License as published by
 29:    the Free Software Foundation.

 31:    SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
 32:    WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
 33:    FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
 34:    more details.

 36:    You  should have received a copy of the GNU Lesser General  Public  License
 37:    along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
 38:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 39: */

 41: #include <slepc/private/epsimpl.h>                /*I "slepceps.h" I*/
 42: #include <../src/eps/impls/davidson/davidson.h>

 46: PetscErrorCode EPSSetFromOptions_GD(PetscOptions *PetscOptionsObject,EPS eps)
 47: {
 49:   PetscBool      flg,op;
 50:   PetscInt       opi,opi0;
 51:   KSP            ksp;
 52:   PetscBool      orth;
 53:   const char     *orth_list[2] = {"I","B"};

 56:   PetscOptionsHead(PetscOptionsObject,"EPS Generalized Davidson (GD) Options");

 58:   EPSGDGetKrylovStart(eps,&op);
 59:   PetscOptionsBool("-eps_gd_krylov_start","Start the searching subspace with a krylov basis","EPSGDSetKrylovStart",op,&op,&flg);
 60:   if (flg) { EPSGDSetKrylovStart(eps,op); }

 62:   EPSGDGetBOrth(eps,&orth);
 63:   PetscOptionsEList("-eps_gd_borth","orthogonalization used in the search subspace","EPSGDSetBOrth",orth_list,2,orth_list[orth?1:0],&opi,&flg);
 64:   if (flg) { EPSGDSetBOrth(eps,opi==1?PETSC_TRUE:PETSC_FALSE); }

 66:   EPSGDGetBlockSize(eps,&opi);
 67:   PetscOptionsInt("-eps_gd_blocksize","Number vectors add to the searching subspace","EPSGDSetBlockSize",opi,&opi,&flg);
 68:   if (flg) { EPSGDSetBlockSize(eps,opi); }

 70:   EPSGDGetRestart(eps,&opi,&opi0);
 71:   PetscOptionsInt("-eps_gd_minv","Set the size of the searching subspace after restarting","EPSGDSetRestart",opi,&opi,&flg);
 72:   if (flg) { EPSGDSetRestart(eps,opi,opi0); }

 74:   PetscOptionsInt("-eps_gd_plusk","Set the number of saved eigenvectors from the previous iteration when restarting","EPSGDSetRestart",opi0,&opi0,&flg);
 75:   if (flg) { EPSGDSetRestart(eps,opi,opi0); }

 77:   EPSGDGetInitialSize(eps,&opi);
 78:   PetscOptionsInt("-eps_gd_initial_size","Set the initial size of the searching subspace","EPSGDSetInitialSize",opi,&opi,&flg);
 79:   if (flg) { EPSGDSetInitialSize(eps,opi); }

 81:   EPSGDGetWindowSizes(eps,&opi,&opi0);
 82:   PetscOptionsInt("-eps_gd_pwindow","(Experimental!) Set the number of converged vectors in the projector","EPSGDSetWindowSizes",opi,&opi,&flg);
 83:   if (flg) { EPSGDSetWindowSizes(eps,opi,opi0); }

 85:   PetscOptionsInt("-eps_gd_qwindow","(Experimental!) Set the number of converged vectors in the projected problem","EPSGDSetWindowSizes",opi0,&opi0,&flg);
 86:   if (flg) { EPSGDSetWindowSizes(eps,opi,opi0); }

 88:   PetscOptionsBool("-eps_gd_double_expansion","use the doble-expansion variant of GD","EPSGDSetDoubleExpansion",PETSC_FALSE,&op,&flg);
 89:   if (flg) { EPSGDSetDoubleExpansion(eps,op); }

 91:   /* Set STPrecond as the default ST */
 92:   if (!((PetscObject)eps->st)->type_name) {
 93:     STSetType(eps->st,STPRECOND);
 94:   }
 95:   STPrecondSetKSPHasMat(eps->st,PETSC_FALSE);

 97:   /* Set the default options of the KSP */
 98:   STGetKSP(eps->st,&ksp);
 99:   if (!((PetscObject)ksp)->type_name) {
100:     KSPSetType(ksp,KSPPREONLY);
101:   }
102:   PetscOptionsTail();
103:   return(0);
104: }

108: PetscErrorCode EPSSetUp_GD(EPS eps)
109: {
111:   PetscBool      t;
112:   KSP            ksp;

115:   /* Set KSPPREONLY as default */
116:   STGetKSP(eps->st,&ksp);
117:   if (!((PetscObject)ksp)->type_name) {
118:     KSPSetType(ksp,KSPPREONLY);
119:   }

121:   /* Setup common for all davidson solvers */
122:   EPSSetUp_XD(eps);

124:   /* Check some constraints */
125:   PetscObjectTypeCompare((PetscObject)ksp,KSPPREONLY,&t);
126:   if (!t) SETERRQ(PetscObjectComm((PetscObject)eps),PETSC_ERR_SUP,"EPSGD only works with KSPPREONLY");
127:   return(0);
128: }

132: PetscErrorCode EPSDestroy_GD(EPS eps)
133: {
134:   PetscErrorCode  ierr;

137:   PetscFree(eps->data);
138:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetKrylovStart_C",NULL);
139:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetKrylovStart_C",NULL);
140:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetBOrth_C",NULL);
141:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetBOrth_C",NULL);
142:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetBlockSize_C",NULL);
143:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetBlockSize_C",NULL);
144:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetRestart_C",NULL);
145:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetRestart_C",NULL);
146:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetInitialSize_C",NULL);
147:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetInitialSize_C",NULL);
148:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetWindowSizes_C",NULL);
149:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetWindowSizes_C",NULL);
150:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetDoubleExpansion_C",NULL);
151:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetDoubleExpansion_C",NULL);
152:   return(0);
153: }

157: /*@
158:    EPSGDSetKrylovStart - Activates or deactivates starting the searching
159:    subspace with a Krylov basis.

161:    Logically Collective on EPS

163:    Input Parameters:
164: +  eps - the eigenproblem solver context
165: -  krylovstart - boolean flag

167:    Options Database Key:
168: .  -eps_gd_krylov_start - Activates starting the searching subspace with a
169:     Krylov basis

171:    Level: advanced

173: .seealso: EPSGDGetKrylovStart()
174: @*/
175: PetscErrorCode EPSGDSetKrylovStart(EPS eps,PetscBool krylovstart)
176: {

182:   PetscTryMethod(eps,"EPSGDSetKrylovStart_C",(EPS,PetscBool),(eps,krylovstart));
183:   return(0);
184: }

188: /*@
189:    EPSGDGetKrylovStart - Returns a flag indicating if the search subspace is started with a
190:    Krylov basis.

192:    Not Collective

194:    Input Parameter:
195: .  eps - the eigenproblem solver context

197:    Output Parameters:
198: .  krylovstart - boolean flag indicating if the search subspace is started
199:    with a Krylov basis

201:    Level: advanced

203: .seealso: EPSGDGetKrylovStart()
204: @*/
205: PetscErrorCode EPSGDGetKrylovStart(EPS eps,PetscBool *krylovstart)
206: {

212:   PetscTryMethod(eps,"EPSGDGetKrylovStart_C",(EPS,PetscBool*),(eps,krylovstart));
213:   return(0);
214: }

218: /*@
219:    EPSGDSetBlockSize - Sets the number of vectors to be added to the searching space
220:    in every iteration.

222:    Logically Collective on EPS

224:    Input Parameters:
225: +  eps - the eigenproblem solver context
226: -  blocksize - number of vectors added to the search space in every iteration

228:    Options Database Key:
229: .  -eps_gd_blocksize - number of vectors added to the search space in every iteration

231:    Level: advanced

233: .seealso: EPSGDSetKrylovStart()
234: @*/
235: PetscErrorCode EPSGDSetBlockSize(EPS eps,PetscInt blocksize)
236: {

242:   PetscTryMethod(eps,"EPSGDSetBlockSize_C",(EPS,PetscInt),(eps,blocksize));
243:   return(0);
244: }

248: /*@
249:    EPSGDGetBlockSize - Returns the number of vectors to be added to the searching space
250:    in every iteration.

252:    Not Collective

254:    Input Parameter:
255: .  eps - the eigenproblem solver context

257:    Output Parameter:
258: .  blocksize - number of vectors added to the search space in every iteration

260:    Level: advanced

262: .seealso: EPSGDSetBlockSize()
263: @*/
264: PetscErrorCode EPSGDGetBlockSize(EPS eps,PetscInt *blocksize)
265: {

271:   PetscTryMethod(eps,"EPSGDGetBlockSize_C",(EPS,PetscInt*),(eps,blocksize));
272:   return(0);
273: }

277: /*@
278:    EPSGDGetRestart - Gets the number of vectors of the searching space after
279:    restarting and the number of vectors saved from the previous iteration.

281:    Not Collective

283:    Input Parameter:
284: .  eps - the eigenproblem solver context

286:    Output Parameter:
287: +  minv - number of vectors of the searching subspace after restarting
288: -  plusk - number of vectors saved from the previous iteration

290:    Level: advanced

292: .seealso: EPSGDSetRestart()
293: @*/
294: PetscErrorCode EPSGDGetRestart(EPS eps,PetscInt *minv,PetscInt *plusk)
295: {

300:   PetscTryMethod(eps,"EPSGDGetRestart_C",(EPS,PetscInt*,PetscInt*),(eps,minv,plusk));
301:   return(0);
302: }

306: /*@
307:    EPSGDSetRestart - Sets the number of vectors of the searching space after
308:    restarting and the number of vectors saved from the previous iteration.

310:    Logically Collective on EPS

312:    Input Parameters:
313: +  eps - the eigenproblem solver context
314: .  minv - number of vectors of the searching subspace after restarting
315: -  plusk - number of vectors saved from the previous iteration

317:    Options Database Keys:
318: +  -eps_gd_minv - number of vectors of the searching subspace after restarting
319: -  -eps_gd_plusk - number of vectors saved from the previous iteration

321:    Level: advanced

323: .seealso: EPSGDSetRestart()
324: @*/
325: PetscErrorCode EPSGDSetRestart(EPS eps,PetscInt minv,PetscInt plusk)
326: {

333:   PetscTryMethod(eps,"EPSGDSetRestart_C",(EPS,PetscInt,PetscInt),(eps,minv,plusk));
334:   return(0);
335: }

339: /*@
340:    EPSGDGetInitialSize - Returns the initial size of the searching space.

342:    Not Collective

344:    Input Parameter:
345: .  eps - the eigenproblem solver context

347:    Output Parameter:
348: .  initialsize - number of vectors of the initial searching subspace

350:    Notes:
351:    If EPSGDGetKrylovStart() is PETSC_FALSE and the user provides vectors with
352:    EPSSetInitialSpace(), up to initialsize vectors will be used; and if the
353:    provided vectors are not enough, the solver completes the subspace with
354:    random vectors. In the case of EPSGDGetKrylovStart() being PETSC_TRUE, the solver
355:    gets the first vector provided by the user or, if not available, a random vector,
356:    and expands the Krylov basis up to initialsize vectors.

358:    Level: advanced

360: .seealso: EPSGDSetInitialSize(), EPSGDGetKrylovStart()
361: @*/
362: PetscErrorCode EPSGDGetInitialSize(EPS eps,PetscInt *initialsize)
363: {

369:   PetscTryMethod(eps,"EPSGDGetInitialSize_C",(EPS,PetscInt*),(eps,initialsize));
370:   return(0);
371: }

375: /*@
376:    EPSGDSetInitialSize - Sets the initial size of the searching space.

378:    Logically Collective on EPS

380:    Input Parameters:
381: +  eps - the eigenproblem solver context
382: -  initialsize - number of vectors of the initial searching subspace

384:    Options Database Key:
385: .  -eps_gd_initial_size - number of vectors of the initial searching subspace

387:    Notes:
388:    If EPSGDGetKrylovStart() is PETSC_FALSE and the user provides vectors with
389:    EPSSetInitialSpace(), up to initialsize vectors will be used; and if the
390:    provided vectors are not enough, the solver completes the subspace with
391:    random vectors. In the case of EPSGDGetKrylovStart() being PETSC_TRUE, the solver
392:    gets the first vector provided by the user or, if not available, a random vector,
393:    and expands the Krylov basis up to initialsize vectors.

395:    Level: advanced

397: .seealso: EPSGDGetInitialSize(), EPSGDGetKrylovStart()
398: @*/
399: PetscErrorCode EPSGDSetInitialSize(EPS eps,PetscInt initialsize)
400: {

406:   PetscTryMethod(eps,"EPSGDSetInitialSize_C",(EPS,PetscInt),(eps,initialsize));
407:   return(0);
408: }

412: /*@
413:    EPSGDSetBOrth - Selects the orthogonalization that will be used in the search
414:    subspace in case of generalized Hermitian problems.

416:    Logically Collective on EPS

418:    Input Parameters:
419: +  eps   - the eigenproblem solver context
420: -  borth - whether to B-orthogonalize the search subspace

422:    Options Database Key:
423: .  -eps_gd_borth - Set the orthogonalization used in the search subspace

425:    Level: advanced

427: .seealso: EPSGDGetBOrth()
428: @*/
429: PetscErrorCode EPSGDSetBOrth(EPS eps,PetscBool borth)
430: {

436:   PetscTryMethod(eps,"EPSGDSetBOrth_C",(EPS,PetscBool),(eps,borth));
437:   return(0);
438: }

442: /*@
443:    EPSGDGetBOrth - Returns the orthogonalization used in the search
444:    subspace in case of generalized Hermitian problems.

446:    Not Collective

448:    Input Parameter:
449: .  eps - the eigenproblem solver context

451:    Output Parameters:
452: .  borth - whether to B-orthogonalize the search subspace

454:    Level: advanced

456: .seealso: EPSGDSetBOrth()
457: @*/
458: PetscErrorCode EPSGDGetBOrth(EPS eps,PetscBool *borth)
459: {

465:   PetscTryMethod(eps,"EPSGDGetBOrth_C",(EPS,PetscBool*),(eps,borth));
466:   return(0);
467: }

471: /*@
472:    EPSGDGetWindowSizes - Gets the number of converged vectors in the projected
473:    problem (or Rayleigh quotient) and in the projector employed in the correction
474:    equation.

476:    Not Collective

478:    Input Parameter:
479: .  eps - the eigenproblem solver context

481:    Output Parameter:
482: +  pwindow - number of converged vectors in the projector
483: -  qwindow - number of converged vectors in the projected problem

485:    Level: advanced

487: .seealso: EPSGDSetWindowSizes()
488: @*/
489: PetscErrorCode EPSGDGetWindowSizes(EPS eps,PetscInt *pwindow,PetscInt *qwindow)
490: {

495:   PetscTryMethod(eps,"EPSGDGetWindowSizes_C",(EPS,PetscInt*,PetscInt*),(eps,pwindow,qwindow));
496:   return(0);
497: }

501: /*@
502:    EPSGDSetWindowSizes - Sets the number of converged vectors in the projected
503:    problem (or Rayleigh quotient) and in the projector employed in the correction
504:    equation.

506:    Logically Collective on EPS

508:    Input Parameters:
509: +  eps - the eigenproblem solver context
510: .  pwindow - number of converged vectors in the projector
511: -  qwindow - number of converged vectors in the projected problem

513:    Options Database Keys:
514: +  -eps_gd_pwindow - set the number of converged vectors in the projector
515: -  -eps_gd_qwindow - set the number of converged vectors in the projected problem

517:    Level: advanced

519: .seealso: EPSGDGetWindowSizes()
520: @*/
521: PetscErrorCode EPSGDSetWindowSizes(EPS eps,PetscInt pwindow,PetscInt qwindow)
522: {

529:   PetscTryMethod(eps,"EPSGDSetWindowSizes_C",(EPS,PetscInt,PetscInt),(eps,pwindow,qwindow));
530:   return(0);
531: }

535: static PetscErrorCode EPSGDSetDoubleExpansion_GD(EPS eps,PetscBool use_gd2)
536: {

540:   EPSXDSetMethod(eps,use_gd2?DVD_METH_GD2:DVD_METH_GD);
541:   return(0);
542: }

546: static PetscErrorCode EPSGDGetDoubleExpansion_GD(EPS eps,PetscBool *flg)
547: {
548:   Method_t       meth;

552:   EPSXDGetMethod_XD(eps,&meth);
553:   if (meth==DVD_METH_GD2) *flg = PETSC_TRUE;
554:   else *flg = PETSC_FALSE;
555:   return(0);
556: }

560: /*@
561:    EPSGDGetDoubleExpansion - Gets a flag indicating whether the double
562:    expansion variant has been activated or not.

564:    Not Collective

566:    Input Parameter:
567: .  eps - the eigenproblem solver context

569:    Output Parameter:
570: .  flg - the flag

572:    Level: advanced

574: .seealso: EPSGDSetDoubleExpansion()
575: @*/
576: PetscErrorCode EPSGDGetDoubleExpansion(EPS eps,PetscBool *flg)
577: {

583:   PetscTryMethod(eps,"EPSGDGetDoubleExpansion_C",(EPS,PetscBool*),(eps,flg));
584:   return(0);
585: }

589: /*@
590:    EPSGDSetDoubleExpansion - Activate a variant where the search subspace is
591:    expanded with K*[A*x B*x] (double expansion) instead of the classic K*r,
592:    where K is the preconditioner, x the selected approximate eigenvector and
593:    r its associated residual vector.

595:    Logically Collective on EPS

597:    Input Parameters:
598: +  eps - the eigenproblem solver context
599: -  use_gd2 - the boolean flag

601:    Options Database Keys:
602: .  -eps_gd_double_expansion - activate the double-expansion variant of GD

604:    Level: advanced
605: @*/
606: PetscErrorCode EPSGDSetDoubleExpansion(EPS eps,PetscBool use_gd2)
607: {

613:   PetscTryMethod(eps,"EPSGDSetDoubleExpansion_C",(EPS,PetscBool),(eps,use_gd2));
614:   return(0);
615: }

619: PETSC_EXTERN PetscErrorCode EPSCreate_GD(EPS eps)
620: {
621:   PetscErrorCode  ierr;

624:   /* Load the Davidson solver */
625:   EPSCreate_XD(eps);
626:   EPSJDSetFix_JD(eps,0.0);
627:   EPSXDSetMethod(eps,DVD_METH_GD);

629:   /* Overload the GD properties */
630:   eps->ops->setfromoptions       = EPSSetFromOptions_GD;
631:   eps->ops->setup                = EPSSetUp_GD;
632:   eps->ops->destroy              = EPSDestroy_GD;

634:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetKrylovStart_C",EPSXDSetKrylovStart_XD);
635:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetKrylovStart_C",EPSXDGetKrylovStart_XD);
636:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetBOrth_C",EPSXDSetBOrth_XD);
637:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetBOrth_C",EPSXDGetBOrth_XD);
638:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetBlockSize_C",EPSXDSetBlockSize_XD);
639:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetBlockSize_C",EPSXDGetBlockSize_XD);
640:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetRestart_C",EPSXDSetRestart_XD);
641:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetRestart_C",EPSXDGetRestart_XD);
642:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetInitialSize_C",EPSXDSetInitialSize_XD);
643:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetInitialSize_C",EPSXDGetInitialSize_XD);
644:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetWindowSizes_C",EPSXDSetWindowSizes_XD);
645:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetWindowSizes_C",EPSXDGetWindowSizes_XD);
646:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDSetDoubleExpansion_C",EPSGDSetDoubleExpansion_GD);
647:   PetscObjectComposeFunction((PetscObject)eps,"EPSGDGetDoubleExpansion_C",EPSGDGetDoubleExpansion_GD);
648:   return(0);
649: }