Actual source code: stfunc.c

  1: /*
  2:     The ST (spectral transformation) interface routines, callable by users.

  4:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  5:       SLEPc - Scalable Library for Eigenvalue Problem Computations
  6:       Copyright (c) 2002-2007, Universidad Politecnica de Valencia, Spain

  8:       This file is part of SLEPc. See the README file for conditions of use
  9:       and additional information.
 10:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 11: */

 13:  #include src/st/stimpl.h

 15: PetscCookie ST_COOKIE = 0;
 16: PetscEvent ST_SetUp = 0, ST_Apply = 0, ST_ApplyTranspose = 0;

 20: /*@C
 21:   STInitializePackage - This function initializes everything in the ST package. It is called
 22:   from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to STCreate()
 23:   when using static libraries.

 25:   Input Parameter:
 26:   path - The dynamic library path, or PETSC_NULL

 28:   Level: developer

 30: .seealso: SlepcInitialize()
 31: @*/
 32: PetscErrorCode STInitializePackage(char *path) {
 33:   static PetscTruth initialized = PETSC_FALSE;
 34:   char              logList[256];
 35:   char             *className;
 36:   PetscTruth        opt;

 40:   if (initialized) return(0);
 41:   initialized = PETSC_TRUE;
 42:   /* Register Classes */
 43:   PetscLogClassRegister(&ST_COOKIE,"Spectral Transform");
 44:   /* Register Constructors */
 45:   STRegisterAll(path);
 46:   /* Register Events */
 47:   PetscLogEventRegister(&ST_SetUp,"STSetUp",ST_COOKIE);
 48:   PetscLogEventRegister(&ST_Apply,"STApply",ST_COOKIE);
 49:   PetscLogEventRegister(&ST_ApplyTranspose,"STApplyTranspose",ST_COOKIE);
 50:   /* Process info exclusions */
 51:   PetscOptionsGetString(PETSC_NULL, "-log_info_exclude", logList, 256, &opt);
 52:   if (opt) {
 53:     PetscStrstr(logList, "st", &className);
 54:     if (className) {
 55:       PetscInfoDeactivateClass(ST_COOKIE);
 56:     }
 57:   }
 58:   /* Process summary exclusions */
 59:   PetscOptionsGetString(PETSC_NULL, "-log_summary_exclude", logList, 256, &opt);
 60:   if (opt) {
 61:     PetscStrstr(logList, "st", &className);
 62:     if (className) {
 63:       PetscLogEventDeactivateClass(ST_COOKIE);
 64:     }
 65:   }
 66:   return(0);
 67: }

 71: /*@
 72:    STDestroy - Destroys ST context that was created with STCreate().

 74:    Collective on ST

 76:    Input Parameter:
 77: .  st - the spectral transformation context

 79:    Level: beginner

 81: .seealso: STCreate(), STSetUp()
 82: @*/
 83: PetscErrorCode STDestroy(ST st)
 84: {

 89:   if (--st->refct > 0) return(0);

 91:   /* if memory was published with AMS then destroy it */
 92:   PetscObjectDepublish(st);

 94:   if (st->ops->destroy) { (*st->ops->destroy)(st); }
 95:   if (st->ksp) { KSPDestroy(st->ksp); }
 96:   if (st->w) { VecDestroy(st->w); }
 97:   if (st->shift_matrix != STMATMODE_INPLACE && st->mat) {
 98:     MatDestroy(st->mat);
 99:   }

101:   PetscHeaderDestroy(st);
102:   return(0);
103: }

107: static PetscErrorCode STPublish_Petsc(PetscObject object)
108: {
110:   return(0);
111: }

115: /*@C
116:    STCreate - Creates a spectral transformation context.

118:    Collective on MPI_Comm

120:    Input Parameter:
121: .  comm - MPI communicator 

123:    Output Parameter:
124: .  st - location to put the spectral transformation context

126:    Level: beginner

128: .seealso: STSetUp(), STApply(), STDestroy(), ST
129: @*/
130: PetscErrorCode STCreate(MPI_Comm comm,ST *newst)
131: {
133:   ST             st;
134:   const char     *prefix;

138:   *newst = 0;

140:   PetscHeaderCreate(st,_p_ST,struct _STOps,ST_COOKIE,-1,"ST",comm,STDestroy,STView);
141:   st->bops->publish       = STPublish_Petsc;
142:   PetscMemzero(st->ops,sizeof(struct _STOps));

144:   st->A                   = 0;
145:   st->B                   = 0;
146:   st->sigma               = 0.0;
147:   st->data                = 0;
148:   st->setupcalled         = 0;
149:   st->w                   = 0;
150:   st->shift_matrix        = STMATMODE_COPY;
151:   st->str                 = DIFFERENT_NONZERO_PATTERN;
152: 
153:   KSPCreate(st->comm,&st->ksp);
154:   STGetOptionsPrefix(st,&prefix);
155:   KSPSetOptionsPrefix(st->ksp,prefix);
156:   KSPAppendOptionsPrefix(st->ksp,"st_");
157: 
158:   *newst                  = st;
159:   PetscPublishAll(st);
160:   return(0);

162: }

166: /*@
167:    STSetOperators - Sets the matrices associated with the eigenvalue problem. 

169:    Collective on ST and Mat

171:    Input Parameters:
172: +  st - the spectral transformation context
173: .  A  - the matrix associated with the eigensystem
174: -  B  - the second matrix in the case of generalized eigenproblems

176:    Notes:
177:    To specify a standard eigenproblem, use PETSC_NULL for B.

179:    Level: intermediate

181: .seealso: STGetOperators()
182:  @*/
183: PetscErrorCode STSetOperators(ST st,Mat A,Mat B)
184: {
191:   st->A = A;
192:   st->B = B;
193:   st->setupcalled = 0;
194:   return(0);
195: }

199: /*@C
200:    STGetOperators - Gets the matrices associated with the eigensystem.

202:    Not collective, though parallel Mats are returned if the ST is parallel

204:    Input Parameter:
205: .  st - the spectral transformation context

207:    Output Parameters:
208: .  A - the matrix associated with the eigensystem
209: -  B - the second matrix in the case of generalized eigenproblems

211:    Level: intermediate

213: .seealso: STSetOperators()
214: @*/
215: PetscErrorCode STGetOperators(ST st,Mat *A,Mat *B)
216: {
219:   if (A) *A = st->A;
220:   if (B) *B = st->B;
221:   return(0);
222: }

226: /*@
227:    STSetShift - Sets the shift associated with the spectral transformation

229:    Not collective

231:    Input Parameters:
232: +  st - the spectral transformation context
233: -  shift - the value of the shift

235:    Note:
236:    In some spectral transformations, changing the shift may have associated
237:    a lot of work, for example recomputing a factorization.
238:    
239:    Level: beginner

241: @*/
242: PetscErrorCode STSetShift(ST st,PetscScalar shift)
243: {

248:   if (st->sigma != shift) {
249:     if (st->ops->setshift) {
250:       (*st->ops->setshift)(st,shift);
251:     }
252:   }
253:   st->sigma = shift;
254:   return(0);
255: }

259: /*@
260:    STGetShift - Gets the shift associated with the spectral transformation.

262:    Not collective

264:    Input Parameter:
265: .  st - the spectral transformation context

267:    Output Parameter:
268: .  shift - the value of the shift

270:    Level: beginner

272: @*/
273: PetscErrorCode STGetShift(ST st,PetscScalar* shift)
274: {
277:   if (shift)  *shift = st->sigma;
278:   return(0);
279: }

283: /*@C
284:    STSetOptionsPrefix - Sets the prefix used for searching for all 
285:    ST options in the database.

287:    Collective on ST

289:    Input Parameters:
290: +  st     - the spectral transformation context
291: -  prefix - the prefix string to prepend to all ST option requests

293:    Notes:
294:    A hyphen (-) must NOT be given at the beginning of the prefix name.
295:    The first character of all runtime options is AUTOMATICALLY the
296:    hyphen.

298:    Level: advanced

300: .seealso: STAppendOptionsPrefix(), STGetOptionsPrefix()
301: @*/
302: PetscErrorCode STSetOptionsPrefix(ST st,const char *prefix)
303: {

308:   PetscObjectSetOptionsPrefix((PetscObject)st,prefix);
309:   KSPSetOptionsPrefix(st->ksp,prefix);
310:   KSPAppendOptionsPrefix(st->ksp,"st_");
311:   return(0);
312: }

316: /*@C
317:    STAppendOptionsPrefix - Appends to the prefix used for searching for all 
318:    ST options in the database.

320:    Collective on ST

322:    Input Parameters:
323: +  st     - the spectral transformation context
324: -  prefix - the prefix string to prepend to all ST option requests

326:    Notes:
327:    A hyphen (-) must NOT be given at the beginning of the prefix name.
328:    The first character of all runtime options is AUTOMATICALLY the
329:    hyphen.

331:    Level: advanced

333: .seealso: STSetOptionsPrefix(), STGetOptionsPrefix()
334: @*/
335: PetscErrorCode STAppendOptionsPrefix(ST st,const char *prefix)
336: {

341:   PetscObjectAppendOptionsPrefix((PetscObject)st,prefix);
342:   KSPSetOptionsPrefix(st->ksp,st->prefix);
343:   KSPAppendOptionsPrefix(st->ksp,"st_");
344:   return(0);
345: }

349: /*@C
350:    STGetOptionsPrefix - Gets the prefix used for searching for all 
351:    ST options in the database.

353:    Not Collective

355:    Input Parameters:
356: .  st - the spectral transformation context

358:    Output Parameters:
359: .  prefix - pointer to the prefix string used, is returned

361:    Notes: On the Fortran side, the user should pass in a string 'prefix' of
362:    sufficient length to hold the prefix.

364:    Level: advanced

366: .seealso: STSetOptionsPrefix(), STAppendOptionsPrefix()
367: @*/
368: PetscErrorCode STGetOptionsPrefix(ST st,const char *prefix[])
369: {

374:   PetscObjectGetOptionsPrefix((PetscObject)st, prefix);
375:   return(0);
376: }

380: /*@C
381:    STView - Prints the ST data structure.

383:    Collective on ST

385:    Input Parameters:
386: +  ST - the ST context
387: -  viewer - optional visualization context

389:    Note:
390:    The available visualization contexts include
391: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
392: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
393:          output where only the first processor opens
394:          the file.  All other processors send their 
395:          data to the first processor to print. 

397:    The user can open an alternative visualization contexts with
398:    PetscViewerASCIIOpen() (output to a specified file).

400:    Level: beginner

402: .seealso: EPSView(), PetscViewerASCIIOpen()
403: @*/
404: PetscErrorCode STView(ST st,PetscViewer viewer)
405: {
406:   PetscErrorCode    ierr;
407:   STType            cstr;
408:   const char*       str;
409:   PetscTruth        isascii,isstring;
410:   PetscViewerFormat format;

414:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(st->comm);

418:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
419:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
420:   if (isascii) {
421:     PetscViewerGetFormat(viewer,&format);
422:     PetscViewerASCIIPrintf(viewer,"ST Object:\n");
423:     STGetType(st,&cstr);
424:     if (cstr) {
425:       PetscViewerASCIIPrintf(viewer,"  type: %s\n",cstr);
426:     } else {
427:       PetscViewerASCIIPrintf(viewer,"  type: not yet set\n");
428:     }
429: #if !defined(PETSC_USE_COMPLEX)
430:     PetscViewerASCIIPrintf(viewer,"  shift: %g\n",st->sigma);
431: #else
432:     PetscViewerASCIIPrintf(viewer,"  shift: %g+%g i\n",PetscRealPart(st->sigma),PetscImaginaryPart(st->sigma));
433: #endif
434:     switch (st->shift_matrix) {
435:     case STMATMODE_COPY:
436:       break;
437:     case STMATMODE_INPLACE:
438:       PetscViewerASCIIPrintf(viewer,"Shifting the matrix and unshifting at exit\n");
439:       break;
440:     case STMATMODE_SHELL:
441:       PetscViewerASCIIPrintf(viewer,"Using a shell matrix\n");
442:       break;
443:     }
444:     if (st->B && st->shift_matrix != STMATMODE_SHELL) {
445:       switch (st->str) {
446:         case SAME_NONZERO_PATTERN:      str = "same nonzero pattern";break;
447:         case DIFFERENT_NONZERO_PATTERN: str = "different nonzero pattern";break;
448:         case SUBSET_NONZERO_PATTERN:    str = "subset nonzero pattern";break;
449:         default:                        SETERRQ(1,"Wrong structure flag");
450:       }
451:       PetscViewerASCIIPrintf(viewer,"Matrices A and B have %s\n",str);
452:     }
453:     if (st->ops->view) {
454:       PetscViewerASCIIPushTab(viewer);
455:       (*st->ops->view)(st,viewer);
456:       PetscViewerASCIIPopTab(viewer);
457:     }
458:   } else if (isstring) {
459:     STGetType(st,&cstr);
460:     PetscViewerStringSPrintf(viewer," %-7.7s",cstr);
461:     if (st->ops->view) {(*st->ops->view)(st,viewer);}
462:   } else {
463:     SETERRQ1(1,"Viewer type %s not supported by ST",((PetscObject)viewer)->type_name);
464:   }
465:   return(0);
466: }

470: PetscErrorCode STView_Default(ST st,PetscViewer viewer)
471: {
473:   PetscTruth     isascii,isstring;

476:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
477:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
478:   if (isascii) {
479:     PetscViewerASCIIPushTab(viewer);
480:     PetscViewerASCIIPrintf(viewer,"Associated KSP object\n");
481:     PetscViewerASCIIPrintf(viewer,"------------------------------\n");
482:     KSPView(st->ksp,viewer);
483:     PetscViewerASCIIPrintf(viewer,"------------------------------\n");
484:     PetscViewerASCIIPopTab(viewer);
485:   } else if (isstring) {
486:     KSPView(st->ksp,viewer);
487:   }
488:   return(0);
489: }

491: /*MC
492:    STRegisterDynamic - Adds a method to the spectral transformation package.

494:    Synopsis:
495:    STRegisterDynamic(char *name_solver,char *path,char *name_create,int (*routine_create)(ST))

497:    Not collective

499:    Input Parameters:
500: +  name_solver - name of a new user-defined solver
501: .  path - path (either absolute or relative) the library containing this solver
502: .  name_create - name of routine to create method context
503: -  routine_create - routine to create method context

505:    Notes:
506:    STRegisterDynamic() may be called multiple times to add several user-defined spectral transformations.

508:    If dynamic libraries are used, then the fourth input argument (routine_create)
509:    is ignored.

511:    Sample usage:
512: .vb
513:    STRegisterDynamic("my_solver","/home/username/my_lib/lib/libO/solaris/mylib.a",
514:               "MySolverCreate",MySolverCreate);
515: .ve

517:    Then, your solver can be chosen with the procedural interface via
518: $     STSetType(st,"my_solver")
519:    or at runtime via the option
520: $     -st_type my_solver

522:    Level: advanced

524:    $PETSC_DIR, $PETSC_ARCH and $PETSC_LIB_DIR occuring in pathname will be replaced with appropriate values.

526: .seealso: STRegisterDestroy(), STRegisterAll()
527: M*/

531: /*@C
532:   STRegister - See STRegisterDynamic()

534:   Level: advanced
535: @*/
536: PetscErrorCode STRegister(const char *sname,const char *path,const char *name,int (*function)(ST))
537: {
539:   char           fullname[256];

542:   PetscFListConcat(path,name,fullname);
543:   PetscFListAdd(&STList,sname,fullname,(void (*)(void))function);
544:   return(0);
545: }

549: /*@
550:    STRegisterDestroy - Frees the list of ST methods that were
551:    registered by STRegisterDynamic().

553:    Not Collective

555:    Level: advanced

557: .seealso: STRegisterDynamic(), STRegisterAll()
558: @*/
559: PetscErrorCode STRegisterDestroy(void)
560: {

564:   PetscFListDestroy(&STList);
565:   STRegisterAll(PETSC_NULL);
566:   return(0);
567: }