# Open source software

Numerical simulations are a critical instrument in our research. We use them to gain or validate intuition and to answer questions that are impossible to address analytically. For as long as the group exists, we publish source code for all of our research projects, which you can find linked in every paper. Whenever we see that a piece of code is useful to others, we invest additional effort to make it faster, more reliable, and easier to use—in other words, we turn it into a software package.

To show how we use these packages together, let us take a look at how we use them to find the topological invariant of a two dimensional crystalline insulator.

*Kwant*. In the beginning we only have a guess: the kind of tight-binding model that
should be topological and an idea of how its edge states should look.
Coding a tight-binding model is an exercise, and many projects do it from
scratch.
Still, it is both tedious and error prone, which is why we use
Kwant, a Python package for quantum transport
simulations.
This package allows us to define complex models defined on arbitrary shapes,
and analyze their spectrum, density of states, currents, and other
coherent properties.
Kwant was published in 2014, and has been used in over a 1000 projects to date.

*Qsymm*. Because the symmetry of the model is of critical importance to us, we
need to be sure that we do not have any other symmetries, or that we
accidentally break the ones we want.
Depending on how many hoppings we include, the model can be very large
and complicated.
This is where Qsymm, a package
for automated symmetry analysis, helps us.
Qsymm finds all the Hamiltonians that respect a group of symmetries,
or otherwise finds all the symmetries of a given Hamiltonian, as shown in the
figure below.

*Pfapack*. Now that we have a model, we are ready to compute its invariant.
These often requires a Pfaffian,
the less well known sibling of a determinant.
The only computational package to do so is
Pfapack.

*Adaptive*. To test that the invariant, we compute it using a grid of parameter
values.
However, this is not very efficient, as the invariant is an integer that
changes only when the system goes through a phase transition.
Instead, we use Adaptive
to efficiently explore the parameter space sampling less points.
Adaptive is a package for adaptive sampling, and we were happy to see that it
was used in a recent paper for the
simulation of wind turbines!
This video shows how Adaptive samples an unknown function progressively.

This is just one example of how our research workflow looks like, and you can see how we use these packages together here in Zenodo. For more context, you can also read its respective paper here.

*Pymablock*. If our model had a large number of orbitals or bands, for example,
we could use an effective model to reduce the size of the Hamiltonian.
To construct it, we would use Pymablock, a package that implements
quasi-degenerate perturbation theory on numerical and analytical Hamiltonians.
Pymablock's algorithm efficiently block-diagonalizes the Hamiltonian order by
order in the perturbations parameters, as illustrated in the figure below.

*PyDACP*. Alternatively, we could use
PyDACP to compute eigenvalues
efficiently.
This package is work in progress, and it aims to implement an algorithm that
computes eigenvalues of Hermitian linear operators within an energy window.

From constructing models to analyzing their properties, we have tools for several steps of our research workflow! These packages are all open source, and we are very happy to see that they have a growing community of users. If you have any questions or suggestions, feel free to contact us or open an issue on their respective repositories.