Python implementation of SpinW for spin wave calculations
Project description
PySpinW
A Python implementation of SpinW for spin wave calculations using linear spin wave theory (LSWT).
Features
- Crystal Structure: Define lattices with space group symmetry (P1, Pm-3m, Fd-3m, P-3, etc.)
- Magnetic Atoms: Arbitrary spin quantum number S and g-tensor
- Exchange Interactions: Heisenberg, anisotropic, Dzyaloshinskii-Moriya (DM)
- Magnetic Structures: Ferromagnetic, antiferromagnetic, helical, spiral, 120° order
- Spin Wave Theory: Full BdG Hamiltonian diagonalization via σz·H method
- Neutron Scattering: S(Q,ω) with magnetic form factors
- Multiple Backends: NumPy (CPU), PyTorch (GPU-accelerated)
Installation
From PyPI (when published)
pip install PySpinW
From source
git clone https://github.com/pyspinw/PySpinW.git
cd PySpinW
pip install -e .
With GPU support
pip install -e ".[gpu]"
Development installation
pip install -e ".[dev]"
Quick Start
Example 1: Ferromagnetic Chain
import numpy as np
from pyspinw import SpinW
# Create spin model
sw = SpinW()
sw.genlattice(lat_const=[3, 8, 8], angled=[90, 90, 90])
sw.addatom(r=[0, 0, 0], S=1, label='Fe')
sw.gencoupling(max_distance=4)
# Add ferromagnetic exchange J = -1 meV
sw.addmatrix(label='J', value=-1.0)
sw.addcoupling(mat='J', bond=1)
# Set ferromagnetic ground state
sw.genmagstr(mode='direct', k=[0, 0, 0], S=np.array([[0, 0, 1]]))
# Calculate spin wave dispersion
spec = sw.spinwave([[0, 0, 0], [1, 0, 0]], n_pts=200)
# Plot
import matplotlib.pyplot as plt
q = np.linspace(0, 1, 200)
plt.plot(q, spec['omega'][:, 0])
plt.xlabel('q (r.l.u.)')
plt.ylabel('Energy (meV)')
plt.title('FM Chain Dispersion')
plt.show()
Example 2: Triangular Antiferromagnet with 120° Order
from pyspinw import SpinW, sw_model
# Use predefined model
sw = sw_model('triAF', J=1.0) # J = 1 meV AFM
# Or build manually:
sw = SpinW()
sw.genlattice(lat_const=[4, 4, 6], angled=[90, 90, 120])
sw.addatom(r=[0, 0, 0], S=1.5, label='Mn')
sw.gencoupling(max_distance=5)
sw.addmatrix(label='J1', value=1.0)
sw.addcoupling(mat='J1', bond=1)
# 120° helical structure
sw.genmagstr(mode='helical', k=[1/3, 1/3, 0], n=[0, 0, 1])
# Calculate along Γ-K-M path
spec = sw.spinwave([[0, 0, 0], [1/3, 1/3, 0], [0.5, 0, 0]], n_pts=150)
Example 3: Square Lattice AFM with DM Interaction
from pyspinw import SpinW
import numpy as np
sw = SpinW()
sw.genlattice(lat_const=[4, 4, 10], angled=[90, 90, 90])
sw.addatom(r=[0, 0, 0], S=1, label='Cu')
sw.gencoupling(max_distance=5)
# Heisenberg exchange
sw.addmatrix(label='J', value=1.0)
sw.addcoupling(mat='J', bond=1)
# DM interaction D·(Si × Sj)
sw.addmatrix(label='D', value=[0, 0, 0.1]) # D_z = 0.1 meV
sw.addcoupling(mat='D', bond=1)
# Néel order
sw.genmagstr(mode='direct', k=[0.5, 0.5, 0], S=np.array([[0, 0, 1]]))
spec = sw.spinwave([[0, 0, 0], [0.5, 0.5, 0]], n_pts=100)
API Reference
SpinW Class
The main class for spin wave calculations.
Lattice Definition
sw.genlattice(lat_const=[a, b, c], angled=[α, β, γ], spgr='P 1')
lat_const: Lattice parameters [a, b, c] in Ångströmsangled: Lattice angles [α, β, γ] in degreesspgr: Space group symbol (e.g., 'Fm-3m', 'P 63/mmc')
Adding Atoms
sw.addatom(r=[x, y, z], S=spin, label='atom_name')
r: Fractional coordinates [x, y, z]S: Spin quantum number (e.g., 0.5, 1, 1.5)label: Atom label for identification
Generating Couplings
sw.gencoupling(max_distance=10.0)
Generates all symmetry-equivalent bonds up to max_distance Å.
Adding Exchange Matrices
# Heisenberg (isotropic)
sw.addmatrix(label='J1', value=1.0)
# Anisotropic exchange
sw.addmatrix(label='J_aniso', value=[[Jxx, Jxy, Jxz],
[Jxy, Jyy, Jyz],
[Jxz, Jyz, Jzz]])
# Dzyaloshinskii-Moriya
sw.addmatrix(label='DM', value=[Dx, Dy, Dz])
Assigning Couplings
sw.addcoupling(mat='J1', bond=1) # Assign J1 to nearest neighbors
sw.addcoupling(mat='J2', bond=2) # Assign J2 to next-nearest neighbors
Magnetic Structure
# Ferromagnetic
sw.genmagstr(mode='direct', k=[0, 0, 0], S=np.array([[0, 0, 1]]))
# Antiferromagnetic (Néel)
sw.genmagstr(mode='direct', k=[0.5, 0.5, 0], S=np.array([[0, 0, 1]]))
# Helical/Spiral
sw.genmagstr(mode='helical', k=[1/3, 1/3, 0], n=[0, 0, 1])
mode: 'direct' for explicit spins, 'helical' for spiral structuresk: Propagation vector in reciprocal lattice unitsn: Rotation axis for helical structuresS: Spin vectors, shape (n_atoms, 3)
Spin Wave Calculation
spec = sw.spinwave(Q_path, n_pts=100, formfact=False)
Q_path: List of Q-points defining the path, e.g.,[[0,0,0], [1,0,0]]n_pts: Number of points along the pathformfact: Include magnetic form factor (default: False)
Returns dictionary with:
omega: Spin wave energies, shape (n_pts, n_modes)Sab: Dynamical structure factor componentshkl: Q-points along path
Energy Calculation
E = sw.energy() # Returns energy per site in meV
Utility Functions
Energy Broadening
from pyspinw.utils import sw_egrid
spec = sw_egrid(spec, dE=0.1, Emin=0, Emax=10, n_E=100)
Convolves with Gaussian of width dE meV.
Plotting
from pyspinw.utils import sw_plotspec
sw_plotspec(spec, mode='color') # Color plot of S(Q,ω)
sw_plotspec(spec, mode='line') # Line plot of dispersion
Predefined Models
from pyspinw import sw_model
sw = sw_model('chain', J=1.0) # 1D antiferromagnetic chain
sw = sw_model('squareAF', J=1.0) # 2D square lattice AFM
sw = sw_model('triAF', J=1.0) # 2D triangular lattice 120° AFM
Physics Background
Linear Spin Wave Theory
PySpinW implements linear spin wave theory (LSWT) following the Holstein-Primakoff transformation:
S⁺ ≈ √(2S) a
S⁻ ≈ √(2S) a†
Sᶻ = S - a†a
The spin Hamiltonian is expanded to quadratic order in bosonic operators, yielding a BdG Hamiltonian:
H = Σ_q [A(q) B(q) ] [a_q ]
[B*(q) A*(q)] [a†_{-q}]
Diagonalization via the σz·H method gives spin wave energies ω(q).
Validation
PySpinW has been validated against:
- Analytical results: FM chain ω(q) = 2|J|S(1-cos(2πq)) with < 10⁻⁹ error
- Sunny.jl: 6/6 SpinW tutorial ports pass (SW01-SW08, CoRh2O4)
- spinw_torch: Minimalist PyTorch reference implementation
Project Structure
PySpinW/
├── pyspinw/ # Package directory (import as: import pyspinw)
│ ├── __init__.py # Package exports
│ ├── core/
│ │ ├── spinw.py # Main SpinW class
│ │ ├── lswt.py # Linear spin wave theory
│ │ ├── lattice.py # Crystal lattice
│ │ ├── magnetic.py # Magnetic structures
│ │ ├── coupling.py # Exchange couplings
│ │ └── constants.py # Physical constants
│ ├── backends/
│ │ ├── numpy_backend.py # CPU implementation
│ │ └── pytorch_backend.py # GPU implementation
│ ├── utils/
│ │ ├── egrid.py # Energy convolution
│ │ ├── plotting.py # Visualization
│ │ └── neutron.py # Neutron scattering
│ ├── tests/
│ │ ├── test_spinw.py # Unit tests (21 tests)
│ │ └── test_sunny_comparison.py # Sunny.jl validation (6 tests)
│ └── examples/
│ ├── quickstart.ipynb # Tutorial notebook
│ └── demos.py # Example scripts
├── pyproject.toml # Build configuration
├── README.md
├── CHANGELOG.md
└── CONTRIBUTING.md
Running Tests
# All tests
pytest
# With coverage
pytest --cov=pyspinw
# Specific test file
pytest tests/test_sunny_comparison.py -v
Known Limitations
- Space groups: 9 of 230 implemented (P1, Pm-3m, Fm-3m, Fd-3m, P-3, P63/mmc, I4/mmm, R-3m, Pnma)
- Form factors: Simplified dipole approximation
- Single-ion anisotropy: Basic support only
- Powder averaging: Not yet implemented
- Inelastic neutron scattering: S(Q,ω) without resolution convolution
References
- SpinW - Original MATLAB implementation
- Sunny.jl - Julia spin dynamics package
- Toth & Lake, J. Phys.: Condens. Matter 27, 166002 (2015)
- Colpa, Physica 93A, 327 (1978)
License
GPL-3.0 (following the original SpinW license)
Contributing
Contributions welcome! Please see CONTRIBUTING.md and submit issues/PRs on GitHub.
Citation
If you use PySpinW in your research, please cite:
@software{PySpinW,
title = {PySpinW: Python Spin Wave Calculator},
url = {https://github.com/pyspinw/PySpinW},
version = {0.1.0},
year = {2024}
}
And the original SpinW paper:
@article{spinw,
author = {Toth, S. and Lake, B.},
title = {Linear spin wave theory for single-Q incommensurate magnetic structures},
journal = {J. Phys.: Condens. Matter},
volume = {27},
pages = {166002},
year = {2015},
doi = {10.1088/0953-8984/27/16/166002}
}
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyspinwave-0.1.0.tar.gz.
File metadata
- Download URL: pyspinwave-0.1.0.tar.gz
- Upload date:
- Size: 45.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d52c76942ce7ebfc7d417254ba7d553aedf312ab127da788748bd7ea4cefb360
|
|
| MD5 |
6c41271b31b033bfdaa03da569e980f2
|
|
| BLAKE2b-256 |
80a9779b00c7ddd2531ee1a901ac8694dffaba4a78c1185b9cdd045f57194cc0
|
File details
Details for the file pyspinwave-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pyspinwave-0.1.0-py3-none-any.whl
- Upload date:
- Size: 43.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d508827dde68169410959c25532a54bfa8819e889022c7e73b97eed23c729667
|
|
| MD5 |
7f70abb7570bdaa923f50c9ad58afb46
|
|
| BLAKE2b-256 |
45f8c148dfb3482564b18a473f5a630de02145f31705df7a5331bd420a652503
|