LCOV - code coverage report
Current view: top level - sys/classes/st/impls/shift - shift.c (source / functions) Hit Total Coverage
Test: SLEPc Lines: 100 100 100.0 %
Date: 2024-12-18 00:51:33 Functions: 7 7 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       3             :    SLEPc - Scalable Library for Eigenvalue Problem Computations
       4             :    Copyright (c) 2002-, 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             :    Shift spectral transformation, applies (A + sigma I) as operator, or
      12             :    inv(B)(A + sigma B) for generalized problems
      13             : */
      14             : 
      15             : #include <slepc/private/stimpl.h>
      16             : 
      17             : /*
      18             :    Special STApply() for the BSE structured matrix
      19             : 
      20             :        H = [ R  C; -C^H -R^T ].
      21             : 
      22             :    Assumes that H is a MATNEST and x,y are VECNEST.
      23             : 
      24             :    Only the upper part of the product y=H*x is computed.
      25             : 
      26             :        y1 = R*x1+C*x2
      27             : 
      28             :    The bottom part of the input vector x2 should normally contain
      29             :    either conj(x1) or -conj(x1).
      30             :    The bottom part of the output vector y2 is not referenced.
      31             : */
      32        8423 : static PetscErrorCode STApply_Shift_BSE(ST st,Vec x,Vec y)
      33             : {
      34        8423 :   Mat   H,R,C;
      35        8423 :   Vec   x1,x2,y1;
      36             : 
      37        8423 :   PetscFunctionBegin;
      38        8423 :   H = st->T[0];
      39        8423 :   PetscCall(MatNestGetSubMat(H,0,0,&R));
      40        8423 :   PetscCall(MatNestGetSubMat(H,0,1,&C));
      41        8423 :   PetscCall(VecNestGetSubVec(x,0,&x1));
      42        8423 :   PetscCall(VecNestGetSubVec(x,1,&x2));
      43        8423 :   PetscCall(VecNestGetSubVec(y,0,&y1));
      44        8423 :   PetscCall(MatMult(C,x2,y1));
      45        8423 :   PetscCall(MatMultAdd(R,x1,y1,y1));
      46        8423 :   PetscFunctionReturn(PETSC_SUCCESS);
      47             : }
      48             : 
      49      853324 : static PetscErrorCode STBackTransform_Shift(ST st,PetscInt n,PetscScalar *eigr,PetscScalar *eigi)
      50             : {
      51      853324 :   PetscInt j;
      52             : 
      53      853324 :   PetscFunctionBegin;
      54     2548173 :   for (j=0;j<n;j++) {
      55     1694849 :     eigr[j] += st->sigma;
      56             :   }
      57      853324 :   PetscFunctionReturn(PETSC_SUCCESS);
      58             : }
      59             : 
      60         573 : static PetscErrorCode STPostSolve_Shift(ST st)
      61             : {
      62         573 :   PetscFunctionBegin;
      63         573 :   if (st->matmode == ST_MATMODE_INPLACE) {
      64           4 :     if (st->nmat>1) PetscCall(MatAXPY(st->A[0],st->sigma,st->A[1],st->str));
      65           3 :     else PetscCall(MatShift(st->A[0],st->sigma));
      66           4 :     st->Astate[0] = ((PetscObject)st->A[0])->state;
      67           4 :     st->state   = ST_STATE_INITIAL;
      68           4 :     st->opready = PETSC_FALSE;
      69             :   }
      70         573 :   PetscFunctionReturn(PETSC_SUCCESS);
      71             : }
      72             : 
      73             : /*
      74             :    Operator (shift):
      75             :                Op               P         M
      76             :    if nmat=1:  A-sI             NULL      A-sI
      77             :    if nmat=2:  B^-1 (A-sB)      B         A-sB
      78             : */
      79         424 : static PetscErrorCode STComputeOperator_Shift(ST st)
      80             : {
      81         424 :   PetscFunctionBegin;
      82         424 :   st->usesksp = (st->nmat>1)? PETSC_TRUE: PETSC_FALSE;
      83         424 :   PetscCall(PetscObjectReference((PetscObject)st->A[1]));
      84         424 :   PetscCall(MatDestroy(&st->T[1]));
      85         424 :   st->T[1] = st->A[1];
      86         424 :   PetscCall(STMatMAXPY_Private(st,-st->sigma,0.0,0,NULL,PetscNot(st->state==ST_STATE_UPDATED),PETSC_FALSE,&st->T[0]));
      87         424 :   if (st->nmat>1) PetscCall(PetscObjectReference((PetscObject)st->T[1]));
      88         424 :   PetscCall(MatDestroy(&st->P));
      89         424 :   st->P = (st->nmat>1)? st->T[1]: NULL;
      90         424 :   st->M = st->T[0];
      91         424 :   if (st->nmat>1 && st->Psplit) {  /* build custom preconditioner from the split matrices */
      92           1 :     PetscCall(MatDestroy(&st->Pmat));
      93           1 :     PetscCall(PetscObjectReference((PetscObject)st->Psplit[1]));
      94           1 :     st->Pmat = st->Psplit[1];
      95             :   }
      96         424 :   PetscFunctionReturn(PETSC_SUCCESS);
      97             : }
      98             : 
      99         501 : static PetscErrorCode STSetUp_Shift(ST st)
     100             : {
     101         501 :   PetscInt       k,nc,nmat=st->nmat;
     102         501 :   PetscScalar    *coeffs=NULL;
     103             : 
     104         501 :   PetscFunctionBegin;
     105         501 :   if (nmat>1) PetscCall(STSetWorkVecs(st,1));
     106         501 :   if (nmat>2) {  /* set-up matrices for polynomial eigenproblems */
     107          77 :     if (st->transform) {
     108          14 :       nc = (nmat*(nmat+1))/2;
     109          14 :       PetscCall(PetscMalloc1(nc,&coeffs));
     110             :       /* Compute coeffs */
     111          14 :       PetscCall(STCoeffs_Monomial(st,coeffs));
     112             :       /* T[n] = A_n */
     113          14 :       k = nmat-1;
     114          14 :       PetscCall(PetscObjectReference((PetscObject)st->A[k]));
     115          14 :       PetscCall(MatDestroy(&st->T[k]));
     116          14 :       st->T[k] = st->A[k];
     117          45 :       for (k=0;k<nmat-1;k++) PetscCall(STMatMAXPY_Private(st,nmat>2?st->sigma:-st->sigma,0.0,k,coeffs?coeffs+((nmat-k)*(nmat-k-1))/2:NULL,PetscNot(st->state==ST_STATE_UPDATED),PETSC_FALSE,&st->T[k]));
     118          14 :       PetscCall(PetscFree(coeffs));
     119          14 :       PetscCall(PetscObjectReference((PetscObject)st->T[nmat-1]));
     120          14 :       PetscCall(MatDestroy(&st->P));
     121          14 :       st->P = st->T[nmat-1];
     122          14 :       if (st->Psplit) {  /* build custom preconditioner from the split matrices */
     123           1 :         PetscCall(STMatMAXPY_Private(st,st->sigma,0.0,nmat-1,coeffs?coeffs:NULL,PETSC_TRUE,PETSC_TRUE,&st->Pmat));
     124             :       }
     125          14 :       PetscCall(ST_KSPSetOperators(st,st->P,st->Pmat?st->Pmat:st->P));
     126             :     } else {
     127         276 :       for (k=0;k<nmat;k++) {
     128         213 :         PetscCall(PetscObjectReference((PetscObject)st->A[k]));
     129         213 :         PetscCall(MatDestroy(&st->T[k]));
     130         213 :         st->T[k] = st->A[k];
     131             :       }
     132             :     }
     133             :   }
     134         501 :   if (st->P) PetscCall(KSPSetUp(st->ksp));
     135         501 :   if (st->structured) st->ops->apply = STApply_Shift_BSE;
     136         501 :   PetscFunctionReturn(PETSC_SUCCESS);
     137             : }
     138             : 
     139          18 : static PetscErrorCode STSetShift_Shift(ST st,PetscScalar newshift)
     140             : {
     141          18 :   PetscInt       k,nc,nmat=PetscMax(st->nmat,2);
     142          18 :   PetscScalar    *coeffs=NULL;
     143             : 
     144          18 :   PetscFunctionBegin;
     145          18 :   if (st->transform) {
     146          16 :     if (st->matmode == ST_MATMODE_COPY && nmat>2) {
     147           2 :       nc = (nmat*(nmat+1))/2;
     148           2 :       PetscCall(PetscMalloc1(nc,&coeffs));
     149             :       /* Compute coeffs */
     150           2 :       PetscCall(STCoeffs_Monomial(st,coeffs));
     151             :     }
     152          38 :     for (k=0;k<nmat-1;k++) PetscCall(STMatMAXPY_Private(st,nmat>2?newshift:-newshift,nmat>2?st->sigma:-st->sigma,k,coeffs?coeffs+((nmat-k)*(nmat-k-1))/2:NULL,PETSC_FALSE,PETSC_FALSE,&st->T[k]));
     153          16 :     if (st->matmode == ST_MATMODE_COPY && nmat>2) PetscCall(PetscFree(coeffs));
     154          16 :     if (st->nmat<=2) st->M = st->T[0];
     155             :   }
     156          18 :   PetscFunctionReturn(PETSC_SUCCESS);
     157             : }
     158             : 
     159         576 : SLEPC_EXTERN PetscErrorCode STCreate_Shift(ST st)
     160             : {
     161         576 :   PetscFunctionBegin;
     162         576 :   st->usesksp = PETSC_TRUE;
     163             : 
     164         576 :   st->ops->apply           = STApply_Generic;
     165         576 :   st->ops->applytrans      = STApplyTranspose_Generic;
     166         576 :   st->ops->applyhermtrans  = STApplyHermitianTranspose_Generic;
     167         576 :   st->ops->backtransform   = STBackTransform_Shift;
     168         576 :   st->ops->setshift        = STSetShift_Shift;
     169         576 :   st->ops->getbilinearform = STGetBilinearForm_Default;
     170         576 :   st->ops->setup           = STSetUp_Shift;
     171         576 :   st->ops->computeoperator = STComputeOperator_Shift;
     172         576 :   st->ops->postsolve       = STPostSolve_Shift;
     173         576 :   st->ops->setdefaultksp   = STSetDefaultKSP_Default;
     174         576 :   PetscFunctionReturn(PETSC_SUCCESS);
     175             : }

Generated by: LCOV version 1.14