Examples using hybrid (Metropolis + Wolff) sampling method
Magnetization as a function of temperature
import IsingModels as Ising
using Statistics, CairoMakie, Random
Random.seed!(1) # make reproducible
βs = 0:0.025:1
fig = Figure(resolution=(600,400))
ax = Axis(fig[1,1], xlabel="β", ylabel="m")
lines!(ax, 0:0.01:1, Ising.onsager_magnetization, color=:black, label="analytical")
mavg = zeros(length(βs))
mstd = zeros(length(βs))
σ = bitrand(32, 32)
for (k,β) in enumerate(βs)
σ_t, M, E = Ising.hybrid!(σ, β, steps=10^7)
m = abs.(M[(length(M) ÷ 2):end]) / length(σ)
mavg[k] = mean(m)
mstd[k] = std(m)
end
scatter!(ax, βs, mavg, color=:blue, markersize=5, label="MC, L=30")
errorbars!(ax, βs, mavg, mstd/2, color=:blue, whiskerwidth=5)
mavg = zeros(length(βs))
mstd = zeros(length(βs))
σ = bitrand(64, 64)
for (k, β) in enumerate(βs)
σ_t, M, E = Ising.hybrid!(σ, β, steps=10^7)
m = abs.(M[(length(M) ÷ 2):end]) / length(σ)
mavg[k] = mean(m)
mstd[k] = std(m)
end
scatter!(ax, βs, mavg, color=:red, markersize=5, label="MC, L=70")
errorbars!(ax, βs, mavg, mstd/2, color=:red, whiskerwidth=5)
axislegend(ax, position=:rb)
fig
Wolff steps are mixed with Metropolis steps
import IsingModels as Ising
using CairoMakie, Random
Random.seed!(5) # make reproducible
β = Ising.βc
Δ = 5
σ = bitrand(32, 32)
Ising.metropolis!(σ, β; steps=10^6) # equilibrate a bit to get some clusters
σ_t, M, E = Ising.hybrid!(σ, β; steps=20, save_interval = 1, local_steps = Δ)
fig = Figure(resolution=(600, 500))
for t ∈ 1:size(σ_t, 3)
ax = Axis(fig[cld(t, Δ), mod1(t, Δ)])
hidedecorations!(ax)
heatmap!(ax, σ_t[:,:,t], colormap=cgrad([:purple, :orange], [0.5]; categorical=true))
end
fig
In the figure above, each row is a sequence of consecutive Metropolis steps. Inside a row the configurations are very similar differing in single sites. When the row ends, a Wolff cluster move is taken. It can be seen that the next row has suffered a larger change, since a cluster was flipped.
Magnetic susceptibility
using Statistics, CairoMakie, Random
import IsingModels as Ising
Random.seed!(1) # make reproducible
Ts = 2:0.01:3
βs = inv.(Ts)
fig = Figure(resolution=(600, 400))
ax = Axis(fig[1,1], xlabel=L"temperature $T$ ($=1/\beta$)", ylabel="susceptibility", yscale=log10)
@time for (L, color) in zip([4, 8, 16, 32], [:green, :orange, :blue, :red])
χ = zeros(length(βs))
for (k, β) in enumerate(βs)
σ = bitrand(L, L)
σ_t, M, E = Ising.hybrid!(σ, β; steps=10^6)
χ[k] = β/length(σ) * var(abs.(M))
end
scatter!(ax, Ts, χ, color=color, markersize=5, label=L"L=%$L")
end
vlines!(ax, [1 / Ising.βc], label=L"Onsager's $T_c$", color=:black, linestyle=:dash)
axislegend(ax, position=:rt)
fig
Heat capacity
using Statistics, CairoMakie, Random
import IsingModels as Ising
Random.seed!(1) # make reproducible
Ts = 1.5:0.01:3
βs = inv.(Ts)
fig = Figure(resolution=(600, 400))
ax = Axis(fig[1,1], xlabel=L"temperature $T$ ($=1/\beta$)", ylabel="heat capacity", yscale=log10)
@time for (L, color) in zip([4, 8, 16, 32], [:green, :orange, :blue, :red])
C = zeros(length(βs))
for (k, β) in enumerate(βs)
σ = bitrand(L, L)
σ_t, M, E = Ising.hybrid!(σ, β; steps=10^7)
C[k] = β^2/length(σ) * var(E)
end
scatter!(ax, Ts, C, color=color, markersize=5, label=L"L=%$L")
end
vlines!(ax, [1 / Ising.βc], label=L"Onsager's $T_c$", color=:black, linestyle=:dash)
axislegend(ax, position=:lt)
fig
Wolff vs. Metropolis spin flip rates
At low temperatures, Wolff flips more spins per unit time than Metropolis. At high temperatures, Metropolis is more efficient. The crossing point approaches the critical temperature for larger system sizes.
using Statistics, CairoMakie, Random
import IsingModels as Ising
Random.seed!(1) # make reproducible
Ts = 1:0.5:5
βs = inv.(Ts)
fig = Figure(resolution=(600, 400))
ax = Axis(fig[1,1], xlabel=L"temperature $T$ ($=1/\beta$)", ylabel="spin flips / second", yscale=log10)
@time for (L, color) in zip([4, 8, 16, 32], [:blue, :red, :orange, :green])
wolff_rates = zeros(length(βs))
local_rates = zeros(length(βs))
for (k, β) in enumerate(βs)
σ = bitrand(L, L)
stats = Ising.HybridStats()
σ_t, M, E = Ising.dynamic_hybrid!(σ, β; steps=10^6, hybrid_stats=stats)
local_rates[k] = stats.local_flip / stats.local_time
wolff_rates[k] = stats.wolff_flip / stats.wolff_time
end
scatterlines!(ax, Ts, local_rates, markersize=15, label=L"$L=%$L$ local", color=color, marker='x', markercolor=color, linestyle=:dash)
scatterlines!(ax, Ts, wolff_rates, markersize=15, label=L"$L=%$L$ wolff", color=color, marker='o', markercolor=color, linestyle=:dot)
end
vlines!(ax, [1 / Ising.βc], label=L"Onsager's $T_c$", color=:black, linewidth=1)
Legend(fig[1,2], ax)
fig
This page was generated using Literate.jl.