The sisl
python package might be useful to you. It has:
- Tools to build hamiltonians with user-defined basis orbitals.
- A very high level API to visualize the most common analysis from your hamiltonian (bands, PDOS, wavefunctions, etc...).
- Lower level APIs to customize your analysis as you wish.
Here's an example of how you might define a tight binding Hamiltonian for graphene:
import sisl
import sisl.viz
import numpy as np
# Define a basis orbital, with a radial function that is defined by us
r = np.linspace(0, 3.5, 50)
f = np.exp(-r)
orb = sisl.AtomicOrbital('2pzZ', (r, f))
# Build a graphene structure using our orbital as basis for the C atoms.
geom = sisl.geom.graphene(atoms=sisl.Atom(6, orb))
# Initialize a hamiltonian matrix for the geometry
H = sisl.Hamiltonian(geom)
# And set the non zero values.
# In this case, matrix elements of atoms that are closer than 0.1 Ang
# (i.e. the same atom) are assigned 0 eV and connections of less than
# 1.44 Ang (first neighbours) are assigned -2.7 eV.
H.construct([(0.1, 1.44), (0, -2.7)], )
# To make it more interesting, we will change the on-site energies of
# the two atoms
H[0,0] = -1
H[1,1] = 1
Now, you can go on and use any of the methods of the Hamiltonian (see docs).
However, if you want a quick analysis you can use the high level API of the visualization module (docs). Following I show you some of the quick analysis you can do. I tweak some parameters of each analysis, but there are more parameters for which I'm using the defaults.
pdos_plot = H.plot.pdos(
kgrid=[90,90,1], nE=500, Erange=[-4, 4],
distribution={"method": "gaussian", "smearing": 0.1}
)
pdos_plot.split_DOS(on="atoms", name="Atom $atoms")

- Wavefunctions (given your defined basis):
H.plot.wavefunction(
i=1, grid_prec=0.05, axes="xy",
represent="mod", nsc=[2,2,1], zsmooth="best"
)

# We need to define a path for the band structure
bz = sisl.BandStructure(
H, points=[[0, 0, 0], [2/3, 1/3, 0], [1/2, 0, 0]],
divisions=30, names=["Gamma", "M", "K"]
)
# Then just plot it
bz.plot()

fatbands = bz.plot.fatbands()
fatbands.split_groups(on="atoms", name="Atom $atoms")

If you have doubts you can go through the documentation or ask specific questions on the discord server.