Actual source code: jd.c

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

  4:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  5:    SLEPc - Scalable Library for Eigenvalue Problem Computations
  6:    Copyright (c) 2002-2010, Universidad 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
 25:  #include private/stimpl.h
 26:  #include ../src/eps/impls/davidson/common/davidson.h
 27:  #include slepcblaslapack.h

 29: PetscErrorCode EPSSetUp_JD(EPS eps);
 30: PetscErrorCode EPSDestroy_JD(EPS eps);

 35: PetscErrorCode EPSSetFromOptions_JD(EPS eps)
 36: {
 37:   PetscErrorCode  ierr;
 38:   PetscTruth      flg,op;
 39:   PetscInt        opi,opi0;
 40:   PetscReal       opf;

 43: 
 44:   PetscOptionsBegin(((PetscObject)eps)->comm,((PetscObject)eps)->prefix,"JD Options","EPS");

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

 54:   EPSJDGetRestart(eps, &opi, &opi0);
 55:   PetscOptionsInt("-eps_jd_minv","Set the size of the searching subspace after restarting (if 0, eps_jd_bs is employed)","EPSJDSetRestart",opi,&opi,&flg);
 56:   if(flg) { EPSJDSetRestart(eps, opi, opi0);  }

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

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

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

 69:   PetscOptionsEnd();
 70: 
 71:   return(0);
 72: }


 78: PetscErrorCode EPSSetUp_JD(EPS eps)
 79: {
 80:   PetscErrorCode  ierr;
 81:   PetscTruth      t;
 82:   KSP             ksp;


 86:   /* Setup common for all davidson solvers */
 87:   EPSSetUp_DAVIDSON(eps);

 89:   /* Check some constraints */
 90:   STSetUp(eps->OP);
 91:   STGetKSP(eps->OP, &ksp);
 92:   PetscTypeCompare((PetscObject)ksp, KSPPREONLY, &t);
 93:   if (t == PETSC_TRUE) SETERRQ(PETSC_ERR_SUP, "jd does not work with preonly ksp of the spectral transformation");

 95:   return(0);
 96: }


102: PetscErrorCode EPSCreate_JD(EPS eps) {
103:   PetscErrorCode  ierr;
104:   KSP             ksp;


108:   /* Load the DAVIDSON solver */
109:   EPSCreate_DAVIDSON(eps);

111:   /* Set the default ksp of the st to gmres */
112:   STGetKSP(eps->OP, &ksp);
113:   KSPSetType(ksp, KSPGMRES);
114:   KSPSetTolerances(ksp, 1e-3, 1e-10, PETSC_DEFAULT, 90);

116:   /* Overload the JD properties */
117:   eps->ops->setfromoptions       = EPSSetFromOptions_JD;
118:   eps->ops->setup                = EPSSetUp_JD;
119:   eps->ops->destroy              = EPSDestroy_JD;

121:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetKrylovStart_C","EPSDAVIDSONSetKrylovStart_DAVIDSON",EPSDAVIDSONSetKrylovStart_DAVIDSON);
122:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetKrylovStart_C","EPSDAVIDSONGetKrylovStart_DAVIDSON",EPSDAVIDSONGetKrylovStart_DAVIDSON);
123:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetBlockSize_C","EPSDAVIDSONSetBlockSize_DAVIDSON",EPSDAVIDSONSetBlockSize_DAVIDSON);
124:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetBlockSize_C","EPSDAVIDSONGetBlockSize_DAVIDSON",EPSDAVIDSONGetBlockSize_DAVIDSON);
125:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetRestart_C","EPSDAVIDSONSetRestart_DAVIDSON",EPSDAVIDSONSetRestart_DAVIDSON);
126:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetRestart_C","EPSDAVIDSONGetRestart_DAVIDSON",EPSDAVIDSONGetRestart_DAVIDSON);
127:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetInitialSize_C","EPSDAVIDSONSetInitialSize_DAVIDSON",EPSDAVIDSONSetInitialSize_DAVIDSON);
128:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetInitialSize_C","EPSDAVIDSONGetInitialSize_DAVIDSON",EPSDAVIDSONGetInitialSize_DAVIDSON);
129:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetFix_C","EPSDAVIDSONSetFix_DAVIDSON",EPSDAVIDSONSetFix_DAVIDSON);
130:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetFix_C","EPSDAVIDSONGetFix_DAVIDSON",EPSDAVIDSONGetFix_DAVIDSON);

132:   return(0);
133: }

138: PetscErrorCode EPSDestroy_JD(EPS eps)
139: {
140:   PetscErrorCode  ierr;


144:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetKrylovStart_C","",PETSC_NULL);
145:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetKrylovStart_C","",PETSC_NULL);
146:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetBlockSize_C","",PETSC_NULL);
147:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetBlockSize_C","",PETSC_NULL);
148:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetRestart_C","",PETSC_NULL);
149:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetRestart_C","",PETSC_NULL);
150:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetInitialSize_C","",PETSC_NULL);
151:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetInitialSize_C","",PETSC_NULL);
152:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDSetFix_C","",PETSC_NULL);
153:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSJDGetFix_C","",PETSC_NULL);

155:   EPSDestroy_DAVIDSON(eps);

157:   return(0);
158: }


163: /*@
164:    EPSJDSetKrylovStart - Activates or deactivates starting the searching
165:    subspace with a Krylov basis. 

167:    Collective on EPS

169:    Input Parameters:
170: +  eps - the eigenproblem solver context
171: -  krylovstart - boolean flag

173:    Options Database Key:
174: .  -eps_jd_krylov_start - Activates starting the searching subspace with a
175:     Krylov basis
176:    
177:    Level: advanced

179: .seealso: EPSJDGetKrylovStart()
180: @*/
181: PetscErrorCode EPSJDSetKrylovStart(EPS eps,PetscTruth krylovstart)
182: {
183:   PetscErrorCode ierr, (*f)(EPS,PetscTruth);

187:   PetscObjectQueryFunction((PetscObject)eps,"EPSJDSetKrylovStart_C",(void (**)())&f);
188:   if (f) {
189:     (*f)(eps,krylovstart);
190:   }
191:   return(0);
192: }

196: /*@
197:    EPSJDGetKrylovStart - Gets if the searching subspace is started with a
198:    Krylov basis.

200:    Collective on EPS

202:    Input Parameter:
203: .  eps - the eigenproblem solver context

205:    Output Parameters:
206: .  krylovstart - boolean flag indicating if starting the searching subspace
207:    with a Krylov basis is enabled.

209:    Level: advanced

211: .seealso: EPSJDGetKrylovStart()
212: @*/
213: PetscErrorCode EPSJDGetKrylovStart(EPS eps,PetscTruth *krylovstart)
214: {
215:   PetscErrorCode ierr, (*f)(EPS,PetscTruth*);

219:   PetscObjectQueryFunction((PetscObject)eps,"EPSJDGetKrylovStart_C",(void (**)())&f);
220:   if (f) {
221:     (*f)(eps,krylovstart);
222:   }
223:   return(0);
224: }

228: /*@
229:    EPSJDSetBlockSize - Sets the number of vectors added to the searching space
230:    every iteration.

232:    Collective on EPS

234:    Input Parameters:
235: +  eps - the eigenproblem solver context
236: -  blocksize - non-zero positive integer

238:    Options Database Key:
239: .  -eps_jd_blocksize - integer indicating the number of vectors added to the
240:    searching space every iteration. 
241:    
242:    Level: advanced

244: .seealso: EPSJDSetKrylovStart()
245: @*/
246: PetscErrorCode EPSJDSetBlockSize(EPS eps,PetscInt blocksize)
247: {
248:   PetscErrorCode ierr, (*f)(EPS,PetscInt);

252:   PetscObjectQueryFunction((PetscObject)eps,"EPSJDSetBlockSize_C",(void (**)())&f);
253:   if (f) {
254:     (*f)(eps,blocksize);
255:   }
256:   return(0);
257: }

261: /*@
262:    EPSJDGetBlockSize - Gets the number of vectors added to the searching space
263:    every iteration.

265:    Collective on EPS

267:    Input Parameter:
268: .  eps - the eigenproblem solver context

270:    Output Parameter:
271: .  blocksize - integer indicating the number of vectors added to the searching
272:    space every iteration.

274:    Level: advanced

276: .seealso: EPSJDSetBlockSize()
277: @*/
278: PetscErrorCode EPSJDGetBlockSize(EPS eps,PetscInt *blocksize)
279: {
280:   PetscErrorCode ierr, (*f)(EPS,PetscInt*);

284:   PetscObjectQueryFunction((PetscObject)eps,"EPSJDGetBlockSize_C",(void (**)())&f);
285:   if (f) {
286:     (*f)(eps,blocksize);
287:   }
288:   return(0);
289: }

293: /*@
294:    EPSJDGetRestart - Gets the number of vectors of the searching space after
295:    restarting and the number of vectors saved from the previous iteration.

297:    Collective on EPS

299:    Input Parameter:
300: .  eps - the eigenproblem solver context

302:    Output Parameter:
303: +  minv - non-zero positive integer indicating the number of vectors of the
304:    searching subspace after restarting
305: -  plusk - positive integer indicating the number of vectors saved from the
306:    previous iteration   

308:    Level: advanced

310: .seealso: EPSJDSetRestart()
311: @*/
312: PetscErrorCode EPSJDGetRestart(EPS eps,PetscInt *minv,PetscInt *plusk)
313: {
314:   PetscErrorCode ierr, (*f)(EPS,PetscInt*,PetscInt*);

318:   PetscObjectQueryFunction((PetscObject)eps,"EPSJDGetRestart_C",(void (**)())&f);
319:   if (f) {
320:     (*f)(eps,minv,plusk);
321:   }
322:   return(0);
323: }

327: /*@
328:    EPSJDSetRestart - Sets the number of vectors of the searching space after
329:    restarting and the number of vectors saved from the previous iteration.

331:    Collective on EPS

333:    Input Parameters:
334: +  eps - the eigenproblem solver context
335: .  minv - non-zero positive integer indicating the number of vectors of the
336:    searching subspace after restarting
337: -  plusk - positive integer indicating the number of vectors saved from the
338:    previous iteration   

340:    Options Database Key:
341: +  -eps_jd_minv - non-zero positive integer indicating the number of vectors
342:     of the searching subspace after restarting
343: -  -eps_jd_plusk - positive integer indicating the number of vectors saved
344:     from the previous iteration   
345:    
346:    Level: advanced

348: .seealso: EPSJDGetRestart()
349: @*/
350: PetscErrorCode EPSJDSetRestart(EPS eps,PetscInt minv,PetscInt plusk)
351: {
352:   PetscErrorCode ierr, (*f)(EPS,PetscInt,PetscInt);

356:   PetscObjectQueryFunction((PetscObject)eps,"EPSJDSetRestart_C",(void (**)())&f);
357:   if (f) {
358:     (*f)(eps,minv,plusk);
359:   }
360:   return(0);
361: }

365: /*@
366:    EPSJDGetInitialSize - Gets the initial size of the searching space. In the 
367:    case of EPSGetKrylovStart is PETSC_FALSE and the user provides vectors by
368:    EPSSetInitialSpace, up to initialsize vectors will be used; and if the
369:    provided vectors are not enough, the solver completes the subspace with
370:    random vectors. In the case of EPSGetKrylovStart is PETSC_TRUE, the solver
371:    gets the first vector provided by the user or, if not, a random vector,
372:    and expands the Krylov basis up to initialsize vectors.

374:    Collective on EPS

376:    Input Parameter:
377: .  eps - the eigenproblem solver context

379:    Output Parameter:
380: .  initialsize - non-zero positive integer indicating the number of vectors of
381:    the initial searching subspace

383:    Level: advanced

385: .seealso: EPSJDSetInitialSize(), EPSGetKrylovStart()
386: @*/
387: PetscErrorCode EPSJDGetInitialSize(EPS eps,PetscInt *initialsize)
388: {
389:   PetscErrorCode ierr, (*f)(EPS,PetscInt*);

393:   PetscObjectQueryFunction((PetscObject)eps,"EPSJDGetInitialSize_C",(void (**)())&f);
394:   if (f) {
395:     (*f)(eps,initialsize);
396:   }
397:   return(0);
398: }

402: /*@
403:    EPSJDSetInitialSize - Sets the initial size of the searching space. In the 
404:    case of EPSGetKrylovStart is PETSC_FALSE and the user provides vectors by
405:    EPSSetInitialSpace, up to initialsize vectors will be used; and if the
406:    provided vectors are not enough, the solver completes the subspace with
407:    random vectors. In the case of EPSGetKrylovStart is PETSC_TRUE, the solver
408:    gets the first vector provided by the user or, if not, a random vector,
409:    and expands the Krylov basis up to initialsize vectors.

411:    Collective on EPS

413:    Input Parameters:
414: +  eps - the eigenproblem solver context
415: -  initialsize - non-zero positive integer indicating the number of vectors of
416:    the initial searching subspace

418:    Options Database Key:
419: .  -eps_jd_initial_size - non-zero positive integer indicating the number of
420:     vectors of the initial searching subspace
421:    
422:    Level: advanced

424: .seealso: EPSJDGetInitialSize(), EPSGetKrylovStart()
425: @*/
426: PetscErrorCode EPSJDSetInitialSize(EPS eps,PetscInt initialsize)
427: {
428:   PetscErrorCode ierr, (*f)(EPS,PetscInt);

432:   PetscObjectQueryFunction((PetscObject)eps,"EPSJDSetInitialSize_C",(void (**)())&f);
433:   if (f) {
434:     (*f)(eps,initialsize);
435:   }
436:   return(0);
437: }

441: /*@
442:    EPSJDGetFix - Gets the threshold for changing the target in the correction
443:    equation. The target in the correction equation is fixed at the first
444:    iterations. When the norm of the residual vector is lower than this value
445:    the target is set to the corresponding eigenvalue.

447:    Collective on EPS

449:    Input Parameters:
450: +  eps - the eigenproblem solver context
451: -  fix - positive float number

453:    Level: advanced

455: .seealso: EPSJDSetFix()
456: @*/
457: PetscErrorCode EPSJDGetFix(EPS eps,PetscReal *fix)
458: {
459:   PetscErrorCode ierr, (*f)(EPS,PetscReal*);

463:   PetscObjectQueryFunction((PetscObject)eps,"EPSJDGetFix_C",(void (**)())&f);
464:   if (f) {
465:     (*f)(eps,fix);
466:   }
467:   return(0);
468: }

472: /*@
473:    EPSJDSetFix - Sets the threshold for changing the target in the correction
474:    equation. The target in the correction equation is fixed at the first
475:    iterations. When the norm of the residual vector is lower than this value
476:    the target is set to the corresponding eigenvalue.

478:    Collective on EPS

480:    Input Parameter:
481: .  eps - the eigenproblem solver context

483:    Output Parameter:
484: .  fix - positive float number

486:    Options Database Key:
487: .  -eps_jd_fix
488:    
489:    Level: advanced

491: .seealso: EPSJDGetFix()
492: @*/
493: PetscErrorCode EPSJDSetFix(EPS eps,PetscReal fix)
494: {
495:   PetscErrorCode ierr, (*f)(EPS,PetscReal);

499:   PetscObjectQueryFunction((PetscObject)eps,"EPSJDSetFix_C",(void (**)())&f);
500:   if (f) {
501:     (*f)(eps,fix);
502:   }
503:   return(0);
504: }