LCOV - code coverage report
Current view: top level - sys/classes/st/impls/shift - shift.c (source / functions) Hit Total Coverage
Test: SLEPc Lines: 86 86 100.0 %
Date: 2024-04-25 00:48:42 Functions: 6 6 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     1592369 : static PetscErrorCode STBackTransform_Shift(ST st,PetscInt n,PetscScalar *eigr,PetscScalar *eigi)
      18             : {
      19     1592369 :   PetscInt j;
      20             : 
      21     1592369 :   PetscFunctionBegin;
      22     4657740 :   for (j=0;j<n;j++) {
      23     3065371 :     eigr[j] += st->sigma;
      24             :   }
      25     1592369 :   PetscFunctionReturn(PETSC_SUCCESS);
      26             : }
      27             : 
      28         567 : static PetscErrorCode STPostSolve_Shift(ST st)
      29             : {
      30         567 :   PetscFunctionBegin;
      31         567 :   if (st->matmode == ST_MATMODE_INPLACE) {
      32           3 :     if (st->nmat>1) PetscCall(MatAXPY(st->A[0],st->sigma,st->A[1],st->str));
      33           2 :     else PetscCall(MatShift(st->A[0],st->sigma));
      34           3 :     st->Astate[0] = ((PetscObject)st->A[0])->state;
      35           3 :     st->state   = ST_STATE_INITIAL;
      36           3 :     st->opready = PETSC_FALSE;
      37             :   }
      38         567 :   PetscFunctionReturn(PETSC_SUCCESS);
      39             : }
      40             : 
      41             : /*
      42             :    Operator (shift):
      43             :                Op               P         M
      44             :    if nmat=1:  A-sI             NULL      A-sI
      45             :    if nmat=2:  B^-1 (A-sB)      B         A-sB
      46             : */
      47         424 : static PetscErrorCode STComputeOperator_Shift(ST st)
      48             : {
      49         424 :   PetscFunctionBegin;
      50         424 :   st->usesksp = (st->nmat>1)? PETSC_TRUE: PETSC_FALSE;
      51         424 :   PetscCall(PetscObjectReference((PetscObject)st->A[1]));
      52         424 :   PetscCall(MatDestroy(&st->T[1]));
      53         424 :   st->T[1] = st->A[1];
      54         424 :   PetscCall(STMatMAXPY_Private(st,-st->sigma,0.0,0,NULL,PetscNot(st->state==ST_STATE_UPDATED),PETSC_FALSE,&st->T[0]));
      55         424 :   if (st->nmat>1) PetscCall(PetscObjectReference((PetscObject)st->T[1]));
      56         424 :   PetscCall(MatDestroy(&st->P));
      57         424 :   st->P = (st->nmat>1)? st->T[1]: NULL;
      58         424 :   st->M = st->T[0];
      59         424 :   if (st->nmat>1 && st->Psplit) {  /* build custom preconditioner from the split matrices */
      60           1 :     PetscCall(MatDestroy(&st->Pmat));
      61           1 :     PetscCall(PetscObjectReference((PetscObject)st->Psplit[1]));
      62           1 :     st->Pmat = st->Psplit[1];
      63             :   }
      64         424 :   PetscFunctionReturn(PETSC_SUCCESS);
      65             : }
      66             : 
      67         492 : static PetscErrorCode STSetUp_Shift(ST st)
      68             : {
      69         492 :   PetscInt       k,nc,nmat=st->nmat;
      70         492 :   PetscScalar    *coeffs=NULL;
      71             : 
      72         492 :   PetscFunctionBegin;
      73         492 :   if (nmat>1) PetscCall(STSetWorkVecs(st,1));
      74         492 :   if (nmat>2) {  /* set-up matrices for polynomial eigenproblems */
      75          68 :     if (st->transform) {
      76          14 :       nc = (nmat*(nmat+1))/2;
      77          14 :       PetscCall(PetscMalloc1(nc,&coeffs));
      78             :       /* Compute coeffs */
      79          14 :       PetscCall(STCoeffs_Monomial(st,coeffs));
      80             :       /* T[n] = A_n */
      81          14 :       k = nmat-1;
      82          14 :       PetscCall(PetscObjectReference((PetscObject)st->A[k]));
      83          14 :       PetscCall(MatDestroy(&st->T[k]));
      84          14 :       st->T[k] = st->A[k];
      85          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]));
      86          14 :       PetscCall(PetscFree(coeffs));
      87          14 :       PetscCall(PetscObjectReference((PetscObject)st->T[nmat-1]));
      88          14 :       PetscCall(MatDestroy(&st->P));
      89          14 :       st->P = st->T[nmat-1];
      90          14 :       if (st->Psplit) {  /* build custom preconditioner from the split matrices */
      91           1 :         PetscCall(STMatMAXPY_Private(st,st->sigma,0.0,nmat-1,coeffs?coeffs:NULL,PETSC_TRUE,PETSC_TRUE,&st->Pmat));
      92             :       }
      93          14 :       PetscCall(ST_KSPSetOperators(st,st->P,st->Pmat?st->Pmat:st->P));
      94             :     } else {
      95         224 :       for (k=0;k<nmat;k++) {
      96         170 :         PetscCall(PetscObjectReference((PetscObject)st->A[k]));
      97         170 :         PetscCall(MatDestroy(&st->T[k]));
      98         170 :         st->T[k] = st->A[k];
      99             :       }
     100             :     }
     101             :   }
     102         492 :   if (st->P) PetscCall(KSPSetUp(st->ksp));
     103         492 :   PetscFunctionReturn(PETSC_SUCCESS);
     104             : }
     105             : 
     106          15 : static PetscErrorCode STSetShift_Shift(ST st,PetscScalar newshift)
     107             : {
     108          15 :   PetscInt       k,nc,nmat=PetscMax(st->nmat,2);
     109          15 :   PetscScalar    *coeffs=NULL;
     110             : 
     111          15 :   PetscFunctionBegin;
     112          15 :   if (st->transform) {
     113          13 :     if (st->matmode == ST_MATMODE_COPY && nmat>2) {
     114           2 :       nc = (nmat*(nmat+1))/2;
     115           2 :       PetscCall(PetscMalloc1(nc,&coeffs));
     116             :       /* Compute coeffs */
     117           2 :       PetscCall(STCoeffs_Monomial(st,coeffs));
     118             :     }
     119          32 :     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]));
     120          13 :     if (st->matmode == ST_MATMODE_COPY && nmat>2) PetscCall(PetscFree(coeffs));
     121          13 :     if (st->nmat<=2) st->M = st->T[0];
     122             :   }
     123          15 :   PetscFunctionReturn(PETSC_SUCCESS);
     124             : }
     125             : 
     126         559 : SLEPC_EXTERN PetscErrorCode STCreate_Shift(ST st)
     127             : {
     128         559 :   PetscFunctionBegin;
     129         559 :   st->usesksp = PETSC_TRUE;
     130             : 
     131         559 :   st->ops->apply           = STApply_Generic;
     132         559 :   st->ops->applytrans      = STApplyTranspose_Generic;
     133         559 :   st->ops->applyhermtrans  = STApplyHermitianTranspose_Generic;
     134         559 :   st->ops->backtransform   = STBackTransform_Shift;
     135         559 :   st->ops->setshift        = STSetShift_Shift;
     136         559 :   st->ops->getbilinearform = STGetBilinearForm_Default;
     137         559 :   st->ops->setup           = STSetUp_Shift;
     138         559 :   st->ops->computeoperator = STComputeOperator_Shift;
     139         559 :   st->ops->postsolve       = STPostSolve_Shift;
     140         559 :   st->ops->setdefaultksp   = STSetDefaultKSP_Default;
     141         559 :   PetscFunctionReturn(PETSC_SUCCESS);
     142             : }

Generated by: LCOV version 1.14