Skip to content

Commit 528928b

Browse files
Add 2D Ising model Monte Carlo simulation
1 parent e2a78d4 commit 528928b

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
"""
2+
Monte Carlo Simulation of the 2D Ising Model using Metropolis Algorithm.
3+
4+
Reference:
5+
https://en.wikipedia.org/wiki/Ising_model
6+
7+
This algorithm simulates spin interactions on a 2D lattice.
8+
It demonstrates how spins evolve toward equilibrium at a given temperature.
9+
10+
>>> result = ising_model_simulation(lattice_size=10, temperature=2.0, sweeps=100)
11+
>>> isinstance(result, np.ndarray)
12+
True
13+
"""
14+
15+
import numpy as np
16+
import matplotlib.pyplot as plt
17+
18+
19+
def delta_energy(matrix: np.ndarray, i: int, j: int, J: float = 1.0) -> float:
20+
"""Compute change in energy (ΔE) if the spin at (i, j) is flipped."""
21+
n = matrix.shape[0]
22+
neighbors = (
23+
matrix[(i + 1) % n, j]
24+
+ matrix[(i - 1) % n, j]
25+
+ matrix[i, (j + 1) % n]
26+
+ matrix[i, (j - 1) % n]
27+
)
28+
return 2 * J * matrix[i, j] * neighbors
29+
30+
31+
def ising_model_simulation(
32+
lattice_size: int = 50,
33+
temperature: float = 1.5,
34+
sweeps: int = 5000,
35+
J: float = 1.0,
36+
kB: float = 1.0,
37+
visualize: bool = False,
38+
) -> np.ndarray:
39+
"""Run the 2D Ising Model Monte Carlo Simulation.
40+
41+
Args:
42+
lattice_size: Number of spins per row/column.
43+
temperature: Simulation temperature (T).
44+
sweeps: Number of Monte Carlo sweeps.
45+
J: Spin coupling constant.
46+
kB: Boltzmann constant.
47+
visualize: If True, display intermediate lattice states.
48+
49+
Returns:
50+
Final spin lattice (numpy array) after equilibration.
51+
"""
52+
# Initialize lattice randomly with spins {-1, +1}
53+
matrix = 2 * np.random.randint(0, 2, size=(lattice_size, lattice_size)) - 1
54+
55+
for sweep in range(sweeps):
56+
for _ in range(lattice_size * lattice_size):
57+
i, j = np.random.randint(0, lattice_size, size=2)
58+
dE = delta_energy(matrix, i, j, J)
59+
60+
# Metropolis criterion
61+
if dE <= 0 or np.random.rand() < np.exp(-dE / (kB * temperature)):
62+
matrix[i, j] *= -1
63+
64+
if visualize and sweep % 500 == 0:
65+
plt.imshow(matrix, cmap="bwr", vmin=-1, vmax=1)
66+
plt.title(f"Sweep {sweep}")
67+
plt.pause(0.01)
68+
69+
if visualize:
70+
plt.imshow(matrix, cmap="bwr", vmin=-1, vmax=1)
71+
plt.title(f"Equilibrated Ising Model at T={temperature}")
72+
plt.show()
73+
74+
return matrix
75+
76+
77+
if __name__ == "__main__":
78+
ising_model_simulation(visualize=True)

0 commit comments

Comments
 (0)