Date: 2013-09-02T10:07:21+00:00

Actual source code: qeplin_n2.c

      1: /*

      3:    Linearization for general QEP, companion form 2.

      5:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      6:    SLEPc - Scalable Library for Eigenvalue Problem Computations
      7:    Copyright (c) 2002-2013, Universitat Politecnica de Valencia, Spain

      9:    This file is part of SLEPc.

     11:    SLEPc is free software: you can redistribute it and/or modify it under  the
     12:    terms of version 3 of the GNU Lesser General Public License as published by
     13:    the Free Software Foundation.

     15:    SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
     16:    WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
     17:    FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
     18:    more details.

     20:    You  should have received a copy of the GNU Lesser General  Public  License
     21:    along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
     22:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     23: */

     25: #include <slepc-private/qepimpl.h>         /*I "slepcqep.h" I*/
     26:  #include linearp.h

     28: /*
     29:     Given the quadratic problem (l^2*M + l*C + K)*x = 0 the following
     30:     linearization is employed:

     32:       A*z = l*B*z   where   A = [ -K   0 ]     B = [ C  M ]     z = [  x  ]
     33:                                 [  0   I ]         [ I  0 ]         [ l*x ]
     34:  */

     38: PetscErrorCode MatMult_Linear_N2A(Mat A,Vec x,Vec y)
     39: {
     40:   PetscErrorCode    ierr;
     41:   QEP_LINEAR        *ctx;
     42:   const PetscScalar *px;
     43:   PetscScalar       *py;
     44:   PetscInt          m;

     47:   MatShellGetContext(A,(void**)&ctx);
     48:   MatGetLocalSize(ctx->M,&m,NULL);
     49:   VecGetArrayRead(x,&px);
     50:   VecGetArray(y,&py);
     51:   VecPlaceArray(ctx->x1,px);
     52:   VecPlaceArray(ctx->x2,px+m);
     53:   VecPlaceArray(ctx->y1,py);
     54:   VecPlaceArray(ctx->y2,py+m);
     55:   /* y1 = -K*x1 */
     56:   MatMult(ctx->K,ctx->x1,ctx->y1);
     57:   VecScale(ctx->y1,-1.0);
     58:   /* y2 = x2 */
     59:   VecCopy(ctx->x2,ctx->y2);
     60:   VecResetArray(ctx->x1);
     61:   VecResetArray(ctx->x2);
     62:   VecResetArray(ctx->y1);
     63:   VecResetArray(ctx->y2);
     64:   VecRestoreArrayRead(x,&px);
     65:   VecRestoreArray(y,&py);
     66:   return(0);
     67: }

     71: PetscErrorCode MatMult_Linear_N2B(Mat B,Vec x,Vec y)
     72: {
     73:   PetscErrorCode    ierr;
     74:   QEP_LINEAR        *ctx;
     75:   const PetscScalar *px;
     76:   PetscScalar       *py;
     77:   PetscInt          m;

     80:   MatShellGetContext(B,(void**)&ctx);
     81:   MatGetLocalSize(ctx->M,&m,NULL);
     82:   VecGetArrayRead(x,&px);
     83:   VecGetArray(y,&py);
     84:   VecPlaceArray(ctx->x1,px);
     85:   VecPlaceArray(ctx->x2,px+m);
     86:   VecPlaceArray(ctx->y1,py);
     87:   VecPlaceArray(ctx->y2,py+m);
     88:   /* y1 = C*x1 + M*x2 */
     89:   MatMult(ctx->C,ctx->x1,ctx->y1);
     90:   VecScale(ctx->y1,ctx->sfactor);
     91:   MatMult(ctx->M,ctx->x2,ctx->y2);
     92:   VecAXPY(ctx->y1,ctx->sfactor*ctx->sfactor,ctx->y2);
     93:   /* y2 = x1 */
     94:   VecCopy(ctx->x1,ctx->y2);
     95:   VecResetArray(ctx->x1);
     96:   VecResetArray(ctx->x2);
     97:   VecResetArray(ctx->y1);
     98:   VecResetArray(ctx->y2);
     99:   VecRestoreArrayRead(x,&px);
    100:   VecRestoreArray(y,&py);
    101:   return(0);
    102: }

    106: PetscErrorCode MatGetDiagonal_Linear_N2A(Mat A,Vec diag)
    107: {
    109:   QEP_LINEAR     *ctx;
    110:   PetscScalar    *pd;
    111:   PetscInt       m;

    114:   MatShellGetContext(A,(void**)&ctx);
    115:   MatGetLocalSize(ctx->M,&m,NULL);
    116:   VecGetArray(diag,&pd);
    117:   VecPlaceArray(ctx->x1,pd);
    118:   VecPlaceArray(ctx->x2,pd+m);
    119:   MatGetDiagonal(ctx->K,ctx->x1);
    120:   VecScale(ctx->x1,-1.0);
    121:   VecSet(ctx->x2,1.0);
    122:   VecResetArray(ctx->x1);
    123:   VecResetArray(ctx->x2);
    124:   VecRestoreArray(diag,&pd);
    125:   return(0);
    126: }

    130: PetscErrorCode MatGetDiagonal_Linear_N2B(Mat B,Vec diag)
    131: {
    133:   QEP_LINEAR     *ctx;
    134:   PetscScalar    *pd;
    135:   PetscInt       m;

    138:   MatShellGetContext(B,(void**)&ctx);
    139:   MatGetLocalSize(ctx->M,&m,NULL);
    140:   VecGetArray(diag,&pd);
    141:   VecPlaceArray(ctx->x1,pd);
    142:   VecPlaceArray(ctx->x2,pd+m);
    143:   MatGetDiagonal(ctx->C,ctx->x1);
    144:   VecScale(ctx->x1,ctx->sfactor);
    145:   VecSet(ctx->x2,0.0);
    146:   VecResetArray(ctx->x1);
    147:   VecResetArray(ctx->x2);
    148:   VecRestoreArray(diag,&pd);
    149:   return(0);
    150: }

    154: PetscErrorCode MatCreateExplicit_Linear_N2A(MPI_Comm comm,QEP_LINEAR *ctx,Mat *A)
    155: {
    157:   PetscInt       M,N,m,n;
    158:   Mat            Id;

    161:   MatGetSize(ctx->M,&M,&N);
    162:   MatGetLocalSize(ctx->M,&m,&n);
    163:   MatCreate(PetscObjectComm((PetscObject)ctx->M),&Id);
    164:   MatSetSizes(Id,m,n,M,N);
    165:   MatSetFromOptions(Id);
    166:   MatSetUp(Id);
    167:   MatAssemblyBegin(Id,MAT_FINAL_ASSEMBLY);
    168:   MatAssemblyEnd(Id,MAT_FINAL_ASSEMBLY);
    169:   MatShift(Id,1.0);
    170:   SlepcMatTile(-1.0,ctx->K,0.0,Id,0.0,Id,1.0,Id,A);
    171:   MatDestroy(&Id);
    172:   return(0);
    173: }

    177: PetscErrorCode MatCreateExplicit_Linear_N2B(MPI_Comm comm,QEP_LINEAR *ctx,Mat *B)
    178: {
    180:   PetscInt       M,N,m,n;
    181:   Mat            Id;

    184:   MatGetSize(ctx->M,&M,&N);
    185:   MatGetLocalSize(ctx->M,&m,&n);
    186:   MatCreate(PetscObjectComm((PetscObject)ctx->M),&Id);
    187:   MatSetSizes(Id,m,n,M,N);
    188:   MatSetFromOptions(Id);
    189:   MatSetUp(Id);
    190:   MatAssemblyBegin(Id,MAT_FINAL_ASSEMBLY);
    191:   MatAssemblyEnd(Id,MAT_FINAL_ASSEMBLY);
    192:   MatShift(Id,1.0);
    193:   SlepcMatTile(ctx->sfactor,ctx->C,ctx->sfactor*ctx->sfactor,ctx->M,1.0,Id,0.0,Id,B);
    194:   MatDestroy(&Id);
    195:   return(0);
    196: }