romerogroup/pyprocar

Changing distance along the kpath (QE)

Opened this issue · 6 comments

Hi, i'm trying to plot the weyl semimetal band structure
Firstly, I'm using pyprocar with quantum espresso
Using the bands.in, I succeeded in creating the band plot I wanted.
**bands.in
K_POINTS {crystal_b}
7
0.000000 0.000000 0.500000 80 !X
0.000000 0.000000 0.000000 80 !G
-0.271448 0.271448 0.271448 80 !Sigma
0.000000 0.500000 0.000000 80 !N
0.271448 0.728552 -0.271448 80 !Sigma1
0.500000 0.500000 -0.500000 80 !Z
0.000000 0.000000 0.000000 80 !G

The figure below is the band structure I plot.
** pyprocar.bandsplot(code='qe', elimit = [-8,2], mode='plain',dirname=data_dir)
Band plot

I wnat to change the distance along the kpath(Sigma - N - Sigma1)
Thank you for letting me know how to change the kpath distance.
Or if you have any examples worth referencing, please let me know.

Hey,

I'm trying to clarify: is the left plot your current result, and you're aiming for the right plot instead?

Currently, I do not believe there is a way to change the distance of certain paths. But I do not think it will be that difficult to add this feature. I provide the code we use to calculate the path below. To change this I would have to add a scaling factor to the calculated distance between the special kpoints.

I am open to suggestions, but I think the best way to implement this is to introduce a list filled with scaling factors for each segment of the path.

In your case, you have 6 kpath segments between special kpoints, so the proposed keyword argument you would have to give to bandsplot would be:

scaling_factors=[1,1,0.5,0.5,1,1]

Here, I shrink the distance between Sigma - N - Sigma1, but I leave the other segments alone

Is this solution okay for you? If it is, I'll go ahead and add this.

In the code, we calculate the path with the following:

for isegment in range(self.kpath.nsegments):
                kstart, kend = self.kpath.special_kpoints[isegment]
                if self.kdirect is False:
                    kstart=np.dot(self.ebs.reciprocal_lattice,kstart)
                    kend=np.dot(self.ebs.reciprocal_lattice,kend)

                distance = np.linalg.norm(kend - kstart)
                if isegment == 0:
                    x = np.linspace(pos, pos + distance,
                                    self.kpath.ngrids[isegment])
                else:
                    x = np.append(
                        x,
                        np.linspace(pos, pos + distance,
                                    self.kpath.ngrids[isegment]),
                        axis=0,
                    )
                pos += distance

Thank you for your attention,

The left plot is my current result, and I'm aiming for the right plot instead.
When I use other dft tool and plot the band without pyprocar(using same high symmetry point), It looks like the picture on the right, just as I want
In the BZ, it is clear that the distance between Sigma-N-Sigma1 and Z-Gamma is short. But not when I use pyprocar.

The method you suggested is to add scaling_factors like this "pyprocar.bandsplot(code='qe', elimit = [-8,2], mode='plain',dirname=data_dir, scaling_factors=[1,1,0.5,0.5,1,1])"?
or to modify the source code?

Sir, I have another question.
K_POINTS {crystal_b}
7
0.000000 0.000000 0.500000 80 !X
0.000000 0.000000 0.000000 80 !G
-0.271448 0.271448 0.271448 80 !Sigma
0.000000 0.500000 0.000000 80 !N
0.271448 0.728552 -0.271448 80 !Sigma1
0.500000 0.500000 -0.500000 80 !Z
0.000000 0.000000 0.000000 80 !G
Using this crystal Kpoint, I calculated the distance between adjacent points.
The distance between adjacent points is [0.5 0.4702 0.4468 0.4468 0.3959 0.866 ].
This result is same when I using this code:
parser = pyprocar.io.Parser(code = 'qe', dir=data_dir)
kpath = parser.kpath
ebs = parser.ebs
kpath = ebs.kpath
print(kpath.tick_positions)
print(kpath.kdistances)

And using a k-points in units of 2 pi/a, , I calculated the distance between adjacent points again.
K_POINTS tpiba_b
7
0.9405481674 0.9405481674 0.0000000000 50 !X
0.0000000000 0.0000000000 0.0000000000 50 !G
1.0212409614 0.0000000000 0.0000000000 50 !Sigma
0.9405481674 0.0000000000 0.2754913057 50 !N
0.8598553735 0.0000000000 0.5509826113 50 !Sigma1
0.0000000000 0.0000000000 0.5509826113 50 !Z
0.0000000000 0.0000000000 0.0000000000 50 !G
The distance between adjacent points is [1.330 1.021 0.287 0.287 0.860 0.551 ].
This Kpath distance corresponds to the Kpath distance of the right band structure I attached.

If I plot a band structure using gnuplot for the same crystal Kpoint with another dft tool, the kpath distance is automatically plotted as [1.330 1.021 0.287 0.287 0.860 0.551] which is resulted from tipiba_b
Does pyprocar reflect the distance between crystal Kpoints?
What method is needed to plot the kpath distance as shown in the right plot?

Hello!

You may have tried it already, but if you haven’t did you check if setting
kdirect=False in the band plotting function helps?

i.e. pyprocar.bandsplot(code='qe', elimit = [-8,2], mode='plain',dirname=data_dir, kdirect=False)

Best,
Uthpala

Hello!

I have already tried 'kdirect=False', but it did not help.

Manual notice that, for 'kdirect=False', an OUTCAR must be supplied for this case to retrieve the reciprocal lattice vectors to transform the coordinates from reduced to cartesian.
Does the 'kdirect=False' function also apply to quantum espresso?

Yes, if the Quantum Espresso output file is present, it will parse the reciprocal lattice vectors from it and apply it to the coordinate transformation required to depict the k-path in cartesian coordinates which is a more accurate representation for non-orthogonal systems.

This was the case for PyProcar v.5.6.6 and below. @lllangWV might be able to provide some insight on how this is done in the newer versions.