Electronic structure setup – part 2

Following part 1 we focus on how to generalize the specification of the hopping parameters in a more generic way.

First, we re-create the square geometry (with one orbital per atom). However, to generalize the specification of the hopping parameters it is essential that we specify how long range the orbitals interact. In the following we set the atomic specie to be a Hydrogen atom with a single orbital with a range of \(1\,Å\)

>>> Hydrogen = Atom(1, R=1.)
>>> square = Geometry([[0.5, 0.5, 0]], Hydrogen,
                      lattice=Lattice([1, 1, 10], nsc=[3, 3, 1]))
>>> H = Hamiltonian(square)
>>> print(H)
{spin: 1, non-zero: 0
 {na: 1, no: 1, species:
  {Atoms(1):
    (1) == [H, Z: 1, orbs: 1, mass(au): 1.00794, maxR: 1.00000],
  },
  nsc: [3, 3, 1], maxR: 1.0
 }
}

Note how the maxR variable has changed from -1.0 to 1.0. This corresponds to the maximal orbital range in the geometry. Here there is only one type of orbital, but for geometries with several different orbitals, there may be different orbital ranges.

Now one can assign the generalized parameters:

>>> for ia in square: # loop atomic indices (here equivalent to the orbital indices)
...     idx_a = square.close(ia, R=[0.1, 1.1])
...     H[ia, idx_a[0]] = -4.
...     H[ia, idx_a[1]] = 1.

The Geometry.close function is a convenience function to return atomic indices of atoms within a certain radius. For instance close(0, R=1.) returns all atomic indices within a spherical radius of \(1\,Å\) from the first atom in the geometry, including it-self. close([0., 0., 1.], R=1.) will return all atomic indices within \(1\,Å\) of the coordinate [0., 0., 1.]. If one specifies a list of R it will return the atomic indices in the sphere within the first element; and for the later values it will return the atomic indices in the spherical shell between the corresponding radii and the previous radii.

The above code is the preferred method of creating a Hamiltonian. It is safe because it ensures that all parameters are set, and symmetrized.

For very large geometries (larger than 50,000 atoms) the above code will be extremely slow. Hence, the preferred method to setup the Hamiltonian for these large geometries is:

>>> for ias, idxs in square.iter_block():
...    for ia in ias:
...        idx_a = square.close(ia, R=[0.1, 1.1], idx=idxs)
...        H[ia, idx_a[0]] = -4.
...        H[ia, idx_a[1]] = 1.

The code above is the preferred method of specifying the Hamiltonian parameters.

The complete code for this example (plus the band-structure) can be found here.