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:29:53 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      849824 : static PetscErrorCode STBackTransform_Shift(ST st,PetscInt n,PetscScalar *eigr,PetscScalar *eigi)
      18             : {
      19      849824 :   PetscInt j;
      20             : 
      21      849824 :   PetscFunctionBegin;
      22     2539797 :   for (j=0;j<n;j++) {
      23     1689973 :     eigr[j] += st->sigma;
      24             :   }
      25      849824 :   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           4 :     if (st->nmat>1) PetscCall(MatAXPY(st->A[0],st->sigma,st->A[1],st->str));
      33           3 :     else PetscCall(MatShift(st->A[0],st->sigma));
      34           4 :     st->Astate[0] = ((PetscObject)st->A[0])->state;
      35           4 :     st->state   = ST_STATE_INITIAL;
      36           4 :     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         406 : static PetscErrorCode STComputeOperator_Shift(ST st)
      48             : {
      49         406 :   PetscFunctionBegin;
      50         406 :   st->usesksp = (st->nmat>1)? PETSC_TRUE: PETSC_FALSE;
      51         406 :   PetscCall(PetscObjectReference((PetscObject)st->A[1]));
      52         406 :   PetscCall(MatDestroy(&st->T[1]));
      53         406 :   st->T[1] = st->A[1];
      54         406 :   PetscCall(STMatMAXPY_Private(st,-st->sigma,0.0,0,NULL,PetscNot(st->state==ST_STATE_UPDATED),PETSC_FALSE,&st->T[0]));
      55         406 :   if (st->nmat>1) PetscCall(PetscObjectReference((PetscObject)st->T[1]));
      56         406 :   PetscCall(MatDestroy(&st->P));
      57         406 :   st->P = (st->nmat>1)? st->T[1]: NULL;
      58         406 :   st->M = st->T[0];
      59         406 :   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         406 :   PetscFunctionReturn(PETSC_SUCCESS);
      65             : }
      66             : 
      67         485 : static PetscErrorCode STSetUp_Shift(ST st)
      68             : {
      69         485 :   PetscInt       k,nc,nmat=st->nmat;
      70         485 :   PetscScalar    *coeffs=NULL;
      71             : 
      72         485 :   PetscFunctionBegin;
      73         485 :   if (nmat>1) PetscCall(STSetWorkVecs(st,1));
      74         156 :   if (nmat>2) {  /* set-up matrices for polynomial eigenproblems */
      75          79 :     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         284 :       for (k=0;k<nmat;k++) {
      96         219 :         PetscCall(PetscObjectReference((PetscObject)st->A[k]));
      97         219 :         PetscCall(MatDestroy(&st->T[k]));
      98         219 :         st->T[k] = st->A[k];
      99             :       }
     100             :     }
     101             :   }
     102         485 :   if (st->P) PetscCall(KSPSetUp(st->ksp));
     103         485 :   PetscFunctionReturn(PETSC_SUCCESS);
     104             : }
     105             : 
     106          18 : static PetscErrorCode STSetShift_Shift(ST st,PetscScalar newshift)
     107             : {
     108          18 :   PetscInt       k,nc,nmat=PetscMax(st->nmat,2);
     109          18 :   PetscScalar    *coeffs=NULL;
     110             : 
     111          18 :   PetscFunctionBegin;
     112          18 :   if (st->transform) {
     113          16 :     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          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]));
     120          16 :     if (st->matmode == ST_MATMODE_COPY && nmat>2) PetscCall(PetscFree(coeffs));
     121          16 :     if (st->nmat<=2) st->M = st->T[0];
     122             :   }
     123          18 :   PetscFunctionReturn(PETSC_SUCCESS);
     124             : }
     125             : 
     126         556 : SLEPC_EXTERN PetscErrorCode STCreate_Shift(ST st)
     127             : {
     128         556 :   PetscFunctionBegin;
     129         556 :   st->usesksp = PETSC_TRUE;
     130             : 
     131         556 :   st->ops->apply           = STApply_Generic;
     132         556 :   st->ops->applytrans      = STApplyTranspose_Generic;
     133         556 :   st->ops->applyhermtrans  = STApplyHermitianTranspose_Generic;
     134         556 :   st->ops->backtransform   = STBackTransform_Shift;
     135         556 :   st->ops->setshift        = STSetShift_Shift;
     136         556 :   st->ops->getbilinearform = STGetBilinearForm_Default;
     137         556 :   st->ops->setup           = STSetUp_Shift;
     138         556 :   st->ops->computeoperator = STComputeOperator_Shift;
     139         556 :   st->ops->postsolve       = STPostSolve_Shift;
     140         556 :   st->ops->setdefaultksp   = STSetDefaultKSP_Default;
     141         556 :   PetscFunctionReturn(PETSC_SUCCESS);
     142             : }

Generated by: LCOV version 1.14