# Interface to Wannier90¶

In this tutorial we will briefly scetch the interface to Wannier90. The
tutorial assumes that `Wannier90`

is installed and `wannier90.x`

,
`postw90.x`

are in your path of executables. We emphasize that this is only
to be regarded as a tutorial on the GPAW interface to `Wannier90`

. Details
and tutorials on the `Wannier90`

code itself can be found at the Wannier90
home page. For details on the theory the review
paper [1] may be consulted. The interface is
documented in Ref. [2]

## Wannier functions of GaAs¶

As a first example we generate the maximally localized Wannier functions of
GaAs. The ground state is calculated and saved with the following script
`GaAs.py`

. Note that symmetry has been swtched off in the
calculation, since the interface do not support symmetry reduced \(k\)-points
at the moment. This should be trivial to implement though. The following
script genrates the maximally localized Wannier functions of the occupied
bands.

```
import os
import gpaw.wannier90 as w90
from gpaw import GPAW
seed = 'GaAs'
calc = GPAW(seed + '.gpw', txt=None)
w90.write_input(calc, orbitals_ai=[[], [0, 1, 2, 3]],
bands=range(4),
seed=seed,
num_iter=1000,
plot=True)
w90.write_wavefunctions(calc, seed=seed)
os.system('wannier90.x -pp ' + seed)
w90.write_projections(calc, orbitals_ai=[[], [0, 1, 2, 3]], seed=seed)
w90.write_eigenvalues(calc, seed=seed)
w90.write_overlaps(calc, seed=seed)
os.system('wannier90.x ' + seed)
```

In general `Wannier90`

, needs an .win input file that the user should
write. This contains the \(k\)-point grid ,unit cell, positions of atoms, and a
range of parameters specifying the Wannier calculations. Here, we have
provided a helper function `write_input_file`

that provides the most basic
input. In addition, the input file needs to specify the bands contributing to
the wannierization and the initial localized orbitals that the Kohn-Sham
states are projected onto. This is provided with the keywords `bands`

,
which should be a list of bands and `orbitals_ai`

, which should be a list
of lists containing atomic orbital indices for each of the atoms in the
structure. In the example above `orbitals_ai`

an empty list (for the As
atom) and `[0, 1, 2, 3]`

corresponding to the s and p orbitals of the Ga
atom. In this particular example we would like to plot the Wannier functions
and include the `plot=True`

keyword. Altenatively, we could have put
`wannier_plot=True`

in the .win file by hand. For this purpose we also need
the `write_wavefunctions`

function, that writes the periodic part of the
wavefunctions in a special format required by `Wannier90`

.

To proceed, we need lists of nearest neighbor \(k\)-points. This is calculated
with `Wannier90`

using the `wannier90.x -pp GaAs`

command and stored in
`GaAs.nnkp`

. With these in place, we are ready to perform the largest
calculation of the interface. Namely the initial projector overlaps \(\langle
u_{n\mathbf{k}}|\tilde p^a_i\rangle\) and the overlaps of Bloch states at
neighboring \(k\)-points \(\langle u_{n\mathbf{k}}|u_{n\mathbf{k+b}}\rangle\).
these are stored in `GaAs.amn`

and `GaAs.mmn`

respectively. In addition,
the Kohn-Sham eigenvalues are written to `GaAs.eig`

.

Finally, the Wannier calculation is initiated with `wannier90.x GaAs`

.
Examining the output `GaAs.wout`

shows that the Wannier functions are Ga
centered s and p orbitals for many iterations. Eventually, additional
localization is obtained by formed four equivalent sp3 orbitals centered at
the bonds. The Wannier90 code actually supports specifying sp3 projectors as
input, but the GPAW interface does cannot handle this yet. The plot keyword
writes the four Wannier functions in `.xsf`

format, which can be plotted
with `xcrysden`

. An example is shown below.

## Fermi surface of Cu¶

The Wannier functions are extremely useful for calculations requiring a large
number of \(k\)-points. In this respect, we can view the Wannier functions as
comprising a minimal orthonormal tight-binding basis, on which the
Hamiltonian can be diagonalized rapidly on a large number of \(k\)-points. As
an example we consider the Fermi surface of Cu. The ground state Kohn-Sham
structure is rapidly obtained with the script `Cu.py`

on a course
\(k\)-point mesh. In general it is somewhat more difficult to obtain Wannier
functions of metals since the bands below a certain energy has to be
disentangled from higher lying bands. The default energy is 0.1 eV above the
Fermi level. The Wannier functions are generated with the script

```
import os
import gpaw.wannier90 as w90
from gpaw import GPAW
seed = 'Cu'
calc = GPAW(seed + '.gpw', txt=None)
w90.write_input(calc,
orbitals_ai=[[0, 1, 4, 5, 6, 7, 8]],
bands=range(20),
num_iter=1000,
dis_num_iter=500)
os.system('wannier90.x -pp ' + seed)
w90.write_projections(calc, orbitals_ai=[[0, 1, 4, 5, 6, 7, 8]])
w90.write_eigenvalues(calc)
w90.write_overlaps(calc)
os.system('wannier90.x ' + seed)
```

Note that we now include many more bands (20 lowest bands) than Wannier
functions, which are defined by the number of initial projections. In this
case we use the s orbital, a single p orbital, and the d-band, which has
proven to work well. The `dis_num_iter`

denotes the number of iterations in
the disentangling algorithm. After running the script, add the following
lines to `Cu.win`

:

```
restart = plot
fermi_surface_plot = True
```

and do:

```
wannier90.x Cu
```

This will diagonalize the Wannier Hamiltonian on a fine \(k\)-mesh and save the
Fermi surface in `Cu.bxsf`

. The result can be plotted with `xcrysden`

and
is shown below. We emphasize that the `write_input_file`

function is just
for generating the basic stuff that should be in the `Cu.win`

input file.
In general this file should be modified according to need before running
`wannier90.x`

.

## Berry curvature and anomalous Hall conductivity of Fe¶

As a final example we calculate the anomalous Hall conductivity of Fe, which
is not easily obtained with GPAW. It can be expressed as a Brillouin zone
integral of the Berry curvature and is an effect of spin-orbit coupling. As
such we need to generate spinorial Wannier functions. The ground state
electronci structure is genrated with the script `Fe.py`

. The
Wannier functions are generated with the script

```
import os
import gpaw.wannier90 as w90
from gpaw import GPAW
from gpaw.spinorbit import get_spinorbit_eigenvalues
seed = 'Fe'
calc = GPAW('Fe.gpw', txt=None)
e_mk, v_knm = get_spinorbit_eigenvalues(calc, return_wfs=True)
w90.write_input(calc,
bands=range(30),
spinors=True,
num_iter=200,
dis_num_iter=500,
dis_mix_ratio=1.0,
dis_froz_max=15.0,
seed=seed)
os.system('wannier90.x -pp ' + seed)
w90.write_projections(calc,
v_knm=v_knm,
seed=seed)
w90.write_eigenvalues(calc, e_km=e_mk.T, seed=seed)
w90.write_overlaps(calc, v_knm=v_knm, seed=seed)
os.system('wannier90.x ' + seed)
```

We have now left out the orbital projections, which means that the default of
all bound projectors are used (s, p and d states in the present case). Note
also that we need to calculate the spin-orbit eigenvalues and wavefunction,
which are supplied as input. After running the script, add the following
lines to `Fe.win`

:

```
kpath = True
kpath_task = curv+bands
kpath_num_points = 1000
begin kpoint_path
G 0.0 0.0 0.0 H 0.5 -0.5 -0.5
H 0.5 -0.5 -0.5 P 0.75 0.25 -0.25
P 0.75 0.25 -0.25 N 0.5 0.0 -0.5
N 0.5 0.0 -0.5 G 0.0 0.0 0.0
G 0.0 0.0 0.0 H 0.5 0.5 0.5
H 0.5 0.5 0.5 N 0.5 0.0 0.0
N 0.5 0.0 0.0 G 0.0 0.0 0.0
G 0.0 0.0 0.0 P 0.75 0.25 -0.25
P 0.75 0.25 -0.25 N 0.5 0.0 0.0
end kpoint_path
```

and run:

```
postw90.x Fe
```

This will calculate the band structure and Berry curvature along the
specified path. Note that the calculatons is orders of magnitude faster
compared to a standard non-selfconsistent band structure calculation with
GPAW. It also generates the script `Fe-bands+curv_z.py`

, which can be used
to plot the band structure along with the \(z\)-component of the Berry
curvature. The result is shown below

The spiky structure of the Berry curvature makes it highly non-trivial to
converge the anomalous Hall conductivity with respect to \(k\)-points. The
Wannier functions can aid the calculations by performing rapid calculations
on a very fine mesh. To perform the calculation set `kpath = False`

in
`Fe.win`

and add the following lines:

```
berry = True
berry_task = ahc
berry_kmesh = 50 50 50
```

Now run `postw90.x Fe`

once more. This calculates the anomalous Hall
conductivity on a \(50\times50\times50\) \(k\)-mesh. The \(z\)-component should be
803 S/cm and can be read from the output file `Fe.wpout`

. This is not too
bad, but one needs to go to much higher \(k\)-point densities to obtain the
converged values of 757 S/cm [3].

[1] | N. Marzari, A. A. Mostofi, J. R. Yates, I. Souza, and D. Vanderbilt
Rev. Mod. Phys. 84, 1419 (2012) |

[2] | T. Olsen
Phys. Rev. B 94, 235106 (2016) |

[3] | X. Wang, J. R. Yates, I. Souza, and D. Vanderbilt
Phys. Rev. B 74, 195118 (2006) |