Hotspice is a kinetic Monte Carlo simulation package for thermally active artificial spin ices, using an Ising-like approximation: the axis and position of each spin is fixed, only their binary state can switch. The time evolution can either follow the Néel-Arrhenius law of switching over an energy barrier in a chronological manner, or alternatively use Metropolis-Hastings to model the statistical behavior while making abstraction of the time variable.
"The design, verification, and applications of Hotspice: a Monte Carlo simulator for artificial spin ice" explains the model and reasoning behind the model variants used by Hotspice for the simulation of ASI, and discusses the main examples provided in the examples/
directory.
To create a new conda environment which only includes the necessary modules for hotspice, one can use the environment.yml
file through the command
conda env create -n hotspice310 -f environment.yml
where hotspice310
is the name of the new environment (because it was developed using Python 3.10).
By default, Hotspice runs on the CPU. To use the GPU, see choosing between GPU or CPU.
On systems with CUDA support, Hotspice can run on the GPU. For this, it relies on the CuPy
library to provide GPU-accelerated array computing for NVIDIA GPUs. When creating a conda environment as shown above, CuPy will be installed automatically.
If this fails, see the CuPy installation guide: the easiest method is likely to use the following conda
command, as this automatically installs the appropriate version of the CUDA toolkit:
conda install -c conda-forge cupy
Hotspice is designed as a Python module, and can therefore simply be imported through import hotspice
.
Several submodules provide various components, most of which are optional.
All of the crucial classes are provided in the default hotspice
namespace. Other modules like hotspice.ASI
provide wrappers and examples for ease of use.
To create a simulation, the first thing one has to do is to create a spin ice. This can be done by instantiating any of the ASI subclasses from the hotspice.ASI
submodule, for example a 'diamond' pinwheel geometry:
import hotspice
mm = hotspice.ASI.IP_Pinwheel(1e-6, 100) # Create the spin ice object
mm.add_energy(hotspice.ZeemanEnergy(magnitude=1e-3)) # Apply a 1mT field
hotspice.gui.show(mm) # Display a GUI showing the current state of the spin ice
Here, 1e-6
is the lattice parameter in meters, and 100
is the size of the underlying grid in both the x and y directions. All ASI in Hotspice are stored as 2D arrays for efficient calculation. Note that this implies that the possible spin ice lattices are restricted to those that can be represented as a periodic structure on a square grid.
The lattice is then defined by leaving some spots on this grid empty, while filling others with a magnet and its relevant parameters like magnetic moment mm.moment
), energy barrier mm.E_B
), temperature mm.T
), orientation...
-
The first parameter (
a=1e-6
) is the lattice parameter, often representing a typical distance between two magnets. The exact definition depends on the lattice used: see Available spin ices for the definition ofa
in the default ASI lattices. -
The second parameter (
n=100
) specifies the length of each axis of these underlying 2D arrays. Hence, the spin ice in the example above will have 10000 available grid-points on which to put a magnet. However, this 'diamond' pinwheel geometry can only be represented on a grid by leaving half of the available cells empty, so the simulation above actually contains 5000 magnets (seemm.n
). -
Additional parameters can be used, for which we refer to the docstring of
hotspice.Magnets()
. Theparams
parameter accepts ahotspice.SimParams
instance which can set technical details for the spin ice, e.g. the update/sampling scheme to use, whether to use a reduced kernel... Energies can be added from theenergies.py
file, whose classes are available in the mainhotspice
namespace.
Examples of usage for several of the ASI lattices are provided in the 'examples' directory.
To perform a single simulation step, call mm.update()
. The scheme used to perform this single step is determined by mm.params.UPDATE_SCHEME
, which is an instance of hotspice.Scheme
. Alternatively, mm.progress()
can be used to advance the simulation by a given duration in time or a number of Monte Carlo steps.
To relax the magnetization to a (meta)stable state, call mm.relax()
or mm.minimize()
(the former is faster for large simulations but less accurate, the latter is faster for small simulations and follows the real relaxation order more closely).
More complex input-output simulations, e.g. for reservoir computing, can be performed using the hotspice.io
and hotspice.experiments
modules.
The hotspice.io
module contains classes that apply external stimuli to the spin ice, or read the state of the spin ice in some manner.
The hotspice.experiments
module contains classes to bundle many input/output runs and calculate relevant metrics from them, as well as classes to perform parameter sweeps.
The hotspice/scripts/ParallelJobs.py
script can be used to run a hotspice.experiments.Sweep
on multiple GPUs or CPU cores. This sweep should be defined in a file that follows a structure similar to examples/SweepKQ_RC_ASI.py
. Running ParallelJobs.py
can be done
- either from the command line by calling
python ParallelJobs.py <sweep_file>
, - or from an interactive python shell by calling
hotspice.utils.ParallelJobs(<sweep_file>)
.
By default, hotspice runs on the CPU. One can also choose to run hotspice on the GPU instead, e.g. for large simulations with over a thousand magnets, where the parallelism of GPU computing becomes beneficial.
At the moment when hotspice is imported through import hotspice
, it
- checks if the command-line argument
--hotspice-use-cpu
or--hotspice-use-gpu
is present, and act accordingly. Otherwise, - the environment variable
'HOTSPICE_USE_GPU'
(default:'False'
) is checked instead, and either the GPU or CPU is used based on this value.
When invoking a script from the command line, the cmd argument can be used. Inside a python script, however, it is discouraged to meddle with sys.argv
. In that case, it is better to set the environment variable as follows:
import os
os.environ['HOTSPICE_USE_GPU'] = 'True' # Must be type 'str'
import hotspice # Only import AFTER setting 'HOTSPICE_USE_GPU'!
Note that the CPU/GPU choice must be made BEFORE the import hotspice
statement (and can thus be made only once)! This is because behind-the-scenes, this choice determines which modules are imported by hotspice (either NumPy or CuPy), and it is not possible to re-assign these without significant runtime issues.
A graphical user interface is available to display and interact with the ASI. As shown earlier, it can be run by calling hotspice.gui.show(mm)
, with mm
the ASI object.
Buttons in the right sidebar allow the user to interact with the ASI by progressing through time. It is also possible to interact with the ASI at a granular level by clicking on the ASI plot directly (for more info on this, click the blue circled i
to the bottom right of the ASI). The bottom left panel shows the elapsed time. The bottom central panel is used to change the main ASI view: it is possible to show the magnetization, domains, various energy contributions and barriers, as well as spatially resolved parameters like temperature, anisotropy and magnetic moment.
Several predefined geometries are available in hotspice.
They are listed below with a small description of their peculiarities.
They all follow the pattern hotspice.ASI.<class>(a, n, nx=None, ny=None, **kwargs)
, where n
is only required if either nx
or ny
is not specified.
The modules comprising Hotspice can be found in this repository in the directory hotspice/
.
core.py
contains the main functionality. It provides the Magnets
class which forms the heart of Hotspice: it implements the Néel-Arrhenius and Metropolis-Hastings algorithms. energies.py
contains the 3 standard energy contributions: magnetostatic interaction, the Zeeman energy, and the exchange energy. Classes from both core.py
and energies.py
are available in the main hotspice
namespace, due to their great importance.
ASI.py
provides subclasses which derive from the Magnets
class to implement several specific lattices. config.py
controls the selection of GPU or CPU. gui.py
implements a Tkinter GUI. The recent addition of the GUI makes many functions in the old plottools.py
redundant. utils.py
contains utility functions used throughout the library and in examples, which are often unrelated to ASI. The io.py
and examples.py
provide functionality for reservoir computing and performing parameter sweeps.