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-2009, 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/stimpl.h

 26: PetscCookie ST_COOKIE = 0;
 27: PetscLogEvent ST_SetUp = 0, ST_Apply = 0, ST_ApplyTranspose = 0;

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

 36:   Input Parameter:
 37:   path - The dynamic library path, or PETSC_NULL

 39:   Level: developer

 41: .seealso: SlepcInitialize()
 42: @*/
 43: PetscErrorCode STInitializePackage(char *path) {
 44:   static PetscTruth initialized = PETSC_FALSE;
 45:   char              logList[256];
 46:   char             *className;
 47:   PetscTruth        opt;

 51:   if (initialized) return(0);
 52:   initialized = PETSC_TRUE;
 53:   /* Register Classes */
 54:   PetscCookieRegister("Spectral Transform",&ST_COOKIE);
 55:   /* Register Constructors */
 56:   STRegisterAll(path);
 57:   /* Register Events */
 58:   PetscLogEventRegister("STSetUp",ST_COOKIE,&ST_SetUp);
 59:   PetscLogEventRegister("STApply",ST_COOKIE,&ST_Apply);
 60:   PetscLogEventRegister("STApplyTranspose",ST_COOKIE,&ST_ApplyTranspose);
 61:   /* Process info exclusions */
 62:   PetscOptionsGetString(PETSC_NULL, "-log_info_exclude", logList, 256, &opt);
 63:   if (opt) {
 64:     PetscStrstr(logList, "st", &className);
 65:     if (className) {
 66:       PetscInfoDeactivateClass(ST_COOKIE);
 67:     }
 68:   }
 69:   /* Process summary exclusions */
 70:   PetscOptionsGetString(PETSC_NULL, "-log_summary_exclude", logList, 256, &opt);
 71:   if (opt) {
 72:     PetscStrstr(logList, "st", &className);
 73:     if (className) {
 74:       PetscLogEventDeactivateClass(ST_COOKIE);
 75:     }
 76:   }
 77:   return(0);
 78: }

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

 85:    Collective on ST

 87:    Input Parameter:
 88: .  st - the spectral transformation context

 90:    Level: beginner

 92: .seealso: STCreate(), STSetUp()
 93: @*/
 94: PetscErrorCode STDestroy(ST st)
 95: {

100:   if (--((PetscObject)st)->refct > 0) return(0);

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

105:   if (st->ops->destroy) { (*st->ops->destroy)(st); }
106:   if (st->A) { MatDestroy(st->A); }
107:   if (st->B) { MatDestroy(st->B); }
108:   if (st->ksp) { KSPDestroy(st->ksp); }
109:   if (st->w) { VecDestroy(st->w); }
110:   if (st->shift_matrix != STMATMODE_INPLACE && st->mat) {
111:     MatDestroy(st->mat);
112:   }

114:   PetscHeaderDestroy(st);
115:   return(0);
116: }

120: /*@C
121:    STCreate - Creates a spectral transformation context.

123:    Collective on MPI_Comm

125:    Input Parameter:
126: .  comm - MPI communicator 

128:    Output Parameter:
129: .  st - location to put the spectral transformation context

131:    Level: beginner

133: .seealso: STSetUp(), STApply(), STDestroy(), ST
134: @*/
135: PetscErrorCode STCreate(MPI_Comm comm,ST *newst)
136: {
138:   ST             st;
139:   const char     *prefix;

143:   *newst = 0;

145:   PetscHeaderCreate(st,_p_ST,struct _STOps,ST_COOKIE,-1,"ST",comm,STDestroy,STView);
146:   PetscMemzero(st->ops,sizeof(struct _STOps));

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

167: }

171: /*@
172:    STSetOperators - Sets the matrices associated with the eigenvalue problem. 

174:    Collective on ST and Mat

176:    Input Parameters:
177: +  st - the spectral transformation context
178: .  A  - the matrix associated with the eigensystem
179: -  B  - the second matrix in the case of generalized eigenproblems

181:    Notes:
182:    To specify a standard eigenproblem, use PETSC_NULL for B.

184:    Level: intermediate

186: .seealso: STGetOperators()
187:  @*/
188: PetscErrorCode STSetOperators(ST st,Mat A,Mat B)
189: {
197:   PetscObjectReference((PetscObject)A);
198:   if (st->A) { MatDestroy(st->A); }
199:   st->A = A;
200:   if (B) { PetscObjectReference((PetscObject)B); }
201:   if (st->B) { MatDestroy(st->B); }
202:   st->B = B;
203:   st->setupcalled = 0;
204:   return(0);
205: }

209: /*@C
210:    STGetOperators - Gets the matrices associated with the eigensystem.

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

214:    Input Parameter:
215: .  st - the spectral transformation context

217:    Output Parameters:
218: .  A - the matrix associated with the eigensystem
219: -  B - the second matrix in the case of generalized eigenproblems

221:    Level: intermediate

223: .seealso: STSetOperators()
224: @*/
225: PetscErrorCode STGetOperators(ST st,Mat *A,Mat *B)
226: {
229:   if (A) *A = st->A;
230:   if (B) *B = st->B;
231:   return(0);
232: }

236: /*@
237:    STSetShift - Sets the shift associated with the spectral transformation

239:    Not collective

241:    Input Parameters:
242: +  st - the spectral transformation context
243: -  shift - the value of the shift

245:    Note:
246:    In some spectral transformations, changing the shift may have associated
247:    a lot of work, for example recomputing a factorization.
248:    
249:    Level: beginner

251: @*/
252: PetscErrorCode STSetShift(ST st,PetscScalar shift)
253: {

258:   if (st->sigma != shift) {
259:     if (st->ops->setshift) {
260:       (*st->ops->setshift)(st,shift);
261:     }
262:   }
263:   st->sigma = shift;
264:   return(0);
265: }

269: /*@
270:    STGetShift - Gets the shift associated with the spectral transformation.

272:    Not collective

274:    Input Parameter:
275: .  st - the spectral transformation context

277:    Output Parameter:
278: .  shift - the value of the shift

280:    Level: beginner

282: @*/
283: PetscErrorCode STGetShift(ST st,PetscScalar* shift)
284: {
287:   if (shift)  *shift = st->sigma;
288:   return(0);
289: }

293: /*@C
294:    STSetOptionsPrefix - Sets the prefix used for searching for all 
295:    ST options in the database.

297:    Collective on ST

299:    Input Parameters:
300: +  st     - the spectral transformation context
301: -  prefix - the prefix string to prepend to all ST option requests

303:    Notes:
304:    A hyphen (-) must NOT be given at the beginning of the prefix name.
305:    The first character of all runtime options is AUTOMATICALLY the
306:    hyphen.

308:    Level: advanced

310: .seealso: STAppendOptionsPrefix(), STGetOptionsPrefix()
311: @*/
312: PetscErrorCode STSetOptionsPrefix(ST st,const char *prefix)
313: {

318:   PetscObjectSetOptionsPrefix((PetscObject)st,prefix);
319:   KSPSetOptionsPrefix(st->ksp,prefix);
320:   KSPAppendOptionsPrefix(st->ksp,"st_");
321:   return(0);
322: }

326: /*@C
327:    STAppendOptionsPrefix - Appends to the prefix used for searching for all 
328:    ST options in the database.

330:    Collective on ST

332:    Input Parameters:
333: +  st     - the spectral transformation context
334: -  prefix - the prefix string to prepend to all ST option requests

336:    Notes:
337:    A hyphen (-) must NOT be given at the beginning of the prefix name.
338:    The first character of all runtime options is AUTOMATICALLY the
339:    hyphen.

341:    Level: advanced

343: .seealso: STSetOptionsPrefix(), STGetOptionsPrefix()
344: @*/
345: PetscErrorCode STAppendOptionsPrefix(ST st,const char *prefix)
346: {

351:   PetscObjectAppendOptionsPrefix((PetscObject)st,prefix);
352:   KSPSetOptionsPrefix(st->ksp,((PetscObject)st)->prefix);
353:   KSPAppendOptionsPrefix(st->ksp,"st_");
354:   return(0);
355: }

359: /*@C
360:    STGetOptionsPrefix - Gets the prefix used for searching for all 
361:    ST options in the database.

363:    Not Collective

365:    Input Parameters:
366: .  st - the spectral transformation context

368:    Output Parameters:
369: .  prefix - pointer to the prefix string used, is returned

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

374:    Level: advanced

376: .seealso: STSetOptionsPrefix(), STAppendOptionsPrefix()
377: @*/
378: PetscErrorCode STGetOptionsPrefix(ST st,const char *prefix[])
379: {

384:   PetscObjectGetOptionsPrefix((PetscObject)st, prefix);
385:   return(0);
386: }

390: /*@C
391:    STView - Prints the ST data structure.

393:    Collective on ST

395:    Input Parameters:
396: +  ST - the ST context
397: -  viewer - optional visualization context

399:    Note:
400:    The available visualization contexts include
401: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
402: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
403:          output where only the first processor opens
404:          the file.  All other processors send their 
405:          data to the first processor to print. 

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

410:    Level: beginner

412: .seealso: EPSView(), PetscViewerASCIIOpen()
413: @*/
414: PetscErrorCode STView(ST st,PetscViewer viewer)
415: {
416:   PetscErrorCode    ierr;
417:   const STType      cstr;
418:   const char*       str;
419:   PetscTruth        isascii,isstring;
420:   PetscViewerFormat format;

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

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

480: PetscErrorCode STView_Default(ST st,PetscViewer viewer)
481: {
483:   PetscTruth     isascii,isstring;

486:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
487:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
488:   if (isascii) {
489:     PetscViewerASCIIPushTab(viewer);
490:     PetscViewerASCIIPrintf(viewer,"Associated KSP object\n");
491:     PetscViewerASCIIPrintf(viewer,"------------------------------\n");
492:     KSPView(st->ksp,viewer);
493:     PetscViewerASCIIPrintf(viewer,"------------------------------\n");
494:     PetscViewerASCIIPopTab(viewer);
495:   } else if (isstring) {
496:     KSPView(st->ksp,viewer);
497:   }
498:   return(0);
499: }

501: /*MC
502:    STRegisterDynamic - Adds a method to the spectral transformation package.

504:    Synopsis:
505:    STRegisterDynamic(char *name_solver,char *path,char *name_create,PetscErrorCode (*routine_create)(ST))

507:    Not collective

509:    Input Parameters:
510: +  name_solver - name of a new user-defined solver
511: .  path - path (either absolute or relative) the library containing this solver
512: .  name_create - name of routine to create method context
513: -  routine_create - routine to create method context

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

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

521:    Sample usage:
522: .vb
523:    STRegisterDynamic("my_solver","/home/username/my_lib/lib/libO/solaris/mylib.a",
524:               "MySolverCreate",MySolverCreate);
525: .ve

527:    Then, your solver can be chosen with the procedural interface via
528: $     STSetType(st,"my_solver")
529:    or at runtime via the option
530: $     -st_type my_solver

532:    Level: advanced

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

536: .seealso: STRegisterDestroy(), STRegisterAll()
537: M*/

541: /*@C
542:   STRegister - See STRegisterDynamic()

544:   Level: advanced
545: @*/
546: PetscErrorCode STRegister(const char *sname,const char *path,const char *name,PetscErrorCode (*function)(ST))
547: {
549:   char           fullname[256];

552:   PetscFListConcat(path,name,fullname);
553:   PetscFListAdd(&STList,sname,fullname,(void (*)(void))function);
554:   return(0);
555: }

559: /*@
560:    STRegisterDestroy - Frees the list of ST methods that were
561:    registered by STRegisterDynamic().

563:    Not Collective

565:    Level: advanced

567: .seealso: STRegisterDynamic(), STRegisterAll()
568: @*/
569: PetscErrorCode STRegisterDestroy(void)
570: {

574:   PetscFListDestroy(&STList);
575:   STRegisterAll(PETSC_NULL);
576:   return(0);
577: }