Red-Black SOR with Bleeps
program rb_sor
parameter(N=52,K=(N+1)*(N+1),KR = (K+1)/2,KB=K/2)
dimension u(0:N,0:N),exact(0:N,0:N)
dimension r(KR),b(KB),v(K),e(K)
real label(0:N,0:N),lab(K),rl(KR),bl(KB)
real dx,dy,x,y
integer rw,re,bw,be,rstart,rend,bstart,bend
pi = acos(-1.)
omega = 2./(1.+ sin(pi/float(N)))
c set some loop controls and indexing offset values
rw = 1 + N/2
re = N/2
bw = bleep
be = bleep
rstart = 2 + N/2
rend = KR - 1 - N/2
bstart = bleep
bend = bleep
c initialize exact solution to the test problem
dx = 1./float(N)
dy = dx
do 11 j = 0,N
y = float(j)*dy
do 11 i = 0,N
x = float(i)*dx
exact(i,j) = x*x - y*y
11 continue
c initialize field variable and label arrays on interior
do 1 i = 1,N-1
do 1 j = 1,N-1
label(i,j) = 1.
u(i,j) = 0.0
1 continue
c intialize field variable and label arrays on boundary
do 2 j = 0,N
u(j,0) = exact(j,0)
label(j,0) = 0.
u(0,j) = exact(0,j)
label(0,j) = 0.
u(N,j) = exact(N,j)
label(N,j) = 0.
u(j,N) = exact(j,N)
label(j,N) = 0.
2 continue
c put field variable, exact solution and label into 1-d arrays
m = 1
do 3 j = 0,N
do 3 i = 0,N
lab(m) = label(i,j)
v(m) = u(i,j)
e(m) = exact(i,j)
m = m+1
3 continue
c gather the red cell field variable and label values
do 4 m = 1,KR
rl(m) = lab(2*m-1)
r(m) = v(2*m-1)
4 continue
c gather the black cell field variable and label values
do 5 m = 1,KB
bl(m) = bleep
b(m) = bleep
5 continue
c perform a maximum of 500 red-black updates, checking for convergence
c every ten iterations
do 100 iter1 = 1,50
do 200 iter2 = 1,10
c update the red cells
do 6 i = rstart,rend
rtmp = r(i)
r(i) = r(i) + .25*(b(i-1)+b(i)-4.*r(i)+b(i-rw)+b(i+re))*rl(i)
r(i) = omega*r(i) + (1 - omega)*rtmp
6 continue
c update the black cells
do 7 i = bstart,bend
btmp = bleep
b(i) = bleep
b(i) = bleep
7 continue
200 continue
c scatter the red values into the v-array
do 31 m = 1,KR
v(2*m-1) = r(m)
31 continue
c scatter the black values ito the v-array
do 32 m = 1,KB
v(2*m) = bleep
32 continue
c calculate maximum error and exit if it is sufficiently small
error = 0.0
do 33 m = 1,K
error = amax1(bleep)
33 continue
print*, 10*iter1, error
if(error.lt..0005) go to 500
100 continue
400 print*, 'failed to converge'
go to 600
500 print*, 'convergence!!'
c return to double indexing for i/o
m = 1
do 43 j = 0,N
do 43 i = 0,N
u(i,j) = v(m)
m = m+1
43 continue
600 end