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-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/stimpl.h>            /*I "slepcst.h" I*/

 26: PetscClassId     ST_CLASSID = 0;
 27: PetscLogEvent    ST_SetUp = 0,ST_Apply = 0,ST_ApplyTranspose = 0;
 28: static PetscBool STPackageInitialized = PETSC_FALSE;

 32: /*@C
 33:    STFinalizePackage - This function destroys everything in the Slepc interface 
 34:    to the ST package. It is called from SlepcFinalize().

 36:    Level: developer

 38: .seealso: SlepcFinalize()
 39: @*/
 40: PetscErrorCode STFinalizePackage(void)
 41: {
 43:   STPackageInitialized = PETSC_FALSE;
 44:   STList               = 0;
 45:   STRegisterAllCalled  = PETSC_FALSE;
 46:   return(0);
 47: }

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

 56:    Input Parameter:
 57: .  path - The dynamic library path, or PETSC_NULL

 59:    Level: developer

 61: .seealso: SlepcInitialize()
 62: @*/
 63: PetscErrorCode STInitializePackage(const char *path)
 64: {
 65:   char           logList[256];
 66:   char           *className;
 67:   PetscBool      opt;

 71:   if (STPackageInitialized) return(0);
 72:   STPackageInitialized = PETSC_TRUE;
 73:   /* Register Classes */
 74:   PetscClassIdRegister("Spectral Transform",&ST_CLASSID);
 75:   /* Register Constructors */
 76:   STRegisterAll(path);
 77:   /* Register Events */
 78:   PetscLogEventRegister("STSetUp",ST_CLASSID,&ST_SetUp);
 79:   PetscLogEventRegister("STApply",ST_CLASSID,&ST_Apply);
 80:   PetscLogEventRegister("STApplyTranspose",ST_CLASSID,&ST_ApplyTranspose);
 81:   /* Process info exclusions */
 82:   PetscOptionsGetString(PETSC_NULL,"-info_exclude",logList,256,&opt);
 83:   if (opt) {
 84:     PetscStrstr(logList,"st",&className);
 85:     if (className) {
 86:       PetscInfoDeactivateClass(ST_CLASSID);
 87:     }
 88:   }
 89:   /* Process summary exclusions */
 90:   PetscOptionsGetString(PETSC_NULL,"-log_summary_exclude",logList,256,&opt);
 91:   if (opt) {
 92:     PetscStrstr(logList,"st",&className);
 93:     if (className) {
 94:       PetscLogEventDeactivateClass(ST_CLASSID);
 95:     }
 96:   }
 97:   PetscRegisterFinalize(STFinalizePackage);
 98:   return(0);
 99: }

103: /*@
104:    STReset - Resets the ST context and removes any allocated objects.

106:    Collective on ST

108:    Input Parameter:
109: .  st - the spectral transformation context

111:    Level: advanced

113: .seealso: STDestroy()
114: @*/
115: PetscErrorCode STReset(ST st)
116: {

121:   if (st->ops->reset) { (*st->ops->reset)(st); }
122:   if (st->ksp) { KSPReset(st->ksp); }
123:   MatDestroy(&st->A);
124:   MatDestroy(&st->B);
125:   VecDestroy(&st->w);
126:   VecDestroy(&st->D);
127:   VecDestroy(&st->wb);
128:   if (st->shift_matrix != ST_MATMODE_INPLACE) {
129:     MatDestroy(&st->mat);
130:   }
131:   STResetOperationCounters(st);
132:   st->setupcalled = 0;
133:   return(0);
134: }

138: /*@C
139:    STDestroy - Destroys ST context that was created with STCreate().

141:    Collective on ST

143:    Input Parameter:
144: .  st - the spectral transformation context

146:    Level: beginner

148: .seealso: STCreate(), STSetUp()
149: @*/
150: PetscErrorCode STDestroy(ST *st)
151: {

155:   if (!*st) return(0);
157:   if (--((PetscObject)(*st))->refct > 0) { *st = 0; return(0); }
158:   STReset(*st);
159:   PetscObjectDepublish(*st);
160:   if ((*st)->ops->destroy) { (*(*st)->ops->destroy)(*st); }
161:   KSPDestroy(&(*st)->ksp);
162:   PetscHeaderDestroy(st);
163:   return(0);
164: }

168: /*@C
169:    STCreate - Creates a spectral transformation context.

171:    Collective on MPI_Comm

173:    Input Parameter:
174: .  comm - MPI communicator 

176:    Output Parameter:
177: .  st - location to put the spectral transformation context

179:    Level: beginner

181: .seealso: STSetUp(), STApply(), STDestroy(), ST
182: @*/
183: PetscErrorCode STCreate(MPI_Comm comm,ST *newst)
184: {
186:   ST             st;

190:   *newst = 0;
191:   PetscHeaderCreate(st,_p_ST,struct _STOps,ST_CLASSID,-1,"ST","Spectral Transformation","ST",comm,STDestroy,STView);
192:   st->A                   = 0;
193:   st->B                   = 0;
194:   st->sigma               = 0.0;
195:   st->sigma_set           = PETSC_FALSE;
196:   st->defsigma            = 0.0;
197:   st->data                = 0;
198:   st->setupcalled         = 0;
199:   st->w                   = 0;
200:   st->D                   = 0;
201:   st->wb                  = 0;
202:   st->mat                 = 0;
203:   st->shift_matrix        = ST_MATMODE_COPY;
204:   st->str                 = DIFFERENT_NONZERO_PATTERN;
205:   *newst = st;
206:   return(0);
207: }

211: /*@
212:    STSetOperators - Sets the matrices associated with the eigenvalue problem. 

214:    Collective on ST and Mat

216:    Input Parameters:
217: +  st - the spectral transformation context
218: .  A  - the matrix associated with the eigensystem
219: -  B  - the second matrix in the case of generalized eigenproblems

221:    Notes:
222:    To specify a standard eigenproblem, use PETSC_NULL for B.

224:    It must be called after STSetUp(). If it is called again after STSetUp() then
225:    the ST object is reset.

227:    Level: intermediate

229: .seealso: STGetOperators(), STSetUp(), STReset()
230:  @*/
231: PetscErrorCode STSetOperators(ST st,Mat A,Mat B)
232: {

241:   if (st->setupcalled) { STReset(st); }
242:   MatDestroy(&st->A);
243:   PetscObjectReference((PetscObject)A);
244:   st->A = A;
245:   MatDestroy(&st->B);
246:   if (B) { PetscObjectReference((PetscObject)B); }
247:   st->B = B;
248:   return(0);
249: }

253: /*@C
254:    STGetOperators - Gets the matrices associated with the eigensystem.

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

258:    Input Parameter:
259: .  st - the spectral transformation context

261:    Output Parameters:
262: .  A - the matrix associated with the eigensystem
263: -  B - the second matrix in the case of generalized eigenproblems

265:    Level: intermediate

267: .seealso: STSetOperators()
268: @*/
269: PetscErrorCode STGetOperators(ST st,Mat *A,Mat *B)
270: {
273:   if (A) *A = st->A;
274:   if (B) *B = st->B;
275:   return(0);
276: }

280: /*@
281:    STSetShift - Sets the shift associated with the spectral transformation.

283:    Logically Collective on ST

285:    Input Parameters:
286: +  st - the spectral transformation context
287: -  shift - the value of the shift

289:    Note:
290:    In some spectral transformations, changing the shift may have associated
291:    a lot of work, for example recomputing a factorization.
292:    
293:    Level: beginner

295: @*/
296: PetscErrorCode STSetShift(ST st,PetscScalar shift)
297: {

303:   if (st->sigma != shift) {
304:     if (st->ops->setshift) {
305:       (*st->ops->setshift)(st,shift);
306:     }
307:   }
308:   st->sigma = shift;
309:   st->sigma_set = PETSC_TRUE;
310:   return(0);
311: }

315: /*@
316:    STGetShift - Gets the shift associated with the spectral transformation.

318:    Not Collective

320:    Input Parameter:
321: .  st - the spectral transformation context

323:    Output Parameter:
324: .  shift - the value of the shift

326:    Level: beginner

328: @*/
329: PetscErrorCode STGetShift(ST st,PetscScalar* shift)
330: {
334:   *shift = st->sigma;
335:   return(0);
336: }

340: /*@
341:    STSetDefaultShift - Sets the value of the shift that should be employed if
342:    the user did not specify one.

344:    Logically Collective on ST

346:    Input Parameters:
347: +  st - the spectral transformation context
348: -  defaultshift - the default value of the shift

350:    Level: developer

352: @*/
353: PetscErrorCode STSetDefaultShift(ST st,PetscScalar defaultshift)
354: {
358:   st->defsigma = defaultshift;
359:   return(0);
360: }

364: /*@
365:    STSetBalanceMatrix - Sets the diagonal matrix to be used for balancing.

367:    Collective on ST and Vec

369:    Input Parameters:
370: +  st - the spectral transformation context
371: -  D  - the diagonal matrix (represented as a vector)

373:    Notes:
374:    If this matrix is set, STApply will effectively apply D*OP*D^{-1}.

376:    Balancing is usually set via EPSSetBalance, but the advanced user may use
377:    this function to bypass the usual balancing methods.
378:    
379:    Level: developer

381: .seealso: EPSSetBalance(), STApply(), STGetBalanceMatrix()
382: @*/
383: PetscErrorCode STSetBalanceMatrix(ST st,Vec D)
384: {

391:   PetscObjectReference((PetscObject)D);
392:   VecDestroy(&st->D);
393:   st->D = D;
394:   st->setupcalled = 0;
395:   return(0);
396: }

400: /*@
401:    STGetBalanceMatrix - Gets the balance matrix used by the spectral transformation.

403:    Not collective, but vector is shared by all processors that share the ST

405:    Input Parameter:
406: .  st - the spectral transformation context

408:    Output Parameter:
409: .  D  - the diagonal matrix (represented as a vector)

411:    Note:
412:    If the matrix was not set, a null pointer will be returned.

414:    Level: developer

416: .seealso: STSetBalanceMatrix()
417: @*/
418: PetscErrorCode STGetBalanceMatrix(ST st,Vec *D)
419: {
423:   *D = st->D;
424:   return(0);
425: }

429: /*@C
430:    STSetOptionsPrefix - Sets the prefix used for searching for all 
431:    ST options in the database.

433:    Logically Collective on ST

435:    Input Parameters:
436: +  st     - the spectral transformation context
437: -  prefix - the prefix string to prepend to all ST option requests

439:    Notes:
440:    A hyphen (-) must NOT be given at the beginning of the prefix name.
441:    The first character of all runtime options is AUTOMATICALLY the
442:    hyphen.

444:    Level: advanced

446: .seealso: STAppendOptionsPrefix(), STGetOptionsPrefix()
447: @*/
448: PetscErrorCode STSetOptionsPrefix(ST st,const char *prefix)
449: {

454:   if (!st->ksp) { STGetKSP(st,&st->ksp); }
455:   KSPSetOptionsPrefix(st->ksp,prefix);
456:   KSPAppendOptionsPrefix(st->ksp,"st_");
457:   PetscObjectSetOptionsPrefix((PetscObject)st,prefix);
458:   return(0);
459: }

463: /*@C
464:    STAppendOptionsPrefix - Appends to the prefix used for searching for all 
465:    ST options in the database.

467:    Logically Collective on ST

469:    Input Parameters:
470: +  st     - the spectral transformation context
471: -  prefix - the prefix string to prepend to all ST option requests

473:    Notes:
474:    A hyphen (-) must NOT be given at the beginning of the prefix name.
475:    The first character of all runtime options is AUTOMATICALLY the
476:    hyphen.

478:    Level: advanced

480: .seealso: STSetOptionsPrefix(), STGetOptionsPrefix()
481: @*/
482: PetscErrorCode STAppendOptionsPrefix(ST st,const char *prefix)
483: {

488:   if (!st->ksp) { STGetKSP(st,&st->ksp); }
489:   KSPSetOptionsPrefix(st->ksp,((PetscObject)st)->prefix);
490:   KSPAppendOptionsPrefix(st->ksp,"st_");
491:   PetscObjectAppendOptionsPrefix((PetscObject)st,prefix);
492:   return(0);
493: }

497: /*@C
498:    STGetOptionsPrefix - Gets the prefix used for searching for all 
499:    ST options in the database.

501:    Not Collective

503:    Input Parameters:
504: .  st - the spectral transformation context

506:    Output Parameters:
507: .  prefix - pointer to the prefix string used, is returned

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

512:    Level: advanced

514: .seealso: STSetOptionsPrefix(), STAppendOptionsPrefix()
515: @*/
516: PetscErrorCode STGetOptionsPrefix(ST st,const char *prefix[])
517: {

523:   PetscObjectGetOptionsPrefix((PetscObject)st,prefix);
524:   return(0);
525: }

529: /*@C
530:    STView - Prints the ST data structure.

532:    Collective on ST

534:    Input Parameters:
535: +  ST - the ST context
536: -  viewer - optional visualization context

538:    Note:
539:    The available visualization contexts include
540: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
541: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
542:          output where only the first processor opens
543:          the file.  All other processors send their 
544:          data to the first processor to print. 

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

549:    Level: beginner

551: .seealso: EPSView(), PetscViewerASCIIOpen()
552: @*/
553: PetscErrorCode STView(ST st,PetscViewer viewer)
554: {
555:   PetscErrorCode    ierr;
556:   const STType      cstr;
557:   const char*       str;
558:   PetscBool         isascii,isstring,flg;
559:   PC                pc;

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

567:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
568:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
569:   if (isascii) {
570:     PetscObjectPrintClassNamePrefixType((PetscObject)st,viewer,"ST Object");
571:     if (st->ops->view) {
572:       PetscViewerASCIIPushTab(viewer);
573:       (*st->ops->view)(st,viewer);
574:       PetscViewerASCIIPopTab(viewer);
575:     }
576: #if !defined(PETSC_USE_COMPLEX)
577:     PetscViewerASCIIPrintf(viewer,"  shift: %G\n",st->sigma);
578: #else
579:     PetscViewerASCIIPrintf(viewer,"  shift: %G+%G i\n",PetscRealPart(st->sigma),PetscImaginaryPart(st->sigma));
580: #endif
581:     switch (st->shift_matrix) {
582:     case ST_MATMODE_COPY:
583:       break;
584:     case ST_MATMODE_INPLACE:
585:       PetscViewerASCIIPrintf(viewer,"  shifting the matrix and unshifting at exit\n");
586:       break;
587:     case ST_MATMODE_SHELL:
588:       PetscViewerASCIIPrintf(viewer,"  using a shell matrix\n");
589:       break;
590:     }
591:     if (st->B && st->shift_matrix != ST_MATMODE_SHELL) {
592:       switch (st->str) {
593:         case SAME_NONZERO_PATTERN:      str = "same nonzero pattern";break;
594:         case DIFFERENT_NONZERO_PATTERN: str = "different nonzero pattern";break;
595:         case SUBSET_NONZERO_PATTERN:    str = "subset nonzero pattern";break;
596:         default:                        SETERRQ(((PetscObject)st)->comm,1,"Wrong structure flag");
597:       }
598:       PetscViewerASCIIPrintf(viewer,"  matrices A and B have %s\n",str);
599:     }
600:   } else if (isstring) {
601:     STGetType(st,&cstr);
602:     PetscViewerStringSPrintf(viewer," %-7.7s",cstr);
603:     if (st->ops->view) {(*st->ops->view)(st,viewer);}
604:   } else {
605:     SETERRQ1(((PetscObject)st)->comm,1,"Viewer type %s not supported by ST",((PetscObject)viewer)->type_name);
606:   }
607:   PetscTypeCompareAny((PetscObject)st,&flg,STSHIFT,STFOLD,"");
608:   if (st->B || !flg) {
609:     if (!st->ksp) { STGetKSP(st,&st->ksp); }
610:     /* Trick for PCView when an unused PC is showed */
611:     KSPGetPC(st->ksp,&pc);
612:     PetscTypeCompare((PetscObject)pc,PCNONE,&flg);
613:     if (flg) {
614:       PCSetOperators(pc,PETSC_NULL,PETSC_NULL,DIFFERENT_NONZERO_PATTERN);
615:     }
616:     PetscViewerASCIIPushTab(viewer);
617:     KSPView(st->ksp,viewer);
618:     PetscViewerASCIIPopTab(viewer);
619:   }
620:   return(0);
621: }

625: /*@C
626:    STRegister - See STRegisterDynamic()

628:    Level: advanced
629: @*/
630: PetscErrorCode STRegister(const char *sname,const char *path,const char *name,PetscErrorCode (*function)(ST))
631: {
633:   char           fullname[PETSC_MAX_PATH_LEN];

636:   PetscFListConcat(path,name,fullname);
637:   PetscFListAdd(&STList,sname,fullname,(void (*)(void))function);
638:   return(0);
639: }

643: /*@
644:    STRegisterDestroy - Frees the list of ST methods that were
645:    registered by STRegisterDynamic().

647:    Not Collective

649:    Level: advanced

651: .seealso: STRegisterDynamic(), STRegisterAll()
652: @*/
653: PetscErrorCode STRegisterDestroy(void)
654: {

658:   PetscFListDestroy(&STList);
659:   STRegisterAllCalled = PETSC_FALSE;
660:   return(0);
661: }