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 |
| 2575 | eromero | 3 | ! Copyright (c) 2002-2011, Universitat 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 | |||
| 2283 | jroman | 35 | #include <finclude/petscsys.h> |
| 36 | #include <finclude/petscvec.h> |
||
| 37 | #include <finclude/petscmat.h> |
||
| 38 | #include <finclude/slepcsys.h> |
||
| 39 | #include <finclude/slepceps.h> |
||
| 6 | dsic.upv.es!jroman | 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 |
||
| 2503 | jroman | 52 | PetscReal tol |
| 53 | PetscInt N, m |
||
| 54 | PetscInt nev, maxit, its |
||
| 1506 | slepc | 55 | PetscMPIInt sz, rank |
| 56 | PetscErrorCode ierr |
||
| 2216 | jroman | 57 | PetscBool flg |
| 6 | dsic.upv.es!jroman | 58 | |
| 59 | ! This is the routine to use for matrix-free approach |
||
| 60 | ! |
||
| 61 | external MatIsing_Mult |
||
| 62 | |||
| 63 | ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
||
| 64 | ! Beginning of program |
||
| 65 | ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
||
| 66 | |||
| 67 | call SlepcInitialize(PETSC_NULL_CHARACTER,ierr) |
||
| 68 | #if defined(PETSC_USE_COMPLEX) |
||
| 214 | dsic.upv.es!antodo | 69 | write(*,*) 'This example requires real numbers.' |
| 6 | dsic.upv.es!jroman | 70 | goto 999 |
| 71 | #endif |
||
| 1506 | slepc | 72 | call MPI_Comm_size(PETSC_COMM_WORLD,sz,ierr) |
| 6 | dsic.upv.es!jroman | 73 | call MPI_Comm_rank(PETSC_COMM_WORLD,rank,ierr) |
| 1506 | slepc | 74 | if (sz .ne. 1) then |
| 6 | dsic.upv.es!jroman | 75 | if (rank .eq. 0) then |
| 214 | dsic.upv.es!antodo | 76 | write(*,*) 'This is a uniprocessor example only!' |
| 6 | dsic.upv.es!jroman | 77 | endif |
| 2214 | jroman | 78 | SETERRQ(PETSC_COMM_WORLD,1,' ',ierr) |
| 6 | dsic.upv.es!jroman | 79 | endif |
| 80 | m = 30 |
||
| 81 | call PetscOptionsGetInt(PETSC_NULL_CHARACTER,'-m',m,flg,ierr) |
||
| 82 | N = 2*m |
||
| 83 | |||
| 84 | if (rank .eq. 0) then |
||
| 214 | dsic.upv.es!antodo | 85 | write(*,*) |
| 86 | write(*,'(A,I6,A)') 'Ising Model Eigenproblem, m=',m,', (N=2*m)' |
||
| 87 | write(*,*) |
||
| 6 | dsic.upv.es!jroman | 88 | endif |
| 89 | |||
| 90 | ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
||
| 91 | ! Register the matrix-vector subroutine for the operator that defines |
||
| 92 | ! the eigensystem, Ax=kx |
||
| 93 | ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
||
| 94 | |||
| 2205 | jroman | 95 | call MatCreateShell(PETSC_COMM_WORLD,N,N,N,N,PETSC_NULL_OBJECT, & |
| 96 | & A,ierr) |
||
| 6 | dsic.upv.es!jroman | 97 | call MatShellSetOperation(A,MATOP_MULT,MatIsing_Mult,ierr) |
| 98 | |||
| 99 | ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
||
| 100 | ! Create the eigensolver and display info |
||
| 101 | ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
||
| 102 | |||
| 103 | ! ** Create eigensolver context |
||
| 104 | call EPSCreate(PETSC_COMM_WORLD,eps,ierr) |
||
| 105 | |||
| 106 | ! ** Set operators. In this case, it is a standard eigenvalue problem |
||
| 107 | call EPSSetOperators(eps,A,PETSC_NULL_OBJECT,ierr) |
||
| 408 | dsic.upv.es!antodo | 108 | call EPSSetProblemType(eps,EPS_NHEP,ierr) |
| 6 | dsic.upv.es!jroman | 109 | |
| 110 | ! ** Set solver parameters at runtime |
||
| 111 | call EPSSetFromOptions(eps,ierr) |
||
| 112 | |||
| 113 | ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
||
| 114 | ! Solve the eigensystem |
||
| 115 | ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
||
| 116 | |||
| 78 | dsic.upv.es!antodo | 117 | call EPSSolve(eps,ierr) |
| 118 | call EPSGetIterationNumber(eps,its,ierr) |
||
| 6 | dsic.upv.es!jroman | 119 | if (rank .eq. 0) then |
| 214 | dsic.upv.es!antodo | 120 | write(*,'(A,I4)') ' Number of iterations of the method: ', its |
| 6 | dsic.upv.es!jroman | 121 | endif |
| 122 | |||
| 123 | ! ** Optional: Get some information from the solver and display it |
||
| 1506 | slepc | 124 | call EPSGetType(eps,tname,ierr) |
| 6 | dsic.upv.es!jroman | 125 | if (rank .eq. 0) then |
| 1506 | slepc | 126 | write(*,'(A,A)') ' Solution method: ', tname |
| 6 | dsic.upv.es!jroman | 127 | endif |
| 2205 | jroman | 128 | call EPSGetDimensions(eps,nev,PETSC_NULL_INTEGER, & |
| 129 | & PETSC_NULL_INTEGER,ierr) |
||
| 6 | dsic.upv.es!jroman | 130 | if (rank .eq. 0) then |
| 214 | dsic.upv.es!antodo | 131 | write(*,'(A,I2)') ' Number of requested eigenvalues:', nev |
| 6 | dsic.upv.es!jroman | 132 | endif |
| 133 | call EPSGetTolerances(eps,tol,maxit,ierr) |
||
| 134 | if (rank .eq. 0) then |
||
| 2205 | jroman | 135 | write(*,'(A,1PE10.4,A,I6)') ' Stopping condition: tol=', tol, & |
| 214 | dsic.upv.es!antodo | 136 | & ', maxit=', maxit |
| 6 | dsic.upv.es!jroman | 137 | endif |
| 138 | |||
| 139 | ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
||
| 140 | ! Display solution and clean up |
||
| 141 | ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
||
| 142 | |||
| 2503 | jroman | 143 | call EPSPrintSolution(eps,PETSC_NULL_OBJECT,ierr) |
| 6 | dsic.upv.es!jroman | 144 | call EPSDestroy(eps,ierr) |
| 145 | call MatDestroy(A,ierr) |
||
| 146 | |||
| 1365 | slepc | 147 | #if defined(PETSC_USE_COMPLEX) |
| 6 | dsic.upv.es!jroman | 148 | 999 continue |
| 1365 | slepc | 149 | #endif |
| 6 | dsic.upv.es!jroman | 150 | call SlepcFinalize(ierr) |
| 151 | end |
||
| 152 | |||
| 153 | ! ------------------------------------------------------------------- |
||
| 154 | ! |
||
| 155 | ! MatIsing_Mult - user provided matrix-vector multiply |
||
| 156 | ! |
||
| 157 | ! Input Parameters: |
||
| 158 | ! A - matrix |
||
| 159 | ! x - input vector |
||
| 160 | ! |
||
| 161 | ! Output Parameter: |
||
| 162 | ! y - output vector |
||
| 163 | ! |
||
| 164 | subroutine MatIsing_Mult(A,x,y,ierr) |
||
| 165 | implicit none |
||
| 166 | |||
| 2283 | jroman | 167 | #include <finclude/petscsys.h> |
| 168 | #include <finclude/petscvec.h> |
||
| 169 | #include <finclude/petscmat.h> |
||
| 6 | dsic.upv.es!jroman | 170 | |
| 1506 | slepc | 171 | Mat A |
| 172 | Vec x,y |
||
| 2503 | jroman | 173 | PetscInt trans,one,N |
| 1506 | slepc | 174 | PetscScalar x_array(1),y_array(1) |
| 175 | PetscOffset i_x,i_y |
||
| 176 | PetscErrorCode ierr |
||
| 6 | dsic.upv.es!jroman | 177 | |
| 178 | ! The actual routine for the matrix-vector product |
||
| 179 | external mvmisg |
||
| 180 | |||
| 181 | call MatGetSize(A,N,PETSC_NULL_INTEGER,ierr) |
||
| 182 | call VecGetArray(x,x_array,i_x,ierr) |
||
| 183 | call VecGetArray(y,y_array,i_y,ierr) |
||
| 184 | |||
| 185 | trans = 0 |
||
| 186 | one = 1 |
||
| 187 | call mvmisg(trans,N,one,x_array(i_x+1),N,y_array(i_y+1),N) |
||
| 188 | |||
| 189 | call VecRestoreArray(x,x_array,i_x,ierr) |
||
| 190 | call VecRestoreArray(y,y_array,i_y,ierr) |
||
| 191 | |||
| 192 | return |
||
| 193 | end |
||
| 194 | |||
| 2356 | jroman | 195 | ! ------------------------------------------------------------------- |
| 196 | ! The actual routine for the matrix-vector product |
||
| 197 | ! See http://math.nist.gov/MatrixMarket/data/NEP/mvmisg/mvmisg.html |
||
| 198 | |||
| 199 | SUBROUTINE MVMISG( TRANS, N, M, X, LDX, Y, LDY ) |
||
| 200 | ! .. |
||
| 201 | ! .. Scalar Arguments .. |
||
| 2503 | jroman | 202 | PetscInt LDY, LDX, M, N, TRANS |
| 2356 | jroman | 203 | ! .. |
| 204 | ! .. Array Arguments .. |
||
| 2503 | jroman | 205 | PetscScalar Y( LDY, * ), X( LDX, * ) |
| 2356 | jroman | 206 | ! .. |
| 207 | ! |
||
| 208 | ! Purpose |
||
| 209 | ! ======= |
||
| 210 | ! |
||
| 211 | ! Compute |
||
| 212 | ! |
||
| 213 | ! Y(:,1:M) = op(A)*X(:,1:M) |
||
| 214 | ! |
||
| 215 | ! where op(A) is A or A' (the transpose of A). The A is the Ising |
||
| 216 | ! matrix. |
||
| 217 | ! |
||
| 218 | ! Arguments |
||
| 219 | ! ========= |
||
| 220 | ! |
||
| 221 | ! TRANS (input) INTEGER |
||
| 222 | ! If TRANS = 0, compute Y(:,1:M) = A*X(:,1:M) |
||
| 223 | ! If TRANS = 1, compute Y(:,1:M) = A'*X(:,1:M) |
||
| 224 | ! |
||
| 225 | ! N (input) INTEGER |
||
| 226 | ! The order of the matrix A. N has to be an even number. |
||
| 227 | ! |
||
| 2503 | jroman | 228 | ! M (input) INTEGER |
| 2356 | jroman | 229 | ! The number of columns of X to multiply. |
| 230 | ! |
||
| 231 | ! X (input) DOUBLE PRECISION array, dimension ( LDX, M ) |
||
| 232 | ! X contains the matrix (vectors) X. |
||
| 233 | ! |
||
| 234 | ! LDX (input) INTEGER |
||
| 235 | ! The leading dimension of array X, LDX >= max( 1, N ) |
||
| 236 | ! |
||
| 237 | ! Y (output) DOUBLE PRECISION array, dimension (LDX, M ) |
||
| 238 | ! contains the product of the matrix op(A) with X. |
||
| 239 | ! |
||
| 240 | ! LDY (input) INTEGER |
||
| 241 | ! The leading dimension of array Y, LDY >= max( 1, N ) |
||
| 242 | ! |
||
| 243 | ! =================================================================== |
||
| 244 | ! |
||
| 245 | ! |
||
| 246 | ! .. PARAMETERS .. |
||
| 2503 | jroman | 247 | PetscReal PI |
| 248 | PARAMETER ( PI = 3.141592653589793D+00 ) |
||
| 249 | PetscReal ALPHA, BETA |
||
| 250 | PARAMETER ( ALPHA = PI/4, BETA = PI/4 ) |
||
| 2356 | jroman | 251 | ! |
| 252 | ! .. Local Variables .. |
||
| 2503 | jroman | 253 | PetscInt I, K |
| 254 | PetscReal COSA, COSB, SINA |
||
| 255 | PetscReal SINB, TEMP, TEMP1 |
||
| 2356 | jroman | 256 | ! |
| 257 | ! .. Intrinsic functions .. |
||
| 2503 | jroman | 258 | INTRINSIC COS, SIN |
| 2356 | jroman | 259 | ! |
| 260 | COSA = COS( ALPHA ) |
||
| 261 | SINA = SIN( ALPHA ) |
||
| 262 | COSB = COS( BETA ) |
||
| 263 | SINB = SIN( BETA ) |
||
| 264 | ! |
||
| 265 | IF ( TRANS.EQ.0 ) THEN |
||
| 266 | ! |
||
| 267 | ! Compute Y(:,1:M) = A*X(:,1:M) |
||
| 268 | |||
| 269 | DO 30 K = 1, M |
||
| 270 | ! |
||
| 271 | Y( 1, K ) = COSB*X( 1, K ) - SINB*X( N, K ) |
||
| 272 | DO 10 I = 2, N-1, 2 |
||
| 273 | Y( I, K ) = COSB*X( I, K ) + SINB*X( I+1, K ) |
||
| 274 | Y( I+1, K ) = -SINB*X( I, K ) + COSB*X( I+1, K ) |
||
| 275 | 10 CONTINUE |
||
| 276 | Y( N, K ) = SINB*X( 1, K ) + COSB*X( N, K ) |
||
| 277 | ! |
||
| 278 | DO 20 I = 1, N, 2 |
||
| 279 | TEMP = COSA*Y( I, K ) + SINA*Y( I+1, K ) |
||
| 280 | Y( I+1, K ) = -SINA*Y( I, K ) + COSA*Y( I+1, K ) |
||
| 281 | Y( I, K ) = TEMP |
||
| 282 | 20 CONTINUE |
||
| 283 | ! |
||
| 284 | 30 CONTINUE |
||
| 285 | ! |
||
| 286 | ELSE IF ( TRANS.EQ.1 ) THEN |
||
| 287 | ! |
||
| 288 | ! Compute Y(:1:M) = A'*X(:,1:M) |
||
| 289 | ! |
||
| 290 | DO 60 K = 1, M |
||
| 291 | ! |
||
| 292 | DO 40 I = 1, N, 2 |
||
| 293 | Y( I, K ) = COSA*X( I, K ) - SINA*X( I+1, K ) |
||
| 294 | Y( I+1, K ) = SINA*X( I, K ) + COSA*X( I+1, K ) |
||
| 295 | 40 CONTINUE |
||
| 296 | TEMP = COSB*Y(1,K) + SINB*Y(N,K) |
||
| 297 | DO 50 I = 2, N-1, 2 |
||
| 298 | TEMP1 = COSB*Y( I, K ) - SINB*Y( I+1, K ) |
||
| 299 | Y( I+1, K ) = SINB*Y( I, K ) + COSB*Y( I+1, K ) |
||
| 300 | Y( I, K ) = TEMP1 |
||
| 301 | 50 CONTINUE |
||
| 302 | Y( N, K ) = -SINB*Y( 1, K ) + COSB*Y( N, K ) |
||
| 303 | Y( 1, K ) = TEMP |
||
| 304 | ! |
||
| 305 | 60 CONTINUE |
||
| 306 | ! |
||
| 307 | END IF |
||
| 308 | ! |
||
| 309 | RETURN |
||
| 310 | ! |
||
| 311 | ! END OF MVMISG |
||
| 312 | END |