PROGRAM 1001
IMPLICIT NONE
! Declare Variables
COMPLEX(KIND=8), DIMENSION(:,:), ALLOCATABLE :: mat
COMPLEX(KIND=8), DIMENSION(:), ALLOCATABLE :: vec, vec_2
REAL(KIND=8), DIMENSION(:,:), ALLOCATABLE :: mat_r, mat_i
REAL(KIND=8), DIMENSION(:), ALLOCATABLE :: vec_r, vec_i, a, b, x
REAL(KIND=8) :: n_x, n_0, k, beta, pi, exp, step, x_i, u_i
REAL(KIND=8) :: start_time, end_time
INTEGER :: lambda, L, m, numEq, i
INTEGER :: allocate_status=0, IO_status
INTEGER :: NRHS, LD_mat, LD_vec, INFO
INTEGER, DIMENSION(:), ALLOCATABLE :: IPIV
CHARACTER(LEN=30) :: fmt, int_char, filename
! Load Parameters File
PRINT *, "Please specify parameter filename: "
READ (*,*) filename
OPEN(1, file=filename, status='old', IOSTAT=IO_status)
IF (IO_status /= 0) THEN
WRITE(*,*) "Error!"
WRITE(*,*) "Cannot open file ", filename, " File cannot be located. Please check file and try again."
GOTO 100
ENDIF
READ(1,*) lambda
READ(1,*) n_x
READ(1,*) n_0
READ(1,*) L
READ(1,*) m
CLOSE(1)
! Output File Contents
WRITE(*,*) 'Wavelength = ' , lambda
WRITE(*,*) 'Refractive Index Function = ' , n_x
WRITE(*,*) 'Refractive Index = ' , n_0
WRITE(*,*) 'Length = ' , L
WRITE(*,*) 'Grid Point Parameter = ', m
! Set Variables
pi = 3.14159265
exp = 2.71828183
k = 2 * pi / lambda
beta = n_0 * k
step = L / m
! Error Checking
IF (lambda <= 0) THEN
WRITE(*,*) "ERROR! Wavelength <= 0"
GOTO 100
ENDIF
IF (n_x <= 0) THEN
WRITE(*,*) "ERROR! Refractive Index Function <= 0"
GOTO 100
ENDIF
IF (n_0 <= 0) THEN
WRITE(*,*) "ERROR! Refractive Index <= 0"
GOTO 100
ENDIF
IF (L <= 0) THEN
WRITE(*,*) "ERROR! Length <= 0"
GOTO 100
ENDIF
IF (m <= 2) THEN
WRITE(*,*) "ERROR! Grid Point Parameter < 2"
GOTO 100
ENDIF
! Bulk Coding
numEq = m + 3
WRITE(*,*) 'Step Size = ', step
ALLOCATE(mat(numEq,numEq), vec(numEq), x(m), &
mat_r(numEq,numEq), vec_r(numEq), a(m-1), &
mat_i(numEq,numEq), vec_i(numEq), b(m-1), &
IPIV(numEq), STAT=allocate_status)
CALL cpu_time(start_time)
! Initialise Matrices and Vectors
mat = 0.0d0
mat_r = 0.0d0
mat_i = 0.0d0
vec = 0.0d0
vec_r = 0.0d0
vec_i = 0.0d0
DO i=0, m
x(i) = i * step
ENDDO
DO i=1, m-1
a(i) = -2+(step**2)*(n_x**2)*(k**2)
b(i) = 1
ENDDO
i=1
mat_r(i,i) = -1
mat_r(i+1,i) = 1
DO i=2,m
mat_r(i-1,i) = b(i-1)
mat_r(i,i) = a(i-1)
mat_r(i+1,i) = b(i-1)
ENDDO
i=m+1
mat_r(i-1,i) = -1
mat_r(i,i) = 1
mat_r(1,i+1) = 1
mat_r(i+1,i+1) = -1
mat_r(i,i+2) = 1
! Input value to imaginary mat
i=1
mat_i(numEq-1,i) = step * beta
i=m+1
mat_i(numEq,i) = -step * beta * (exp**(beta * L))
mat_i(numEq,i+2) = -exp**(beta * L)
! Input value to real and imaginary vec
vec_r(numEq-1) = 1
vec_i(1) = step * beta
! Combine real and imaginary data to mat and vec
mat = mat_r+(0.0d0, 1.0d0)*mat_i
vec = vec_r+(0.0d0, 1.0d0)*vec_i
! Formatting fmt
write(int_char,*) numEq
FMT = "(" // TRIM(ADJUSTL(int_char)) // "(' (',f10.4,',',f10.4,') '))"
IF (numEq <= 10) then
WRITE(*,*) "Matrix (A):"
WRITE(*,FMT) mat
WRITE(*,*) "Vector (B):"
WRITE(*,FMT) vec
ENDIF
! Solve
NRHS = 1
LD_mat = numEq
LD_vec = numEq
CALL ZGESV(numEq, NRHS, mat, LD_mat, IPIV, vec, LD_vec, INFO)
IF (numEq <= 10) then
WRITE(*,FMT) vec
ENDIF
CALL cpu_time(end_time)
WRITE(*,*) "Run time = ", end_time - start_time
! Saving the solution
OPEN(2, file='solution.txt', status='unknown', IOSTAT=IO_status)
IF (IO_status /= 0) then
WRITE(*,*) "Error opening the file solutions.txt"
GOTO 100
ELSE
i=numEq-1
WRITE(2,'(2(f20.15))') 'r = ', vec(i)
i=numEq
WRITE(2,'(2(f20.15))') 't = ', vec(i)
ENDIF
CLOSE(2)
100 CONTINUE
END PROGRAM 1001