Z2PackDev / Z2Pack

A tool for calculating topological invariants.
https://z2pack.greschd.ch
GNU General Public License v3.0
84 stars 51 forks source link

Chern numbers of given bands of a 3D material #80

Closed ghost closed 4 years ago

ghost commented 4 years ago

Hello Sir,

First off, I would like to give a big like to Z2Pack. It was just recently that I came across with this nice post-processing code for topological invariant calculations. I was learning how to use it through the given examples. However, If I am not mistaken, I cannot find any relevant information of how to calculate the Chern number of a given band of a 3D material (BZ is now three dimensional). Suppose I already have the file wannier90_hr.dat for this 3D material. Could you please indicate me in a short but instructive way how to perform such a calculation from constructing a TB model with this file? Many thanks !

Best, Leon

greschd commented 4 years ago

Hi Leon,

Glad to hear you liked using Z2Pack so far. Calculating the Chern number for 3D materials from tight-binding models works as follows:

First, you need to load the tight-binding model using TBmodels: http://z2pack.ethz.ch/tbmodels/doc/1.3/reference.html#tbmodels.Model.from_wannier_files

If there's only a _hr.dat file, that would be

import tbmodels
import z2pack
model = tbmodels.Model.from_wannier_files(
    hr_file='path_to_your_file_hr.dat', 
    occ=number_occupied_bands
)
system = z2pack.tb.System(model)

where you need to set number_occupied_bands to the number of occupied bands, so that the occupied subspace is correctly chosen.

Since the Chern number is fundamentally two-dimensional (flux through a surface), you then need to choose which (closed) surface the Chern number should be calculated for. For example, we can pick z=0. This determines the surface parameter in the calculation, which is a parametrization of that surface:

res = z2pack.surface.run(
    system=system,
    surface=lambda s, t: [s, t, 0]
)
print(z2pack.invariant.chern(res))

Hope this helps, Dominik

ghost commented 4 years ago

Hi Dominik,

Thanks for your reply. Your short instruction is appreciable.

Nonetheless, I am still facing with three concerns as follows: (i) Why it has to set "number_occupied_bands" as Berry curvature can in principle be defined for an arbitrary band. In case my understanding is correct then what's going on for those unoccupied bands ? (ii) Is it possible to get the Chern number for a particularly specified band, lets say e.g. the lowest conduction band or the highest valence band for a semiconducting or an insulating 3D material. As a matter of fact, this is what I am really interested in for which you may find some literature results (including your own published papers). (iii) In the script: res = z2pack.surface.run(system=system, surface=lambda s, t: [s, t, 0]), do I need to specify the values of s and t explicitly or they are of this general form ? In case they are material-specific values, could you demonstrate a bit detail for a realistic material ?

Look forward to your kind explanations and thank you once more.

Best, Leon

greschd commented 4 years ago

Regarding the choice of bands: Yes, in principle you can choose an arbitrary set of bands -- as long as they are separated (on the surface to be calculated) by a band gap from the rest of the bands. The underlying reason for this is that the states must span a smooth manifold, which is ensured by having a gap. If you want to look at more complicated topological phases, symmetries can also be used to enforce this criterion. In any case, you can choose a specific band or set of bands by passing the bands parameter to when creating the Z2Pack system: if an integer is passed this is interpreted as the number of bands (from below) to choose, but you can select specific bands by passing a list of indices. Choosing the occupied bands is the most common kind however, since this tells you about the topology of the ground state. If you were to pick all the bands for example, this will always give you a trivial topology, because the system can be smoothly transformed to the atomic limit.

As for the choice of surface: the two parameters s and t go from zero to one. The function should describe a closed surface in reduced reciprocal space. So in general you don't need to adapt the surface function for a specific material, but it does depend on which kind of topology you are studying.

greschd commented 4 years ago

I also want to mention: I have written a book chapter that should be a bit more accessible than the papers, and probably does a better job of explaining things than I've done above -- it can be accessed freely here: http://z2pack.ethz.ch/doc/2.2/other_material.html

ghost commented 4 years ago

I also want to mention: I have written a book chapter that should be a bit more accessible than the papers, and probably does a better job of explaining things than I've done above -- it can be accessed freely here: http://z2pack.ethz.ch/doc/2.2/other_material.html

Thanks, Dominik. Hopefully this book chapter would give me some more instructions. PS: Do you mind if I would like to keep you updated about this issue ?

Best, Leon

greschd commented 4 years ago

I don't mind at all, feel free to ask more questions.

ghost commented 4 years ago

Hello Dominik,

long time no see. now i get back to you with some feedbacks. i have 36 wannier bands for a 3D material and would like to calculate e.g. the chern number of the 1st wannier band. thus i used the following snippets for the purpose:

settings = {'num_lines': 101,
            'pos_tol': 1e-3,
            'gap_tol': 1e-3,
            'move_tol': 1e-2,
            'iterator': range(10, 101, 2),
            'min_neighbour_dist': 1e-3,
           }

model = tbmodels.Model.from_wannier_files(hr_file='wannier90_hr.dat')
system = z2pack.tb.System(model, bands=[1]) # the first wannier band
result = z2pack.surface.run(system=system, surface=lambda s, t: [s, t, 0], **settings)
print(z2pack.invariant.chern(result))

what i found is that these 36 wannier bands are not well separated (though some of them are disentangled). thus i was wondering is it reliable to calculate the chern number of each individual band using the above snippets. Thanks !

Best, Leon

greschd commented 4 years ago

Hi Leon,

The Chern number (and Z2 invariant) is only well-defined if the band (or set of bands) is separated at all k-points in question by a direct band gap. If there are band crossings, the fiber bundle spanned by that band is not guaranteed to be smooth, in which case it's not possible to define a Chern number.

So to answer your question: No, you should consider disentangled groups of bands to have a meaningful result.

As a side note: The bands=[1] gives you the second band. Z2Pack follows the Python convention to use zero-based indices, so the first band would be bands=[0].

Best, Dominik

ghost commented 4 years ago

Hi Dominik,

Thanks for short explanation which resolves my this concern for some time and also for your side note (i forgot python indexing is 0-based, :D).

I think you can now close this issue. If any other issues do occur, i will open a new channel.

Best, Leon