forked from burakbayramli/books
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathising.py
79 lines (69 loc) · 1.95 KB
/
ising.py
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
import math, pylab, random
J = 1.0 # exchange energy
L = input('number of atoms per side of lattice -> ')
nsweep = input('number sweeps to average -> ')
seed = input('random number seed -> ')
random.seed(seed)
N = L**2
kT = pylab.arange(0.1, 5.0, 0.1)
e = pylab.zeros(len(kT))
m = pylab.zeros(len(kT))
c = pylab.zeros(len(kT))
# initial data
s = pylab.ones((L, L))
E = 0.0
M = 0.0
for i in range(L):
for j in range(L):
E -= J*s[i,j]*(s[(i+1)%L,j]+s[i,(j+1)%L])
M += s[i,j]
# prepare animated plot
pylab.ion()
image = pylab.imshow(s, vmax=1, vmin=-1)
# slowly warm up
for t in range(len(kT)):
# average nsweep sweeps
for sweep in range(nsweep):
# update animated plot
image.set_data(s)
pylab.title('kT = %g'%kT[t])
pylab.draw()
# sweep over all particles in lattice
for i in range(L):
for j in range(L):
# compute energy required to flip spin
dE = s[(i+1)%L,j]+s[(i-1)%L,j]+s[i,(j+1)%L]+s[i,(j-1)%L]
dE *= 2.0*J*s[i,j]
# Metropolis algorithm to see if we should accept trial
if dE <= 0.0 or random.random() <= math.exp(-dE/kT[t]):
# accept trial: reverse spin; return dE and dM
s[i,j] *= -1
M += 2.0*s[i,j]
E += dE
# update running means and variances
deltae = E-e[t]
deltam = M-m[t]
e[t] += deltae/(sweep+1)
m[t] += deltam/(sweep+1)
c[t] += deltae*(E-e[t])
e[t] /= N
m[t] /= N
c[t] /= nsweep*N*kT[t]**2
# produce plots
pylab.ioff()
pylab.figure()
pylab.plot(kT, e, 'o')
pylab.xlabel('temperature')
pylab.ylabel('energy per atom')
pylab.grid()
pylab.figure()
pylab.plot(kT, m, 'o')
pylab.xlabel('temperature')
pylab.ylabel('magnetization per atom')
pylab.grid()
pylab.figure()
pylab.plot(kT, c, 'o')
pylab.xlabel('temperature')
pylab.ylabel('heat capacity per atom')
pylab.grid()
pylab.show()