-
Notifications
You must be signed in to change notification settings - Fork 0
/
Ising2D.jl
105 lines (88 loc) · 1.84 KB
/
Ising2D.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
using PyPlot
using Statistics
# Find neighbors imposing periodic
# boundary conditions.
function neighborhood(M,idy,idx)
Ny,Nx = size(M)
if (idx > 1)
Nl = M[idy,idx-1]
else
Nl = M[idy,Ny]
end
if (idx < Nx)
Nr = M[idy,idx+1]
else
Nr = M[idy,1]
end
if (idy > 1)
Nu = M[idy-1,idx]
else
Nu = M[idy,Nx]
end
if (idy < Ny)
Nd = M[idy+1,idx]
else
Nd = M[idy,1]
end
return Nl + Nr + Nu + Nd
end
# Solve Ising model using Monte Carlo
function Ising(N,β,B)
s = rand([-1,1],N,N)
Energy = []
Magnetization = []
J = 1.0
# Initial magnetization
M = sum(s)
# Initial energy
ε = B*M
for j in 1:N
for i in 1:N
z = neighborhood(s,i,j)
ε += -0.5*J*z
end
end
NTerm = 2E7
for step in 1:NTerm
# Pick a site
idx = rand(1:N)
idy = rand(1:N)
# Find change in energy due to spin flipping
# and perform Metropolis update.
z = neighborhood(s,idy,idx)
Δε = 2*s[idy,idx]*(J*z + B)
if (rand() < exp(-β*Δε))
s[idy,idx] = -s[idy,idx]
ε += Δε
M += 2*s[idy,idx]
end
# Save statistics
if (mod(step,10) == 0)
push!(Energy,ε)
push!(Magnetization,M)
end
end
return Energy,Magnetization
end
# Collect statistics
function stats(N,β,B)
εₙ,Mₙ = Ising(N,β,B)
M = abs(mean(Mₙ))/N^2
χ = β*var(Mₙ)/N^2
return M,χ
end
# Plot
Tsp = LinRange(1,4,100)
χsp = []
Msp = []
for T in Tsp
β = 1.0/T
M,χ = stats(20,β,0.0)
push!(χsp,χ)
push!(Msp,M)
end
plot(Tsp,Msp,"*")
ax1 = gca()
ax2 = ax1.twinx()
ax2.semilogy(Tsp,χsp,"s",color="orange")
show()