The Ising model is an important idea at the intersection of many areas of physics and math. In its most literal form, it is a simple model for
magnetism in materials. Namely, by adjusting three parameters of the model

- temperature \(T\)
- coupling strength \(J\)
- external magnetic field \(B\)

we can qualitatively recreate features of ferromagnetism and paramagnetism. It works by imagining a lattice of magnetic dipoles, which can be in
one of two states or orientations - let's call them up and down.
The dipole states respons
to the external magnetic field \(B\) and to the magnetic influence of their nearest neighbors. This influence could be dependent on dipole moment of
the dipoles and the distance between neighbors, but we just combine these as the parameter \(J\). For example, large \(J\) means that a dipole in the
up state will strongly influence its neighbors to also be in the up state.
Finally, the model can take another parameter representing temperature \(T\), which adds randomly perturbs some dipoles to flip their state.

Beyond classical magnetism, the Ising model shows up in the study of universality and critical phenomena.

###
Run the Ising model in browser

The simulation is achieved by iterating through states at discrete timesteps. The color of the squares on the grid
represent the up or positive (dark colored) and down or negative (light colored) states of individual dipoles.
The most interesting behavior happens when \(B=0\) and \(J\) is somewhat
larger than \(R\). This corresponds to a regime where domains of mostly up and mostly down states coexist, and random fluctuations cause the shape
of these domains to evolve over time.

I haven't added units to anything - maybe I'll get to that some day.

Be careful with the array size; it's a good way to cause CPU spikes :)

###
Regimes of the model

A paramagnet, theoretically speaking, is an object that tends to align its own magnetic dipole moment with that of an external field. Here the "object"
is the ensemble of states represented by colored squares on a grid. Set the temperature
much higher than the coupling, and then adjust the magnetic field. The color of the squares should follow your input after some finite response time.
This behavior is what we might call the "boring" regime.

A ferromagnet, in constrast, exhibits hysteresis, which means that the magnetic dipole moment of the ensemble depends on the past state. If the coupling is
much larger than the temperature, than it is possible to have most of the squares be anti-aligned with the magnetic field you set. However, making the field
stronger will eventually overpower the coupling.

{
"packages": ["numpy", "matplotlib"]
}
from js import createObject
from pyodide.ffi import create_proxy
createObject(create_proxy(globals()), "pyodideGlobals")
import numpy as np
import js
from pyodide.ffi import create_proxy
from random import randint
class Sim():
def __init__(self, size):
self.SS = np.random.rand(size,size)-0.5
self.SS = np.round(self.SS*0.5+0.5)*2-1
def get_SS(self):
return SS.tolist()
def Ising_step(self, J, B, R):
'''
Parameters
----------
J : float
coupling.
B : float
external field.
R : float
amplitude of random fluctuations.
Returns
-------
updated SS array
'''
R = R+1e-4
k_B = 1
SS = self.SS
m,n = np.shape(self.SS)
Z = 0
NW = SS[0:-2,0:-2]
N = SS[0:-2,1:-1]
NE = SS[0:-2,2:]
W = SS[1:-1,0:-2]
E = SS[1:-1,2:]
SW = SS[2:,0:-2]
S = SS[2:,1:-1]
SE = SS[2:,2:]
Jterm = np.zeros([m,n])
Jterm[1:-1,1:-1] = (NW+N+NE+W+E+SW+S+SE)/8 * J
SSfloat = Jterm + B + R*(np.random.normal(size=[m,n]))
SSn = np.round(SSfloat*0.5+0.5)*2-1
canonicalE = -(Jterm + B)*SSn
Z += np.exp(-1/R * canonicalE) # note that R is basically k_B T
self.SS = SSn