Actual source code: gd.c

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

  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_GD(EPS eps);
 30: PetscErrorCode EPSDestroy_GD(EPS eps);

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

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

 45:   EPSGDGetKrylovStart(eps, &op);
 46:   PetscOptionsTruth("-eps_gd_krylov_start","Start the searching subspace with a krylov basis","EPSGDSetKrylovStart",op,&op,&flg);
 47:   if(flg) { EPSGDSetKrylovStart(eps, op);  }
 48: 
 49:   EPSGDGetBlockSize(eps, &opi);
 50:   PetscOptionsInt("-eps_gd_blocksize","Number vectors add to the searching subspace (if 0, nev employed)","EPSGDSetBlockSize",opi,&opi,&flg);
 51:   if(flg) { EPSGDSetBlockSize(eps, opi);  }

 53:   EPSGDGetRestart(eps, &opi, &opi0);
 54:   PetscOptionsInt("-eps_gd_minv","Set the size of the searching subspace after restarting (if 0, eps_gd_bs is employed)","EPSGDSetRestart",opi,&opi,&flg);
 55:   if(flg) { EPSGDSetRestart(eps, opi, opi0);  }

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

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

 64:   PetscOptionsEnd();
 65: 
 66:   return(0);
 67: }


 73: PetscErrorCode EPSSetUp_GD(EPS eps)
 74: {
 75:   PetscErrorCode  ierr;
 76:   PetscTruth      t;
 77:   KSP             ksp;


 81:   /* Setup common for all davidson solvers */
 82:   EPSSetUp_DAVIDSON(eps);

 84:   /* Check some constraints */
 85:   STSetUp(eps->OP);
 86:   STGetKSP(eps->OP, &ksp);
 87:   PetscTypeCompare((PetscObject)ksp, KSPPREONLY, &t);
 88:   if (t == PETSC_FALSE) SETERRQ(PETSC_ERR_SUP, "gd only works with preonly ksp of the spectral transformation");

 90:   return(0);
 91: }


 97: PetscErrorCode EPSCreate_GD(EPS eps) {
 98:   PetscErrorCode  ierr;


102:   /* Load the DAVIDSON solver */
103:   EPSCreate_DAVIDSON(eps);

105:   /* Overload the GD properties */
106:   eps->ops->setfromoptions       = EPSSetFromOptions_GD;
107:   eps->ops->setup                = EPSSetUp_GD;
108:   eps->ops->destroy              = EPSDestroy_GD;

110:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetKrylovStart_C","EPSDAVIDSONSetKrylovStart_DAVIDSON",EPSDAVIDSONSetKrylovStart_DAVIDSON);
111:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetKrylovStart_C","EPSDAVIDSONGetKrylovStart_DAVIDSON",EPSDAVIDSONGetKrylovStart_DAVIDSON);
112:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetBlockSize_C","EPSDAVIDSONSetBlockSize_DAVIDSON",EPSDAVIDSONSetBlockSize_DAVIDSON);
113:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetBlockSize_C","EPSDAVIDSONGetBlockSize_DAVIDSON",EPSDAVIDSONGetBlockSize_DAVIDSON);
114:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetRestart_C","EPSDAVIDSONSetRestart_DAVIDSON",EPSDAVIDSONSetRestart_DAVIDSON);
115:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetRestart_C","EPSDAVIDSONGetRestart_DAVIDSON",EPSDAVIDSONGetRestart_DAVIDSON);
116:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetInitialSize_C","EPSDAVIDSONSetInitialSize_DAVIDSON",EPSDAVIDSONSetInitialSize_DAVIDSON);
117:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetInitialSize_C","EPSDAVIDSONGetInitialSize_DAVIDSON",EPSDAVIDSONGetInitialSize_DAVIDSON);

119:   return(0);
120: }

125: PetscErrorCode EPSDestroy_GD(EPS eps)
126: {
127:   PetscErrorCode  ierr;


131:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetKrylovStart_C","",PETSC_NULL);
132:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetKrylovStart_C","",PETSC_NULL);
133:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetBlockSize_C","",PETSC_NULL);
134:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetBlockSize_C","",PETSC_NULL);
135:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetRestart_C","",PETSC_NULL);
136:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetRestart_C","",PETSC_NULL);
137:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDSetInitialSize_C","",PETSC_NULL);
138:   PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSGDGetInitialSize_C","",PETSC_NULL);

140:   EPSDestroy_DAVIDSON(eps);

142:   return(0);
143: }


148: /*@
149:    EPSGDSetKrylovStart - Activates or deactivates starting the searching
150:    subspace with a Krylov basis. 

152:    Collective on EPS

154:    Input Parameters:
155: +  eps - the eigenproblem solver context
156: -  krylovstart - boolean flag

158:    Options Database Key:
159: .  -eps_gd_krylovstart - Activates starting the searching subspace with a
160:     Krylov basis
161:    
162:    Level: advanced

164: .seealso: EPSGDGetKrylovStart()
165: @*/
166: PetscErrorCode EPSGDSetKrylovStart(EPS eps,PetscTruth krylovstart)
167: {
168:   PetscErrorCode ierr, (*f)(EPS,PetscTruth);

172:   PetscObjectQueryFunction((PetscObject)eps,"EPSGDSetKrylovStart_C",(void (**)())&f);
173:   if (f) {
174:     (*f)(eps,krylovstart);
175:   }
176:   return(0);
177: }

181: /*@
182:    EPSGDGetKrylovStart - Gets if the searching subspace is started with a
183:    Krylov basis.

185:    Collective on EPS

187:    Input Parameter:
188: .  eps - the eigenproblem solver context

190:    Output Parameters:
191: .  krylovstart - boolean flag indicating if starting the searching subspace
192:    with a Krylov basis is enabled.

194:    Level: advanced

196: .seealso: EPSGDGetKrylovStart()
197: @*/
198: PetscErrorCode EPSGDGetKrylovStart(EPS eps,PetscTruth *krylovstart)
199: {
200:   PetscErrorCode ierr, (*f)(EPS,PetscTruth*);

204:   PetscObjectQueryFunction((PetscObject)eps,"EPSGDGetKrylovStart_C",(void (**)())&f);
205:   if (f) {
206:     (*f)(eps,krylovstart);
207:   }
208:   return(0);
209: }

213: /*@
214:    EPSGDSetBlockSize - Sets the number of vectors added to the searching space
215:    every iteration.

217:    Collective on EPS

219:    Input Parameters:
220: +  eps - the eigenproblem solver context
221: -  blocksize - non-zero positive integer

223:    Options Database Key:
224: .  -eps_gd_blocksize - integer indicating the number of vectors added to the
225:    searching space every iteration. 
226:    
227:    Level: advanced

229: .seealso: EPSGDSetKrylovStart()
230: @*/
231: PetscErrorCode EPSGDSetBlockSize(EPS eps,PetscInt blocksize)
232: {
233:   PetscErrorCode ierr, (*f)(EPS,PetscInt);

237:   PetscObjectQueryFunction((PetscObject)eps,"EPSGDSetBlockSize_C",(void (**)())&f);
238:   if (f) {
239:     (*f)(eps,blocksize);
240:   }
241:   return(0);
242: }

246: /*@
247:    EPSGDGetBlockSize - Gets the number of vectors added to the searching space
248:    every iteration.

250:    Collective on EPS

252:    Input Parameter:
253: .  eps - the eigenproblem solver context

255:    Output Parameter:
256: .  blocksize - integer indicating the number of vectors added to the searching
257:    space every iteration.

259:    Level: advanced

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

269:   PetscObjectQueryFunction((PetscObject)eps,"EPSGDGetBlockSize_C",(void (**)())&f);
270:   if (f) {
271:     (*f)(eps,blocksize);
272:   }
273:   return(0);
274: }

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

282:    Collective on EPS

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

287:    Output Parameter:
288: +  minv - non-zero positive integer indicating the number of vectors of the
289:    searching subspace after restarting
290: -  plusk - positive integer indicating the number of vectors saved from the
291:    previous iteration   

293:    Level: advanced

295: .seealso: EPSGDSetRestart()
296: @*/
297: PetscErrorCode EPSGDGetRestart(EPS eps,PetscInt *minv,PetscInt *plusk)
298: {
299:   PetscErrorCode ierr, (*f)(EPS,PetscInt*,PetscInt*);

303:   PetscObjectQueryFunction((PetscObject)eps,"EPSGDGetRestart_C",(void (**)())&f);
304:   if (f) {
305:     (*f)(eps,minv,plusk);
306:   }
307:   return(0);
308: }

312: /*@
313:    EPSGDSetRestart - Sets the number of vectors of the searching space after
314:    restarting and the number of vectors saved from the previous iteration.

316:    Collective on EPS

318:    Input Parameters:
319: +  eps - the eigenproblem solver context
320: .  minv - non-zero positive integer indicating the number of vectors of the
321:    searching subspace after restarting
322: -  plusk - positive integer indicating the number of vectors saved from the
323:    previous iteration   

325:    Options Database Key:
326: +  -eps_gd_minv - non-zero positive integer indicating the number of vectors
327:     of the searching subspace after restarting
328: -  -eps_gd_plusk - positive integer indicating the number of vectors saved
329:     from the previous iteration   
330:    
331:    Level: advanced

333: .seealso: EPSGDSetRestart()
334: @*/
335: PetscErrorCode EPSGDSetRestart(EPS eps,PetscInt minv,PetscInt plusk)
336: {
337:   PetscErrorCode ierr, (*f)(EPS,PetscInt,PetscInt);

341:   PetscObjectQueryFunction((PetscObject)eps,"EPSGDSetRestart_C",(void (**)())&f);
342:   if (f) {
343:     (*f)(eps,minv,plusk);
344:   }
345:   return(0);
346: }

350: /*@
351:    EPSGDGetInitialSize - Gets the initial size of the searching space. In the 
352:    case of EPSGetKrylovStart is PETSC_FALSE and the user provides vectors by
353:    EPSSetInitialSpace, up to initialsize vectors will be used; and if the
354:    provided vectors are not enough, the solver completes the subspace with
355:    random vectors. In the case of EPSGetKrylovStart is PETSC_TRUE, the solver
356:    gets the first vector provided by the user or, if not, a random vector,
357:    and expands the Krylov basis up to initialsize vectors.

359:    Collective on EPS

361:    Input Parameter:
362: .  eps - the eigenproblem solver context

364:    Output Parameter:
365: .  initialsize - non-zero positive integer indicating the number of vectors of
366:    the initial searching subspace

368:    Level: advanced

370: .seealso: EPSGDSetInitialSize(), EPSGetKrylovStart()
371: @*/
372: PetscErrorCode EPSGDGetInitialSize(EPS eps,PetscInt *initialsize)
373: {
374:   PetscErrorCode ierr, (*f)(EPS,PetscInt*);

378:   PetscObjectQueryFunction((PetscObject)eps,"EPSGDGetInitialSize_C",(void (**)())&f);
379:   if (f) {
380:     (*f)(eps,initialsize);
381:   }
382:   return(0);
383: }

387: /*@
388:    EPSGDSetInitialSize - Sets the initial size of the searching space. In the 
389:    case of EPSGetKrylovStart is PETSC_FALSE and the user provides vectors by
390:    EPSSetInitialSpace, up to initialsize vectors will be used; and if the
391:    provided vectors are not enough, the solver completes the subspace with
392:    random vectors. In the case of EPSGetKrylovStart is PETSC_TRUE, the solver
393:    gets the first vector provided by the user or, if not, a random vector,
394:    and expands the Krylov basis up to initialsize vectors.

396:    Collective on EPS

398:    Input Parameters:
399: +  eps - the eigenproblem solver context
400: -  initialsize - non-zero positive integer indicating the number of vectors of
401:    the initial searching subspace

403:    Options Database Key:
404: .  -eps_gd_initial_size - non-zero positive integer indicating the number of
405:     vectors of the initial searching subspace
406:    
407:    Level: advanced

409: .seealso: EPSGDGetInitialSize(), EPSGetKrylovStart()
410: @*/
411: PetscErrorCode EPSGDSetInitialSize(EPS eps,PetscInt initialsize)
412: {
413:   PetscErrorCode ierr, (*f)(EPS,PetscInt);

417:   PetscObjectQueryFunction((PetscObject)eps,"EPSGDSetInitialSize_C",(void (**)())&f);
418:   if (f) {
419:     (*f)(eps,initialsize);
420:   }
421:   return(0);
422: }