Subversion Repositories slepc-dev

Rev

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

Rev Author Line No. Line
1376 slepc 1
/*
2
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1672 slepc 3
   SLEPc - Scalable Library for Eigenvalue Problem Computations
2575 eromero 4
   Copyright (c) 2002-2011, Universitat Politecnica de Valencia, Spain
6 dsic.upv.es!jroman 5
 
1672 slepc 6
   This file is part of SLEPc.
7
 
8
   SLEPc is free software: you can redistribute it and/or modify it under  the
9
   terms of version 3 of the GNU Lesser General Public License as published by
10
   the Free Software Foundation.
11
 
12
   SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
13
   WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
14
   FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
15
   more details.
16
 
17
   You  should have received a copy of the GNU Lesser General  Public  License
18
   along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
1376 slepc 19
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
20
*/
21
 
228 dsic.upv.es!jroman 22
static char help[] = "Solves the same eigenproblem as in example ex2, but using a shell matrix. "
161 dsic.upv.es!antodo 23
  "The problem is a standard symmetric eigenproblem corresponding to the 2-D Laplacian operator.\n\n"
1156 slepc 24
  "The command line options are:\n"
6 dsic.upv.es!jroman 25
  "  -n <n>, where <n> = number of grid subdivisions in both x and y dimensions.\n\n";
26
 
2283 jroman 27
#include <slepceps.h>
28
#include <petscblaslapack.h>
6 dsic.upv.es!jroman 29
 
30
/*
31
   User-defined routines
32
*/
2331 jroman 33
PetscErrorCode MatLaplacian2D_Mult(Mat A,Vec x,Vec y);
34
PetscErrorCode MatLaplacian2D_GetDiagonal(Mat A,Vec diag);
6 dsic.upv.es!jroman 35
 
36
#undef __FUNCT__
37
#define __FUNCT__ "main"
2331 jroman 38
int main(int argc,char **argv)
6 dsic.upv.es!jroman 39
{
1505 slepc 40
  Mat            A;               /* operator matrix */
41
  EPS            eps;             /* eigenproblem solver context */
1507 slepc 42
  const EPSType  type;
2557 eromero 43
  PetscReal      tol=1000*PETSC_MACHINE_EPSILON;
1505 slepc 44
  PetscMPIInt    size;
2557 eromero 45
  PetscInt       N,n=10,nev,maxit;
2317 jroman 46
  PetscErrorCode ierr;
6 dsic.upv.es!jroman 47
 
48
  SlepcInitialize(&argc,&argv,(char*)0,help);
49
  ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
2214 jroman 50
  if (size != 1) SETERRQ(PETSC_COMM_WORLD,1,"This is a uniprocessor example only!");
6 dsic.upv.es!jroman 51
 
52
  ierr = PetscOptionsGetInt(PETSC_NULL,"-n",&n,PETSC_NULL);CHKERRQ(ierr);
53
  N = n*n;
2503 jroman 54
  ierr = PetscPrintf(PETSC_COMM_WORLD,"\n2-D Laplacian Eigenproblem (matrix-free version), N=%D (%Dx%D grid)\n\n",N,n,n);CHKERRQ(ierr);
6 dsic.upv.es!jroman 55
 
56
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
57
     Compute the operator matrix that defines the eigensystem, Ax=kx
58
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
59
 
60
  ierr = MatCreateShell(PETSC_COMM_WORLD,N,N,N,N,&n,&A);CHKERRQ(ierr);
61
  ierr = MatSetFromOptions(A);CHKERRQ(ierr);
62
  ierr = MatShellSetOperation(A,MATOP_MULT,(void(*)())MatLaplacian2D_Mult);CHKERRQ(ierr);
58 dsic.upv.es!jroman 63
  ierr = MatShellSetOperation(A,MATOP_MULT_TRANSPOSE,(void(*)())MatLaplacian2D_Mult);CHKERRQ(ierr);
1732 antodo 64
  ierr = MatShellSetOperation(A,MATOP_GET_DIAGONAL,(void(*)())MatLaplacian2D_GetDiagonal);CHKERRQ(ierr);
6 dsic.upv.es!jroman 65
 
66
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
67
                Create the eigensolver and set various options
68
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
69
 
70
  /*
71
     Create eigensolver context
72
  */
73
  ierr = EPSCreate(PETSC_COMM_WORLD,&eps);CHKERRQ(ierr);
74
 
75
  /*
76
     Set operators. In this case, it is a standard eigenvalue problem
77
  */
78
  ierr = EPSSetOperators(eps,A,PETSC_NULL);CHKERRQ(ierr);
408 dsic.upv.es!antodo 79
  ierr = EPSSetProblemType(eps,EPS_HEP);CHKERRQ(ierr);
2557 eromero 80
  ierr = EPSSetTolerances(eps,tol,PETSC_DECIDE);CHKERRQ(ierr);
6 dsic.upv.es!jroman 81
 
82
  /*
83
     Set solver parameters at runtime
84
  */
85
  ierr = EPSSetFromOptions(eps);CHKERRQ(ierr);
86
 
87
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
88
                      Solve the eigensystem
89
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
90
 
78 dsic.upv.es!antodo 91
  ierr = EPSSolve(eps);CHKERRQ(ierr);
6 dsic.upv.es!jroman 92
 
93
  /*
94
     Optional: Get some information from the solver and display it
95
  */
96
  ierr = EPSGetType(eps,&type);CHKERRQ(ierr);
97
  ierr = PetscPrintf(PETSC_COMM_WORLD," Solution method: %s\n\n",type);CHKERRQ(ierr);
1575 slepc 98
  ierr = EPSGetDimensions(eps,&nev,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
2503 jroman 99
  ierr = PetscPrintf(PETSC_COMM_WORLD," Number of requested eigenvalues: %D\n",nev);CHKERRQ(ierr);
6 dsic.upv.es!jroman 100
  ierr = EPSGetTolerances(eps,&tol,&maxit);CHKERRQ(ierr);
2503 jroman 101
  ierr = PetscPrintf(PETSC_COMM_WORLD," Stopping condition: tol=%.4G, maxit=%D\n",tol,maxit);CHKERRQ(ierr);
6 dsic.upv.es!jroman 102
 
103
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
104
                    Display solution and clean up
105
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
106
 
2503 jroman 107
  ierr = EPSPrintSolution(eps,PETSC_NULL);CHKERRQ(ierr);
2308 jroman 108
  ierr = EPSDestroy(&eps);CHKERRQ(ierr);
2305 jroman 109
  ierr = MatDestroy(&A);CHKERRQ(ierr);
6 dsic.upv.es!jroman 110
  ierr = SlepcFinalize();CHKERRQ(ierr);
111
  return 0;
112
}
113
 
114
/*
115
    Compute the matrix vector multiplication y<---T*x where T is a nx by nx
116
    tridiagonal matrix with DD on the diagonal, DL on the subdiagonal, and
117
    DU on the superdiagonal.
118
 */  
2342 jroman 119
static void tv(int nx,const PetscScalar *x,PetscScalar *y)
6 dsic.upv.es!jroman 120
{
2331 jroman 121
  PetscScalar dd,dl,du;
6 dsic.upv.es!jroman 122
  int         j;
123
 
124
  dd  = 4.0;
125
  dl  = -1.0;
126
  du  = -1.0;
127
 
128
  y[0] =  dd*x[0] + du*x[1];
2331 jroman 129
  for (j=1;j<nx-1;j++)
6 dsic.upv.es!jroman 130
    y[j] = dl*x[j-1] + dd*x[j] + du*x[j+1];
131
  y[nx-1] = dl*x[nx-2] + dd*x[nx-1];
132
}
133
 
134
#undef __FUNCT__
135
#define __FUNCT__ "MatLaplacian2D_Mult"
136
/*
137
    Matrix-vector product subroutine for the 2D Laplacian.
138
 
139
    The matrix used is the 2 dimensional discrete Laplacian on unit square with
140
    zero Dirichlet boundary condition.
141
 
142
    Computes y <-- A*x, where A is the block tridiagonal matrix
143
 
144
                 | T -I          |
145
                 |-I  T -I       |
146
             A = |   -I  T       |
147
                 |        ...  -I|
148
                 |           -I T|
149
 
150
    The subroutine TV is called to compute y<--T*x.
151
 */
2331 jroman 152
PetscErrorCode MatLaplacian2D_Mult(Mat A,Vec x,Vec y)
6 dsic.upv.es!jroman 153
{
2334 jroman 154
  void              *ctx;
155
  int               nx,lo,j,one=1;
156
  const PetscScalar *px;
157
  PetscScalar       *py,dmone=-1.0;
158
  PetscErrorCode    ierr;
6 dsic.upv.es!jroman 159
 
983 slepc 160
  PetscFunctionBegin;
2331 jroman 161
  ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr);
162
  nx = *(int*)ctx;
2334 jroman 163
  ierr = VecGetArrayRead(x,&px);CHKERRQ(ierr);
2331 jroman 164
  ierr = VecGetArray(y,&py);CHKERRQ(ierr);
6 dsic.upv.es!jroman 165
 
2331 jroman 166
  tv(nx,&px[0],&py[0]);
167
  BLASaxpy_(&nx,&dmone,&px[nx],&one,&py[0],&one);
6 dsic.upv.es!jroman 168
 
2331 jroman 169
  for (j=2;j<nx;j++) {
6 dsic.upv.es!jroman 170
    lo = (j-1)*nx;
2331 jroman 171
    tv(nx,&px[lo],&py[lo]);
172
    BLASaxpy_(&nx,&dmone,&px[lo-nx],&one,&py[lo],&one);
173
    BLASaxpy_(&nx,&dmone,&px[lo+nx],&one,&py[lo],&one);
6 dsic.upv.es!jroman 174
  }
175
 
176
  lo = (nx-1)*nx;
2331 jroman 177
  tv(nx,&px[lo],&py[lo]);
178
  BLASaxpy_(&nx,&dmone,&px[lo-nx],&one,&py[lo],&one);
6 dsic.upv.es!jroman 179
 
2334 jroman 180
  ierr = VecRestoreArrayRead(x,&px);CHKERRQ(ierr);
2331 jroman 181
  ierr = VecRestoreArray(y,&py);CHKERRQ(ierr);
983 slepc 182
  PetscFunctionReturn(0);
6 dsic.upv.es!jroman 183
}
184
 
1732 antodo 185
#undef __FUNCT__
186
#define __FUNCT__ "MatLaplacian2D_GetDiagonal"
2331 jroman 187
PetscErrorCode MatLaplacian2D_GetDiagonal(Mat A,Vec diag)
1732 antodo 188
{
189
  PetscErrorCode ierr;
190
 
191
  PetscFunctionBegin;
192
  ierr = VecSet(diag,4.0);CHKERRQ(ierr);
193
  PetscFunctionReturn(0);
194
}
195