! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
! SLEPc - Scalable Library for Eigenvalue Problem Computations
! Copyright (c) 2002-2011, Universitat Politecnica de Valencia, Spain
!
! This file is part of SLEPc.
!
! SLEPc is free software: you can redistribute it and/or modify it under the
! terms of version 3 of the GNU Lesser General Public License as published by
! the Free Software Foundation.
!
! SLEPc is distributed in the hope that it will be useful, but WITHOUT ANY
! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
! FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
! more details.
!
! You should have received a copy of the GNU Lesser General Public License
! along with SLEPc. If not, see .
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
!
! Program usage: mpirun -np n ex1f [-help] [-n ] [all SLEPc options]
!
! Description: Simple example that solves an eigensystem with the EPS object.
! The standard symmetric eigenvalue problem to be solved corresponds to the
! Laplacian operator in 1 dimension.
!
! The command line options are:
! -n , where = number of grid points = matrix size
!
! ----------------------------------------------------------------------
!
program main
implicit none
#include
#include
#include
#include
#include
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
! Declarations
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
!
! Variables:
! A operator matrix
! eps eigenproblem solver context
Mat A
EPS eps
EPSType tname
PetscReal tol, error
PetscScalar kr, ki
PetscInt n, i, Istart, Iend
PetscInt nev, maxit, its, nconv
PetscInt col(3)
PetscInt i1,i2,i3
PetscMPIInt rank
PetscErrorCode ierr
PetscBool flg
PetscScalar value(3)
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
! Beginning of program
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
call SlepcInitialize(PETSC_NULL_CHARACTER,ierr)
call MPI_Comm_rank(PETSC_COMM_WORLD,rank,ierr)
n = 30
call PetscOptionsGetInt(PETSC_NULL_CHARACTER,'-n',n,flg,ierr)
if (rank .eq. 0) then
write(*,100) n
endif
100 format (/'1-D Laplacian Eigenproblem, n =',I3,' (Fortran)')
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
! Compute the operator matrix that defines the eigensystem, Ax=kx
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
call MatCreate(PETSC_COMM_WORLD,A,ierr)
call MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,n,n,ierr)
call MatSetFromOptions(A,ierr)
call MatSetUp(A,ierr)
i1 = 1
i2 = 2
i3 = 3
call MatGetOwnershipRange(A,Istart,Iend,ierr)
if (Istart .eq. 0) then
i = 0
col(1) = 0
col(2) = 1
value(1) = 2.0
value(2) = -1.0
call MatSetValues(A,i1,i,i2,col,value,INSERT_VALUES,ierr)
Istart = Istart+1
endif
if (Iend .eq. n) then
i = n-1
col(1) = n-2
col(2) = n-1
value(1) = -1.0
value(2) = 2.0
call MatSetValues(A,i1,i,i2,col,value,INSERT_VALUES,ierr)
Iend = Iend-1
endif
value(1) = -1.0
value(2) = 2.0
value(3) = -1.0
do i=Istart,Iend-1
col(1) = i-1
col(2) = i
col(3) = i+1
call MatSetValues(A,i1,i,i3,col,value,INSERT_VALUES,ierr)
enddo
call MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY,ierr)
call MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY,ierr)
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
! Create the eigensolver and display info
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
! ** Create eigensolver context
call EPSCreate(PETSC_COMM_WORLD,eps,ierr)
! ** Set operators. In this case, it is a standard eigenvalue problem
call EPSSetOperators(eps,A,PETSC_NULL_OBJECT,ierr)
call EPSSetProblemType(eps,EPS_HEP,ierr)
! ** Set solver parameters at runtime
call EPSSetFromOptions(eps,ierr)
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
! Solve the eigensystem
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
call EPSSolve(eps,ierr)
call EPSGetIterationNumber(eps,its,ierr)
if (rank .eq. 0) then
write(*,110) its
endif
110 format (/' Number of iterations of the method:',I4)
! ** Optional: Get some information from the solver and display it
call EPSGetType(eps,tname,ierr)
if (rank .eq. 0) then
write(*,120) tname
endif
120 format (' Solution method: ',A)
call EPSGetDimensions(eps,nev,PETSC_NULL_INTEGER, &
& PETSC_NULL_INTEGER,ierr)
if (rank .eq. 0) then
write(*,130) nev
endif
130 format (' Number of requested eigenvalues:',I2)
call EPSGetTolerances(eps,tol,maxit,ierr)
if (rank .eq. 0) then
write(*,140) tol, maxit
endif
140 format (' Stopping condition: tol=',1P,E10.4,', maxit=',I4)
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
! Display solution and clean up
! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
! ** Get number of converged eigenpairs
call EPSGetConverged(eps,nconv,ierr)
if (rank .eq. 0) then
write(*,150) nconv
endif
150 format (' Number of converged eigenpairs:',I2/)
! ** Display eigenvalues and relative errors
if (nconv.gt.0) then
if (rank .eq. 0) then
write(*,*) ' k ||Ax-kx||/||kx||'
write(*,*) ' ----------------- ------------------'
endif
do i=0,nconv-1
! ** Get converged eigenpairs: i-th eigenvalue is stored in kr
! ** (real part) and ki (imaginary part)
call EPSGetEigenpair(eps,i,kr,ki,PETSC_NULL_OBJECT, &
& PETSC_NULL_OBJECT,ierr)
! ** Compute the relative error associated to each eigenpair
call EPSComputeRelativeError(eps,i,error,ierr)
if (rank .eq. 0) then
write(*,160) PetscRealPart(kr), error
endif
160 format (1P,' ',E12.4,' ',E12.4)
enddo
if (rank .eq. 0) then
write(*,*)
endif
endif
! ** Free work space
call EPSDestroy(eps,ierr)
call MatDestroy(A,ierr)
call SlepcFinalize(ierr)
end