Skip to content

Commit 8c2922e

Browse files
committed
Add Jacobi solver for Poisson equation as advanced exercise.
1 parent 6ba3b21 commit 8c2922e

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

content/week11/poisson_jacobi.f90

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
program poisson
2+
! Declare and/or Initialize variables
3+
implicit none
4+
integer :: NDEF = 64
5+
integer :: MAXITER = 1000, OUTFREQ = 1000
6+
logical :: FOUT = .TRUE.
7+
8+
integer :: n
9+
real(kind=8) :: h = 1.
10+
real(kind=8) :: eps = 1.D-6
11+
12+
real(kind=8), dimension(:,:), allocatable :: uold, unew, f
13+
14+
integer :: narg, i, j, iter = 0, nthreads
15+
real(kind=8) :: x, y, err, terr, ffac, strt, stop, err0, ftot
16+
real(kind=8) :: res, lap, omega = 1.0
17+
character(len=20) :: arg
18+
19+
! Parse input
20+
narg = command_argument_count()
21+
if (narg .eq. 0) then
22+
n = NDEF
23+
else if (narg .eq. 1) then
24+
call get_command_argument(1, arg)
25+
read(arg,*) n
26+
else if (narg .eq. 2) then
27+
call get_command_argument(1, arg)
28+
read(arg,*) n
29+
call get_command_argument(2, arg)
30+
read(arg,*) eps
31+
else
32+
write(*,*) 'Usage: ./poisson [n eps]'
33+
call exit(1)
34+
end if
35+
36+
h = 1./n
37+
38+
! Allocate and fill the working arrays
39+
allocate(uold(0:n+1,0:n+1))
40+
allocate(unew(0:n+1,0:n+1))
41+
allocate(f(1:n,1:n))
42+
uold = 0.
43+
unew = 0.
44+
f = 0.
45+
46+
! Fill in the source function
47+
ftot = 0.
48+
do i = 1, n
49+
x = (i - .5) * h
50+
do j = 1, n
51+
y = (j - .5) * h
52+
f(i,j) = 0.0
53+
if(i .eq. n/2 .and. j .eq. n/2) f(i,j)=1.
54+
ftot = ftot + f(i,j)
55+
end do
56+
end do
57+
ftot = 0. !ftot/dble(n*n)
58+
59+
! Main loop
60+
ffac = h**2.
61+
err = huge(err)
62+
call cpu_time(strt)
63+
64+
do while((err .gt. eps) .and. (iter .lt. MAXITER))
65+
66+
! Jacobi method
67+
err = 0.
68+
69+
do j = 1,n
70+
do i = 1,n
71+
72+
lap = uold(i-1,j)+uold(i+1,j)+uold(i,j-1)+uold(i,j+1)-4.0*uold(i,j)
73+
res = lap - ffac * (f(i,j) - ftot)
74+
unew(i,j) = uold(i,j) + omega*0.25*res
75+
76+
err = MAX(err,abs(unew(i,j) - uold(i,j)))
77+
end do
78+
end do
79+
80+
! Neumann boundary conditions
81+
do i = 1, n
82+
unew(i,0) = 0. !unew(i,n)
83+
unew(i,n+1) = 0. !unew(i,1)
84+
unew(0,i) = 0. !unew(n,i)
85+
unew(n+1,i) = 0. !unew(1,i)
86+
end do
87+
88+
do j = 1,n
89+
do i = 1,n
90+
uold(i,j) = unew(i,j)
91+
end do
92+
end do
93+
94+
iter = iter + 1
95+
if ((mod(iter,OUTFREQ) .eq. 0) .or. (err .lt. eps)) then
96+
write(*, '(A, I8, A, ES13.6)') 'Iter. ', iter, ', err = ', err
97+
end if
98+
99+
end do
100+
101+
! Print timing
102+
call cpu_time(stop)
103+
104+
write(*,'(A, ES13.6, A)') 'Finished in ', stop-strt, ' s'
105+
106+
107+
! Final time step output
108+
if (FOUT) then
109+
open(7, file = 'final_phi.dat')
110+
write(7, *) n, eps, iter, err
111+
do i = 1, n
112+
write(7, '(*(ES13.6))') uold(i,1:n)
113+
end do
114+
close(7)
115+
end if
116+
117+
deallocate(uold)
118+
deallocate(unew)
119+
deallocate(f)
120+
121+
end program poisson

0 commit comments

Comments
 (0)