Snakes

Snakes#

This example shows how we can simulate the snakes described in [Penty et al., 2025]:

“Controllable gliders in a nanomagnetic metamaterial.” Nature Communications 16, 2025.

We start by creating a model of a 30x30 pinwheel ASI

from flatspin.model import PinwheelSpinIceDiamond
import numpy as np
params = dict(
    size=(30, 30),
    use_opencl=1,
    spin_angle=-45,
    spin_axis=0,
    alpha=0.0013,
    hc=0.2,
    sw_b=0.38,
    sw_c=1,
    sw_beta=1.3,
    sw_gamma=3.6,
)
model = PinwheelSpinIceDiamond(**params)
# Define drawing style
style = dict(style="stadium", width=.25, scale=1.3)

We can make a convenience function which allows us to easily draw snakes at different positions in the ASI

def init_snake(model, length, pos):
    G = model.grid()
    y, x = pos

    grid_inds = [(y, x+i) for i in range(2*length)]
    grid_inds += [(y+1, x+i+1) for i in range(2*length)]
    spin_inds = [G.point_index(gi) for gi in grid_inds]
    spin_inds = np.concatenate(spin_inds)
    model.spin[spin_inds] = 1
# polarize then draw some snakes
model.polarize(-1)

init_snake(model, 6, (15, 24)) # Leftwards snake
init_snake(model, 6, (30, 24)) # Rightwards snake
init_snake(model, 6, (45, 24)) # Leftwards snake

model.plot(**style);
../_images/8a6a562578ee95ff501a07d4ff29dfc4831bdaa0943651d344f1eace0a042a83.png

To get the snake moving we need to use Astroid Clocking.

We can use the flatspin PulseTrain Encoder to create a sequence of global fields to apply

# Set up clock fields and encoder
from flatspin.encoder import PulseTrain

H_AB = 0.0765
H_ab = 0.072

pulses={
    "A": (H_AB,  22),    # (field strength, angle)
    "a": (H_ab, 180+22),
    "B": (H_AB, -22),
    "b": (H_ab, 180-22)
}

encoder = PulseTrain(pulses=pulses)
from flatspin.plotting import animate_spins
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from IPython.display import HTML

sequence = "ABab" * 14
h_ext = encoder(list(sequence))
spins = [model.spin.copy()]
for h_ext_i in h_ext:
    model.set_h_ext(h_ext_i)
    model.relax()
    spins.append(model.spin.copy())

labels = ["init"] + list(sequence)
anim = animate_spins(model, spins, labels, highlight_flips=True, fps=5, **style)
plt.close() # Only show the animation

HTML(anim.to_jshtml())
/builds/flatspin/flatspin/.tox/docs/lib/python3.10/site-packages/pyopencl/__init__.py:570: CompilerWarning: Non-empty compiler output encountered. Set the environment variable PYOPENCL_COMPILER_OUTPUT=1 to see more.
  lambda: self._prg.build(options_bytes, devices),