This program calculates the isotropic exchange coupling parameters
where
python version requires numba
c++ version is implemented as cpp_modules, which requires Eigen and pybind11 libraries during compilation via CMake:
mkdir build
cd build/
cmake -DCMAKE_BUILD_TYPE=Releas .. (add Eigen and pybind11 path)
make
Run python xchange.py within directory with in.json together with hopping files spin_up.dat and spin_dn.dat from wannier90.
As an example we calculate exchange interactions in square lattice with nearest neighbor hopping
in.json file contains the following information:
"cell_vectors": [[1.000000, 0.000000, 0.000000],
[0.000000, 1.000000, 0.000000],
[0.000000, 0.000000, 10.000000]],
"number_of_magnetic_atoms": 1,
"positions_of_magnetic_atoms": [[0.00000, 0.00000, 0.00000]],
"central_atom": 0,
"orbitals_of_magnetic_atoms":[1],
"max_sphere_num": 2,
"exchange_for_specific_atoms": [[0, 0, 0, 0]],
"spin": 0.5,
"ncol": 1000,
"nrow": 500,
"smearing": 0.01,
"e_low": -2,
"e_fermi": 0,
"kmesh": [20, 20, 1]
- cell_vectors - (3x3)(dfloat) matrix of unit cell vectors (in Ang);
- number_of_magnetic_atoms - (int) number of magnetic atoms in unit cell;
- positions_of_magnetic_atoms - (3 x number_of_magnetic_atoms)(dfloat) matrix of magnetic atoms positions in unit cell (in Ang);
- central_atom - (int) atomic number of magnetic atom, for which we want to calculate exchange interactions (0 in our case);
- orbitals_of_magnetic_atoms - (number_of_magnetic_atoms) (int) array of magnetic orbitals
- max_sphere_num - (int) maximum number of coordination sphere to calculate exchange couplings around central_atom. This number breaks the loop;
- exchange_for_specific_atoms - (4 x required setups)(int) matrix used for calculation of exchange couplings only between central_atom and atom given by element[3], connected with radius-vector R = element[0] * cell_vector1 + element[1] * cell_vector2 + element[2] * cell_vector3. All zero elements [0,0,0,0] makes the program calculate all possible exchange interactions restricted by max_sphere_num;
- spin - (int) spin number of the system;
- ncol - (int) number of energy point for integration along real axis;
- nrow - (int) number of energy point for integration along imaginary axis;
- smearing - (dfloat) numerical smearing parameter;
- e_low - (dfloat) lower boundary of orbital energies;
- e_fermi - (dfloat) Femi energy;
- kmesh [3x1] (int) array - k-mesh for Brillouin zone integration;
Resulting value of nearest neighbor exchange coupling
Now let's calcualte exchange interactions in BaMoP2O8 system [Phys. Rev. B 98, 094406 (2018)]. DFT+U electronic structure near Fermi level was parametrized by Wannier functions of one Mo(d) and eight O(p) orbitals (5 + 8 * 3 = 29 orbitals):
in.json file in this case is the following:
"cell_vectors": [[4.880000, 0.000000, 0.000000],
[2.028352, 4.438489, 0.000000],
[0.547938, 0.352040, 7.788818]],
"number_of_magnetic_atoms": 1,
"positions_of_magnetic_atoms": [[0.00000, 0.00000, 0.00000]],
"central_atom": 0,
"orbitals_of_magnetic_atoms":[5],
"max_sphere_num": 3,
"exchange_for_specific_atoms": [[0, 0, 0, 0]],
"spin": 1,
"ncol": 1000,
"nrow": 500,
"smearing": 0.01,
"e_low": -9,
"e_fermi": 3.2188,
"kmesh": [5, 5, 5]
Orbitals of magnetic atoms in spin_up.dat and spin_dn.dat go first. Keep this in mind during wannierization.
As a result, program will print the occupation difference between spin up and down (i.e. magnetization):
Occupation matrix (N_up - N_dn) for atom 0
and exchange interactions between atoms:
Atom 0 (000)<-->Atom 0 ( 0 1 0 ) with radius 4.8800 is # 1
# 0 0 0 1 0 0.000157 eV
...
Atom 0 (000)<-->Atom 0 ( 1 -1 0 ) with radius 5.2756 is # 1
# 0 0 1 -1 0 0.004862 eV
...
Atom 0 (000)<-->Atom 0 ( 0 0 1 ) with radius 7.8160 is # 1
# 0 0 0 0 1 0.000282 eV
It results