Subversion Repositories slepc-dev

Rev

Go to most recent revision | 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
8
   Copyright (c) 2002-2009, Universidad 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
 
1521 slepc 27
#include "private/stimpl.h"
347 dsic.upv.es!antodo 28
 
29
#undef __FUNCT__
30
#define __FUNCT__ "STMatShellMult"
476 dsic.upv.es!antodo 31
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
 
39
  ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr);
40
  if (ctx->sigma != 0.0) {
41
    if (ctx->B) {  /* y = (A - sB) x */
42
      ierr = MatMult(ctx->B,x,ctx->w);CHKERRQ(ierr);
828 dsic.upv.es!antodo 43
      ierr = VecAXPY(y,-ctx->sigma,ctx->w);CHKERRQ(ierr);
44
    } else {    /* y = (A - sI) x */
45
      ierr = VecAXPY(y,-ctx->sigma,x);CHKERRQ(ierr);
347 dsic.upv.es!antodo 46
    }
47
  }
48
  PetscFunctionReturn(0);
49
}
50
 
51
#undef __FUNCT__
780 dsic.upv.es!jroman 52
#define __FUNCT__ "STMatShellMultTranspose"
53
PetscErrorCode STMatShellMultTranspose(Mat A,Vec x,Vec y)
54
{
55
  PetscErrorCode ierr;
56
  ST             ctx;
57
 
58
  PetscFunctionBegin;
59
  ierr = MatShellGetContext(A,(void**)&ctx);CHKERRQ(ierr);
60
 
61
  ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr);
62
  if (ctx->sigma != 0.0) {
63
    if (ctx->B) {  /* y = (A - sB) x */
64
      ierr = MatMultTranspose(ctx->B,x,ctx->w);CHKERRQ(ierr);
828 dsic.upv.es!antodo 65
      ierr = VecAXPY(y,-ctx->sigma,ctx->w);CHKERRQ(ierr);
66
    } else {    /* y = (A - sI) x */
67
      ierr = VecAXPY(y,-ctx->sigma,x);CHKERRQ(ierr);
780 dsic.upv.es!jroman 68
    }
69
  }
70
  PetscFunctionReturn(0);
71
}
72
 
73
#undef __FUNCT__
347 dsic.upv.es!antodo 74
#define __FUNCT__ "STMatShellGetDiagonal"
476 dsic.upv.es!antodo 75
PetscErrorCode STMatShellGetDiagonal(Mat A,Vec diag)
347 dsic.upv.es!antodo 76
{
476 dsic.upv.es!antodo 77
  PetscErrorCode ierr;
78
  ST             ctx;
79
  Vec            diagb;
347 dsic.upv.es!antodo 80
 
81
  PetscFunctionBegin;
82
  ierr = MatShellGetContext(A,(void**)&ctx);CHKERRQ(ierr);
83
 
84
  ierr = MatGetDiagonal(ctx->A,diag);CHKERRQ(ierr);
85
  if (ctx->sigma != 0.0) {
86
    if (ctx->B) {
87
      ierr = VecDuplicate(diag,&diagb);CHKERRQ(ierr);
88
      ierr = MatGetDiagonal(ctx->B,diagb);CHKERRQ(ierr);
828 dsic.upv.es!antodo 89
      ierr = VecAXPY(diag,-ctx->sigma,diagb);CHKERRQ(ierr);
347 dsic.upv.es!antodo 90
      ierr = VecDestroy(diagb);CHKERRQ(ierr);
828 dsic.upv.es!antodo 91
    } else {
92
      ierr = VecShift(diag,-ctx->sigma);CHKERRQ(ierr);
347 dsic.upv.es!antodo 93
    }
94
  }
95
  PetscFunctionReturn(0);
96
}
97
 
98
#undef __FUNCT__  
99
#define __FUNCT__ "STMatShellCreate"
476 dsic.upv.es!antodo 100
PetscErrorCode STMatShellCreate(ST st,Mat *mat)
347 dsic.upv.es!antodo 101
{
476 dsic.upv.es!antodo 102
  PetscErrorCode ierr;
982 slepc 103
  PetscInt       n, m, N, M;
476 dsic.upv.es!antodo 104
  PetscTruth     hasA, hasB;
347 dsic.upv.es!antodo 105
 
106
  PetscFunctionBegin;
107
  ierr = MatGetSize(st->A,&M,&N);CHKERRQ(ierr);  
108
  ierr = MatGetLocalSize(st->A,&m,&n);CHKERRQ(ierr);  
1422 slepc 109
  ierr = MatCreateShell(((PetscObject)st)->comm,m,n,M,N,(void*)st,mat);CHKERRQ(ierr);
347 dsic.upv.es!antodo 110
  ierr = MatShellSetOperation(*mat,MATOP_MULT,(void(*)(void))STMatShellMult);CHKERRQ(ierr);
780 dsic.upv.es!jroman 111
  ierr = MatShellSetOperation(*mat,MATOP_MULT_TRANSPOSE,(void(*)(void))STMatShellMultTranspose);CHKERRQ(ierr);
347 dsic.upv.es!antodo 112
 
113
  ierr = MatHasOperation(st->A,MATOP_GET_DIAGONAL,&hasA);CHKERRQ(ierr);
114
  if (st->B) { ierr = MatHasOperation(st->B,MATOP_GET_DIAGONAL,&hasB);CHKERRQ(ierr); }
115
  if ( (hasA && !st->B) || (hasA && hasB) ) {
116
    ierr = MatShellSetOperation(*mat,MATOP_GET_DIAGONAL,(void(*)(void))STMatShellGetDiagonal);CHKERRQ(ierr);
117
  }
118
 
119
  PetscFunctionReturn(0);
120
}
121