Code workflow
KITE has 3 different layers: a user interface (Python); a main program (C++); and a postprocessing tool (C++). The TB model is built and exported together with the calculation settings to a HDF5 file (*.h5
), which is then used as I/O to the main program (called KITEx). The workflow is as follows:
 Export model and calculation settings to a
*.h5
file for KITEx;  Run KITEx;
 Run the postprocessing tools and visualise the data;
Below, we illustrate the use of the Pybinding package to build a TB model for a crystal and illustrate the basic funcionalities of KITE. Those already familiar with Pybinding may consider skipping to Examples.
Building and exporting a TB model
KITE’s intuitive user interface is based on Pybinding with bespoke features for complex disorder/fields modifications and target functions e.g., DoS, conductivity, etc.
Importing the Pybinding package
If all the installation requirements are fulfilled, Pybinding package can be imported in the python script. In this tutorial, the required packages will be included with the following aliases:
import kite
import pybinding as pb
import numpy as np
import matplotlib.pyplot as plt
If you want to use pybinding predefined styles for visualizing the lattice, simply add to the script:
pb.pltutils.use_style()
Building the model
The most important object for building a TB model is pb.Lattice, which carries the information about the crystal structure (lattice and basis) and hopping parameters. Pybinding also provides additional features based on the realspace information, as for example, the reciprocal vectors and the Brillouin zone. As a simple example, let us consider a square lattice with a single lattice site.
First, import all the packages (including KITE special features):
import kite
import pybinding as pb
import numpy as np
import matplotlib.pyplot as plt
The following syntax can be used to define primitive lattice vectors:
a1 = np.array([1,0]) # [nm] define the first lattice vector
a2 = np.array([0, 1]) # [nm] define the second lattice vector
lat = pb.Lattice(a1=a1, a2=a2) # define a lattice object
Add the desired lattice sites inside the unit cell:
lat.add_sublattices(
# make a lattice site (sublattice) with a tuple
# (name, position, and onsite potential)
('A', [0, 0], onsite[0])
)
By default the main cell has the index [n1,n2] = [0, 0]
. The hoppings between neighboring sites can be added with the simple syntax:
lat.add_hoppings(
# make an hopping between lattice site with a tuple
# (relative unit cell index, site from, site to, hopping energy)
([1, 0], 'A', 'A',  1 ),
([0, 1], 'A', 'A',  1 )
)
Here, the relative indices n1,n2
represent the number of integer steps needed to reach a neighboring cell starting from the main one.
Important note: When adding the hopping (n, m)
between sites n
and m
, the conjugate hopping term (m, n)
is added automatically and it is not allowed to add them twice.
Now we can plot the lattice:
lat.plot()
plt.show()
and visualize the Brillouin zone:
lat.plot_brillouin_zone()
plt.show()
For a crystal with two atoms per unit cell see our graphene example. For other examples and predefined lattices consult the Pybinding documentation.
Calculation settings and KITE target functions
The following Python classes from KITE are used to define the target functions and calculation settings:
Configuration
Calculation
Modification
Configuration
The class Configuration
carries the following information:
divisions
– integer number that defines the number of decomposition parts in each spatial direction. KITEx implements a domain decomposition technique to divide the lattice into various partitions that are computed in parallel. To activate this feature set a number of decomposition parts larger than unitnx * ny > 1
. For example:
nx = ny = 2
decomposes a 2D lattice into four regions of equal size. The product nx * ny
equals the number of threads used by KITEx and thus must not exceed the number of avaliable cores in the computer.
The domain decomposition is optimized at the design level and allows a substantial speed up of multithreaded calculations. We recommend its usage.
length
– integer number of unit cells along the direction of lattice vectors:
lx = 256
ly = 256
The lateral size of the decomposed parts are given by lx/nx and ly/ny that need to be integer numbers.

boundaries
– boolean value. True for periodic boundary conditions and False for open boundary conditions. Currently, KITEx only accepts periodic boundary conditions. 
is_complex
– boolean value. For optimisation purposes, KITEx only considers and stores complex data with the setting is_complex=True. False should be used for real symmetric Hamiltonians. 
precision
– integer identifier of data type. KITEx allows users to define the precision of the calculation. Use 0 for float, 1 for double, and 2 for long double. 
spectrum_range
– array of reals (OPTIONAL). By default KITE executes an automated rescaling of the Hamiltonian; see Resources. Advanced users can override this feature usingspectrum_range=[Emin,Emax]
, whereEmin(Emax)
are the minimum (maximum) eigenvalues of the TB matrix.
As a result, a Configuration
object is structured in the following way:
configuration = ex.Configuration(divisions=[nx, ny], length=[lx, ly], boundaries=[True, True], is_complex=False, precision=1)
Calculation
Finally, the Calculation
object carries out the information about the quantities that are going to be calculated i.e., the CPGF target functions. For this part, we still need to include more parameters, related to the Chebyshev expansion (our examples already have optimized parameters for a standard desktop computer). All target functions require the following parameters:

num_moments defines the number of moments of the Chebyshev expansion and hence the energy resolution of the calculation; see Resources.

num_random defines the number of random vectors for the stochastic evaluation of target functions; see Resources.

num_disorder defines the number of disorder realisations.
The target function functions currently available are:
dos
conductivity_optical
conductivity_dc
conductivity_optical_nonlinear
singleshot_conductivity_dc
with the following parameters:
direction
– direction along which the conductivity is calculated (longitudinal: ‘xx’, ‘yy’, transversal: ‘xy’, ‘yx’)temperature
– temperature used in Fermi Dirac distribution that is used for the calculation of optical and DC conductivities.num_points
– number of points the in energy axis that is going to be used by the postprocessing tool to output the density of states.special
– simplified form of nonlinear optical conductivity hBN exampleenergy
– selected value of energy at which we want to calculate the singleshot_conductivity_dceta
– imaginary term in the denominator of the Green function’s that provides a controlled broadening / inelastic energy scale (for technical details, see Resources).
The calculation is structured in the following way:
calculation = Calculation(configuration)
calculation.dos(num_points=1000, num_random=10, num_disorder=1, num_moments=512)
calculation.conductivity_optical(num_points=1000, num_random=1, num_disorder=1, num_moments=512, direction='xx')
calculation.conductivity_dc(num_points=1000, num_moments=256, num_random=1, num_disorder=1,direction='xy', temperature=1)
calculation.singleshot_conductivity_dc(energy=[(n/100.0  0.5)*2 for n in range(101)], num_moments=256, num_random=1, num_disorder=1,direction='xx', gamma=0.02)
calculation.conductivity_optical_nonlinear(num_points=1000, num_moments=256, num_random=1, num_disorder=1,direction='xxx', temperature=1.0, special=1)
Important note: The user can decide what functions are used in a calculation. However, it is not possible to configure the same function twice in the same Python script (HDF5 file).
When these objects are defined, we can export the file that will contain set of input instructions for KITEx:
kite.export_lattice(lattice, configuration, calculation, 'test.h5')
Running the code
To run the code and the postprocess it, use
./KITEx test.h5
./tools/KITEtools test.h5
Visualizing the data
After calculating the quantity of interest and postprocessing the data, we can plot the resulting data with the following script:
import matplotlib.pyplot as plt  
import h5py  
import matplotlib as mpl  
import numpy as np  
#************************************  
#keep these definitions for kite website  
import seaborn as sns  
mpl.rcParams['figure.dpi'] = 100  
mpl.rcParams['savefig.dpi'] = 100  
sns.set_style("white")  
#Kite color scheme  
colors = ["dusty purple", "faded green","windows blue", "amber", "greyish"]  
current_palette=sns.xkcd_palette(colors)  
sns.set_palette(current_palette)  
sns.set_style("ticks")  
sns.set_context("talk",font_scale=1.1)  
#*************************************  
data=np.loadtxt('dos.dat')  
plt.plot(data[:,0],data[:,1])  
plt.xlabel('E (eV)')  
plt.ylabel('DOS (a.u)')  
plt.ylim(ymin=0)  
#plt.xlim(3.5,3.5)  
plt.legend()  
plt.tight_layout()  
plt.show() 
!
If you want to make these steps more automatic, you can use the following Bash script
#!/bin/bash  
file_out=example1 # define name of a python script that exports the *.h5 file file  
file_in=example1 # define name of an input *.h5 exported from when running previous script file  
python ${file_out}.py # make a model  
./KITEx ${file_in}.h5 # run Quantum Kite  
./tools/KITEtools ${file_in}.h5 # run PostProccesingCode  
python plot_dos.py # display the data 