LCOV - code coverage report
Current view: top level - sys/classes/st/interface - stsolve.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 221 223 99.1 %
Date: 2019-09-16 06:01:52 Functions: 15 15 100.0 %

          Line data    Source code
       1             : /*
       2             :    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       3             :    SLEPc - Scalable Library for Eigenvalue Problem Computations
       4             :    Copyright (c) 2002-2019, Universitat Politecnica de Valencia, Spain
       5             : 
       6             :    This file is part of SLEPc.
       7             :    SLEPc is distributed under a 2-clause BSD license (see LICENSE).
       8             :    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       9             : */
      10             : /*
      11             :    ST interface routines, callable by users
      12             : */
      13             : 
      14             : #include <slepc/private/stimpl.h>            /*I "slepcst.h" I*/
      15             : 
      16             : /*@
      17             :    STApply - Applies the spectral transformation operator to a vector, for
      18             :    instance (A - sB)^-1 B in the case of the shift-and-invert transformation
      19             :    and generalized eigenproblem.
      20             : 
      21             :    Collective on st
      22             : 
      23             :    Input Parameters:
      24             : +  st - the spectral transformation context
      25             : -  x  - input vector
      26             : 
      27             :    Output Parameter:
      28             : .  y - output vector
      29             : 
      30             :    Level: developer
      31             : 
      32             : .seealso: STApplyTranspose()
      33             : @*/
      34      127258 : PetscErrorCode STApply(ST st,Vec x,Vec y)
      35             : {
      36             :   PetscErrorCode ierr;
      37             : 
      38      127258 :   PetscFunctionBegin;
      39      127258 :   PetscValidHeaderSpecific(st,ST_CLASSID,1);
      40      127258 :   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
      41      127258 :   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
      42      127258 :   PetscValidType(st,1);
      43      127258 :   STCheckMatrices(st,1);
      44      127258 :   if (x == y) SETERRQ(PetscObjectComm((PetscObject)st),PETSC_ERR_ARG_IDN,"x and y must be different vectors");
      45      127258 :   ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr);
      46             : 
      47      127258 :   if (st->state!=ST_STATE_SETUP) { ierr = STSetUp(st);CHKERRQ(ierr); }
      48             : 
      49      127258 :   if (!st->ops->apply) SETERRQ(PetscObjectComm((PetscObject)st),PETSC_ERR_SUP,"ST does not have apply");
      50      127258 :   ierr = VecLockReadPush(x);CHKERRQ(ierr);
      51      127258 :   ierr = PetscLogEventBegin(ST_Apply,st,x,y,0);CHKERRQ(ierr);
      52      127258 :   if (st->D) { /* with balancing */
      53         842 :     ierr = VecPointwiseDivide(st->wb,x,st->D);CHKERRQ(ierr);
      54         842 :     ierr = (*st->ops->apply)(st,st->wb,y);CHKERRQ(ierr);
      55         842 :     ierr = VecPointwiseMult(y,y,st->D);CHKERRQ(ierr);
      56             :   } else {
      57      126416 :     ierr = (*st->ops->apply)(st,x,y);CHKERRQ(ierr);
      58             :   }
      59      127258 :   ierr = PetscLogEventEnd(ST_Apply,st,x,y,0);CHKERRQ(ierr);
      60      127258 :   ierr = VecLockReadPop(x);CHKERRQ(ierr);
      61      127258 :   PetscFunctionReturn(0);
      62             : }
      63             : 
      64             : /*@
      65             :    STApplyTranspose - Applies the transpose of the operator to a vector, for
      66             :    instance B^T(A - sB)^-T in the case of the shift-and-invert transformation
      67             :    and generalized eigenproblem.
      68             : 
      69             :    Collective on st
      70             : 
      71             :    Input Parameters:
      72             : +  st - the spectral transformation context
      73             : -  x  - input vector
      74             : 
      75             :    Output Parameter:
      76             : .  y - output vector
      77             : 
      78             :    Level: developer
      79             : 
      80             : .seealso: STApply()
      81             : @*/
      82         966 : PetscErrorCode STApplyTranspose(ST st,Vec x,Vec y)
      83             : {
      84             :   PetscErrorCode ierr;
      85             : 
      86         966 :   PetscFunctionBegin;
      87         966 :   PetscValidHeaderSpecific(st,ST_CLASSID,1);
      88         966 :   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
      89         966 :   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
      90         966 :   PetscValidType(st,1);
      91         966 :   STCheckMatrices(st,1);
      92         966 :   if (x == y) SETERRQ(PetscObjectComm((PetscObject)st),PETSC_ERR_ARG_IDN,"x and y must be different vectors");
      93         966 :   ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr);
      94             : 
      95         966 :   if (st->state!=ST_STATE_SETUP) { ierr = STSetUp(st);CHKERRQ(ierr); }
      96             : 
      97         966 :   if (!st->ops->applytrans) SETERRQ(PetscObjectComm((PetscObject)st),PETSC_ERR_SUP,"ST does not have applytrans");
      98         966 :   ierr = VecLockReadPush(x);CHKERRQ(ierr);
      99         966 :   ierr = PetscLogEventBegin(ST_ApplyTranspose,st,x,y,0);CHKERRQ(ierr);
     100         966 :   if (st->D) { /* with balancing */
     101          60 :     ierr = VecPointwiseMult(st->wb,x,st->D);CHKERRQ(ierr);
     102          60 :     ierr = (*st->ops->applytrans)(st,st->wb,y);CHKERRQ(ierr);
     103          60 :     ierr = VecPointwiseDivide(y,y,st->D);CHKERRQ(ierr);
     104             :   } else {
     105         906 :     ierr = (*st->ops->applytrans)(st,x,y);CHKERRQ(ierr);
     106             :   }
     107         966 :   ierr = PetscLogEventEnd(ST_ApplyTranspose,st,x,y,0);CHKERRQ(ierr);
     108         966 :   ierr = VecLockReadPop(x);CHKERRQ(ierr);
     109         966 :   PetscFunctionReturn(0);
     110             : }
     111             : 
     112             : /*@
     113             :    STGetBilinearForm - Returns the matrix used in the bilinear form with a
     114             :    generalized problem with semi-definite B.
     115             : 
     116             :    Not collective, though a parallel Mat may be returned
     117             : 
     118             :    Input Parameters:
     119             : .  st - the spectral transformation context
     120             : 
     121             :    Output Parameter:
     122             : .  B - output matrix
     123             : 
     124             :    Notes:
     125             :    The output matrix B must be destroyed after use. It will be NULL in
     126             :    case of standard eigenproblems.
     127             : 
     128             :    Level: developer
     129             : @*/
     130          67 : PetscErrorCode STGetBilinearForm(ST st,Mat *B)
     131             : {
     132             :   PetscErrorCode ierr;
     133             : 
     134          67 :   PetscFunctionBegin;
     135          67 :   PetscValidHeaderSpecific(st,ST_CLASSID,1);
     136          67 :   PetscValidType(st,1);
     137          67 :   PetscValidPointer(B,2);
     138          67 :   STCheckMatrices(st,1);
     139          67 :   ierr = (*st->ops->getbilinearform)(st,B);CHKERRQ(ierr);
     140          67 :   PetscFunctionReturn(0);
     141             : }
     142             : 
     143          60 : PetscErrorCode STGetBilinearForm_Default(ST st,Mat *B)
     144             : {
     145             :   PetscErrorCode ierr;
     146             : 
     147          60 :   PetscFunctionBegin;
     148          60 :   if (st->nmat==1) *B = NULL;
     149             :   else {
     150          60 :     *B = st->A[1];
     151          60 :     ierr = PetscObjectReference((PetscObject)*B);CHKERRQ(ierr);
     152             :   }
     153          60 :   PetscFunctionReturn(0);
     154             : }
     155             : 
     156       48387 : static PetscErrorCode MatMult_STOperator(Mat Op,Vec x,Vec y)
     157             : {
     158             :   PetscErrorCode ierr;
     159             :   ST             st;
     160             : 
     161       48387 :   PetscFunctionBegin;
     162       48387 :   ierr = MatShellGetContext(Op,(void**)&st);CHKERRQ(ierr);
     163       48387 :   ierr = STApply(st,x,y);CHKERRQ(ierr);
     164       48387 :   PetscFunctionReturn(0);
     165             : }
     166             : 
     167           3 : static PetscErrorCode MatMultTranspose_STOperator(Mat Op,Vec x,Vec y)
     168             : {
     169             :   PetscErrorCode ierr;
     170             :   ST             st;
     171             : 
     172           3 :   PetscFunctionBegin;
     173           3 :   ierr = MatShellGetContext(Op,(void**)&st);CHKERRQ(ierr);
     174           3 :   ierr = STApplyTranspose(st,x,y);CHKERRQ(ierr);
     175           3 :   PetscFunctionReturn(0);
     176             : }
     177             : 
     178             : /*@
     179             :    STGetOperator - Returns a shell matrix that represents the spectral transformation.
     180             : 
     181             :    Collective on st
     182             : 
     183             :    Input Parameters:
     184             : .  st - the spectral transformation context
     185             : 
     186             :    Output Parameter:
     187             : .  Op - output matrix
     188             : 
     189             :    Notes:
     190             :    The returned shell matrix is essentially a wrapper to the STApply() and
     191             :    STApplyTranspose() operations. It must be destroyed after use.
     192             : 
     193             :    Level: advanced
     194             : 
     195             : .seealso: STApply(), STApplyTranspose()
     196             : @*/
     197          19 : PetscErrorCode STGetOperator(ST st,Mat *Op)
     198             : {
     199             :   PetscErrorCode ierr;
     200             :   PetscInt       m,n,M,N;
     201             : 
     202          19 :   PetscFunctionBegin;
     203          19 :   PetscValidHeaderSpecific(st,ST_CLASSID,1);
     204          19 :   PetscValidType(st,1);
     205          19 :   PetscValidPointer(Op,2);
     206          19 :   STCheckMatrices(st,1);
     207             : 
     208          19 :   ierr = MatGetLocalSize(st->A[0],&m,&n);CHKERRQ(ierr);
     209          19 :   ierr = MatGetSize(st->A[0],&M,&N);CHKERRQ(ierr);
     210          19 :   ierr = MatCreateShell(PetscObjectComm((PetscObject)st),m,n,M,N,st,Op);CHKERRQ(ierr);
     211          19 :   ierr = MatShellSetOperation(*Op,MATOP_MULT,(void(*)(void))MatMult_STOperator);CHKERRQ(ierr);
     212          19 :   ierr = MatShellSetOperation(*Op,MATOP_MULT_TRANSPOSE,(void(*)(void))MatMultTranspose_STOperator);CHKERRQ(ierr);
     213          19 :   PetscFunctionReturn(0);
     214             : }
     215             : 
     216             : /*@
     217             :    STSetUp - Prepares for the use of a spectral transformation.
     218             : 
     219             :    Collective on st
     220             : 
     221             :    Input Parameter:
     222             : .  st - the spectral transformation context
     223             : 
     224             :    Level: advanced
     225             : 
     226             : .seealso: STCreate(), STApply(), STDestroy()
     227             : @*/
     228         920 : PetscErrorCode STSetUp(ST st)
     229             : {
     230             :   PetscInt       i,n,k;
     231             :   PetscErrorCode ierr;
     232             : 
     233         920 :   PetscFunctionBegin;
     234         920 :   PetscValidHeaderSpecific(st,ST_CLASSID,1);
     235         920 :   PetscValidType(st,1);
     236         920 :   STCheckMatrices(st,1);
     237         920 :   switch (st->state) {
     238             :     case ST_STATE_INITIAL:
     239         802 :       ierr = PetscInfo(st,"Setting up new ST\n");CHKERRQ(ierr);
     240         802 :       if (!((PetscObject)st)->type_name) {
     241           0 :         ierr = STSetType(st,STSHIFT);CHKERRQ(ierr);
     242             :       }
     243             :       break;
     244             :     case ST_STATE_SETUP:
     245         111 :       PetscFunctionReturn(0);
     246             :     case ST_STATE_UPDATED:
     247           7 :       ierr = PetscInfo(st,"Setting up updated ST\n");CHKERRQ(ierr);
     248             :       break;
     249             :   }
     250         809 :   ierr = PetscLogEventBegin(ST_SetUp,st,0,0,0);CHKERRQ(ierr);
     251         809 :   if (!st->T) {
     252         599 :     ierr = PetscMalloc1(PetscMax(2,st->nmat),&st->T);CHKERRQ(ierr);
     253         599 :     ierr = PetscLogObjectMemory((PetscObject)st,PetscMax(2,st->nmat)*sizeof(Mat));CHKERRQ(ierr);
     254        1507 :     for (i=0;i<PetscMax(2,st->nmat);i++) st->T[i] = NULL;
     255         210 :   } else if (st->state!=ST_STATE_UPDATED) {
     256         414 :     for (i=0;i<PetscMax(2,st->nmat);i++) {
     257         414 :       ierr = MatDestroy(&st->T[i]);CHKERRQ(ierr);
     258             :     }
     259             :   }
     260         809 :   if (st->state!=ST_STATE_UPDATED) { ierr = MatDestroy(&st->P);CHKERRQ(ierr); }
     261         809 :   if (st->D) {
     262           8 :     ierr = MatGetLocalSize(st->A[0],NULL,&n);CHKERRQ(ierr);
     263           8 :     ierr = VecGetLocalSize(st->D,&k);CHKERRQ(ierr);
     264           8 :     if (n != k) SETERRQ2(PetscObjectComm((PetscObject)st),PETSC_ERR_ARG_SIZ,"Balance matrix has wrong dimension %D (should be %D)",k,n);
     265           8 :     if (!st->wb) {
     266           8 :       ierr = VecDuplicate(st->D,&st->wb);CHKERRQ(ierr);
     267           8 :       ierr = PetscLogObjectParent((PetscObject)st,(PetscObject)st->wb);CHKERRQ(ierr);
     268             :     }
     269             :   }
     270         809 :   ierr = STSetDefaultKSP(st);CHKERRQ(ierr);
     271         809 :   if (st->ops->setup) { ierr = (*st->ops->setup)(st);CHKERRQ(ierr); }
     272         809 :   st->state = ST_STATE_SETUP;
     273         809 :   ierr = PetscLogEventEnd(ST_SetUp,st,0,0,0);CHKERRQ(ierr);
     274         809 :   PetscFunctionReturn(0);
     275             : }
     276             : 
     277             : /*
     278             :    Computes coefficients for the transformed polynomial,
     279             :    and stores the result in argument S.
     280             : 
     281             :    alpha - value of the parameter of the transformed polynomial
     282             :    beta - value of the previous shift (only used in inplace mode)
     283             :    k - number of A matrices involved in the computation
     284             :    coeffs - coefficients of the expansion
     285             :    initial - true if this is the first time (only relevant for shell mode)
     286             : */
     287         899 : PetscErrorCode STMatMAXPY_Private(ST st,PetscScalar alpha,PetscScalar beta,PetscInt k,PetscScalar *coeffs,PetscBool initial,Mat *S)
     288             : {
     289             :   PetscErrorCode ierr;
     290         899 :   PetscInt       *matIdx=NULL,nmat,i,ini=-1;
     291         899 :   PetscScalar    t=1.0,ta,gamma;
     292         899 :   PetscBool      nz=PETSC_FALSE;
     293             : 
     294         899 :   PetscFunctionBegin;
     295         899 :   nmat = st->nmat-k;
     296         899 :   switch (st->shift_matrix) {
     297             :   case ST_MATMODE_INPLACE:
     298          18 :     if (st->nmat>2) SETERRQ(PetscObjectComm((PetscObject)st),PETSC_ERR_SUP,"ST_MATMODE_INPLACE not supported for polynomial eigenproblems");
     299          18 :     if (initial) {
     300          10 :       ierr = PetscObjectReference((PetscObject)st->A[0]);CHKERRQ(ierr);
     301          10 :       *S = st->A[0];
     302          10 :       gamma = alpha;
     303           8 :     } else gamma = alpha-beta;
     304          18 :     if (gamma != 0.0) {
     305          15 :       if (st->nmat>1) {
     306           5 :         ierr = MatAXPY(*S,gamma,st->A[1],st->str);CHKERRQ(ierr);
     307             :       } else {
     308          10 :         ierr = MatShift(*S,gamma);CHKERRQ(ierr);
     309             :       }
     310             :     }
     311             :     break;
     312             :   case ST_MATMODE_SHELL:
     313          63 :     if (initial) {
     314          45 :       if (st->nmat>2) {
     315          10 :         ierr = PetscMalloc1(nmat,&matIdx);CHKERRQ(ierr);
     316          29 :         for (i=0;i<nmat;i++) matIdx[i] = k+i;
     317             :       }
     318          45 :       ierr = STMatShellCreate(st,alpha,nmat,matIdx,coeffs,S);CHKERRQ(ierr);
     319          45 :       ierr = PetscLogObjectParent((PetscObject)st,(PetscObject)*S);CHKERRQ(ierr);
     320          45 :       if (st->nmat>2) { ierr = PetscFree(matIdx);CHKERRQ(ierr); }
     321             :     } else {
     322          18 :       ierr = STMatShellShift(*S,alpha);CHKERRQ(ierr);
     323             :     }
     324             :     break;
     325             :   case ST_MATMODE_COPY:
     326         818 :     if (coeffs) {
     327         294 :       for (i=0;i<nmat && ini==-1;i++) {
     328         294 :         if (coeffs[i]!=0.0) ini = i;
     329          86 :         else t *= alpha;
     330             :       }
     331         208 :       if (coeffs[ini] != 1.0) nz = PETSC_TRUE;
     332         208 :       for (i=ini+1;i<nmat&&!nz;i++) if (coeffs[i]!=0.0) nz = PETSC_TRUE;
     333             :     } else { nz = PETSC_TRUE; ini = 0; }
     334         818 :     if ((alpha == 0.0 || !nz) && t==1.0) {
     335         369 :       ierr = PetscObjectReference((PetscObject)st->A[k+ini]);CHKERRQ(ierr);
     336         369 :       ierr = MatDestroy(S);CHKERRQ(ierr);
     337         369 :       *S = st->A[k+ini];
     338             :     } else {
     339         449 :       if (*S && *S!=st->A[k+ini]) {
     340         283 :         ierr = MatSetOption(*S,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
     341         283 :         ierr = MatCopy(st->A[k+ini],*S,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
     342             :       } else {
     343         166 :         ierr = MatDestroy(S);CHKERRQ(ierr);
     344         166 :         ierr = MatDuplicate(st->A[k+ini],MAT_COPY_VALUES,S);CHKERRQ(ierr);
     345         166 :         ierr = MatSetOption(*S,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
     346         166 :         ierr = PetscLogObjectParent((PetscObject)st,(PetscObject)*S);CHKERRQ(ierr);
     347             :       }
     348         449 :       if (coeffs && coeffs[ini]!=1.0) {
     349           0 :         ierr = MatScale(*S,coeffs[ini]);CHKERRQ(ierr);
     350             :       }
     351        1137 :       for (i=ini+k+1;i<PetscMax(2,st->nmat);i++) {
     352         688 :         t *= alpha;
     353         688 :         ta = t;
     354         688 :         if (coeffs) ta *= coeffs[i-k];
     355         688 :         if (ta!=0.0) {
     356         688 :           if (st->nmat>1) {
     357         586 :             ierr = MatAXPY(*S,ta,st->A[i],st->str);CHKERRQ(ierr);
     358             :           } else {
     359         102 :             ierr = MatShift(*S,ta);CHKERRQ(ierr);
     360             :           }
     361             :         }
     362             :       }
     363             :     }
     364             :   }
     365         899 :   ierr = STMatSetHermitian(st,*S);CHKERRQ(ierr);
     366         899 :   PetscFunctionReturn(0);
     367             : }
     368             : 
     369             : /*
     370             :    Computes the values of the coefficients required by STMatMAXPY_Private
     371             :    for the case of monomial basis.
     372             : */
     373          34 : PetscErrorCode STCoeffs_Monomial(ST st, PetscScalar *coeffs)
     374             : {
     375             :   PetscInt  k,i,ini,inip;
     376             : 
     377          34 :   PetscFunctionBegin;
     378             :   /* Compute binomial coefficients */
     379          34 :   ini = (st->nmat*(st->nmat-1))/2;
     380          34 :   for (i=0;i<st->nmat;i++) coeffs[ini+i]=1.0;
     381         142 :   for (k=st->nmat-1;k>=1;k--) {
     382          74 :     inip = ini+1;
     383          74 :     ini = (k*(k-1))/2;
     384          74 :     coeffs[ini] = 1.0;
     385          74 :     for (i=1;i<k;i++) coeffs[ini+i] = coeffs[ini+i-1]+coeffs[inip+i-1];
     386             :   }
     387          34 :   PetscFunctionReturn(0);
     388             : }
     389             : 
     390             : /*@
     391             :    STPostSolve - Optional post-solve phase, intended for any actions that must
     392             :    be performed on the ST object after the eigensolver has finished.
     393             : 
     394             :    Collective on st
     395             : 
     396             :    Input Parameters:
     397             : .  st  - the spectral transformation context
     398             : 
     399             :    Level: developer
     400             : 
     401             : .seealso: EPSSolve()
     402             : @*/
     403         663 : PetscErrorCode STPostSolve(ST st)
     404             : {
     405             :   PetscErrorCode ierr;
     406             : 
     407         663 :   PetscFunctionBegin;
     408         663 :   PetscValidHeaderSpecific(st,ST_CLASSID,1);
     409         663 :   PetscValidType(st,1);
     410         663 :   if (st->ops->postsolve) {
     411         486 :     ierr = (*st->ops->postsolve)(st);CHKERRQ(ierr);
     412             :   }
     413         663 :   PetscFunctionReturn(0);
     414             : }
     415             : 
     416             : /*@
     417             :    STBackTransform - Back-transformation phase, intended for
     418             :    spectral transformations which require to transform the computed
     419             :    eigenvalues back to the original eigenvalue problem.
     420             : 
     421             :    Not Collective
     422             : 
     423             :    Input Parameters:
     424             : +  st   - the spectral transformation context
     425             :    eigr - real part of a computed eigenvalue
     426             : -  eigi - imaginary part of a computed eigenvalue
     427             : 
     428             :    Level: developer
     429             : 
     430             : .seealso: STIsInjective()
     431             : @*/
     432     1262057 : PetscErrorCode STBackTransform(ST st,PetscInt n,PetscScalar* eigr,PetscScalar* eigi)
     433             : {
     434             :   PetscErrorCode ierr;
     435             : 
     436     1262057 :   PetscFunctionBegin;
     437     1262057 :   PetscValidHeaderSpecific(st,ST_CLASSID,1);
     438     1262057 :   PetscValidType(st,1);
     439     1262057 :   if (st->ops->backtransform) {
     440      632907 :     ierr = (*st->ops->backtransform)(st,n,eigr,eigi);CHKERRQ(ierr);
     441             :   }
     442     1262057 :   PetscFunctionReturn(0);
     443             : }
     444             : 
     445             : /*@
     446             :    STIsInjective - Ask if this spectral transformation is injective or not
     447             :    (that is, if it corresponds to a one-to-one mapping). If not, then it
     448             :    does not make sense to call STBackTransform().
     449             : 
     450             :    Not collective
     451             : 
     452             :    Input Parameter:
     453             : .  st   - the spectral transformation context
     454             : 
     455             :    Output Parameter:
     456             : .  is - the answer
     457             : 
     458             :    Level: developer
     459             : 
     460             : .seealso: STBackTransform()
     461             : @*/
     462         362 : PetscErrorCode STIsInjective(ST st,PetscBool* is)
     463             : {
     464             :   PetscErrorCode ierr;
     465             :   PetscBool      shell;
     466             : 
     467         362 :   PetscFunctionBegin;
     468         362 :   PetscValidHeaderSpecific(st,ST_CLASSID,1);
     469         362 :   PetscValidType(st,1);
     470         362 :   PetscValidBoolPointer(is,2);
     471             : 
     472         362 :   ierr = PetscObjectTypeCompare((PetscObject)st,STSHELL,&shell);CHKERRQ(ierr);
     473         362 :   if (shell) {
     474          28 :     ierr = STIsInjective_Shell(st,is);CHKERRQ(ierr);
     475         334 :   } else *is = st->ops->backtransform? PETSC_TRUE: PETSC_FALSE;
     476         362 :   PetscFunctionReturn(0);
     477             : }
     478             : 
     479             : /*@
     480             :    STMatSetUp - Build the preconditioner matrix used in STMatSolve().
     481             : 
     482             :    Collective on st
     483             : 
     484             :    Input Parameters:
     485             : +  st     - the spectral transformation context
     486             : .  sigma  - the shift
     487             : -  coeffs - the coefficients (may be NULL)
     488             : 
     489             :    Note:
     490             :    This function is not intended to be called by end users, but by SLEPc
     491             :    solvers that use ST. It builds matrix st->P as follows, then calls KSPSetUp().
     492             : .vb
     493             :     If (coeffs):  st->P = Sum_{i=0:nmat-1} coeffs[i]*sigma^i*A_i.
     494             :     else          st->P = Sum_{i=0:nmat-1} sigma^i*A_i
     495             : .ve
     496             : 
     497             :    Level: developer
     498             : 
     499             : .seealso: STMatSolve()
     500             : @*/
     501         144 : PetscErrorCode STMatSetUp(ST st,PetscScalar sigma,PetscScalar *coeffs)
     502             : {
     503             :   PetscErrorCode ierr;
     504             : 
     505         144 :   PetscFunctionBegin;
     506         144 :   PetscValidHeaderSpecific(st,ST_CLASSID,1);
     507         288 :   PetscValidLogicalCollectiveScalar(st,sigma,2);
     508         144 :   STCheckMatrices(st,1);
     509             : 
     510         144 :   ierr = PetscLogEventBegin(ST_MatSetUp,st,0,0,0);CHKERRQ(ierr);
     511         144 :   ierr = STMatMAXPY_Private(st,sigma,0.0,0,coeffs,PETSC_TRUE,&st->P);CHKERRQ(ierr);
     512         144 :   if (!st->ksp) { ierr = STGetKSP(st,&st->ksp);CHKERRQ(ierr); }
     513         144 :   ierr = STCheckFactorPackage(st);CHKERRQ(ierr);
     514         144 :   ierr = KSPSetOperators(st->ksp,st->P,st->P);CHKERRQ(ierr);
     515         144 :   ierr = KSPSetUp(st->ksp);CHKERRQ(ierr);
     516         144 :   ierr = PetscLogEventEnd(ST_MatSetUp,st,0,0,0);CHKERRQ(ierr);
     517         144 :   PetscFunctionReturn(0);
     518             : }
     519             : 
     520             : /*@
     521             :    STSetWorkVecs - Sets a number of work vectors into the ST object.
     522             : 
     523             :    Collective on st
     524             : 
     525             :    Input Parameters:
     526             : +  st - the spectral transformation context
     527             : -  nw - number of work vectors to allocate
     528             : 
     529             :    Developers Note:
     530             :    This is SLEPC_EXTERN because it may be required by shell STs.
     531             : 
     532             :    Level: developer
     533             : @*/
     534         260 : PetscErrorCode STSetWorkVecs(ST st,PetscInt nw)
     535             : {
     536             :   PetscErrorCode ierr;
     537             :   PetscInt       i;
     538             : 
     539         260 :   PetscFunctionBegin;
     540         260 :   PetscValidHeaderSpecific(st,ST_CLASSID,1);
     541         520 :   PetscValidLogicalCollectiveInt(st,nw,2);
     542         260 :   if (nw <= 0) SETERRQ1(PetscObjectComm((PetscObject)st),PETSC_ERR_ARG_OUTOFRANGE,"nw must be > 0: nw = %D",nw);
     543         260 :   if (st->nwork < nw) {
     544         238 :     ierr = VecDestroyVecs(st->nwork,&st->work);CHKERRQ(ierr);
     545         238 :     st->nwork = nw;
     546         238 :     ierr = PetscMalloc1(nw,&st->work);CHKERRQ(ierr);
     547         255 :     for (i=0;i<nw;i++) { ierr = STMatCreateVecs(st,&st->work[i],NULL);CHKERRQ(ierr); }
     548         255 :     ierr = PetscLogObjectParents(st,nw,st->work);CHKERRQ(ierr);
     549             :   }
     550         260 :   PetscFunctionReturn(0);
     551             : }
     552             : 

Generated by: LCOV version 1.13