Hamiltonian
configuration file section: [hamiltonian]
The full Spin-Hamiltonian is the sum over all interactions.
Zeeman
### External magnetic field [T]
external_field.magnitude = 25.0
external_field.direction = [0.0, 0.0, 1.0]
- spirit.hamiltonian.set_field(p_state, magnitude, direction, idx_image=-1, idx_chain=-1)
Set the (homogeneous) external magnetic field.
- spirit.hamiltonian.get_field(p_state, idx_image=-1, idx_chain=-1)
Returns the magnitude and an array of shape(3) containing the direction of the external magnetic field.
Anisotropy
The anisotropy term is implemented in terms of three components:
Uniaxial Anisotropy
Cubic Anisotropy
### Uniaxial anisotropy constant [meV]
anisotropy.magnitude = 0.0
anisotropy.normal = [0.0, 0.0, 1.0]
### Cubic anisotropy constant [meV]
cubic_anisotropy = 0.0
By specifying a number of anisotropy axes via n_anisotropy,
This way one or more anisotropy axes can be set for the atoms in the basis cell.
Specify columns via headers: an index i and an axis Kx Ky Kz or Ka Kb Kc,
as well as optionally a magnitude K. The optional column K4 can be used to also
specify the cubic anisotropy on a per-atom basis.
anisotropy = """
i Kx Ky Kz K K4
0 0 0 1 1.0 0.0
"""
- spirit.hamiltonian.get_anisotropy(p_state, idx_image=-1, idx_chain=-1)
Get the magnetocrystalline anisotropy.
- spirit.hamiltonian.set_anisotropy(p_state, magnitude, normal, idx_image=-1, idx_chain=-1)
Set the (homogeneous) magnetocrystalline anisotropy.
Biaxial Anisotropy
Where for any site \(j\) the vectors \(\hat{K}_j^{(1)}\), \(\hat{K}_j^{(2)}\) and \(\hat{K}_j^{(3)} = \hat{K}_j^{(1)} \times \hat{K}_j^{(2)}\) are pairwise orthonormal.
The uniaxial anisotropy is equivalent to the biaxial anisotropy up to an offset to the total energy when setting
The configuration uses two tables: biaxial_anisotropy_axes and biaxial_anisotropy_terms.
### Biaxial anisotropy axes (normalized)
biaxial_anisotropy_axes = """
i k1x k1y k1z k2x k2y k2z
0 0.0 0.0 1.0 1.0 0.0 0.0
"""
### Biaxial anisotropy terms with k [meV]
### This example is equivalent to a uniaxial anisotropy
biaxial_anisotropy_terms = """
i n1 n2 n3 K
0 1 0 0 1.0
"""
- spirit.hamiltonian.get_biaxial_anisotropy(p_state, n_indices=None, n_terms=None, idx_image=-1, idx_chain=-1)
Get the data representing the biaxial anisotropy.
- spirit.hamiltonian.set_biaxial_anisotropy(p_state, magnitude, exponents, primary, secondary, n_terms=None, idx_image=-1, idx_chain=-1)
Set the (homogeneous) biaxial magnetocrystalline anisotropy.
Pair interactions
Heisenberg exchange
Dzyaloshinskii–Moriya Interaction (DMI)
where it is important to note that <ij> denotes the unique pairs of interacting spins i and j.
Consequently, pair-wise interaction parameters always mean energy per unique pair <ij>
(i.e., not per neighbour).
Pair-wise interactions are typically handled in terms of (isotropic) neighbour shells:
### Exchange: number of shells and constants [meV / unique pair]
Jij = [10.0, 1.0]
### DMI: number of shells and constants [meV / unique pair]
Dij = [6.0, 0.5]
### Chirality of DM vectors (+/-1=bloch, +/-2=neel)
dmi_chirality = 2
You may alternatively input pair interaction explicitly as a table, giving you more granular control over the system and the ability to specify non-isotropic interactions.
### Pairs
pairs = """
i j da db dc Jij Dij Dijx Dijy Dijz
0 0 1 0 0 10.0 6.0 1.0 0.0 0.0
0 0 0 1 0 10.0 6.0 0.0 1.0 0.0
0 0 0 0 1 10.0 6.0 0.0 0.0 1.0
"""
Leaving out either exchange or DMI in the pairs is allowed and columns can be placed in arbitrary order.
Note that instead of specifying the DM-vector as Dijx Dijy Dijz, you may specify it as Dija Dijb Dijc if you prefer.
You may also specify the magnitude separately as a column Dij, but note that if you do, the vector (e.g. Dijx Dijy Dijz) will be normalized.
If the Jij or Dij keywords used for shells are present the associated columns in this table will be ignored. This allows combining neighbour shell interactions with an anisotropic part.
- spirit.hamiltonian.CHIRALITY_BLOCH = 1
DMI Bloch chirality type for neighbour shells
- spirit.hamiltonian.CHIRALITY_NEEL = 2
DMI Neel chirality type for neighbour shells
- spirit.hamiltonian.CHIRALITY_BLOCH_INVERSE = -1
DMI Bloch chirality type for neighbour shells with opposite sign
- spirit.hamiltonian.CHIRALITY_NEEL_INVERSE = -2
DMI Neel chirality type for neighbour shells with opposite sign
- spirit.hamiltonian.set_dmi(p_state, n_shells, D_ij, chirality=1, idx_image=-1, idx_chain=-1)
Set the Dzyaloshinskii-Moriya interaction in terms of neighbour shells.
- spirit.hamiltonian.set_exchange(p_state, n_shells, J_ij, idx_image=-1, idx_chain=-1)
Set the Exchange interaction in terms of neighbour shells.
-
SPIRIT_CHIRALITY_BLOCH 1
Bloch chirality.
-
SPIRIT_CHIRALITY_NEEL 2
Neel chirality.
-
SPIRIT_CHIRALITY_BLOCH_INVERSE -1
Bloch chirality, inverted DM vectors.
-
SPIRIT_CHIRALITY_NEEL_INVERSE -2
Neel chirality, inverted DM vectors.
-
void Hamiltonian_Set_DMI(State *state, int n_shells, const scalar *dij, int chirality = SPIRIT_CHIRALITY_BLOCH, int idx_image = -1, int idx_chain = -1)
Set the Dzyaloshinskii-Moriya interaction in terms of neighbour shells [meV].
-
void Hamiltonian_Get_DMI_Shells(State *state, int *n_shells, scalar *dij, int *chirality, int idx_image = -1, int idx_chain = -1)
Retrieves the Dzyaloshinskii-Moriya interaction in terms of neighbour shells.
Note: if the interactions were specified as pairs, this function will retrieve
n_shells=0.
-
int Hamiltonian_Get_DMI_N_Pairs(State *state, int idx_image = -1, int idx_chain = -1)
Returns the number of Dzyaloshinskii-Moriya interaction pairs.
-
void Hamiltonian_Set_Exchange(State *state, int n_shells, const scalar *jij, int idx_image = -1, int idx_chain = -1)
Set the exchange interaction in terms of neighbour shells [meV].
-
void Hamiltonian_Get_Exchange_Shells(State *state, int *n_shells, scalar *jij, int idx_image = -1, int idx_chain = -1)
Retrieves the exchange interaction in terms of neighbour shells.
Note: if the interactions were specified as pairs, this function will retrieve
n_shells=0.
Two-Site Anisotropy
The Two-Site Anisotropy interaction covers the symmetric, traceless part of the two-site interaction tensor. It is specified in terms of the symmetry reduced Cartesian coordinates in a table. If one of the diagonal entries is omitted it will be computed from the other two to ensure that the trace of the tensor vanishes.
Warning
This interaction can overlap with the Heisenberg exchange, if \(K_{ij}^{xx} + K_{ij}^{yy} + K_{ij}^{zz} \neq 0\).
### Two Site Anisotropy in meV per pair
two_site_anisotropy = """
i j da db dc Kijxx Kijyy Kijzz Kijyz Kijxz Kijxy
0 0 1 0 0 -1.0 0.5 0.5 0.0 0.0 0.0
0 0 0 1 0 0.5 -1.0 0.5 0.0 0.0 0.0
0 0 0 0 1 0.5 0.5 -1.0 0.0 0.0 0.0
"""
Not yet implemented
Not yet implemented
Dipole-Dipole Interaction
Via the keyword ddi_method the method employed to calculate the dipole-dipole interactions is specified.
`none` - Dipole-Dipole interactions are neglected
`fft` - Uses a fast convolution method to accelerate the calculation (RECOMMENDED)
`cutoff` - Lets only spins within a maximal distance of 'ddi_radius' interact
`fmm` - Uses the Fast-Multipole-Method (NOT YET IMPLEMENTED!)
If the cutoff-method has been chosen the cutoff-radius can be specified via ddi_radius.
Note: If ddi_radius < 0 a direct summation (i.e. brute force) over the whole system is performed. This is very inefficient and only encouraged for very small systems and/or unit-testing/debugging.
If the boundary conditions are periodic ddi_n_periodic_images specifies how many images are taken in the respective direction.
Note: The images are appended on both sides (the edges get filled too) i.e. 1 0 0 → one image in +a direction and one image in -a direction
If the boundary conditions are open in a lattice direction and sufficiently many periodic images are chosen, zero-padding in that direction can be skipped.
This improves the speed and memory footprint of the calculation, but comes at the cost of a very slight asymmetry in the interactions (decreasing with increasing periodic images).
If ddi_pb_zero_padding is set to 1, zero-padding is performed - even if the boundary condition is periodic in a direction. If it is set to 0, zero-padding is skipped.
### Dipole-dipole interaction caclulation method
### (none, fft, fmm, cutoff)
ddi_method = 'fft'
### DDI number of periodic images (fft and fmm) in (a b c)
ddi_n_periodic_images = [4, 4, 4]
### DDI cutoff radius (if cutoff is used)
ddi_radius = 0.0
ddi_pb_zero_padding = 1.0
- spirit.hamiltonian.DDI_METHOD_NONE = 0
Dipole-dipole interaction: do not calculate
- spirit.hamiltonian.DDI_METHOD_FFT = 1
Dipole-dipole interaction: use FFT convolutions
- spirit.hamiltonian.DDI_METHOD_CUTOFF = 3
Dipole-dipole interaction: use a direct summation with a cutoff radius
- spirit.hamiltonian.get_ddi(p_state, idx_image=-1, idx_chain=-1)
Returns a dictionary, containing information about the used ddi settings
- spirit.hamiltonian.set_ddi(p_state, ddi_method, n_periodic_images=[4, 4, 4], radius=0.0, pb_zero_padding=True, idx_image=-1, idx_chain=-1)
Set the dipolar interaction calculation method.
ddi_method: one of the integers defined above
n_periodic_images: the number of periodical images in the three translation directions, taken into account when boundaries in the corresponding direction are periodical
radius: the cutoff radius for the direct summation method
pb_zero_padding: if True zero padding is used for periodical directions
-
SPIRIT_DDI_METHOD_NONE 0
Do not use dipolar interactions.
-
SPIRIT_DDI_METHOD_FFT 1
Use fast Fourier transform (FFT) convolutions.
-
SPIRIT_DDI_METHOD_CUTOFF 3
Use a direct summation with a cutoff radius.
-
void Hamiltonian_Set_DDI(State *state, int ddi_method, int n_periodic_images[3], scalar cutoff_radius = 0, bool pb_zero_padding = true, int idx_image = -1, int idx_chain = -1)
Configure the dipole-dipole interaction
ddi_method: see integers defined aboven_periodic_images: how many repetition of the spin configuration to append along the translation directions [a, b, c], if periodical boundary conditions are usedcutoff_radius: the distance at which to stop the direct summation, if usedpb_zero_padding: ifTruezero padding is used even for periodical directions
-
void Hamiltonian_Get_DDI(State *state, int *ddi_method, int n_periodic_images[3], scalar *cutoff_radius, bool *pb_zero_padding, int idx_image = -1, int idx_chain = -1)
Retrieves the dipole-dipole interaction configuration.
ddi_method: see integers defined aboven_periodic_images: how many repetitions of the spin configuration to append along the translation directions [a, b, c], if periodical boundary conditions are usedcutoff_radius: the distance at which to stop the direct summation, if method_cutoff is usedpb_zero_padding: ifTruezero padding is used even for periodical directions
Quadruplet Interaction
Quadruplets are specified in meV per unique quadruplet <ijkl>.
### Quadruplets in meV per unique quadruplet <ijkl>
quadruplets = """
i j da_j db_j dc_j k da_k db_k dc_k l da_l db_l dc_l Q
0 0 1 0 0 0 0 1 0 0 0 0 1 3.0
"""
Columns for these may also be placed in arbitrary order.
Not yet implemented
Not yet implemented
Custom Interaction
The Hamiltonian implementation is modular, so custom interactions can be easily implemented. See Custom Interaction for details.