LCOV - code coverage report
Current view: top level - sys/classes/st/interface - stsles.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 190 197 96.4 %
Date: 2019-09-16 06:01:52 Functions: 13 13 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 related to the KSP object associated with it
      12             : */
      13             : 
      14             : #include <slepc/private/stimpl.h>            /*I "slepcst.h" I*/
      15             : 
      16             : /*
      17             :    This is used to set a default type for the KSP and PC objects.
      18             :    It is called at STSetFromOptions (before KSPSetFromOptions)
      19             :    and also at STSetUp (in case STSetFromOptions was not called).
      20             : */
      21        1332 : PetscErrorCode STSetDefaultKSP(ST st)
      22             : {
      23             :   PetscErrorCode ierr;
      24             : 
      25        1332 :   PetscFunctionBegin;
      26        1332 :   PetscValidHeaderSpecific(st,ST_CLASSID,1);
      27        1332 :   PetscValidType(st,1);
      28        1332 :   if (!st->ksp) { ierr = STGetKSP(st,&st->ksp);CHKERRQ(ierr); }
      29        1332 :   if (st->ops->setdefaultksp) { ierr = (*st->ops->setdefaultksp)(st);CHKERRQ(ierr); }
      30        1332 :   PetscFunctionReturn(0);
      31             : }
      32             : 
      33             : /*
      34             :    Checks whether the ST matrix is symmetric
      35             : */
      36         395 : PETSC_STATIC_INLINE PetscErrorCode STMatIsSymmetricKnown(ST st,PetscBool *symm)
      37             : {
      38             :   PetscErrorCode ierr;
      39             :   PetscInt       i;
      40             :   PetscBool      set,sbaij,asymm;
      41             : 
      42         395 :   PetscFunctionBegin;
      43         395 :   *symm = PETSC_FALSE;
      44         395 :   if (!st->nmat) PetscFunctionReturn(0);  /* STSetMatrices() not called yet */
      45             :   /* check if problem matrices are all sbaij */
      46           4 :   for (i=0;i<st->nmat;i++) {
      47         219 :     ierr = PetscObjectTypeCompareAny((PetscObject)st->A[i],&sbaij,MATSEQSBAIJ,MATMPISBAIJ,"");CHKERRQ(ierr);
      48         219 :     if (!sbaij) break;
      49             :   }
      50         217 :   if (sbaij) *symm = PETSC_TRUE;
      51             :   else {
      52             :     /* check if user has set the symmetric flag */
      53           0 :     for (i=0;i<st->nmat;i++) {
      54         215 :       ierr = MatIsSymmetricKnown(st->A[i],&set,&asymm);CHKERRQ(ierr);
      55         215 :       if (!set) asymm = PETSC_FALSE;
      56         215 :       if (!asymm) PetscFunctionReturn(0);
      57           2 :       if (PetscRealPart(st->sigma)==0.0) break;
      58             :     }
      59           2 :     *symm = PETSC_TRUE;
      60             :   }
      61           4 :   PetscFunctionReturn(0);
      62             : }
      63             : 
      64             : /*
      65             :    This is done by all ST types except PRECOND.
      66             :    The default is an LU direct solver, or GMRES+Jacobi if matmode=shell.
      67             : */
      68        1016 : PetscErrorCode STSetDefaultKSP_Default(ST st)
      69             : {
      70             :   PetscErrorCode ierr;
      71             :   PC             pc;
      72             :   PCType         pctype;
      73             :   KSPType        ksptype;
      74             :   PetscBool      asymm;
      75             : 
      76        1016 :   PetscFunctionBegin;
      77        1016 :   ierr = KSPGetPC(st->ksp,&pc);CHKERRQ(ierr);
      78        1016 :   ierr = KSPGetType(st->ksp,&ksptype);CHKERRQ(ierr);
      79        1016 :   ierr = PCGetType(pc,&pctype);CHKERRQ(ierr);
      80        1016 :   if (!pctype && !ksptype) {
      81         420 :     if (st->shift_matrix == ST_MATMODE_SHELL) {
      82          25 :       ierr = KSPSetType(st->ksp,KSPGMRES);CHKERRQ(ierr);
      83          25 :       ierr = PCSetType(pc,PCJACOBI);CHKERRQ(ierr);
      84             :     } else {
      85         395 :       ierr = STMatIsSymmetricKnown(st,&asymm);CHKERRQ(ierr);
      86         395 :       ierr = KSPSetType(st->ksp,KSPPREONLY);CHKERRQ(ierr);
      87         395 :       ierr = PCSetType(pc,asymm?PCCHOLESKY:PCLU);CHKERRQ(ierr);
      88             :     }
      89             :   }
      90        1016 :   ierr = KSPSetErrorIfNotConverged(st->ksp,PETSC_TRUE);CHKERRQ(ierr);
      91        1016 :   PetscFunctionReturn(0);
      92             : }
      93             : 
      94             : /*@
      95             :    STMatMult - Computes the matrix-vector product y = T[k] x, where T[k] is
      96             :    the k-th matrix of the spectral transformation.
      97             : 
      98             :    Neighbor-wise Collective on st
      99             : 
     100             :    Input Parameters:
     101             : +  st - the spectral transformation context
     102             : .  k  - index of matrix to use
     103             : -  x  - the vector to be multiplied
     104             : 
     105             :    Output Parameter:
     106             : .  y - the result
     107             : 
     108             :    Level: developer
     109             : 
     110             : .seealso: STMatMultTranspose()
     111             : @*/
     112       45717 : PetscErrorCode STMatMult(ST st,PetscInt k,Vec x,Vec y)
     113             : {
     114             :   PetscErrorCode ierr;
     115             : 
     116       45717 :   PetscFunctionBegin;
     117       45717 :   PetscValidHeaderSpecific(st,ST_CLASSID,1);
     118       91434 :   PetscValidLogicalCollectiveInt(st,k,2);
     119       45717 :   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
     120       45717 :   PetscValidHeaderSpecific(y,VEC_CLASSID,4);
     121       45717 :   STCheckMatrices(st,1);
     122       45717 :   if (k<0 || k>=PetscMax(2,st->nmat)) SETERRQ1(PetscObjectComm((PetscObject)st),PETSC_ERR_ARG_OUTOFRANGE,"k must be between 0 and %D",st->nmat);
     123       45717 :   if (x == y) SETERRQ(PetscObjectComm((PetscObject)st),PETSC_ERR_ARG_IDN,"x and y must be different vectors");
     124       45717 :   ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr);
     125             : 
     126       45717 :   if (st->state!=ST_STATE_SETUP) { ierr = STSetUp(st);CHKERRQ(ierr); }
     127       45717 :   ierr = VecLockReadPush(x);CHKERRQ(ierr);
     128       45717 :   ierr = PetscLogEventBegin(ST_MatMult,st,x,y,0);CHKERRQ(ierr);
     129       45717 :   if (!st->T[k]) {
     130             :     /* T[k]=NULL means identity matrix */
     131           0 :     ierr = VecCopy(x,y);CHKERRQ(ierr);
     132             :   } else {
     133       45717 :     ierr = MatMult(st->T[k],x,y);CHKERRQ(ierr);
     134             :   }
     135       45717 :   ierr = PetscLogEventEnd(ST_MatMult,st,x,y,0);CHKERRQ(ierr);
     136       45717 :   ierr = VecLockReadPop(x);CHKERRQ(ierr);
     137       45717 :   PetscFunctionReturn(0);
     138             : }
     139             : 
     140             : /*@
     141             :    STMatMultTranspose - Computes the matrix-vector product y = T[k]' x, where T[k] is
     142             :    the k-th matrix of the spectral transformation.
     143             : 
     144             :    Neighbor-wise Collective on st
     145             : 
     146             :    Input Parameters:
     147             : +  st - the spectral transformation context
     148             : .  k  - index of matrix to use
     149             : -  x  - the vector to be multiplied
     150             : 
     151             :    Output Parameter:
     152             : .  y - the result
     153             : 
     154             :    Level: developer
     155             : 
     156             : .seealso: STMatMult()
     157             : @*/
     158           3 : PetscErrorCode STMatMultTranspose(ST st,PetscInt k,Vec x,Vec y)
     159             : {
     160             :   PetscErrorCode ierr;
     161             : 
     162           3 :   PetscFunctionBegin;
     163           3 :   PetscValidHeaderSpecific(st,ST_CLASSID,1);
     164           6 :   PetscValidLogicalCollectiveInt(st,k,2);
     165           3 :   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
     166           3 :   PetscValidHeaderSpecific(y,VEC_CLASSID,4);
     167           3 :   STCheckMatrices(st,1);
     168           3 :   if (k<0 || k>=PetscMax(2,st->nmat)) SETERRQ1(PetscObjectComm((PetscObject)st),PETSC_ERR_ARG_OUTOFRANGE,"k must be between 0 and %D",st->nmat);
     169           3 :   if (x == y) SETERRQ(PetscObjectComm((PetscObject)st),PETSC_ERR_ARG_IDN,"x and y must be different vectors");
     170           3 :   ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr);
     171             : 
     172           3 :   if (st->state!=ST_STATE_SETUP) { ierr = STSetUp(st);CHKERRQ(ierr); }
     173           3 :   ierr = VecLockReadPush(x);CHKERRQ(ierr);
     174           3 :   ierr = PetscLogEventBegin(ST_MatMultTranspose,st,x,y,0);CHKERRQ(ierr);
     175           3 :   if (!st->T[k]) {
     176             :     /* T[k]=NULL means identity matrix */
     177           0 :     ierr = VecCopy(x,y);CHKERRQ(ierr);
     178             :   } else {
     179           3 :     ierr = MatMultTranspose(st->T[k],x,y);CHKERRQ(ierr);
     180             :   }
     181           3 :   ierr = PetscLogEventEnd(ST_MatMultTranspose,st,x,y,0);CHKERRQ(ierr);
     182           3 :   ierr = VecLockReadPop(x);CHKERRQ(ierr);
     183           3 :   PetscFunctionReturn(0);
     184             : }
     185             : 
     186             : /*@
     187             :    STMatSolve - Solves P x = b, where P is the preconditioner matrix of
     188             :    the spectral transformation, using a KSP object stored internally.
     189             : 
     190             :    Collective on st
     191             : 
     192             :    Input Parameters:
     193             : +  st - the spectral transformation context
     194             : -  b  - right hand side vector
     195             : 
     196             :    Output Parameter:
     197             : .  x - computed solution
     198             : 
     199             :    Level: developer
     200             : 
     201             : .seealso: STMatSolveTranspose()
     202             : @*/
     203       77609 : PetscErrorCode STMatSolve(ST st,Vec b,Vec x)
     204             : {
     205             :   PetscErrorCode ierr;
     206             :   PetscInt       its;
     207             :   PetscBool      flg;
     208             : 
     209       77609 :   PetscFunctionBegin;
     210       77609 :   PetscValidHeaderSpecific(st,ST_CLASSID,1);
     211       77609 :   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
     212       77609 :   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
     213       77609 :   STCheckMatrices(st,1);
     214       77609 :   if (x == b) SETERRQ(PetscObjectComm((PetscObject)st),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
     215       77609 :   ierr = VecSetErrorIfLocked(x,3);CHKERRQ(ierr);
     216             : 
     217       77609 :   if (st->state!=ST_STATE_SETUP) { ierr = STSetUp(st);CHKERRQ(ierr); }
     218       77609 :   ierr = VecLockReadPush(b);CHKERRQ(ierr);
     219       77609 :   ierr = PetscLogEventBegin(ST_MatSolve,st,b,x,0);CHKERRQ(ierr);
     220       77609 :   ierr = PetscObjectTypeCompareAny((PetscObject)st,&flg,STPRECOND,STSHELL,"");CHKERRQ(ierr);
     221       77609 :   if (!flg && !st->P) {
     222             :     /* P=NULL means identity matrix */
     223           8 :     ierr = VecCopy(b,x);CHKERRQ(ierr);
     224             :   } else {
     225       77601 :     if (!st->ksp) { ierr = STGetKSP(st,&st->ksp);CHKERRQ(ierr); }
     226       77601 :     ierr = KSPSolve(st->ksp,b,x);CHKERRQ(ierr);
     227       77601 :     ierr = KSPGetIterationNumber(st->ksp,&its);CHKERRQ(ierr);
     228       77601 :     ierr = PetscInfo1(st,"Linear solve iterations=%D\n",its);CHKERRQ(ierr);
     229             :   }
     230       77609 :   ierr = PetscLogEventEnd(ST_MatSolve,st,b,x,0);CHKERRQ(ierr);
     231       77609 :   ierr = VecLockReadPop(b);CHKERRQ(ierr);
     232       77609 :   PetscFunctionReturn(0);
     233             : }
     234             : 
     235             : /*@
     236             :    STMatSolveTranspose - Solves P' x = b, where P is the preconditioner matrix of
     237             :    the spectral transformation, using a KSP object stored internally.
     238             : 
     239             :    Collective on st
     240             : 
     241             :    Input Parameters:
     242             : .  st - the spectral transformation context
     243             : .  b  - right hand side vector
     244             : 
     245             :    Output Parameter:
     246             : .  x - computed solution
     247             : 
     248             :    Level: developer
     249             : 
     250             : .seealso: STMatSolve()
     251             : @*/
     252         605 : PetscErrorCode STMatSolveTranspose(ST st,Vec b,Vec x)
     253             : {
     254             :   PetscErrorCode ierr;
     255             :   PetscInt       its;
     256             :   PetscBool      flg;
     257             : 
     258         605 :   PetscFunctionBegin;
     259         605 :   PetscValidHeaderSpecific(st,ST_CLASSID,1);
     260         605 :   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
     261         605 :   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
     262         605 :   STCheckMatrices(st,1);
     263         605 :   if (x == b) SETERRQ(PetscObjectComm((PetscObject)st),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
     264         605 :   ierr = VecSetErrorIfLocked(x,3);CHKERRQ(ierr);
     265             : 
     266         605 :   if (st->state!=ST_STATE_SETUP) { ierr = STSetUp(st);CHKERRQ(ierr); }
     267         605 :   ierr = VecLockReadPush(b);CHKERRQ(ierr);
     268         605 :   ierr = PetscLogEventBegin(ST_MatSolveTranspose,st,b,x,0);CHKERRQ(ierr);
     269         605 :   ierr = PetscObjectTypeCompareAny((PetscObject)st,&flg,STPRECOND,STSHELL,"");CHKERRQ(ierr);
     270         605 :   if (!flg && !st->P) {
     271             :     /* P=NULL means identity matrix */
     272           0 :     ierr = VecCopy(b,x);CHKERRQ(ierr);
     273             :   } else {
     274         605 :     if (!st->ksp) { ierr = STGetKSP(st,&st->ksp);CHKERRQ(ierr); }
     275         605 :     ierr = KSPSolveTranspose(st->ksp,b,x);CHKERRQ(ierr);
     276         605 :     ierr = KSPGetIterationNumber(st->ksp,&its);CHKERRQ(ierr);
     277         605 :     ierr = PetscInfo1(st,"Linear solve iterations=%D\n",its);CHKERRQ(ierr);
     278             :   }
     279         605 :   ierr = PetscLogEventEnd(ST_MatSolveTranspose,st,b,x,0);CHKERRQ(ierr);
     280         605 :   ierr = VecLockReadPop(b);CHKERRQ(ierr);
     281         605 :   PetscFunctionReturn(0);
     282             : }
     283             : 
     284             : /*
     285             :    STMatSetHermitian - Sets the symmetric and/or Hermitian flag to the ST matrix.
     286             : 
     287             :    Input Parameters:
     288             : .  st - the spectral transformation context
     289             : .  M  - matrix
     290             : */
     291         942 : PetscErrorCode STMatSetHermitian(ST st,Mat M)
     292             : {
     293             :   PetscErrorCode ierr;
     294             :   PetscBool      set,aherm,mherm;
     295             :   PetscInt       i;
     296             : 
     297         942 :   PetscFunctionBegin;
     298         942 :   if (!st->nmat) PetscFunctionReturn(0);  /* STSetMatrices() not called yet */
     299             :   mherm = PETSC_TRUE;
     300          64 :   for (i=0;i<st->nmat;i++) {
     301         974 :     ierr = MatIsSymmetricKnown(st->A[i],&set,&aherm);CHKERRQ(ierr);
     302         974 :     if (!set) aherm = PETSC_FALSE;
     303         974 :     if (!aherm) { mherm = PETSC_FALSE; break; }
     304          68 :     if (PetscRealPart(st->sigma)==0.0) break;
     305             :   }
     306         942 :   ierr = MatSetOption(M,MAT_SYMMETRIC,mherm);CHKERRQ(ierr);
     307             : #if defined(PETSC_USE_COMPLEX)
     308             :   if (PetscImaginaryPart(st->sigma)==0.0) {
     309             :     mherm = PETSC_TRUE;
     310             :     for (i=0;i<st->nmat;i++) {
     311             :       ierr = MatIsHermitianKnown(st->A[i],&set,&aherm);CHKERRQ(ierr);
     312             :       if (!set) aherm = PETSC_FALSE;
     313             :       if (!aherm) { mherm = PETSC_FALSE; break; }
     314             :       if (PetscRealPart(st->sigma)==0.0) break;
     315             :     }
     316             :     ierr = MatSetOption(M,MAT_HERMITIAN,mherm);CHKERRQ(ierr);
     317             :   }
     318             : #endif
     319         942 :   PetscFunctionReturn(0);
     320             : }
     321             : 
     322         317 : PetscErrorCode STCheckFactorPackage(ST st)
     323             : {
     324             :   PetscErrorCode ierr;
     325             :   PC             pc;
     326             :   PetscMPIInt    size;
     327             :   PetscBool      flg;
     328             :   MatSolverType  stype;
     329             : 
     330         317 :   PetscFunctionBegin;
     331         317 :   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)st),&size);CHKERRQ(ierr);
     332         317 :   if (size==1) PetscFunctionReturn(0);
     333          32 :   ierr = KSPGetPC(st->ksp,&pc);CHKERRQ(ierr);
     334          32 :   ierr = PCFactorGetMatSolverType(pc,&stype);CHKERRQ(ierr);
     335          32 :   if (stype) {   /* currently selected PC is a factorization */
     336           0 :     ierr = PetscStrcmp(stype,MATSOLVERPETSC,&flg);CHKERRQ(ierr);
     337           0 :     if (flg) SETERRQ(PetscObjectComm((PetscObject)st),PETSC_ERR_SUP,"You chose to solve linear systems with a factorization, but in parallel runs you need to select an external package; see the users guide for details");
     338             :   }
     339          32 :   PetscFunctionReturn(0);
     340             : }
     341             : 
     342             : /*@
     343             :    STSetKSP - Sets the KSP object associated with the spectral
     344             :    transformation.
     345             : 
     346             :    Collective on st
     347             : 
     348             :    Input Parameters:
     349             : +  st   - the spectral transformation context
     350             : -  ksp  - the linear system context
     351             : 
     352             :    Level: advanced
     353             : @*/
     354           3 : PetscErrorCode STSetKSP(ST st,KSP ksp)
     355             : {
     356             :   PetscErrorCode ierr;
     357             : 
     358           3 :   PetscFunctionBegin;
     359           3 :   PetscValidHeaderSpecific(st,ST_CLASSID,1);
     360           3 :   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
     361           3 :   PetscCheckSameComm(st,1,ksp,2);
     362           3 :   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
     363           3 :   ierr = KSPDestroy(&st->ksp);CHKERRQ(ierr);
     364           3 :   st->ksp = ksp;
     365           3 :   ierr = PetscLogObjectParent((PetscObject)st,(PetscObject)st->ksp);CHKERRQ(ierr);
     366           3 :   PetscFunctionReturn(0);
     367             : }
     368             : 
     369             : /*@
     370             :    STGetKSP - Gets the KSP object associated with the spectral
     371             :    transformation.
     372             : 
     373             :    Not Collective
     374             : 
     375             :    Input Parameter:
     376             : .  st - the spectral transformation context
     377             : 
     378             :    Output Parameter:
     379             : .  ksp  - the linear system context
     380             : 
     381             :    Level: intermediate
     382             : @*/
     383        2714 : PetscErrorCode STGetKSP(ST st,KSP* ksp)
     384             : {
     385             :   PetscErrorCode ierr;
     386             : 
     387        2714 :   PetscFunctionBegin;
     388        2714 :   PetscValidHeaderSpecific(st,ST_CLASSID,1);
     389        2714 :   PetscValidPointer(ksp,2);
     390        2714 :   if (!st->ksp) {
     391         557 :     ierr = KSPCreate(PetscObjectComm((PetscObject)st),&st->ksp);CHKERRQ(ierr);
     392         557 :     ierr = PetscObjectIncrementTabLevel((PetscObject)st->ksp,(PetscObject)st,1);CHKERRQ(ierr);
     393         557 :     ierr = KSPSetOptionsPrefix(st->ksp,((PetscObject)st)->prefix);CHKERRQ(ierr);
     394         557 :     ierr = KSPAppendOptionsPrefix(st->ksp,"st_");CHKERRQ(ierr);
     395         557 :     ierr = PetscLogObjectParent((PetscObject)st,(PetscObject)st->ksp);CHKERRQ(ierr);
     396         557 :     ierr = PetscObjectSetOptions((PetscObject)st->ksp,((PetscObject)st)->options);CHKERRQ(ierr);
     397         557 :     ierr = KSPSetTolerances(st->ksp,SLEPC_DEFAULT_TOL,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
     398             :   }
     399        2714 :   *ksp = st->ksp;
     400        2714 :   PetscFunctionReturn(0);
     401             : }
     402             : 
     403           1 : PetscErrorCode STCheckNullSpace_Default(ST st,BV V)
     404             : {
     405             :   PetscErrorCode ierr;
     406             :   PetscInt       nc,i,c;
     407             :   PetscReal      norm;
     408             :   Vec            *T,w,vi;
     409             :   Mat            A;
     410             :   PC             pc;
     411             :   MatNullSpace   nullsp;
     412             : 
     413           1 :   PetscFunctionBegin;
     414           1 :   ierr = BVGetNumConstraints(V,&nc);CHKERRQ(ierr);
     415           1 :   ierr = PetscMalloc1(nc,&T);CHKERRQ(ierr);
     416           1 :   if (!st->ksp) { ierr = STGetKSP(st,&st->ksp);CHKERRQ(ierr); }
     417           1 :   ierr = KSPGetPC(st->ksp,&pc);CHKERRQ(ierr);
     418           1 :   ierr = PCGetOperators(pc,&A,NULL);CHKERRQ(ierr);
     419           1 :   ierr = MatCreateVecs(A,NULL,&w);CHKERRQ(ierr);
     420             :   c = 0;
     421           1 :   for (i=0;i<nc;i++) {
     422           1 :     ierr = BVGetColumn(V,-nc+i,&vi);CHKERRQ(ierr);
     423           1 :     ierr = MatMult(A,vi,w);CHKERRQ(ierr);
     424           1 :     ierr = VecNorm(w,NORM_2,&norm);CHKERRQ(ierr);
     425           1 :     if (norm < 1e-8) {
     426           1 :       ierr = PetscInfo2(st,"Vector %D norm=%g\n",i,(double)norm);CHKERRQ(ierr);
     427           1 :       ierr = BVCreateVec(V,T+c);CHKERRQ(ierr);
     428           1 :       ierr = VecCopy(vi,T[c]);CHKERRQ(ierr);
     429           1 :       c++;
     430             :     }
     431           1 :     ierr = BVRestoreColumn(V,-nc+i,&vi);CHKERRQ(ierr);
     432             :   }
     433           1 :   ierr = VecDestroy(&w);CHKERRQ(ierr);
     434           1 :   if (c>0) {
     435           1 :     ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)st),PETSC_FALSE,c,T,&nullsp);CHKERRQ(ierr);
     436           1 :     ierr = MatSetNullSpace(A,nullsp);CHKERRQ(ierr);
     437           1 :     ierr = MatNullSpaceDestroy(&nullsp);CHKERRQ(ierr);
     438           1 :     ierr = VecDestroyVecs(c,&T);CHKERRQ(ierr);
     439             :   } else {
     440           0 :     ierr = PetscFree(T);CHKERRQ(ierr);
     441             :   }
     442           1 :   PetscFunctionReturn(0);
     443             : }
     444             : 
     445             : /*@
     446             :    STCheckNullSpace - Given a basis vectors object, this function tests each
     447             :    of its constraint vectors to be a nullspace vector of the coefficient
     448             :    matrix of the associated KSP object. All these nullspace vectors are passed
     449             :    to the KSP object.
     450             : 
     451             :    Collective on st
     452             : 
     453             :    Input Parameters:
     454             : +  st - the spectral transformation context
     455             : -  V  - basis vectors to be checked
     456             : 
     457             :    Note:
     458             :    This function allows to handle singular pencils and to solve some problems
     459             :    in which the nullspace is important (see the users guide for details).
     460             : 
     461             :    Level: developer
     462             : 
     463             : .seealso: EPSSetDeflationSpace()
     464             : @*/
     465          14 : PetscErrorCode STCheckNullSpace(ST st,BV V)
     466             : {
     467             :   PetscErrorCode ierr;
     468             :   PetscInt       nc;
     469             : 
     470          14 :   PetscFunctionBegin;
     471          14 :   PetscValidHeaderSpecific(st,ST_CLASSID,1);
     472          14 :   PetscValidHeaderSpecific(V,BV_CLASSID,2);
     473          14 :   PetscValidType(st,1);
     474          14 :   PetscCheckSameComm(st,1,V,2);
     475          14 :   if (!st->state) SETERRQ(PetscObjectComm((PetscObject)st),PETSC_ERR_ARG_WRONGSTATE,"Must call STSolve() first");
     476             : 
     477          14 :   ierr = BVGetNumConstraints(V,&nc);CHKERRQ(ierr);
     478          14 :   if (nc && st->ops->checknullspace) {
     479           1 :     ierr = (*st->ops->checknullspace)(st,V);CHKERRQ(ierr);
     480             :   }
     481          14 :   PetscFunctionReturn(0);
     482             : }
     483             : 

Generated by: LCOV version 1.13