Are there any known codes or scripts to generate an adaptive k-mesh for DFT calculations? For example, I'd like to make the k-mesh near the $\Gamma$ point (e.g., half the zone) more denser ($20\times20\times20$) than other region ($8\times8\times8$).
In sisl one can create a Monkhorst-Pack grid with zooming capabilities.
Here is a small Python snippet which creates the k-points for the zoomed in region.
import numpy as np import sisl # time-reversal-symmetry trs = True # first argument is the lattice vectors (in case you want them in 1/Ang) # in this case it is just a square box of side-lengths 1 Ang MP_3x3 = sisl.MonkhorstPack(1, [3, 3, 1], trs=trs) assert np.allclose(MP_3x3.weight.sum(), 1.) MP_3x3_zoom = sisl.MonkhorstPack(1, [3, 3, 1], size=[1/3, 1/3, 1], trs=trs) # density is only 1 / 9 assert np.allclose(MP_3x3_zoom.weight.sum(), 1. / 3 ** 2) MP = MP_3x3.copy() MP.replace( * 3, MP_3x3_zoom) assert np.allclose(MP.weight.sum(), 1.) # List k-points print(MP_3x3.k[:, :2]) print(MP_3x3_zoom.k[:, :2]) print(MP.k[:, :2]) import matplotlib.pyplot as plt def kplot(MP): plt.scatter(MP.k[:, 0], MP.k[:, 1], MP.weight * 500, alpha=0.5) #kplot(MP_3x3) #kplot(MP_3x3_zoom) kplot(MP) plt.show()
The script in sisl also checks whether weights are preserved and whether the sizes of the BZ correspond to each other.
For your case you could do:
# Replace a single point (Gamma) with higher density MP = sisl.MonkhorstPack(1,  * 3, trs=trs) MP_20 = sisl.MonkhorstPack(1,  * 3, size=[1/8] * 3,trs=trs) MP.replace( * 3, MP_20) # Replace 3x3x3 k-points around Gamma by MP = sisl.MonkhorstPack(1,  * 3, trs=trs) MP_20 = sisl.MonkhorstPack(1,  * 3, size=[3/8] * 3,trs=trs) MP.replace( * 3, MP_20)
If you try to do something that is invalid, you'll get error messages ;) E.g. if the weight/volume of the replaced k-point(s) does not match the weights of the inserted k-points. Note, with the above machinery you can nest as many zoom regions as necessary.
Disclaimer: I am the author of the package.