Exchange Hamiltonian#
For the full reference see Exchange module.
ExchangeHamiltonian is build on some Crystal,
which defines the structure (lattice + atoms). It stores bonds between Atom
\(i\), which is located in \((0, 0, 0)\) unit cell and Atom \(j\),
which is located in \((i, j, k)\) unit cell and corresponding exchange parameters.
The notation of the exchange Hamiltonian is an important issue, since without clear notation
exchange parameters does not make much sense. ExchangeHamiltonian can support any
notation out of the most common ones. Detailed description of the notation is given in
correspondent section: Structure of the Hamiltonian. We encourage you to read it once
with full attention.
The main building block of the exchange Hamiltonian is exchange parameter
(\(\boldsymbol{J}\)). It is separated in a separate class ExchangeParameter.
For the guide on exchange parameter see:
Crystal of the exchange Hamiltonian#
Exchange Hamiltonian is build for some structure,
which is defined by an instance of Crystal.
Any property, which is related to the structure is expected to be addressed through
the crystal property. For example:
>>> import radtools as rad
>>> lattice = rad.lattice_example("TET")
>>> crystal = rad.Crystal(lattice)
>>> hamiltonian = rad.ExchangeHamiltonian(crystal)
>>> hamiltonian.crystal.lattice.variation
'TET'
>>> hamiltonian.crystal.lattice.a1
array([3.14159265, 0. , 0. ])
>>> hamiltonian.crystal.lattice.cell
array([[3.14159265, 0. , 0. ],
[0. , 3.14159265, 0. ],
[0. , 0. , 4.71238898]])
For the full guide on the crystal see Crystal and Lattice. For the full reference see Crystal and Lattice.
The routines, which are the most important for the exchange Hamiltonian are:
Creation of the Hamiltonian#
The Hamiltonian could be created from the scratch or from the TB2J file.
For the creation on the basis of the TB2J file see read_tb2j_model().
Here we cover the creation from scratch.
An instance of the ExchangeHamiltonian is created by:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
It could take two optional parameters:
Crystalinstance, which defines the structure of the Hamiltonian.
>>> import radtools as rad
>>> lattice = rad.lattice_example("TET")
>>> crystal = rad.Crystal(lattice)
>>> hamiltonian = rad.ExchangeHamiltonian(crystal)
notation: notation of the Hamiltonian. See Structure of the Hamiltonian.
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian(notation="standard")
When the instance of the ExchangeHamiltonian is created,
it is empty. It need to be filled with bonds and exchange parameters.
Adding atoms#
There are no difference in the addition of atoms to the ExchangeHamiltonian
or to the Crystal with ExchangeHamiltonian.crystal property:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> len(hamiltonian.crystal.atoms)
0
>>> hamiltonian.add_atom(rad.Atom("Cr", spin=1.5, position=(1,0,0)))
>>> hamiltonian.crystal.add_atom(rad.Atom("Br"))
>>> len(hamiltonian.crystal.atoms)
2
However, removing an atom from the ExchangeHamiltonian and from the
Crystal is different. When atom is removed from the ExchangeHamiltonian
it is removed from the Crystal and all the bonds, which are connected to it
are removed as well. When atom is removed from the Crystal it is only removed from the
Crystal, but all the bonds, which are connected to it are still present in the
ExchangeHamiltonian.
Adding bonds#
The bond is added to the Hamiltonian with ExchangeHamiltonian.add_bond() method:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> Cr = rad.Atom("Cr", spin=1.5)
>>> hamiltonian.add_bond(rad.ExchangeParameter(iso=1), Cr, Cr, (1, 0, 0))
>>> hamiltonian[Cr, Cr, (1, 0, 0)].iso
1.0
Note
The bond is added to the Hamiltonian, but no atom is added to the crystal.
You can skip the atom addition if you are using Atom instances,
not the string literals, because then new atom is just added to the system.
When string literal is used, atom object is extracted from the crystal, thus
it has to be added to the crystal first.
Equivalent way to add bond:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> Cr = rad.Atom("Cr", spin=1.5)
>>> hamiltonian[Cr, Cr, (1, 0, 0)] = rad.ExchangeParameter(iso=1)
>>> hamiltonian[Cr, Cr, (1, 0, 0)].iso
1.0
To remove bond use ExchangeHamiltonian.remove_bond() method:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> Cr = rad.Atom("Cr", spin=1.5)
>>> hamiltonian.add_bond(rad.ExchangeParameter(iso=1), Cr, Cr, (1, 0, 0))
>>> (Cr, Cr, (1, 0, 0)) in hamiltonian
True
>>> hamiltonian.remove_bond("Cr", Cr, (1, 0, 0))
>>> (Cr, Cr, (1, 0, 0)) in hamiltonian
False
Hint
Note how we used string literal to remove the bond.
Equivalent way to delete bond:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> Cr = rad.Atom("Cr", spin=1.5)
>>> hamiltonian.add_bond(rad.ExchangeParameter(iso=1), Cr, Cr, (1, 0, 0))
>>> (Cr, Cr, (1, 0, 0)) in hamiltonian
True
>>> del hamiltonian[Cr, Cr, (1, 0, 0)]
>>> (Cr, Cr, (1, 0, 0)) in hamiltonian
False
Structure of the Hamiltonian#
Main idea of the exchange Hamiltonian structure could be expressed as
(atom1, atom2, (i,j,k)) -> exchange_parameter
where atom1 and atom2 are instances of Atom, (i,j,k) is a tuple of
integers, which defines the unit cell, and exchange_parameter is an instance of
ExchangeParameter.
Exchange Hamiltonian is iterable over bonds:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> Cr = rad.Atom("Cr", spin=1.5)
>>> hamiltonian.add_bond(rad.ExchangeParameter(iso=1), Cr, Cr, (1, 0, 0))
>>> hamiltonian.add_bond(rad.ExchangeParameter(iso=2), Cr, Cr, (0, 1, 0))
>>> for atom1, atom2, (i,j,k), J in hamiltonian:
... print(atom1.fullname, atom2.fullname, (i,j,k), J.iso)
...
Cr__1 Cr__1 (1, 0, 0) 1.0
Cr__1 Cr__1 (0, 1, 0) 2.0
It could be check for the presence of the bond:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> Cr = rad.Atom("Cr", spin=1.5)
>>> hamiltonian.add_bond(rad.ExchangeParameter(iso=1), Cr, Cr, (1, 0, 0))
>>> (Cr, Cr, (1, 0, 0)) in hamiltonian
True
>>> (Cr, Cr, (0, 1, 0)) in hamiltonian
False
The exchange parameter could be accessed (and set) directly:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> Cr = rad.Atom("Cr", spin=1.5)
>>> hamiltonian[Cr, Cr, (1, 0, 0)] = rad.ExchangeParameter(iso=1)
>>> hamiltonian[Cr, Cr, (1, 0, 0)].iso
1.0
len() of the Hamiltonian returns the number of bonds:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> Cr = rad.Atom("Cr", spin=1.5)
>>> len(hamiltonian)
0
>>> hamiltonian.add_bond(rad.ExchangeParameter(iso=1), Cr, Cr, (1, 0, 0))
>>> len(hamiltonian)
1
>>> hamiltonian.add_bond(rad.ExchangeParameter(iso=2), Cr, Cr, (0, 1, 0))
>>> len(hamiltonian)
2
Atom as a part of the key#
Atom object or string literal could be used to access atoms in the Hamiltonian.
String literal is the Atom.name property of the atom if there is only
one atom with that name in the ExchangeHamiltonian.crystal. Otherwise
Atom.fullname property of the atom has to be used.
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> hamiltonian.crystal.add_atom(rad.Atom("Cr", spin=1.5, position=(0,0,0)))
>>> hamiltonian.add_bond(rad.ExchangeParameter(iso=1), "Cr", "Cr", (0, 1, 0))
>>> for atom1, atom2, (i,j,k), J in hamiltonian:
... print(atom1.fullname, atom2.fullname, (i,j,k), J.iso)
...
Cr__1 Cr__1 (0, 1, 0) 1.0
>>> hamiltonian.crystal.add_atom(rad.Atom("Cr", spin=1.5, position=(1,0,0)))
>>> hamiltonian.add_bond(rad.ExchangeParameter(iso=1), "Cr__1", "Cr__1", (0, 1, 0))
>>> hamiltonian.add_bond(rad.ExchangeParameter(iso=2), "Cr__1", "Cr__2", (0, 0, 0))
>>> for atom1, atom2, (i,j,k), J in hamiltonian:
... print(atom1.fullname, atom2.fullname, (i,j,k), J.iso)
...
Cr__1 Cr__1 (0, 1, 0) 1.0
Cr__1 Cr__2 (0, 0, 0) 2.0
If you want to get an Atom instance from the ExchangeHamiltonian
you can use ExchangeHamiltonian.crystal.get_atom()
(Crystal.get_atom()) method:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> hamiltonian.crystal.add_atom(rad.Atom("Cr", spin=1.5, position=(0,0,0)))
>>> hamiltonian.crystal.add_atom(rad.Atom("Cr", spin=1.5, position=(1,0,0)))
>>> hamiltonian.crystal.get_atom("Cr__1").fullname
'Cr__1'
>>> hamiltonian.crystal.get_atom("Cr__2").fullname
'Cr__2'
Magnetic atoms#
Atoms, which has at least one bond attached to them are called magnetic atoms.
They could be accessed with ExchangeHamiltonian.magnetic_atoms property:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> hamiltonian.crystal.add_atom(rad.Atom("Cr", spin=1.5, position=(0,0,0)))
>>> hamiltonian.crystal.add_atom(rad.Atom("Cr", spin=1.5, position=(1,0,0)))
>>> hamiltonian.magnetic_atoms
[]
>>> hamiltonian.add_bond(rad.ExchangeParameter(iso=1), "Cr__1", "Cr__1", (0, 1, 0))
>>> for atom in hamiltonian.magnetic_atoms:
... print(atom.fullname)
...
Cr__1
>>> hamiltonian.add_bond(rad.ExchangeParameter(iso=1), "Cr__1", "Cr__2", (0, 0, 0))
>>> for atom in hamiltonian.magnetic_atoms:
... print(atom.fullname)
...
Cr__1
Cr__2
Filtering the Hamiltonian#
Exchange Hamiltonian could be filtered by distance, template or set of (i,j,k) tuples (R vectors).
Use ExchangeHamiltonian.filter() to filter the instance of the
ExchangeHamiltonian and ExchangeHamiltonian.filtered() to get
the filtered copy of the ExchangeHamiltonian:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> hamiltonian.crystal.add_atom(rad.Atom("Cr", (0.25, 0.25, 0)))
>>> hamiltonian.crystal.add_atom(rad.Atom("Cr", (0.75, 0.75, 0)))
>>> bonds = [
... (12, "Cr__1", "Cr__2", (0, 0, 0)),
... (12, "Cr__2", "Cr__1", (0, 0, 0)),
... (12, "Cr__1", "Cr__1", (1, 0, 0)),
... (12, "Cr__1", "Cr__1", (-1, 0, 0)),
... (12, "Cr__2", "Cr__2", (1, 0, 0)),
... (12, "Cr__2", "Cr__2", (-1, 0, 0)),
... (12, "Cr__1", "Cr__1", (0, 2, 0)),
... (12, "Cr__1", "Cr__1", (0, -2, 0)),
... (12, "Cr__2", "Cr__2", (0, 2, 0)),
... (12, "Cr__2", "Cr__2", (0, -2, 0)),
... (12, "Cr__2", "Cr__1", (2, 2, 0)),
... (12, "Cr__1", "Cr__2", (-2, -2, 0)),
... ]
>>> for J, atom1, atom2, R in bonds:
... hamiltonian.add_bond(rad.ExchangeParameter(iso=J), atom1, atom2, R)
>>> for atom1, atom2, R, J in hamiltonian:
... print(atom1.fullname, atom2.fullname, R, J.iso)
...
Cr__1 Cr__2 (0, 0, 0) 12.0
Cr__2 Cr__1 (0, 0, 0) 12.0
Cr__1 Cr__1 (1, 0, 0) 12.0
Cr__1 Cr__1 (-1, 0, 0) 12.0
Cr__2 Cr__2 (1, 0, 0) 12.0
Cr__2 Cr__2 (-1, 0, 0) 12.0
Cr__1 Cr__1 (0, 2, 0) 12.0
Cr__1 Cr__1 (0, -2, 0) 12.0
Cr__2 Cr__2 (0, 2, 0) 12.0
Cr__2 Cr__2 (0, -2, 0) 12.0
Cr__2 Cr__1 (2, 2, 0) 12.0
Cr__1 Cr__2 (-2, -2, 0) 12.0
>>> filtered_hamiltonian = hamiltonian.filtered(max_distance=1)
>>> for atom1, atom2, R, J in filtered_hamiltonian:
... print(atom1.fullname, atom2.fullname, R, J.iso)
...
Cr__1 Cr__2 (0, 0, 0) 12.0
Cr__2 Cr__1 (0, 0, 0) 12.0
Cr__1 Cr__1 (1, 0, 0) 12.0
Cr__1 Cr__1 (-1, 0, 0) 12.0
Cr__2 Cr__2 (1, 0, 0) 12.0
Cr__2 Cr__2 (-1, 0, 0) 12.0
>>> filtered_hamiltonian = hamiltonian.filtered(min_distance=2.1)
>>> for atom1, atom2, R, J in filtered_hamiltonian:
... print(atom1.fullname, atom2.fullname, R, J.iso)
...
Cr__2 Cr__1 (2, 2, 0) 12.0
Cr__1 Cr__2 (-2, -2, 0) 12.0
>>> filtered_hamiltonian = hamiltonian.filtered(R_vector=[(0, 0, 0), (1, 0, 0)])
>>> for atom1, atom2, R, J in filtered_hamiltonian:
... print(atom1.fullname, atom2.fullname, R, J.iso)
...
Cr__1 Cr__2 (0, 0, 0) 12.0
Cr__2 Cr__1 (0, 0, 0) 12.0
Cr__1 Cr__1 (1, 0, 0) 12.0
Cr__2 Cr__2 (1, 0, 0) 12.0
>>> filtered_hamiltonian = hamiltonian.filtered(template=[("Cr__1", "Cr__2", (0, 0, 0))])
>>> for atom1, atom2, R, J in filtered_hamiltonian:
... print(atom1.fullname, atom2.fullname, R, J.iso)
...
Cr__1 Cr__2 (0, 0, 0) 12.0
Hint
Filtering options may be combined together.
Energy#
Ferromagnetic energy of the Hamiltonian could be calculated with
ExchangeHamiltonian.ferromagnetic_energy() method:
Note
The notation of the Hamiltonian has to be defined in order to calculate the energy.
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> hamiltonian.crystal.add_atom(rad.Atom("Cr", spin=1.5, position=(0,0,0)))
>>> hamiltonian.crystal.add_atom(rad.Atom("Cr", spin=1.5, position=(1,0,0)))
>>> hamiltonian.add_bond(rad.ExchangeParameter(iso=1), "Cr__1", "Cr__1", (0, 1, 0))
>>> hamiltonian.add_bond(rad.ExchangeParameter(iso=2), "Cr__1", "Cr__2", (0, 0, 0))
>>> hamiltonian.ferromagnetic_energy()
Traceback (most recent call last):
...
radtools.exchange.hamiltonian.NotationError:
...
>>> hamiltonian.notation = "standard"
>>> hamiltonian.ferromagnetic_energy()
-13.5
Save the Hamiltonian#
The Hamiltonian could be saved in a .txt file with
ExchangeHamiltonian.summary_as_txt() method.
Notation#
Here is the Hamiltonian in the notation, which is considered to be the standard for the RAD-tools:
It has double-counting, spins are not normalized, and the exchange parameter is positive for ferromagnetic order.
Note
The "standard" here does not mean that the ExchangeHamiltonian is
always has this notation. For example when ExchangeHamiltonian is
read from TB2J file (read_tb2j_model()) it has the notation of TB2J.
There are five properties, that has to be defined in order to describe the exchange Hamiltonian`s notation:
double_countingWhether both pairs \((i, j)\) and \((j, i)\) are included in the sum.
Double counting is avoided it is usually indicated under the sum sign:
\[\sum_{i < j} \text{ or } \sum_{i > j}\]When it is not present there are no indication in the sum:
\[\sum_{ij}\]However, some authors are using
\[\sum_{<ij>}\]as an indication of the avoided double counting, which we find confusing and discourage you to use it in this way. In textbooks this indication is usually imply that only near-neighbors are included in the sum, which is not the same as avoiding double counting (consecutively \(\sum_{<<ij>>}\) is used to indicate next-nearest neighbors and so on).
Note
Indication
\[\sum_{i \ne j}\]Does not mean that double counting is avoided. It specifies that there is no exchange between the same atom.
spin_normalized\(\boldsymbol{S}_i\) in the exchange Hamiltonian is viewed as spin operator or as classical spin vector. In the latter case it could be normalized to 1 or not. In case of normalisation exchange parameter absorbs the factor \(\vert\boldsymbol{S}_i\vert \vert\boldsymbol{S}_j\vert\).
factor_one_halfFactor \(1/2\) is sometimes included in order to correct for double counting. If it is included, then it is simply written before the sum sign. It is usually used when double counting is present.
factor_twoFactor \(2\) is sometimes included in order to account for double counting. If it is included, then it is simply written before the sum sign. It is usually used when double counting is avoided.
minus_signWhether the minus sign is included in the Hamiltonian.
Caution
We would like to note that not all authors are thoughtful with the definition of the Hamiltonian, so additional care is required when reading the literature.
RAD-tools utilize those five properties in order to define the notation of the
exchange Hamiltonian. During the creation of the ExchangeHamiltonian object the notation
is deliberately not defined, because it depends on your interpretation. Therefore,
the notation has to be defined explicitly by you. If the notation is not defined,
and the you are trying to use the properties and methods, which expect the notation
to be defined, then the NotationError is raised.
The notation could be defined in two ways:
By setting each individual property. For example:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> hamiltonian.double_counting = True
>>> hamiltonian.spin_normalized = False
>>> hamiltonian.factor_one_half = False
>>> hamiltonian.factor_two = True
>>> hamiltonian.minus_sign = True
By setting the
notationproperty directly. For example:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> hamiltonian.notation = (True, False, False, True, True)
>>> hamiltonian.notation
H = -2 sum_{i,j} S_i J_ij S_j
Double counting is present.
Spin vectors are not normalized.
(True, False, False, True, True)
>>> hamiltonian.double_counting
True
>>> hamiltonian.spin_normalized
False
>>> hamiltonian.factor_one_half
False
>>> hamiltonian.factor_two
True
>>> hamiltonian.minus_sign
True
Once the notation or any of the individual properties are set, the following redefinition of the notation or corresponding property will change exchange parameters. See Examples.
If you want to change the notation once is set, but keep the parameters intact use
ExchangeHamiltonian.set_interpretation() method:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> hamiltonian.double_counting = True
>>> hamiltonian.spin_normalized = False
>>> hamiltonian.factor_one_half = False
>>> hamiltonian.factor_two = True
>>> hamiltonian.minus_sign = True
>>> hamiltonian.notation
H = -2 sum_{i,j} S_i J_ij S_j
Double counting is present.
Spin vectors are not normalized.
(True, False, False, True, True)
>>> hamiltonian.set_interpretation(double_counting=False, spin_normalized=True, factor_one_half=False, factor_two=False, minus_sign=True)
>>> hamiltonian.notation
H = -sum_{i>=j} S_i J_ij S_j
No double counting.
Spin vectors are normalized to 1.
(False, True, False, False, True)
Predefined notations#
Order: (double counting, spin normalized, factor 1/2, factor 2, minus sign).
- Standard
(True, False, False, False, True)
\[H = -\sum_{i,j} \hat{\boldsymbol{S}}_i \cdot \boldsymbol{J}_{i,j} \hat{\boldsymbol{S}}_j\]where double counting is present (\(ij\) and \(ji\) is in the sum). Spin vectors are not normalized.
- TB2J
(True, True, False, False, True)
\[H = -\sum_{i,j} \hat{\boldsymbol{S}}_i \cdot \boldsymbol{J}_{i,j} \hat{\boldsymbol{S}}_j\]where double counting is present (\(ij\) and \(ji\) is in the sum). Spin vectors are normalized to 1.
- SpinW
(True, False, False, False, False)
\[H = \sum_{i,j} \hat{\boldsymbol{S}}_i \cdot \boldsymbol{J}_{i,j} \hat{\boldsymbol{S}}_j\]where double counting is present (\(ij\) and \(ji\) is in the sum). Spin vectors are not normalized.
They could be set directly through the notation property:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> hamiltonian.notation = 'standard'
>>> hamiltonian.notation
H = -sum_{i,j} S_i J_ij S_j
Double counting is present.
Spin vectors are not normalized.
(True, False, False, False, True)
>>> hamiltonian.notation = 'tb2j'
>>> hamiltonian.notation
H = -sum_{i,j} S_i J_ij S_j
Double counting is present.
Spin vectors are normalized to 1.
(True, True, False, False, True)
>>> hamiltonian.notation = 'spinw'
>>> hamiltonian.notation
H = sum_{i,j} S_i J_ij S_j
Double counting is present.
Spin vectors are not normalized.
(True, False, False, False, False)
Examples#
Setting one of the predefined notations:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> hamiltonian.notation = "standard"
>>> hamiltonian.notation
H = -sum_{i,j} S_i J_ij S_j
Double counting is present.
Spin vectors are not normalized.
(True, False, False, False, True)
>>> hamiltonian.notation = "TB2J"
>>> hamiltonian.notation
H = -sum_{i,j} S_i J_ij S_j
Double counting is present.
Spin vectors are normalized to 1.
(True, True, False, False, True)
>>> hamiltonian.notation = "SpinW"
>>> hamiltonian.notation
H = sum_{i,j} S_i J_ij S_j
Double counting is present.
Spin vectors are not normalized.
(True, False, False, False, False)
Setting the notation:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> Cr = rad.Atom("Cr", spin=1.5)
>>> hamiltonian.add_bond(rad.ExchangeParameter(iso=1), Cr, Cr, (1, 0, 0))
>>> hamiltonian[Cr, Cr, (1, 0, 0)].iso
1.0
>>> # For the first time interpretation is set,
>>> # values of exchange are not changed
>>> hamiltonian.notation = "standard"
>>> hamiltonian[Cr, Cr, (1, 0, 0)].iso
1.0
>>> # Once the notation is set the values
>>> # are changing if the notation is changed again.
>>> hamiltonian.notation = "TB2J"
>>> hamiltonian[Cr, Cr, (1, 0, 0)].iso
2.25
>>> hamiltonian.notation = "SpinW"
>>> hamiltonian[Cr, Cr, (1, 0, 0)].iso
-1.0
>>> hamiltonian.notation = "standard"
>>> hamiltonian[Cr, Cr, (1, 0, 0)].iso
1.0
Setting individual properties:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> Cr = rad.Atom("Cr", spin=1.5)
>>> hamiltonian.add_bond(rad.ExchangeParameter(iso=1), Cr, Cr, (1, 0, 0))
>>> hamiltonian[Cr, Cr, (1, 0, 0)].iso
1.0
>>> # For the first time interpretation is set,
>>> # values of exchange are not changed
>>> hamiltonian.minus_sign = True
>>> hamiltonian[Cr, Cr, (1, 0, 0)].iso
1.0
>>> # Once the property is set the values
>>> # are changing if the property is changed again.
>>> hamiltonian.minus_sign = False
>>> hamiltonian[Cr, Cr, (1, 0, 0)].iso
-1.0
Changing individual properties:
>>> import radtools as rad
>>> hamiltonian = rad.ExchangeHamiltonian()
>>> Cr = rad.Atom("Cr", spin=1.5)
>>> hamiltonian.add_bond(rad.ExchangeParameter(iso=1), Cr, Cr, (1, 0, 0))
>>> hamiltonian[Cr, Cr, (1, 0, 0)].iso
1.0
>>> hamiltonian.notation = "standard"
>>> hamiltonian[Cr, Cr, (1, 0, 0)].iso
1.0
>>> hamiltonian.double_counting, hamiltonian.spin_normalized, hamiltonian.factor_one_half, hamiltonian.factor_two, hamiltonian.minus_sign
(True, False, False, False, True)
>>> hamiltonian.minus_sign = False
>>> hamiltonian[Cr, Cr, (1, 0, 0)].iso
-1.0
>>> hamiltonian.factor_one_half, hamiltonian.factor_two
(False, False)
>>> hamiltonian.factor_one_half = True
>>> hamiltonian[Cr, Cr, (1, 0, 0)].iso
-2.0
>>> hamiltonian.factor_one_half, hamiltonian.factor_two
(True, False)
>>> hamiltonian.factor_two = True
>>> hamiltonian[Cr, Cr, (1, 0, 0)].iso
-1.0
>>> # Note that the values are switched to False,
>>> # since factor one half and two are cancelling each other
>>> hamiltonian.factor_one_half, hamiltonian.factor_two
(False, False)
>>> hamiltonian.spin_normalized = True
>>> hamiltonian[Cr, Cr, (1, 0, 0)].iso
-2.25
>>> hamiltonian.double_counting = False
>>> hamiltonian[Cr, Cr, (1, 0, 0)].iso
-4.5