Subversion Repositories slepc-dev

Rev

Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
347 dsic.upv.es!antodo 1
/*
2
      This file contains the subroutines which implement various operations
3
      of the matrix associated to the shift-and-invert technique for eigenvalue
4
      problems, and also a subroutine to create it.
1376 slepc 5
 
6
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1672 slepc 7
   SLEPc - Scalable Library for Eigenvalue Problem Computations
2575 eromero 8
   Copyright (c) 2002-2011, Universitat Politecnica de Valencia, Spain
1376 slepc 9
 
1672 slepc 10
   This file is part of SLEPc.
11
 
12
   SLEPc is free software: you can redistribute it and/or modify it under  the
13
   terms of version 3 of the GNU Lesser General Public License as published by
14
   the Free Software Foundation.
15
 
16
   SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
17
   WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
18
   FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
19
   more details.
20
 
21
   You  should have received a copy of the GNU Lesser General  Public  License
22
   along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
1376 slepc 23
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
347 dsic.upv.es!antodo 24
*/
25
 
1376 slepc 26
 
2283 jroman 27
#include <private/stimpl.h>
347 dsic.upv.es!antodo 28
 
29
#undef __FUNCT__
30
#define __FUNCT__ "STMatShellMult"
2317 jroman 31
static PetscErrorCode STMatShellMult(Mat A,Vec x,Vec y)
347 dsic.upv.es!antodo 32
{
476 dsic.upv.es!antodo 33
  PetscErrorCode ierr;
34
  ST             ctx;
347 dsic.upv.es!antodo 35
 
36
  PetscFunctionBegin;
37
  ierr = MatShellGetContext(A,(void**)&ctx);CHKERRQ(ierr);
38
  ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr);
39
  if (ctx->sigma != 0.0) {
40
    if (ctx->B) {  /* y = (A - sB) x */
41
      ierr = MatMult(ctx->B,x,ctx->w);CHKERRQ(ierr);
828 dsic.upv.es!antodo 42
      ierr = VecAXPY(y,-ctx->sigma,ctx->w);CHKERRQ(ierr);
43
    } else {    /* y = (A - sI) x */
44
      ierr = VecAXPY(y,-ctx->sigma,x);CHKERRQ(ierr);
347 dsic.upv.es!antodo 45
    }
46
  }
47
  PetscFunctionReturn(0);
48
}
49
 
50
#undef __FUNCT__
780 dsic.upv.es!jroman 51
#define __FUNCT__ "STMatShellMultTranspose"
2317 jroman 52
static PetscErrorCode STMatShellMultTranspose(Mat A,Vec x,Vec y)
780 dsic.upv.es!jroman 53
{
54
  PetscErrorCode ierr;
55
  ST             ctx;
56
 
57
  PetscFunctionBegin;
58
  ierr = MatShellGetContext(A,(void**)&ctx);CHKERRQ(ierr);
59
  ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr);
60
  if (ctx->sigma != 0.0) {
61
    if (ctx->B) {  /* y = (A - sB) x */
62
      ierr = MatMultTranspose(ctx->B,x,ctx->w);CHKERRQ(ierr);
828 dsic.upv.es!antodo 63
      ierr = VecAXPY(y,-ctx->sigma,ctx->w);CHKERRQ(ierr);
64
    } else {    /* y = (A - sI) x */
65
      ierr = VecAXPY(y,-ctx->sigma,x);CHKERRQ(ierr);
780 dsic.upv.es!jroman 66
    }
67
  }
68
  PetscFunctionReturn(0);
69
}
70
 
71
#undef __FUNCT__
347 dsic.upv.es!antodo 72
#define __FUNCT__ "STMatShellGetDiagonal"
2317 jroman 73
static PetscErrorCode STMatShellGetDiagonal(Mat A,Vec diag)
347 dsic.upv.es!antodo 74
{
476 dsic.upv.es!antodo 75
  PetscErrorCode ierr;
76
  ST             ctx;
77
  Vec            diagb;
347 dsic.upv.es!antodo 78
 
79
  PetscFunctionBegin;
80
  ierr = MatShellGetContext(A,(void**)&ctx);CHKERRQ(ierr);
81
  ierr = MatGetDiagonal(ctx->A,diag);CHKERRQ(ierr);
82
  if (ctx->sigma != 0.0) {
83
    if (ctx->B) {
84
      ierr = VecDuplicate(diag,&diagb);CHKERRQ(ierr);
85
      ierr = MatGetDiagonal(ctx->B,diagb);CHKERRQ(ierr);
828 dsic.upv.es!antodo 86
      ierr = VecAXPY(diag,-ctx->sigma,diagb);CHKERRQ(ierr);
2305 jroman 87
      ierr = VecDestroy(&diagb);CHKERRQ(ierr);
828 dsic.upv.es!antodo 88
    } else {
89
      ierr = VecShift(diag,-ctx->sigma);CHKERRQ(ierr);
347 dsic.upv.es!antodo 90
    }
91
  }
92
  PetscFunctionReturn(0);
93
}
94
 
95
#undef __FUNCT__  
96
#define __FUNCT__ "STMatShellCreate"
476 dsic.upv.es!antodo 97
PetscErrorCode STMatShellCreate(ST st,Mat *mat)
347 dsic.upv.es!antodo 98
{
476 dsic.upv.es!antodo 99
  PetscErrorCode ierr;
2331 jroman 100
  PetscInt       n,m,N,M;
101
  PetscBool      hasA,hasB;
347 dsic.upv.es!antodo 102
 
103
  PetscFunctionBegin;
104
  ierr = MatGetSize(st->A,&M,&N);CHKERRQ(ierr);  
105
  ierr = MatGetLocalSize(st->A,&m,&n);CHKERRQ(ierr);  
1422 slepc 106
  ierr = MatCreateShell(((PetscObject)st)->comm,m,n,M,N,(void*)st,mat);CHKERRQ(ierr);
347 dsic.upv.es!antodo 107
  ierr = MatShellSetOperation(*mat,MATOP_MULT,(void(*)(void))STMatShellMult);CHKERRQ(ierr);
780 dsic.upv.es!jroman 108
  ierr = MatShellSetOperation(*mat,MATOP_MULT_TRANSPOSE,(void(*)(void))STMatShellMultTranspose);CHKERRQ(ierr);
347 dsic.upv.es!antodo 109
 
110
  ierr = MatHasOperation(st->A,MATOP_GET_DIAGONAL,&hasA);CHKERRQ(ierr);
111
  if (st->B) { ierr = MatHasOperation(st->B,MATOP_GET_DIAGONAL,&hasB);CHKERRQ(ierr); }
2331 jroman 112
  if ((hasA && !st->B) || (hasA && hasB)) {
347 dsic.upv.es!antodo 113
    ierr = MatShellSetOperation(*mat,MATOP_GET_DIAGONAL,(void(*)(void))STMatShellGetDiagonal);CHKERRQ(ierr);
114
  }
115
  PetscFunctionReturn(0);
116
}
117