Actual source code: stfunc.c

slepc-3.18.1 2022-11-02
Report Typos and Errors
  1: /*
  2:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3:    SLEPc - Scalable Library for Eigenvalue Problem Computations
  4:    Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain

  6:    This file is part of SLEPc.
  7:    SLEPc is distributed under a 2-clause BSD license (see LICENSE).
  8:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  9: */
 10: /*
 11:    The ST interface routines, callable by users
 12: */

 14: #include <slepc/private/stimpl.h>

 16: PetscClassId     ST_CLASSID = 0;
 17: PetscLogEvent    ST_SetUp = 0,ST_ComputeOperator = 0,ST_Apply = 0,ST_ApplyTranspose = 0,ST_MatSetUp = 0,ST_MatMult = 0,ST_MatMultTranspose = 0,ST_MatSolve = 0,ST_MatSolveTranspose = 0;
 18: static PetscBool STPackageInitialized = PETSC_FALSE;

 20: const char *STMatModes[] = {"COPY","INPLACE","SHELL","STMatMode","ST_MATMODE_",NULL};

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

 26:    Level: developer

 28: .seealso: SlepcFinalize()
 29: @*/
 30: PetscErrorCode STFinalizePackage(void)
 31: {
 32:   PetscFunctionListDestroy(&STList);
 33:   STPackageInitialized = PETSC_FALSE;
 34:   STRegisterAllCalled  = PETSC_FALSE;
 35:   return 0;
 36: }

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

 43:    Level: developer

 45: .seealso: SlepcInitialize()
 46: @*/
 47: PetscErrorCode STInitializePackage(void)
 48: {
 49:   char           logList[256];
 50:   PetscBool      opt,pkg;
 51:   PetscClassId   classids[1];

 53:   if (STPackageInitialized) return 0;
 54:   STPackageInitialized = PETSC_TRUE;
 55:   /* Register Classes */
 56:   PetscClassIdRegister("Spectral Transform",&ST_CLASSID);
 57:   /* Register Constructors */
 58:   STRegisterAll();
 59:   /* Register Events */
 60:   PetscLogEventRegister("STSetUp",ST_CLASSID,&ST_SetUp);
 61:   PetscLogEventRegister("STComputeOperatr",ST_CLASSID,&ST_ComputeOperator);
 62:   PetscLogEventRegister("STApply",ST_CLASSID,&ST_Apply);
 63:   PetscLogEventRegister("STApplyTranspose",ST_CLASSID,&ST_ApplyTranspose);
 64:   PetscLogEventRegister("STMatSetUp",ST_CLASSID,&ST_MatSetUp);
 65:   PetscLogEventRegister("STMatMult",ST_CLASSID,&ST_MatMult);
 66:   PetscLogEventRegister("STMatMultTranspose",ST_CLASSID,&ST_MatMultTranspose);
 67:   PetscLogEventRegister("STMatSolve",ST_CLASSID,&ST_MatSolve);
 68:   PetscLogEventRegister("STMatSolveTranspose",ST_CLASSID,&ST_MatSolveTranspose);
 69:   /* Process Info */
 70:   classids[0] = ST_CLASSID;
 71:   PetscInfoProcessClass("st",1,&classids[0]);
 72:   /* Process summary exclusions */
 73:   PetscOptionsGetString(NULL,NULL,"-log_exclude",logList,sizeof(logList),&opt);
 74:   if (opt) {
 75:     PetscStrInList("st",logList,',',&pkg);
 76:     if (pkg) PetscLogEventDeactivateClass(ST_CLASSID);
 77:   }
 78:   /* Register package finalizer */
 79:   PetscRegisterFinalize(STFinalizePackage);
 80:   return 0;
 81: }

 83: /*@
 84:    STReset - Resets the ST context to the initial state (prior to setup)
 85:    and destroys any allocated Vecs and Mats.

 87:    Collective on st

 89:    Input Parameter:
 90: .  st - the spectral transformation context

 92:    Level: advanced

 94: .seealso: STDestroy()
 95: @*/
 96: PetscErrorCode STReset(ST st)
 97: {
 99:   if (!st) return 0;
100:   STCheckNotSeized(st,1);
101:   PetscTryTypeMethod(st,reset);
102:   if (st->ksp) KSPReset(st->ksp);
103:   MatDestroyMatrices(PetscMax(2,st->nmat),&st->T);
104:   MatDestroyMatrices(PetscMax(2,st->nmat),&st->A);
105:   st->nmat = 0;
106:   PetscFree(st->Astate);
107:   MatDestroy(&st->Op);
108:   MatDestroy(&st->P);
109:   MatDestroy(&st->Pmat);
110:   MatDestroyMatrices(st->nsplit,&st->Psplit);
111:   st->nsplit = 0;
112:   VecDestroyVecs(st->nwork,&st->work);
113:   st->nwork = 0;
114:   VecDestroy(&st->wb);
115:   VecDestroy(&st->wht);
116:   VecDestroy(&st->D);
117:   st->state   = ST_STATE_INITIAL;
118:   st->opready = PETSC_FALSE;
119:   return 0;
120: }

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

125:    Collective on st

127:    Input Parameter:
128: .  st - the spectral transformation context

130:    Level: beginner

132: .seealso: STCreate(), STSetUp()
133: @*/
134: PetscErrorCode STDestroy(ST *st)
135: {
136:   if (!*st) return 0;
138:   if (--((PetscObject)(*st))->refct > 0) { *st = NULL; return 0; }
139:   STReset(*st);
140:   PetscTryTypeMethod(*st,destroy);
141:   KSPDestroy(&(*st)->ksp);
142:   PetscHeaderDestroy(st);
143:   return 0;
144: }

146: /*@
147:    STCreate - Creates a spectral transformation context.

149:    Collective

151:    Input Parameter:
152: .  comm - MPI communicator

154:    Output Parameter:
155: .  newst - location to put the spectral transformation context

157:    Level: beginner

159: .seealso: STSetUp(), STApply(), STDestroy(), ST
160: @*/
161: PetscErrorCode STCreate(MPI_Comm comm,ST *newst)
162: {
163:   ST             st;

166:   *newst = NULL;
167:   STInitializePackage();
168:   SlepcHeaderCreate(st,ST_CLASSID,"ST","Spectral Transformation","ST",comm,STDestroy,STView);

170:   st->A            = NULL;
171:   st->nmat         = 0;
172:   st->sigma        = 0.0;
173:   st->defsigma     = 0.0;
174:   st->matmode      = ST_MATMODE_COPY;
175:   st->str          = UNKNOWN_NONZERO_PATTERN;
176:   st->transform    = PETSC_FALSE;
177:   st->D            = NULL;
178:   st->Pmat         = NULL;
179:   st->Pmat_set     = PETSC_FALSE;
180:   st->Psplit       = NULL;
181:   st->nsplit       = 0;
182:   st->strp         = UNKNOWN_NONZERO_PATTERN;

184:   st->ksp          = NULL;
185:   st->usesksp      = PETSC_FALSE;
186:   st->nwork        = 0;
187:   st->work         = NULL;
188:   st->wb           = NULL;
189:   st->wht          = NULL;
190:   st->state        = ST_STATE_INITIAL;
191:   st->Astate       = NULL;
192:   st->T            = NULL;
193:   st->Op           = NULL;
194:   st->opseized     = PETSC_FALSE;
195:   st->opready      = PETSC_FALSE;
196:   st->P            = NULL;
197:   st->M            = NULL;
198:   st->sigma_set    = PETSC_FALSE;
199:   st->asymm        = PETSC_FALSE;
200:   st->aherm        = PETSC_FALSE;
201:   st->data         = NULL;

203:   *newst = st;
204:   return 0;
205: }

207: /*
208:    Checks whether the ST matrices are all symmetric or hermitian.
209: */
210: static inline PetscErrorCode STMatIsSymmetricKnown(ST st,PetscBool *symm,PetscBool *herm)
211: {
212:   PetscInt       i;
213:   PetscBool      sbaij=PETSC_FALSE,set,flg=PETSC_FALSE;

215:   /* check if problem matrices are all sbaij */
216:   for (i=0;i<st->nmat;i++) {
217:     PetscObjectTypeCompareAny((PetscObject)st->A[i],&sbaij,MATSEQSBAIJ,MATMPISBAIJ,"");
218:     if (!sbaij) break;
219:   }
220:   /* check if user has set the symmetric flag */
221:   *symm = PETSC_TRUE;
222:   for (i=0;i<st->nmat;i++) {
223:     MatIsSymmetricKnown(st->A[i],&set,&flg);
224:     if (!set || !flg) { *symm = PETSC_FALSE; break; }
225:   }
226:   if (sbaij) *symm = PETSC_TRUE;
227: #if defined(PETSC_USE_COMPLEX)
228:   /* check if user has set the hermitian flag */
229:   *herm = PETSC_TRUE;
230:   for (i=0;i<st->nmat;i++) {
231:     MatIsHermitianKnown(st->A[i],&set,&flg);
232:     if (!set || !flg) { *herm = PETSC_FALSE; break; }
233:   }
234: #else
235:   *herm = *symm;
236: #endif
237:   return 0;
238: }

240: /*@
241:    STSetMatrices - Sets the matrices associated with the eigenvalue problem.

243:    Collective on st

245:    Input Parameters:
246: +  st - the spectral transformation context
247: .  n  - number of matrices in array A
248: -  A  - the array of matrices associated with the eigensystem

250:    Notes:
251:    It must be called before STSetUp(). If it is called again after STSetUp() then
252:    the ST object is reset.

254:    Level: intermediate

256: .seealso: STGetMatrix(), STGetNumMatrices(), STSetUp(), STReset()
257: @*/
258: PetscErrorCode STSetMatrices(ST st,PetscInt n,Mat A[])
259: {
260:   PetscInt       i;
261:   PetscBool      same=PETSC_TRUE;

268:   STCheckNotSeized(st,1);

271:   if (st->state) {
272:     if (n!=st->nmat) same = PETSC_FALSE;
273:     for (i=0;same&&i<n;i++) {
274:       if (A[i]!=st->A[i]) same = PETSC_FALSE;
275:     }
276:     if (!same) STReset(st);
277:   } else same = PETSC_FALSE;
278:   if (!same) {
279:     MatDestroyMatrices(PetscMax(2,st->nmat),&st->A);
280:     PetscCalloc1(PetscMax(2,n),&st->A);
281:     PetscFree(st->Astate);
282:     PetscMalloc1(PetscMax(2,n),&st->Astate);
283:   }
284:   for (i=0;i<n;i++) {
286:     PetscObjectReference((PetscObject)A[i]);
287:     MatDestroy(&st->A[i]);
288:     st->A[i] = A[i];
289:     st->Astate[i] = ((PetscObject)A[i])->state;
290:   }
291:   if (n==1) {
292:     st->A[1] = NULL;
293:     st->Astate[1] = 0;
294:   }
295:   st->nmat = n;
296:   if (same) st->state = ST_STATE_UPDATED;
297:   else st->state = ST_STATE_INITIAL;
299:   st->opready = PETSC_FALSE;
300:   if (!same) STMatIsSymmetricKnown(st,&st->asymm,&st->aherm);
301:   return 0;
302: }

304: /*@
305:    STGetMatrix - Gets the matrices associated with the original eigensystem.

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

309:    Input Parameters:
310: +  st - the spectral transformation context
311: -  k  - the index of the requested matrix (starting in 0)

313:    Output Parameters:
314: .  A - the requested matrix

316:    Level: intermediate

318: .seealso: STSetMatrices(), STGetNumMatrices()
319: @*/
320: PetscErrorCode STGetMatrix(ST st,PetscInt k,Mat *A)
321: {
325:   STCheckMatrices(st,1);
328:   *A = st->A[k];
329:   return 0;
330: }

332: /*@
333:    STGetMatrixTransformed - Gets the matrices associated with the transformed eigensystem.

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

337:    Input Parameters:
338: +  st - the spectral transformation context
339: -  k  - the index of the requested matrix (starting in 0)

341:    Output Parameters:
342: .  T - the requested matrix

344:    Level: developer

346: .seealso: STGetMatrix(), STGetNumMatrices()
347: @*/
348: PetscErrorCode STGetMatrixTransformed(ST st,PetscInt k,Mat *T)
349: {
353:   STCheckMatrices(st,1);
356:   *T = st->T[k];
357:   return 0;
358: }

360: /*@
361:    STGetNumMatrices - Returns the number of matrices stored in the ST.

363:    Not collective

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

368:    Output Parameters:
369: .  n - the number of matrices passed in STSetMatrices()

371:    Level: intermediate

373: .seealso: STSetMatrices()
374: @*/
375: PetscErrorCode STGetNumMatrices(ST st,PetscInt *n)
376: {
379:   *n = st->nmat;
380:   return 0;
381: }

383: /*@
384:    STResetMatrixState - Resets the stored state of the matrices in the ST.

386:    Logically Collective on st

388:    Input Parameter:
389: .  st - the spectral transformation context

391:    Note:
392:    This is useful in solvers where the user matrices are modified during
393:    the computation, as in nonlinear inverse iteration. The effect is that
394:    STGetMatrix() will retrieve the modified matrices as if they were
395:    the matrices originally provided by the user.

397:    Level: developer

399: .seealso: STGetMatrix(), EPSPowerSetNonlinear()
400: @*/
401: PetscErrorCode STResetMatrixState(ST st)
402: {
403:   PetscInt i;

406:   for (i=0;i<st->nmat;i++) st->Astate[i] = ((PetscObject)st->A[i])->state;
407:   return 0;
408: }

410: /*@
411:    STSetPreconditionerMat - Sets the matrix to be used to build the preconditioner.

413:    Collective on st

415:    Input Parameters:
416: +  st  - the spectral transformation context
417: -  mat - the matrix that will be used in constructing the preconditioner

419:    Notes:
420:    This matrix will be passed to the internal KSP object (via the last argument
421:    of KSPSetOperators()) as the matrix to be used when constructing the preconditioner.
422:    If no matrix is set or mat is set to NULL, A-sigma*B will be used
423:    to build the preconditioner, being sigma the value set by STSetShift().

425:    More precisely, this is relevant for spectral transformations that represent
426:    a rational matrix function, and use a KSP object for the denominator, called
427:    K in the description of STGetOperator(). It includes also the STPRECOND case.
428:    If the user has a good approximation to matrix K that can be used to build a
429:    cheap preconditioner, it can be passed with this function. Note that it affects
430:    only the Pmat argument of KSPSetOperators(), not the Amat argument.

432:    If a preconditioner matrix is set, the default is to use an iterative KSP
433:    rather than a direct method.

435:    An alternative to pass an approximation of A-sigma*B with this function is
436:    to provide approximations of A and B via STSetSplitPreconditioner(). The
437:    difference is that when sigma changes the preconditioner is recomputed.

439:    Use NULL to remove a previously set matrix.

441:    Level: advanced

443: .seealso: STGetPreconditionerMat(), STSetShift(), STGetOperator(), STSetSplitPreconditioner()
444: @*/
445: PetscErrorCode STSetPreconditionerMat(ST st,Mat mat)
446: {
448:   if (mat) {
451:   }
452:   STCheckNotSeized(st,1);
454:   if (mat) PetscObjectReference((PetscObject)mat);
455:   MatDestroy(&st->Pmat);
456:   st->Pmat     = mat;
457:   st->Pmat_set = mat? PETSC_TRUE: PETSC_FALSE;
458:   st->state    = ST_STATE_INITIAL;
459:   st->opready  = PETSC_FALSE;
460:   return 0;
461: }

463: /*@
464:    STGetPreconditionerMat - Returns the matrix previously set by STSetPreconditionerMat().

466:    Not Collective

468:    Input Parameter:
469: .  st - the spectral transformation context

471:    Output Parameter:
472: .  mat - the matrix that will be used in constructing the preconditioner or
473:    NULL if no matrix was set by STSetPreconditionerMat().

475:    Level: advanced

477: .seealso: STSetPreconditionerMat()
478: @*/
479: PetscErrorCode STGetPreconditionerMat(ST st,Mat *mat)
480: {
483:   *mat = st->Pmat_set? st->Pmat: NULL;
484:   return 0;
485: }

487: /*@
488:    STSetSplitPreconditioner - Sets the matrices from which to build the preconditioner
489:    in split form.

491:    Collective on st

493:    Input Parameters:
494: +  st     - the spectral transformation context
495: .  n      - number of matrices
496: .  Psplit - array of matrices
497: -  strp   - structure flag for Psplit matrices

499:    Notes:
500:    The number of matrices passed here must be the same as in STSetMatrices().

502:    For linear eigenproblems, the preconditioner matrix is computed as
503:    Pmat(sigma) = A0-sigma*B0, where A0 and B0 are approximations of A and B
504:    (the eigenproblem matrices) provided via the Psplit array in this function.
505:    Compared to STSetPreconditionerMat(), this function allows setting a preconditioner
506:    in a way that is independent of the shift sigma. Whenever the value of sigma
507:    changes the preconditioner is recomputed.

509:    Similarly, for polynomial eigenproblems the matrix for the preconditioner
510:    is expressed as Pmat(sigma) = sum_i Psplit_i*phi_i(sigma), for i=1,...,n, where
511:    the phi_i's are the polynomial basis functions.

513:    The structure flag provides information about the relative nonzero pattern of the
514:    Psplit_i matrices, in the same way as in STSetMatStructure().

516:    Use n=0 to reset a previously set split preconditioner.

518:    Level: advanced

520: .seealso: STGetSplitPreconditionerTerm(), STGetSplitPreconditionerInfo(), STSetPreconditionerMat(), STSetMatrices(), STSetMatStructure()
521: @*/
522: PetscErrorCode STSetSplitPreconditioner(ST st,PetscInt n,Mat Psplit[],MatStructure strp)
523: {
524:   PetscInt       i,N=0,M,M0=0,mloc,nloc,mloc0=0;

533:   STCheckNotSeized(st,1);

535:   for (i=0;i<n;i++) {
538:     MatGetSize(Psplit[i],&M,&N);
539:     MatGetLocalSize(Psplit[i],&mloc,&nloc);
542:     if (!i) { M0 = M; mloc0 = mloc; }
545:     PetscObjectReference((PetscObject)Psplit[i]);
546:   }

548:   if (st->Psplit) MatDestroyMatrices(st->nsplit,&st->Psplit);

550:   /* allocate space and copy matrices */
551:   if (n) {
552:     PetscMalloc1(n,&st->Psplit);
553:     for (i=0;i<n;i++) st->Psplit[i] = Psplit[i];
554:   }
555:   st->nsplit = n;
556:   st->strp   = strp;
557:   st->state  = ST_STATE_INITIAL;
558:   return 0;
559: }

561: /*@
562:    STGetSplitPreconditionerTerm - Gets the matrices associated with
563:    the split preconditioner.

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

567:    Input Parameters:
568: +  st - the spectral transformation context
569: -  k  - the index of the requested matrix (starting in 0)

571:    Output Parameter:
572: .  Psplit - the returned matrix

574:    Level: advanced

576: .seealso: STSetSplitPreconditioner(), STGetSplitPreconditionerInfo()
577: @*/
578: PetscErrorCode STGetSplitPreconditionerTerm(ST st,PetscInt k,Mat *Psplit)
579: {
585:   *Psplit = st->Psplit[k];
586:   return 0;
587: }

589: /*@
590:    STGetSplitPreconditionerInfo - Returns the number of matrices of the split
591:    preconditioner, as well as the structure flag.

593:    Not collective

595:    Input Parameter:
596: .  st - the spectral transformation context

598:    Output Parameters:
599: +  n    - the number of matrices passed in STSetSplitPreconditioner()
600: -  strp - the matrix structure flag passed in STSetSplitPreconditioner()

602:    Level: advanced

604: .seealso: STSetSplitPreconditioner(), STGetSplitPreconditionerTerm()
605: @*/
606: PetscErrorCode STGetSplitPreconditionerInfo(ST st,PetscInt *n,MatStructure *strp)
607: {
609:   if (n)    *n    = st->nsplit;
610:   if (strp) *strp = st->strp;
611:   return 0;
612: }

614: /*@
615:    STSetShift - Sets the shift associated with the spectral transformation.

617:    Logically Collective on st

619:    Input Parameters:
620: +  st - the spectral transformation context
621: -  shift - the value of the shift

623:    Notes:
624:    In some spectral transformations, changing the shift may have associated
625:    a lot of work, for example recomputing a factorization.

627:    This function is normally not directly called by users, since the shift is
628:    indirectly set by EPSSetTarget().

630:    Level: intermediate

632: .seealso: EPSSetTarget(), STGetShift(), STSetDefaultShift()
633: @*/
634: PetscErrorCode STSetShift(ST st,PetscScalar shift)
635: {
639:   if (st->sigma != shift) {
640:     STCheckNotSeized(st,1);
641:     if (st->state==ST_STATE_SETUP) PetscTryTypeMethod(st,setshift,shift);
642:     st->sigma = shift;
643:   }
644:   st->sigma_set = PETSC_TRUE;
645:   return 0;
646: }

648: /*@
649:    STGetShift - Gets the shift associated with the spectral transformation.

651:    Not Collective

653:    Input Parameter:
654: .  st - the spectral transformation context

656:    Output Parameter:
657: .  shift - the value of the shift

659:    Level: intermediate

661: .seealso: STSetShift()
662: @*/
663: PetscErrorCode STGetShift(ST st,PetscScalar* shift)
664: {
667:   *shift = st->sigma;
668:   return 0;
669: }

671: /*@
672:    STSetDefaultShift - Sets the value of the shift that should be employed if
673:    the user did not specify one.

675:    Logically Collective on st

677:    Input Parameters:
678: +  st - the spectral transformation context
679: -  defaultshift - the default value of the shift

681:    Level: developer

683: .seealso: STSetShift()
684: @*/
685: PetscErrorCode STSetDefaultShift(ST st,PetscScalar defaultshift)
686: {
689:   if (st->defsigma != defaultshift) {
690:     st->defsigma = defaultshift;
691:     st->state    = ST_STATE_INITIAL;
692:     st->opready  = PETSC_FALSE;
693:   }
694:   return 0;
695: }

697: /*@
698:    STScaleShift - Multiply the shift with a given factor.

700:    Logically Collective on st

702:    Input Parameters:
703: +  st     - the spectral transformation context
704: -  factor - the scaling factor

706:    Note:
707:    This function does not update the transformation matrices, as opposed to
708:    STSetShift().

710:    Level: developer

712: .seealso: STSetShift()
713: @*/
714: PetscErrorCode STScaleShift(ST st,PetscScalar factor)
715: {
718:   st->sigma *= factor;
719:   return 0;
720: }

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

725:    Collective on st

727:    Input Parameters:
728: +  st - the spectral transformation context
729: -  D  - the diagonal matrix (represented as a vector)

731:    Notes:
732:    If this matrix is set, STApply will effectively apply D*OP*D^{-1}. Use NULL
733:    to reset a previously passed D.

735:    Balancing is usually set via EPSSetBalance, but the advanced user may use
736:    this function to bypass the usual balancing methods.

738:    Level: developer

740: .seealso: EPSSetBalance(), STApply(), STGetBalanceMatrix()
741: @*/
742: PetscErrorCode STSetBalanceMatrix(ST st,Vec D)
743: {
745:   if (st->D == D) return 0;
746:   STCheckNotSeized(st,1);
747:   if (D) {
750:     PetscObjectReference((PetscObject)D);
751:   }
752:   VecDestroy(&st->D);
753:   st->D = D;
754:   st->state   = ST_STATE_INITIAL;
755:   st->opready = PETSC_FALSE;
756:   return 0;
757: }

759: /*@
760:    STGetBalanceMatrix - Gets the balance matrix used by the spectral transformation.

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

764:    Input Parameter:
765: .  st - the spectral transformation context

767:    Output Parameter:
768: .  D  - the diagonal matrix (represented as a vector)

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

773:    Level: developer

775: .seealso: STSetBalanceMatrix()
776: @*/
777: PetscErrorCode STGetBalanceMatrix(ST st,Vec *D)
778: {
781:   *D = st->D;
782:   return 0;
783: }

785: /*@C
786:    STMatCreateVecs - Get vector(s) compatible with the ST matrices.

788:    Collective on st

790:    Input Parameter:
791: .  st - the spectral transformation context

793:    Output Parameters:
794: +  right - (optional) vector that the matrix can be multiplied against
795: -  left  - (optional) vector that the matrix vector product can be stored in

797:    Level: developer

799: .seealso: STMatCreateVecsEmpty()
800: @*/
801: PetscErrorCode STMatCreateVecs(ST st,Vec *right,Vec *left)
802: {
803:   STCheckMatrices(st,1);
804:   MatCreateVecs(st->A[0],right,left);
805:   return 0;
806: }

808: /*@C
809:    STMatCreateVecsEmpty - Get vector(s) compatible with the ST matrices, i.e. with the same
810:    parallel layout, but without internal array.

812:    Collective on st

814:    Input Parameter:
815: .  st - the spectral transformation context

817:    Output Parameters:
818: +  right - (optional) vector that the matrix can be multiplied against
819: -  left  - (optional) vector that the matrix vector product can be stored in

821:    Level: developer

823: .seealso: STMatCreateVecs(), MatCreateVecsEmpty()
824: @*/
825: PetscErrorCode STMatCreateVecsEmpty(ST st,Vec *right,Vec *left)
826: {
827:   STCheckMatrices(st,1);
828:   MatCreateVecsEmpty(st->A[0],right,left);
829:   return 0;
830: }

832: /*@
833:    STMatGetSize - Returns the number of rows and columns of the ST matrices.

835:    Not Collective

837:    Input Parameter:
838: .  st - the spectral transformation context

840:    Output Parameters:
841: +  m - the number of global rows
842: -  n - the number of global columns

844:    Level: developer

846: .seealso: STMatGetLocalSize()
847: @*/
848: PetscErrorCode STMatGetSize(ST st,PetscInt *m,PetscInt *n)
849: {
850:   STCheckMatrices(st,1);
851:   MatGetSize(st->A[0],m,n);
852:   return 0;
853: }

855: /*@
856:    STMatGetLocalSize - Returns the number of local rows and columns of the ST matrices.

858:    Not Collective

860:    Input Parameter:
861: .  st - the spectral transformation context

863:    Output Parameters:
864: +  m - the number of local rows
865: -  n - the number of local columns

867:    Level: developer

869: .seealso: STMatGetSize()
870: @*/
871: PetscErrorCode STMatGetLocalSize(ST st,PetscInt *m,PetscInt *n)
872: {
873:   STCheckMatrices(st,1);
874:   MatGetLocalSize(st->A[0],m,n);
875:   return 0;
876: }

878: /*@C
879:    STSetOptionsPrefix - Sets the prefix used for searching for all
880:    ST options in the database.

882:    Logically Collective on st

884:    Input Parameters:
885: +  st     - the spectral transformation context
886: -  prefix - the prefix string to prepend to all ST option requests

888:    Notes:
889:    A hyphen (-) must NOT be given at the beginning of the prefix name.
890:    The first character of all runtime options is AUTOMATICALLY the
891:    hyphen.

893:    Level: advanced

895: .seealso: STAppendOptionsPrefix(), STGetOptionsPrefix()
896: @*/
897: PetscErrorCode STSetOptionsPrefix(ST st,const char *prefix)
898: {
900:   if (!st->ksp) STGetKSP(st,&st->ksp);
901:   KSPSetOptionsPrefix(st->ksp,prefix);
902:   KSPAppendOptionsPrefix(st->ksp,"st_");
903:   PetscObjectSetOptionsPrefix((PetscObject)st,prefix);
904:   return 0;
905: }

907: /*@C
908:    STAppendOptionsPrefix - Appends to the prefix used for searching for all
909:    ST options in the database.

911:    Logically Collective on st

913:    Input Parameters:
914: +  st     - the spectral transformation context
915: -  prefix - the prefix string to prepend to all ST option requests

917:    Notes:
918:    A hyphen (-) must NOT be given at the beginning of the prefix name.
919:    The first character of all runtime options is AUTOMATICALLY the
920:    hyphen.

922:    Level: advanced

924: .seealso: STSetOptionsPrefix(), STGetOptionsPrefix()
925: @*/
926: PetscErrorCode STAppendOptionsPrefix(ST st,const char *prefix)
927: {
929:   PetscObjectAppendOptionsPrefix((PetscObject)st,prefix);
930:   if (!st->ksp) STGetKSP(st,&st->ksp);
931:   KSPSetOptionsPrefix(st->ksp,((PetscObject)st)->prefix);
932:   KSPAppendOptionsPrefix(st->ksp,"st_");
933:   return 0;
934: }

936: /*@C
937:    STGetOptionsPrefix - Gets the prefix used for searching for all
938:    ST options in the database.

940:    Not Collective

942:    Input Parameters:
943: .  st - the spectral transformation context

945:    Output Parameters:
946: .  prefix - pointer to the prefix string used, is returned

948:    Note:
949:    On the Fortran side, the user should pass in a string 'prefix' of
950:    sufficient length to hold the prefix.

952:    Level: advanced

954: .seealso: STSetOptionsPrefix(), STAppendOptionsPrefix()
955: @*/
956: PetscErrorCode STGetOptionsPrefix(ST st,const char *prefix[])
957: {
960:   PetscObjectGetOptionsPrefix((PetscObject)st,prefix);
961:   return 0;
962: }

964: /*@C
965:    STView - Prints the ST data structure.

967:    Collective on st

969:    Input Parameters:
970: +  st - the ST context
971: -  viewer - optional visualization context

973:    Note:
974:    The available visualization contexts include
975: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
976: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
977:          output where only the first processor opens
978:          the file.  All other processors send their
979:          data to the first processor to print.

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

984:    Level: beginner

986: .seealso: EPSView()
987: @*/
988: PetscErrorCode STView(ST st,PetscViewer viewer)
989: {
990:   STType         cstr;
991:   char           str[50];
992:   PetscBool      isascii,isstring;

995:   if (!viewer) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)st),&viewer);

999:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
1000:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
1001:   if (isascii) {
1002:     PetscObjectPrintClassNamePrefixType((PetscObject)st,viewer);
1003:     PetscViewerASCIIPushTab(viewer);
1004:     PetscTryTypeMethod(st,view,viewer);
1005:     PetscViewerASCIIPopTab(viewer);
1006:     SlepcSNPrintfScalar(str,sizeof(str),st->sigma,PETSC_FALSE);
1007:     PetscViewerASCIIPrintf(viewer,"  shift: %s\n",str);
1008:     PetscViewerASCIIPrintf(viewer,"  number of matrices: %" PetscInt_FMT "\n",st->nmat);
1009:     switch (st->matmode) {
1010:     case ST_MATMODE_COPY:
1011:       break;
1012:     case ST_MATMODE_INPLACE:
1013:       PetscViewerASCIIPrintf(viewer,"  shifting the matrix and unshifting at exit\n");
1014:       break;
1015:     case ST_MATMODE_SHELL:
1016:       PetscViewerASCIIPrintf(viewer,"  using a shell matrix\n");
1017:       break;
1018:     }
1019:     if (st->nmat>1 && st->matmode != ST_MATMODE_SHELL) PetscViewerASCIIPrintf(viewer,"  nonzero pattern of the matrices: %s\n",MatStructures[st->str]);
1020:     if (st->Psplit) PetscViewerASCIIPrintf(viewer,"  using split preconditioner matrices with %s\n",MatStructures[st->strp]);
1021:     if (st->transform && st->nmat>2) PetscViewerASCIIPrintf(viewer,"  computing transformed matrices\n");
1022:   } else if (isstring) {
1023:     STGetType(st,&cstr);
1024:     PetscViewerStringSPrintf(viewer," %-7.7s",cstr);
1025:     PetscTryTypeMethod(st,view,viewer);
1026:   }
1027:   if (st->usesksp) {
1028:     if (!st->ksp) STGetKSP(st,&st->ksp);
1029:     PetscViewerASCIIPushTab(viewer);
1030:     KSPView(st->ksp,viewer);
1031:     PetscViewerASCIIPopTab(viewer);
1032:   }
1033:   return 0;
1034: }

1036: /*@C
1037:    STViewFromOptions - View from options

1039:    Collective on ST

1041:    Input Parameters:
1042: +  st   - the spectral transformation context
1043: .  obj  - optional object
1044: -  name - command line option

1046:    Level: intermediate

1048: .seealso: STView(), STCreate()
1049: @*/
1050: PetscErrorCode STViewFromOptions(ST st,PetscObject obj,const char name[])
1051: {
1053:   PetscObjectViewFromOptions((PetscObject)st,obj,name);
1054:   return 0;
1055: }

1057: /*@C
1058:    STRegister - Adds a method to the spectral transformation package.

1060:    Not collective

1062:    Input Parameters:
1063: +  name - name of a new user-defined transformation
1064: -  function - routine to create method context

1066:    Notes:
1067:    STRegister() may be called multiple times to add several user-defined
1068:    spectral transformations.

1070:    Sample usage:
1071: .vb
1072:     STRegister("my_transform",MyTransformCreate);
1073: .ve

1075:    Then, your spectral transform can be chosen with the procedural interface via
1076: $     STSetType(st,"my_transform")
1077:    or at runtime via the option
1078: $     -st_type my_transform

1080:    Level: advanced

1082: .seealso: STRegisterAll()
1083: @*/
1084: PetscErrorCode STRegister(const char *name,PetscErrorCode (*function)(ST))
1085: {
1086:   STInitializePackage();
1087:   PetscFunctionListAdd(&STList,name,function);
1088:   return 0;
1089: }