Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Add 2D Ising model Monte Carlo simulation
  • Loading branch information
kaal-bhairav69 committed Oct 27, 2025
commit 528928b7d065333d69a4823789d271a156bb283e
78 changes: 78 additions & 0 deletions modelling_simulation/ising_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
"""

Check failure on line 1 in modelling_simulation/ising_model.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (INP001)

modelling_simulation/ising_model.py:1:1: INP001 File `modelling_simulation/ising_model.py` is part of an implicit namespace package. Add an `__init__.py`.
Monte Carlo Simulation of the 2D Ising Model using Metropolis Algorithm.

Reference:
https://en.wikipedia.org/wiki/Ising_model

This algorithm simulates spin interactions on a 2D lattice.
It demonstrates how spins evolve toward equilibrium at a given temperature.

>>> result = ising_model_simulation(lattice_size=10, temperature=2.0, sweeps=100)
>>> isinstance(result, np.ndarray)
True
"""

import numpy as np
import matplotlib.pyplot as plt

Check failure on line 16 in modelling_simulation/ising_model.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (I001)

modelling_simulation/ising_model.py:15:1: I001 Import block is un-sorted or un-formatted


def delta_energy(matrix: np.ndarray, i: int, j: int, J: float = 1.0) -> float:

Check failure on line 19 in modelling_simulation/ising_model.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (N803)

modelling_simulation/ising_model.py:19:54: N803 Argument name `J` should be lowercase
"""Compute change in energy (ΔE) if the spin at (i, j) is flipped."""
n = matrix.shape[0]
neighbors = (
matrix[(i + 1) % n, j]
+ matrix[(i - 1) % n, j]
+ matrix[i, (j + 1) % n]
+ matrix[i, (j - 1) % n]
)
return 2 * J * matrix[i, j] * neighbors


def ising_model_simulation(
lattice_size: int = 50,
temperature: float = 1.5,
sweeps: int = 5000,
J: float = 1.0,

Check failure on line 35 in modelling_simulation/ising_model.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (N803)

modelling_simulation/ising_model.py:35:5: N803 Argument name `J` should be lowercase
kB: float = 1.0,

Check failure on line 36 in modelling_simulation/ising_model.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (N803)

modelling_simulation/ising_model.py:36:5: N803 Argument name `kB` should be lowercase
visualize: bool = False,
) -> np.ndarray:
"""Run the 2D Ising Model Monte Carlo Simulation.

Args:
lattice_size: Number of spins per row/column.
temperature: Simulation temperature (T).
sweeps: Number of Monte Carlo sweeps.
J: Spin coupling constant.
kB: Boltzmann constant.
visualize: If True, display intermediate lattice states.

Returns:
Final spin lattice (numpy array) after equilibration.
"""
# Initialize lattice randomly with spins {-1, +1}
matrix = 2 * np.random.randint(0, 2, size=(lattice_size, lattice_size)) - 1

Check failure on line 53 in modelling_simulation/ising_model.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (NPY002)

modelling_simulation/ising_model.py:53:18: NPY002 Replace legacy `np.random.randint` call with `np.random.Generator`

for sweep in range(sweeps):
for _ in range(lattice_size * lattice_size):
i, j = np.random.randint(0, lattice_size, size=2)

Check failure on line 57 in modelling_simulation/ising_model.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (NPY002)

modelling_simulation/ising_model.py:57:20: NPY002 Replace legacy `np.random.randint` call with `np.random.Generator`
dE = delta_energy(matrix, i, j, J)

Check failure on line 58 in modelling_simulation/ising_model.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (N806)

modelling_simulation/ising_model.py:58:13: N806 Variable `dE` in function should be lowercase

# Metropolis criterion
if dE <= 0 or np.random.rand() < np.exp(-dE / (kB * temperature)):

Check failure on line 61 in modelling_simulation/ising_model.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (NPY002)

modelling_simulation/ising_model.py:61:27: NPY002 Replace legacy `np.random.rand` call with `np.random.Generator`
matrix[i, j] *= -1

if visualize and sweep % 500 == 0:
plt.imshow(matrix, cmap="bwr", vmin=-1, vmax=1)
plt.title(f"Sweep {sweep}")
plt.pause(0.01)

if visualize:
plt.imshow(matrix, cmap="bwr", vmin=-1, vmax=1)
plt.title(f"Equilibrated Ising Model at T={temperature}")
plt.show()

return matrix


if __name__ == "__main__":
ising_model_simulation(visualize=True)
Loading