Actual source code: jd.c

  1: /*
  2:   SLEPc eigensolver: "jd"

  4:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  5:    SLEPc - Scalable Library for Eigenvalue Problem Computations
  6:    Copyright (c) 2002-2011, 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 <private/epsimpl.h>                /*I "slepceps.h" I*/
 25: #include <../src/eps/impls/davidson/common/davidson.h>

 27: PetscErrorCode EPSSetUp_JD(EPS eps);
 28: PetscErrorCode EPSDestroy_JD(EPS eps);

 30: EXTERN_C_BEGIN
 33: PetscErrorCode EPSSetFromOptions_JD(EPS eps)
 34: {
 36:   PetscBool      flg,op;
 37:   PetscInt       opi,opi0;
 38:   PetscReal      opf;
 39:   KSP            ksp;

 42:   PetscOptionsHead("EPS Jacobi-Davidson (JD) Options");

 44:   EPSJDGetKrylovStart(eps,&op);
 45:   PetscOptionsBool("-eps_jd_krylov_start","Start the searching subspace with a krylov basis","EPSJDSetKrylovStart",op,&op,&flg);
 46:   if(flg) { EPSJDSetKrylovStart(eps,op); }
 47: 
 48:   EPSJDGetBlockSize(eps,&opi);
 49:   PetscOptionsInt("-eps_jd_blocksize","Number vectors add to the searching subspace","EPSJDSetBlockSize",opi,&opi,&flg);
 50:   if(flg) { EPSJDSetBlockSize(eps,opi); }

 52:   EPSJDGetRestart(eps,&opi,&opi0);
 53:   PetscOptionsInt("-eps_jd_minv","Set the size of the searching subspace after restarting","EPSJDSetRestart",opi,&opi,&flg);
 54:   if(flg) { EPSJDSetRestart(eps,opi,opi0); }

 56:   PetscOptionsInt("-eps_jd_plusk","Set the number of saved eigenvectors from the previous iteration when restarting","EPSJDSetRestart",opi0,&opi0,&flg);
 57:   if(flg) { EPSJDSetRestart(eps,opi,opi0); }

 59:   EPSJDGetInitialSize(eps,&opi);
 60:   PetscOptionsInt("-eps_jd_initial_size","Set the initial size of the searching subspace","EPSJDSetInitialSize",opi,&opi,&flg);
 61:   if(flg) { EPSJDSetInitialSize(eps,opi); }

 63:   EPSJDGetFix(eps,&opf);
 64:   PetscOptionsReal("-eps_jd_fix","Set the tolerance for changing the target in the correction equation","EPSJDSetFix",opf,&opf,&flg);
 65:   if(flg) { EPSJDSetFix(eps,opf); }

 67:   EPSJDGetConstantCorrectionTolerance(eps,&op);
 68:   PetscOptionsBool("-eps_jd_constant_correction_tolerance","Disable the dynamic stopping criterion when solving the correction equation","EPSJDSetConstantCorrectionTolerance",op,&op,&flg);
 69:   if(flg) { EPSJDSetConstantCorrectionTolerance(eps,op); }

 71:   EPSJDGetWindowSizes(eps,&opi,&opi0);
 72:   PetscOptionsInt("-eps_jd_pwindow","(Experimental!) Set the number of converged vectors in the projector","EPSJDSetWindowSizes",opi,&opi,&flg);
 73:   if(flg) { EPSJDSetWindowSizes(eps,opi,opi0); }

 75:   PetscOptionsInt("-eps_jd_qwindow","(Experimental!) Set the number of converged vectors in the projected problem","EPSJDSetWindowSizes",opi0,&opi0,&flg);
 76:   if(flg) { EPSJDSetWindowSizes(eps,opi,opi0); }

 78:   PetscOptionsTail();

 80:   /* Set STPrecond as the default ST */
 81:   if (!((PetscObject)eps->OP)->type_name) {
 82:     STSetType(eps->OP,STPRECOND);
 83:   }
 84:   STPrecondSetKSPHasMat(eps->OP,PETSC_FALSE);

 86:   /* Set the default options of the KSP */
 87:   STGetKSP(eps->OP,&ksp);
 88:   if (!((PetscObject)ksp)->type_name) {
 89:     KSPSetType(ksp,KSPBCGSL);
 90:     KSPSetTolerances(ksp,1e-4,PETSC_DEFAULT,PETSC_DEFAULT,90);
 91:   }
 92: 
 93:   return(0);
 94: }
 95: EXTERN_C_END

 99: PetscErrorCode EPSSetUp_JD(EPS eps)
100: {
102:   PetscBool      t;
103:   KSP            ksp;


107:   /* Setup common for all davidson solvers */
108:   EPSSetUp_Davidson(eps);

110:   /* Set the default options of the KSP */
111:   STGetKSP(eps->OP,&ksp);
112:   if (!((PetscObject)ksp)->type_name) {
113:     KSPSetType(ksp,KSPBCGSL);
114:     KSPSetTolerances(ksp,1e-4,PETSC_DEFAULT,PETSC_DEFAULT,90);
115:   }
116: 
117:   /* Check some constraints */
118:   PetscTypeCompare((PetscObject)ksp,KSPPREONLY,&t);
119:   if (t) SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"EPSJD does not work with KSPPREONLY");
120:   return(0);
121: }

123: EXTERN_C_BEGIN
126: PetscErrorCode EPSCreate_JD(EPS eps)
127: {

131:   /* Load the Davidson solver */
132:   EPSCreate_Davidson(eps);

134:   /* Overload the JD properties */
135:   eps->ops->setfromoptions       = EPSSetFromOptions_JD;
136:   eps->ops->setup                = EPSSetUp_JD;
137:   eps->ops->destroy              = EPSDestroy_JD;

139:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetKrylovStart_C","EPSDavidsonSetKrylovStart_Davidson",EPSDavidsonSetKrylovStart_Davidson);
140:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetKrylovStart_C","EPSDavidsonGetKrylovStart_Davidson",EPSDavidsonGetKrylovStart_Davidson);
141:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetBlockSize_C","EPSDavidsonSetBlockSize_Davidson",EPSDavidsonSetBlockSize_Davidson);
142:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetBlockSize_C","EPSDavidsonGetBlockSize_Davidson",EPSDavidsonGetBlockSize_Davidson);
143:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetRestart_C","EPSDavidsonSetRestart_Davidson",EPSDavidsonSetRestart_Davidson);
144:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetRestart_C","EPSDavidsonGetRestart_Davidson",EPSDavidsonGetRestart_Davidson);
145:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetInitialSize_C","EPSDavidsonSetInitialSize_Davidson",EPSDavidsonSetInitialSize_Davidson);
146:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetInitialSize_C","EPSDavidsonGetInitialSize_Davidson",EPSDavidsonGetInitialSize_Davidson);
147:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetFix_C","EPSDavidsonSetFix_Davidson",EPSDavidsonSetFix_Davidson);
148:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetFix_C","EPSDavidsonGetFix_Davidson",EPSDavidsonGetFix_Davidson);
149:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetConstantCorrectionTolerance_C","EPSDavidsonSetConstantCorrectionTolerance_Davidson",EPSDavidsonSetConstantCorrectionTolerance_Davidson);
150:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetConstantCorrectionTolerance_C","EPSDavidsonGetConstantCorrectionTolerance_Davidson",EPSDavidsonGetConstantCorrectionTolerance_Davidson);
151:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetWindowSizes_C","EPSDavidsonSetWindowSizes_Davidson",EPSDavidsonSetWindowSizes_Davidson);
152:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetWindowSizes_C","EPSDavidsonGetWindowSizes_Davidson",EPSDavidsonGetWindowSizes_Davidson);
153:   return(0);
154: }
155: EXTERN_C_END

159: PetscErrorCode EPSDestroy_JD(EPS eps)
160: {
161:   PetscErrorCode  ierr;

164:   PetscFree(eps->data);
165:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetKrylovStart_C","",PETSC_NULL);
166:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetKrylovStart_C","",PETSC_NULL);
167:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetBlockSize_C","",PETSC_NULL);
168:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetBlockSize_C","",PETSC_NULL);
169:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetRestart_C","",PETSC_NULL);
170:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetRestart_C","",PETSC_NULL);
171:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetInitialSize_C","",PETSC_NULL);
172:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetInitialSize_C","",PETSC_NULL);
173:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetFix_C","",PETSC_NULL);
174:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetFix_C","",PETSC_NULL);
175:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetConstantCorrectionTolerance_C","",PETSC_NULL);
176:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetConstantCorrectionTolerance_C","",PETSC_NULL);
177:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetWindowSizes_C","",PETSC_NULL);
178:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetWindowSizes_C","",PETSC_NULL);
179:   return(0);
180: }

184: /*@
185:    EPSJDSetKrylovStart - Activates or deactivates starting the searching
186:    subspace with a Krylov basis. 

188:    Logically Collective on EPS

190:    Input Parameters:
191: +  eps - the eigenproblem solver context
192: -  krylovstart - boolean flag

194:    Options Database Key:
195: .  -eps_jd_krylov_start - Activates starting the searching subspace with a
196:     Krylov basis
197:    
198:    Level: advanced

200: .seealso: EPSJDGetKrylovStart()
201: @*/
202: PetscErrorCode EPSJDSetKrylovStart(EPS eps,PetscBool krylovstart)
203: {

209:   PetscTryMethod(eps,"EPSJDSetKrylovStart_C",(EPS,PetscBool),(eps,krylovstart));
210:   return(0);
211: }

215: /*@
216:    EPSJDGetKrylovStart - Returns a flag indicating if the searching subspace is started with a
217:    Krylov basis.

219:    Not Collective

221:    Input Parameter:
222: .  eps - the eigenproblem solver context

224:    Output Parameters:
225: .  krylovstart - boolean flag indicating if the searching subspace is started
226:    with a Krylov basis

228:    Level: advanced

230: .seealso: EPSJDGetKrylovStart()
231: @*/
232: PetscErrorCode EPSJDGetKrylovStart(EPS eps,PetscBool *krylovstart)
233: {

239:   PetscTryMethod(eps,"EPSJDGetKrylovStart_C",(EPS,PetscBool*),(eps,krylovstart));
240:   return(0);
241: }

245: /*@
246:    EPSJDSetBlockSize - Sets the number of vectors to be added to the searching space
247:    in every iteration.

249:    Logically Collective on EPS

251:    Input Parameters:
252: +  eps - the eigenproblem solver context
253: -  blocksize - number of vectors added to the search space in every iteration

255:    Options Database Key:
256: .  -eps_jd_blocksize - number of vectors added to the searching space every iteration
257:    
258:    Level: advanced

260: .seealso: EPSJDSetKrylovStart()
261: @*/
262: PetscErrorCode EPSJDSetBlockSize(EPS eps,PetscInt blocksize)
263: {

269:   PetscTryMethod(eps,"EPSJDSetBlockSize_C",(EPS,PetscInt),(eps,blocksize));
270:   return(0);
271: }

275: /*@
276:    EPSJDGetBlockSize - Returns the number of vectors to be added to the searching space
277:    in every iteration.

279:    Not Collective

281:    Input Parameter:
282: .  eps - the eigenproblem solver context

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

287:    Level: advanced

289: .seealso: EPSJDSetBlockSize()
290: @*/
291: PetscErrorCode EPSJDGetBlockSize(EPS eps,PetscInt *blocksize)
292: {

298:   PetscTryMethod(eps,"EPSJDGetBlockSize_C",(EPS,PetscInt*),(eps,blocksize));
299:   return(0);
300: }

304: /*@
305:    EPSJDGetRestart - Gets the number of vectors of the searching space after
306:    restarting and the number of vectors saved from the previous iteration.

308:    Not Collective

310:    Input Parameter:
311: .  eps - the eigenproblem solver context

313:    Output Parameter:
314: +  minv - number of vectors of the searching subspace after restarting
315: -  plusk - number of vectors saved from the previous iteration   

317:    Level: advanced

319: .seealso: EPSJDSetRestart()
320: @*/
321: PetscErrorCode EPSJDGetRestart(EPS eps,PetscInt *minv,PetscInt *plusk)
322: {

329:   PetscTryMethod(eps,"EPSJDGetRestart_C",(EPS,PetscInt*,PetscInt*),(eps,minv,plusk));
330:   return(0);
331: }

335: /*@
336:    EPSJDSetRestart - Sets the number of vectors of the searching space after
337:    restarting and the number of vectors saved from the previous iteration.

339:    Logically Collective on EPS

341:    Input Parameters:
342: +  eps - the eigenproblem solver context
343: .  minv - number of vectors of the searching subspace after restarting
344: -  plusk - number of vectors saved from the previous iteration   

346:    Options Database Keys:
347: +  -eps_jd_minv - number of vectors of the searching subspace after restarting
348: -  -eps_jd_plusk - number of vectors saved from the previous iteration   
349:    
350:    Level: advanced

352: .seealso: EPSJDGetRestart()
353: @*/
354: PetscErrorCode EPSJDSetRestart(EPS eps,PetscInt minv,PetscInt plusk)
355: {

362:   PetscTryMethod(eps,"EPSJDSetRestart_C",(EPS,PetscInt,PetscInt),(eps,minv,plusk));
363:   return(0);
364: }

368: /*@
369:    EPSJDGetInitialSize - Returns the initial size of the searching space.

371:    Not Collective

373:    Input Parameter:
374: .  eps - the eigenproblem solver context

376:    Output Parameter:
377: .  initialsize - number of vectors of the initial searching subspace

379:    Notes:
380:    If EPSGDGetKrylovStart() is PETSC_FALSE and the user provides vectors with
381:    EPSSetInitialSpace(), up to initialsize vectors will be used; and if the
382:    provided vectors are not enough, the solver completes the subspace with
383:    random vectors. In the case of EPSGDGetKrylovStart() being PETSC_TRUE, the solver
384:    gets the first vector provided by the user or, if not available, a random vector,
385:    and expands the Krylov basis up to initialsize vectors.

387:    Level: advanced

389: .seealso: EPSJDSetInitialSize(), EPSJDGetKrylovStart()
390: @*/
391: PetscErrorCode EPSJDGetInitialSize(EPS eps,PetscInt *initialsize)
392: {

398:   PetscTryMethod(eps,"EPSJDGetInitialSize_C",(EPS,PetscInt*),(eps,initialsize));
399:   return(0);
400: }

404: /*@
405:    EPSJDSetInitialSize - Sets the initial size of the searching space.

407:    Logically Collective on EPS

409:    Input Parameters:
410: +  eps - the eigenproblem solver context
411: -  initialsize - number of vectors of the initial searching subspace

413:    Options Database Key:
414: .  -eps_jd_initial_size - number of vectors of the initial searching subspace
415:    
416:    Notes:
417:    If EPSGDGetKrylovStart() is PETSC_FALSE and the user provides vectors with
418:    EPSSetInitialSpace(), up to initialsize vectors will be used; and if the
419:    provided vectors are not enough, the solver completes the subspace with
420:    random vectors. In the case of EPSGDGetKrylovStart() being PETSC_TRUE, the solver
421:    gets the first vector provided by the user or, if not available, a random vector,
422:    and expands the Krylov basis up to initialsize vectors.

424:    Level: advanced

426: .seealso: EPSJDGetInitialSize(), EPSJDGetKrylovStart()
427: @*/
428: PetscErrorCode EPSJDSetInitialSize(EPS eps,PetscInt initialsize)
429: {

435:   PetscTryMethod(eps,"EPSJDSetInitialSize_C",(EPS,PetscInt),(eps,initialsize));
436:   return(0);
437: }

441: /*@
442:    EPSJDGetFix - Returns the threshold for changing the target in the correction
443:    equation.

445:    Not Collective

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

450:    Output Parameter:
451: .  fix - threshold for changing the target

453:    Note:
454:    The target in the correction equation is fixed at the first iterations.
455:    When the norm of the residual vector is lower than the fix value,
456:    the target is set to the corresponding eigenvalue.

458:    Level: advanced

460: .seealso: EPSJDSetFix()
461: @*/
462: PetscErrorCode EPSJDGetFix(EPS eps,PetscReal *fix)
463: {

469:   PetscTryMethod(eps,"EPSJDGetFix_C",(EPS,PetscReal*),(eps,fix));
470:   return(0);
471: }

475: /*@
476:    EPSJDSetFix - Sets the threshold for changing the target in the correction
477:    equation.

479:    Logically Collective on EPS

481:    Input Parameters:
482: +  eps - the eigenproblem solver context
483: -  fix - threshold for changing the target

485:    Options Database Key:
486: .  -eps_jd_fix - the fix value
487:    
488:    Note:
489:    The target in the correction equation is fixed at the first iterations.
490:    When the norm of the residual vector is lower than the fix value,
491:    the target is set to the corresponding eigenvalue.

493:    Level: advanced

495: .seealso: EPSJDGetFix()
496: @*/
497: PetscErrorCode EPSJDSetFix(EPS eps,PetscReal fix)
498: {

504:   PetscTryMethod(eps,"EPSJDSetFix_C",(EPS,PetscReal),(eps,fix));
505:   return(0);
506: }

510: /*@
511:    EPSJDSetConstantCorrectionTolerance - If true, deactivates the dynamic stopping criterion
512:    (also called Newton) that sets the KSP relative tolerance
513:    to 0.5**i, where i is the number of EPS iterations from the last converged value.

515:    Logically Collective on EPS

517:    Input Parameters:
518: +  eps - the eigenproblem solver context
519: -  constant - if false, the KSP relative tolerance is set to 0.5**i.

521:    Options Database Key:
522: .  -eps_jd_constant_correction_tolerance - Deactivates the dynamic stopping criterion.
523:    
524:    Level: advanced

526: .seealso: EPSJDGetConstantCorrectionTolerance()
527: @*/
528: PetscErrorCode EPSJDSetConstantCorrectionTolerance(EPS eps,PetscBool constant)
529: {

535:   PetscTryMethod(eps,"EPSJDSetConstantCorrectionTolerance_C",(EPS,PetscBool),(eps,constant));
536:   return(0);
537: }

541: /*@
542:    EPSJDGetConstantCorrectionTolerance - Returns a flag indicating if the dynamic stopping is being used for
543:    solving the correction equation. If the flag is false the KSP relative tolerance is set
544:    to 0.5**i, where i is the number of EPS iterations from the last converged value.

546:    Not Collective

548:    Input Parameter:
549: .  eps - the eigenproblem solver context

551:    Output Parameters:
552: .  constant - boolean flag indicating if the dynamic stopping criterion is not being used.

554:    Level: advanced

556: .seealso: EPSJDGetConstantCorrectionTolerance()
557: @*/
558: PetscErrorCode EPSJDGetConstantCorrectionTolerance(EPS eps,PetscBool *constant)
559: {

565:   PetscTryMethod(eps,"EPSJDGetConstantCorrectionTolerance",(EPS,PetscBool*),(eps,constant));
566:   return(0);
567: }

571: /*@
572:    EPSJDGetWindowSizes - Gets the number of converged vectors in the projected
573:    problem (or Rayleigh quotient) and in the projector employed in the correction
574:    equation.

576:    Not Collective

578:    Input Parameter:
579: .  eps - the eigenproblem solver context

581:    Output Parameter:
582: +  pwindow - number of converged vectors in the projector
583: -  qwindow - number of converged vectors in the projected problem

585:    Level: advanced

587: .seealso: EPSJDSetWindowSizes()
588: @*/
589: PetscErrorCode EPSJDGetWindowSizes(EPS eps,PetscInt *pwindow,PetscInt *qwindow)
590: {

597:   PetscTryMethod(eps,"EPSJDGetWindowSizes_C",(EPS,PetscInt*,PetscInt*),(eps,pwindow,qwindow));
598:   return(0);
599: }

603: /*@
604:    EPSJDSetWindowSizes - Sets the number of converged vectors in the projected
605:    problem (or Rayleigh quotient) and in the projector employed in the correction
606:    equation.

608:    Logically Collective on EPS

610:    Input Parameters:
611: +  eps - the eigenproblem solver context
612: .  pwindow - number of converged vectors in the projector
613: -  qwindow - number of converged vectors in the projected problem

615:    Options Database Keys:
616: +  -eps_jd_pwindow - set the number of converged vectors in the projector
617: -  -eps_jd_qwindow - set the number of converged vectors in the projected problem  
618:    
619:    Level: advanced

621: .seealso: EPSJDGetWindowSizes()
622: @*/
623: PetscErrorCode EPSJDSetWindowSizes(EPS eps,PetscInt pwindow,PetscInt qwindow)
624: {

631:   PetscTryMethod(eps,"EPSJDSetWindowSizes_C",(EPS,PetscInt,PetscInt),(eps,pwindow,qwindow));
632:   return(0);
633: }