using Plots
using MPI
using Statistics
using DelimitedFiles
function real_psi(N, R_current, I_current, delta_t, delta_x, V)
R_next = fill(0.0, N)
s = delta_t/(2*delta_x^2)
for x in 2:N-1
R_next[x] = R_current[x]-s*(I_current[x+1]-2*I_current[x]+I_current[x-1])+delta_t*V[x].*I_current[x]
R_next[1] = R_next[2]
R_next[N] = R_next[N-1]
end
return R_next
end
function imag_psi(N, I_current, R_current, delta_t, delta_x, V)
I_next = fill(0.0, N)
s = delta_t/(2*delta_x^2)
for x in 2:N-1
I_next[x] = I_current[x]+s*(R_current[x+1]-2*R_current[x]+R_current[x-1])-delta_t*V[x].*R_current[x];
I_next[1] = I_next[2]
I_next[N] = I_next[N-1]
end
return I_next
end
function leapfrog(comm, shared, width)
rank = MPI.Comm_rank(comm)
ENV["PLOTS_TEST"] = "true"
ENV["GKSwstype"] = "100"
N = 1000
x = collect(0:(1/(N-1)):1)
x_0 = fill(0.4, N)
C = fill(10.0, N)
σ_sqrd = fill(1e-3, N)
k_0 = 500.0
Δ_x = 1e-3
Δ_t = 5e-8
ψ = C.*exp.((-(x-x_0).^2)./σ_sqrd).*exp.((k_0*x)*1im)
R_cur = real(ψ)
I_cur = imag(ψ)
V = fill(0.0, N)
for i = 600:convert(Int64, 600+width)
V[i] = rank*8000
end
I_next = imag_psi(N, I_cur, R_cur, Δ_t, Δ_x, V)
before = fill(0.0, 386)
after = before
# Do the leapfrog
anim = @animate for time_step = 1:20000
R_next = real_psi(N, R_cur, I_cur, Δ_t, Δ_x, V)
R_cur = R_next
I_next = imag_psi(N, I_cur, R_cur, Δ_t, Δ_x, V)
prob_density = R_cur.^2+I_next.*I_cur
I_cur = I_next
if time_step == 1
before = filter(!isnan, prob_density[200:585])
end
if time_step == 19999
after = filter(!isnan, prob_density[200:585])
end
plot(x, prob_density,
title = "Wave packet against $(convert(Int64, round(V[600]))) high $width width barrier",
xlabel = "x",
ylabel = "Probability density",
ylims = (0,200),
legend = false,
show = false
)
plot!(x,abs.(V))
end every 20
percentage = round(100*(((mean(before)-mean(after))/mean(before))); digits=2)
gif(anim, "./Figures/ParallelTest/MPILeapFrog_height_$(convert(Int64, round(V[600])))_width_$(width)_barrier_$(percentage).gif", fps=30)
MPI.Win_lock(MPI.LOCK_EXCLUSIVE, 0, 0, win)
MPI.Put([Float64(convert(Int64, round(V[600])))], 1, 0, convert(Int64, ((2*MPI.Comm_rank(comm)))), win)
MPI.Put([Float64(percentage)], 1, 0, convert(Int64, (1+(2*MPI.Comm_rank(comm)))), win)
MPI.Win_unlock(0, win)
MPI.Barrier(comm)
end
MPI.Init()
comm = MPI.COMM_WORLD
shared = zeros(MPI.Comm_size(comm)*2)
win = MPI.Win()
MPI.Win_create(shared, MPI.INFO_NULL, comm, win)
MPI.Barrier(comm)
open("./Files/MPIresults.csv", "w") do fo
for width = 0:25:200
if MPI.Comm_rank(comm) == 0
@time leapfrog(comm, win, width)
else
leapfrog(comm, win, width)
end
if MPI.Comm_rank(comm) == 0
for i = 0:MPI.Comm_size(comm)-1
height = shared[convert(Int64, (1+(2*i)))]
percentage = shared[convert(Int64, (2+(2*i)))]
writedlm(fo, [i height width percentage], ",")
end
end
end
end
MPI.Barrier(comm)
MPI.Finalize()
This code was used to produce a huge set of data which resulted in the following graphs.

This graph shows the effect of barrier height and width of the wave packet. Every single point on this graph has an associated animation that are all available on the GitHub. But here is a few sample ones.

