Subversion Repositories slepc-dev

Rev

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

Rev Author Line No. Line
1379 slepc 1
!  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1672 slepc 2
!  SLEPc - Scalable Library for Eigenvalue Problem Computations
2116 eromero 3
!  Copyright (c) 2002-2010, Universidad Politecnica de Valencia, Spain
6 dsic.upv.es!jroman 4
!
1672 slepc 5
!  This file is part of SLEPc.
6
!
7
!  SLEPc is free software: you can redistribute it and/or modify it under  the
8
!  terms of version 3 of the GNU Lesser General Public License as published by
9
!  the Free Software Foundation.
10
!
11
!  SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
12
!  WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
13
!  FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
14
!  more details.
15
!
16
!  You  should have received a copy of the GNU Lesser General  Public  License
17
!  along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
1379 slepc 18
!  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
19
!
6 dsic.upv.es!jroman 20
!  Program usage: mpirun -np n ex6f [-help] [-m <m>] [all SLEPc options]
21
!
22
!  Description: This example solves the eigensystem arising in the Ising
23
!  model for ferromagnetic materials. The file mvmisg.f must be linked
24
!  together. Information about the model can be found at the following
25
!  site http://math.nist.gov/MatrixMarket/data/NEP
26
!
27
!  The command line options are:
28
!    -m <m>, where <m> is the number of 2x2 blocks, i.e. matrix size N=2*m
29
!
30
! ----------------------------------------------------------------------
31
!
32
      program main
33
      implicit none
34
 
1885 jroman 35
#include "finclude/petscsys.h"
6 dsic.upv.es!jroman 36
#include "finclude/petscvec.h"
37
#include "finclude/petscmat.h"
1885 jroman 38
#include "finclude/slepcsys.h"
6 dsic.upv.es!jroman 39
#include "finclude/slepceps.h"
40
 
41
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
42
!     Declarations
43
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
44
!
45
!  Variables:
46
!     A     operator matrix
47
!     eps   eigenproblem solver context
48
 
1506 slepc 49
      Mat            A
50
      EPS            eps
51
      EPSType        tname
52
      PetscReal      tol, error
53
      PetscScalar    kr, ki
1526 slepc 54
      PetscInt       N, m, i
55
      PetscInt       nev, maxit, its, nconv
1506 slepc 56
      PetscMPIInt    sz, rank
57
      PetscErrorCode ierr
58
      PetscTruth     flg
6 dsic.upv.es!jroman 59
 
60
!     This is the routine to use for matrix-free approach
61
!
62
      external MatIsing_Mult
63
 
64
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
65
!     Beginning of program
66
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
67
 
68
      call SlepcInitialize(PETSC_NULL_CHARACTER,ierr)
69
#if defined(PETSC_USE_COMPLEX)
214 dsic.upv.es!antodo 70
      write(*,*) 'This example requires real numbers.'
6 dsic.upv.es!jroman 71
      goto 999
72
#endif
1506 slepc 73
      call MPI_Comm_size(PETSC_COMM_WORLD,sz,ierr)
6 dsic.upv.es!jroman 74
      call MPI_Comm_rank(PETSC_COMM_WORLD,rank,ierr)
1506 slepc 75
      if (sz .ne. 1) then
6 dsic.upv.es!jroman 76
         if (rank .eq. 0) then
214 dsic.upv.es!antodo 77
            write(*,*) 'This is a uniprocessor example only!'
6 dsic.upv.es!jroman 78
         endif
79
         SETERRQ(1,' ',ierr)
80
      endif
81
      m = 30
82
      call PetscOptionsGetInt(PETSC_NULL_CHARACTER,'-m',m,flg,ierr)
83
      N = 2*m
84
 
85
      if (rank .eq. 0) then
214 dsic.upv.es!antodo 86
        write(*,*)
87
        write(*,'(A,I6,A)') 'Ising Model Eigenproblem, m=',m,', (N=2*m)'
88
        write(*,*)
6 dsic.upv.es!jroman 89
      endif
90
 
91
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
92
!     Register the matrix-vector subroutine for the operator that defines
93
!     the eigensystem, Ax=kx
94
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
95
 
96
      call MatCreateShell(PETSC_COMM_WORLD,N,N,N,N,PETSC_NULL_OBJECT,A,
97
     &                    ierr)
98
      call MatShellSetOperation(A,MATOP_MULT,MatIsing_Mult,ierr)
99
 
100
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
101
!     Create the eigensolver and display info
102
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
103
 
104
!     ** Create eigensolver context
105
      call EPSCreate(PETSC_COMM_WORLD,eps,ierr)
106
 
107
!     ** Set operators. In this case, it is a standard eigenvalue problem
108
      call EPSSetOperators(eps,A,PETSC_NULL_OBJECT,ierr)
408 dsic.upv.es!antodo 109
      call EPSSetProblemType(eps,EPS_NHEP,ierr)
6 dsic.upv.es!jroman 110
 
111
!     ** Set solver parameters at runtime
112
      call EPSSetFromOptions(eps,ierr)
113
 
114
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
115
!     Solve the eigensystem
116
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
117
 
78 dsic.upv.es!antodo 118
      call EPSSolve(eps,ierr)
119
      call EPSGetIterationNumber(eps,its,ierr)
6 dsic.upv.es!jroman 120
      if (rank .eq. 0) then
214 dsic.upv.es!antodo 121
        write(*,'(A,I4)') ' Number of iterations of the method: ', its
6 dsic.upv.es!jroman 122
      endif
123
 
124
!     ** Optional: Get some information from the solver and display it
1506 slepc 125
      call EPSGetType(eps,tname,ierr)
6 dsic.upv.es!jroman 126
      if (rank .eq. 0) then
1506 slepc 127
        write(*,'(A,A)') ' Solution method: ', tname
6 dsic.upv.es!jroman 128
      endif
1575 slepc 129
      call EPSGetDimensions(eps,nev,PETSC_NULL_INTEGER,
130
     +                      PETSC_NULL_INTEGER,ierr)
6 dsic.upv.es!jroman 131
      if (rank .eq. 0) then
214 dsic.upv.es!antodo 132
        write(*,'(A,I2)') ' Number of requested eigenvalues:', nev
6 dsic.upv.es!jroman 133
      endif
134
      call EPSGetTolerances(eps,tol,maxit,ierr)
135
      if (rank .eq. 0) then
214 dsic.upv.es!antodo 136
        write(*,'(A,1PE10.4,A,I6)') ' Stopping condition: tol=', tol,
137
     &                              ', maxit=', maxit
6 dsic.upv.es!jroman 138
      endif
139
 
140
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
141
!     Display solution and clean up
142
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
143
 
97 dsic.upv.es!antodo 144
!     ** Get number of converged eigenpairs
132 dsic.upv.es!antodo 145
      call EPSGetConverged(eps,nconv,ierr)
6 dsic.upv.es!jroman 146
      if (rank .eq. 0) then
214 dsic.upv.es!antodo 147
        write(*,'(A,I2)') ' Number of converged eigenpairs:', nconv
6 dsic.upv.es!jroman 148
      endif
149
 
150
!     ** Display eigenvalues and relative errors
132 dsic.upv.es!antodo 151
      if (nconv.gt.0 .and. rank.eq.0) then
214 dsic.upv.es!antodo 152
        write(*,*)
153
        write(*,*) '           k          ||Ax-kx||/||kx||'
154
        write(*,*) '   ----------------- ------------------'
132 dsic.upv.es!antodo 155
        do i=0,nconv-1
214 dsic.upv.es!antodo 156
!         ** Get converged eigenpairs: i-th eigenvalue is stored in kr
157
!         ** (real part) and ki (imaginary part)
1866 jroman 158
          call EPSGetEigenpair(eps,i,kr,ki,PETSC_NULL_OBJECT,
159
     +                         PETSC_NULL_OBJECT,ierr)
97 dsic.upv.es!antodo 160
 
214 dsic.upv.es!antodo 161
!         ** Compute the relative error associated to each eigenpair
97 dsic.upv.es!antodo 162
          call EPSComputeRelativeError(eps,i,error,ierr)
163
 
164
          if (ki.ne.0.D0) then
214 dsic.upv.es!antodo 165
            write(*,'(1P,E11.4,E11.4,A,E12.4)') kr, ki, ' j ', error
6 dsic.upv.es!jroman 166
          else
214 dsic.upv.es!antodo 167
            write(*,'(1P,A,E12.4,A,E12.4)') '   ', kr, '       ', error
6 dsic.upv.es!jroman 168
          endif
169
        enddo
170
      endif
1034 slepc 171
      write(*,*)
6 dsic.upv.es!jroman 172
 
173
!     ** Free work space
174
      call EPSDestroy(eps,ierr)
175
      call MatDestroy(A,ierr)
176
 
1365 slepc 177
#if defined(PETSC_USE_COMPLEX)
6 dsic.upv.es!jroman 178
 999  continue
1365 slepc 179
#endif
6 dsic.upv.es!jroman 180
      call SlepcFinalize(ierr)
181
      end
182
 
183
! -------------------------------------------------------------------
184
!
185
!   MatIsing_Mult - user provided matrix-vector multiply
186
!
187
!   Input Parameters:
188
!   A - matrix
189
!   x - input vector
190
!
191
!   Output Parameter:
192
!   y - output vector
193
!
194
      subroutine MatIsing_Mult(A,x,y,ierr)
195
      implicit none
196
 
1885 jroman 197
#include "finclude/petscsys.h"
198
#include "finclude/petscvec.h"
199
#include "finclude/petscmat.h"
6 dsic.upv.es!jroman 200
 
1506 slepc 201
      Mat            A
202
      Vec            x,y
203
      integer        trans,one,N
204
      PetscScalar    x_array(1),y_array(1)
205
      PetscOffset    i_x,i_y
206
      PetscErrorCode ierr
6 dsic.upv.es!jroman 207
 
208
!     The actual routine for the matrix-vector product
209
      external mvmisg
210
 
211
      call MatGetSize(A,N,PETSC_NULL_INTEGER,ierr)
212
      call VecGetArray(x,x_array,i_x,ierr)
213
      call VecGetArray(y,y_array,i_y,ierr)
214
 
215
      trans = 0
216
      one = 1
217
      call mvmisg(trans,N,one,x_array(i_x+1),N,y_array(i_y+1),N)
218
 
219
      call VecRestoreArray(x,x_array,i_x,ierr)
220
      call VecRestoreArray(y,y_array,i_y,ierr)
221
 
222
      return
223
      end
224