Actual source code: stfunc.c

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

 6:  #include src/st/stimpl.h

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

 13:    Collective on ST

 15:    Input Parameter:
 16: .  st - the spectral transformation context

 18:    Level: beginner

 20: .seealso: STCreate(), STSetUp()
 21: @*/
 22: PetscErrorCode STDestroy(ST st)
 23: {
 24:   PetscErrorCode ierr;

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

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

 33:   if (st->ops->destroy) { (*st->ops->destroy)(st); }
 34:   if (st->ksp) { KSPDestroy(st->ksp); }
 35:   if (st->w) { VecDestroy(st->w); }
 36:   if (st->Bx) { VecDestroy(st->Bx); }
 37:   if (st->shift_matrix != STMATMODE_INPLACE && st->mat) {
 38:     MatDestroy(st->mat);
 39:   }

 41:   PetscLogObjectDestroy(st);
 42:   PetscHeaderDestroy(st);
 43:   return(0);
 44: }

 48: static PetscErrorCode STPublish_Petsc(PetscObject object)
 49: {
 51:   return(0);
 52: }

 56: /*@C
 57:    STCreate - Creates a spectral transformation context.

 59:    Collective on MPI_Comm

 61:    Input Parameter:
 62: .  comm - MPI communicator 

 64:    Output Parameter:
 65: .  st - location to put the spectral transformation context

 67:    Level: beginner

 69: .seealso: STSetUp(), STApply(), STDestroy()
 70: @*/
 71: PetscErrorCode STCreate(MPI_Comm comm,ST *newst)
 72: {
 73:   PetscErrorCode ierr;
 74:   ST             st;
 75:   char*          prefix;

 79:   *newst = 0;
 80: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
 81:   PCRegisterAll(PETSC_NULL);
 82: #endif

 84:   PetscHeaderCreate(st,_p_ST,struct _STOps,ST_COOKIE,-1,"ST",comm,STDestroy,STView);
 85:   PetscLogObjectCreate(st);
 86:   st->bops->publish       = STPublish_Petsc;
 87:   PetscMemzero(st->ops,sizeof(struct _STOps));

 89:   st->A                   = 0;
 90:   st->B                   = 0;
 91:   st->sigma               = 0.0;
 92:   st->data                = 0;
 93:   st->setupcalled         = 0;
 94:   st->w                   = 0;
 95:   st->shift_matrix        = STMATMODE_COPY;
 96:   st->bilinear_form       = STINNER_HERMITIAN;
 97:   st->str                 = DIFFERENT_NONZERO_PATTERN;
 98: 
 99:   KSPCreate(st->comm,&st->ksp);
100:   STGetOptionsPrefix(st,&prefix);
101:   KSPSetOptionsPrefix(st->ksp,prefix);
102:   KSPAppendOptionsPrefix(st->ksp,"st_");
103: 
104:   *newst                  = st;
105:   PetscPublishAll(st);
106:   return(0);

108: }

112: /*@
113:    STSetOperators - Sets the matrices associated with the eigenvalue problem. 

115:    Collective on ST and Mat

117:    Input Parameters:
118: +  st - the spectral transformation context
119: .  A  - the matrix associated with the eigensystem
120: -  B  - the second matrix in the case of generalized eigenproblems

122:    Notes:
123:    To specify a standard eigenproblem, use PETSC_NULL for B.

125:    Level: intermediate

127: .seealso: STGetOperators()
128:  @*/
129: PetscErrorCode STSetOperators(ST st,Mat A,Mat B)
130: {
135:   st->A = A;
136:   st->B = B;
137:   st->setupcalled = 0;
138:   return(0);
139: }

143: /*@C
144:    STGetOperators - Gets the matrices associated with the eigensystem.

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

148:    Input Parameter:
149: .  st - the spectral transformation context

151:    Output Parameters:
152: .  A - the matrix associated with the eigensystem
153: -  B - the second matrix in the case of generalized eigenproblems

155:    Level: intermediate

157: .seealso: STSetOperators()
158: @*/
159: PetscErrorCode STGetOperators(ST st,Mat *A,Mat *B)
160: {
163:   if (A) *A = st->A;
164:   if (B) *B = st->B;
165:   return(0);
166: }

170: /*@
171:    STSetShift - Sets the shift associated with the spectral transformation

173:    Not collective

175:    Input Parameters:
176: +  st - the spectral transformation context
177: -  shift - the value of the shift

179:    Note:
180:    In some spectral transformations, changing the shift may have associated
181:    a lot of work, for example recomputing a factorization.
182:    
183:    Level: beginner

185: @*/
186: PetscErrorCode STSetShift(ST st,PetscScalar shift)
187: {
188:   PetscErrorCode ierr;

192:   if (st->sigma != shift) {
193:     if (st->ops->setshift) {
194:       (*st->ops->setshift)(st,shift);
195:     }
196:   }
197:   st->sigma = shift;
198:   return(0);
199: }

203: /*@
204:    STGetShift - Gets the shift associated with the spectral transformation.

206:    Not collective

208:    Input Parameter:
209: .  st - the spectral transformation context

211:    Output Parameter:
212: .  shift - the value of the shift

214:    Level: beginner

216: @*/
217: PetscErrorCode STGetShift(ST st,PetscScalar* shift)
218: {
221:   if (shift)  *shift = st->sigma;
222:   return(0);
223: }

227: /*@C
228:    STSetOptionsPrefix - Sets the prefix used for searching for all 
229:    ST options in the database.

231:    Collective on ST

233:    Input Parameters:
234: +  st     - the spectral transformation context
235: -  prefix - the prefix string to prepend to all ST option requests

237:    Notes:
238:    A hyphen (-) must NOT be given at the beginning of the prefix name.
239:    The first character of all runtime options is AUTOMATICALLY the
240:    hyphen.

242:    Level: advanced

244: .seealso: STAppendOptionsPrefix(), STGetOptionsPrefix()
245: @*/
246: PetscErrorCode STSetOptionsPrefix(ST st,char *prefix)
247: {
248:   PetscErrorCode ierr;

252:   PetscObjectSetOptionsPrefix((PetscObject)st, prefix);
253:   return(0);
254: }

258: /*@C
259:    STAppendOptionsPrefix - Appends to the prefix used for searching for all 
260:    ST options in the database.

262:    Collective on ST

264:    Input Parameters:
265: +  st     - the spectral transformation context
266: -  prefix - the prefix string to prepend to all ST option requests

268:    Notes:
269:    A hyphen (-) must NOT be given at the beginning of the prefix name.
270:    The first character of all runtime options is AUTOMATICALLY the
271:    hyphen.

273:    Level: advanced

275: .seealso: STSetOptionsPrefix(), STGetOptionsPrefix()
276: @*/
277: PetscErrorCode STAppendOptionsPrefix(ST st,char *prefix)
278: {
279:   PetscErrorCode ierr;

283:   PetscObjectAppendOptionsPrefix((PetscObject)st, prefix);
284:   return(0);
285: }

289: /*@C
290:    STGetOptionsPrefix - Gets the prefix used for searching for all 
291:    ST options in the database.

293:    Not Collective

295:    Input Parameters:
296: .  st - the spectral transformation context

298:    Output Parameters:
299: .  prefix - pointer to the prefix string used, is returned

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

304:    Level: advanced

306: .seealso: STSetOptionsPrefix(), STAppendOptionsPrefix()
307: @*/
308: PetscErrorCode STGetOptionsPrefix(ST st,char **prefix)
309: {
310:   PetscErrorCode ierr;

314:   PetscObjectGetOptionsPrefix((PetscObject)st, prefix);
315:   return(0);
316: }

320: /*@C
321:    STView - Prints the ST data structure.

323:    Collective on ST

325:    Input Parameters:
326: +  ST - the ST context
327: -  viewer - optional visualization context

329:    Note:
330:    The available visualization contexts include
331: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
332: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
333:          output where only the first processor opens
334:          the file.  All other processors send their 
335:          data to the first processor to print. 

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

340:    Level: beginner

342: .seealso: EPSView(), PetscViewerASCIIOpen()
343: @*/
344: PetscErrorCode STView(ST st,PetscViewer viewer)
345: {
346:   PetscErrorCode    ierr;
347:   STType            cstr;
348:   char*             str;
349:   PetscTruth        isascii,isstring;
350:   PetscViewerFormat format;

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

358:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
359:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
360:   if (isascii) {
361:     PetscViewerGetFormat(viewer,&format);
362:     PetscViewerASCIIPrintf(viewer,"ST Object:\n");
363:     STGetType(st,&cstr);
364:     if (cstr) {
365:       PetscViewerASCIIPrintf(viewer,"  type: %s\n",cstr);
366:     } else {
367:       PetscViewerASCIIPrintf(viewer,"  type: not yet set\n");
368:     }
369: #if !defined(PETSC_USE_COMPLEX)
370:     PetscViewerASCIIPrintf(viewer,"  shift: %g\n",st->sigma);
371: #else
372:     PetscViewerASCIIPrintf(viewer,"  shift: %g+%g i\n",PetscRealPart(st->sigma),PetscImaginaryPart(st->sigma));
373: #endif
374:     switch (st->shift_matrix) {
375:     case STMATMODE_COPY:
376:       break;
377:     case STMATMODE_INPLACE:
378:       PetscViewerASCIIPrintf(viewer,"Shifting the matrix and unshifting at exit\n");
379:       break;
380:     case STMATMODE_SHELL:
381:       PetscViewerASCIIPrintf(viewer,"Using a shell matrix\n");
382:       break;
383:     }
384:     if (st->B && st->shift_matrix != STMATMODE_SHELL) {
385:       switch (st->str) {
386:         case SAME_NONZERO_PATTERN:      str = "same nonzero pattern";break;
387:         case DIFFERENT_NONZERO_PATTERN: str = "different nonzero pattern";break;
388:         case SUBSET_NONZERO_PATTERN:    str = "subset nonzero pattern";break;
389:         default:                        SETERRQ(1,"Wrong structure flag");break;
390:       }
391:       PetscViewerASCIIPrintf(viewer,"Matrices A and B have %s\n",str);
392:     }
393:     if (st->ops->view) {
394:       PetscViewerASCIIPushTab(viewer);
395:       (*st->ops->view)(st,viewer);
396:       PetscViewerASCIIPopTab(viewer);
397:     }
398:   } else if (isstring) {
399:     STGetType(st,&cstr);
400:     PetscViewerStringSPrintf(viewer," %-7.7s",cstr);
401:     if (st->ops->view) {(*st->ops->view)(st,viewer);}
402:   } else {
403:     SETERRQ1(1,"Viewer type %s not supported by ST",((PetscObject)viewer)->type_name);
404:   }
405:   return(0);
406: }

410: PetscErrorCode STView_Default(ST st,PetscViewer viewer)
411: {
412:   PetscErrorCode ierr;
413:   PetscTruth     isascii,isstring;

416:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
417:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
418:   if (isascii) {
419:     PetscViewerASCIIPushTab(viewer);
420:     PetscViewerASCIIPrintf(viewer,"Associated KSP object\n");
421:     PetscViewerASCIIPrintf(viewer,"------------------------------\n");
422:     KSPView(st->ksp,viewer);
423:     PetscViewerASCIIPrintf(viewer,"------------------------------\n");
424:     PetscViewerASCIIPopTab(viewer);
425:   } else if (isstring) {
426:     KSPView(st->ksp,viewer);
427:   }
428:   return(0);
429: }

431: /*MC
432:    STRegisterDynamic - Adds a method to the spectral transformation package.

434:    Synopsis:
435:    STRegisterDynamic(char *name_solver,char *path,char *name_create,int (*routine_create)(ST))

437:    Not collective

439:    Input Parameters:
440: +  name_solver - name of a new user-defined solver
441: .  path - path (either absolute or relative) the library containing this solver
442: .  name_create - name of routine to create method context
443: -  routine_create - routine to create method context

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

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

451:    Sample usage:
452: .vb
453:    STRegisterDynamic("my_solver","/home/username/my_lib/lib/libO/solaris/mylib.a",
454:               "MySolverCreate",MySolverCreate);
455: .ve

457:    Then, your solver can be chosen with the procedural interface via
458: $     STSetType(st,"my_solver")
459:    or at runtime via the option
460: $     -st_type my_solver

462:    Level: advanced

464:    $SLEPC_DIR, $PETSC_ARCH and $BOPT occuring in pathname will be replaced with appropriate values.

466: .seealso: STRegisterAll(), STRegisterDestroy(), STRegister()
467: M*/

471: PetscErrorCode STRegister(char *sname,char *path,char *name,int (*function)(ST))
472: {
473:   PetscErrorCode ierr;
474:   char           fullname[256];

477:   PetscFListConcat(path,name,fullname);
478:   PetscFListAdd(&STList,sname,fullname,(void (*)(void))function);
479:   return(0);
480: }