def get_K_index(self, K): """Find the index of a given K.""" K = np.array([K]) bzKG = to1bz(K, self.acell_cv)[0] iK = self.kd.where_is_q(bzKG, self.kd.bzk_kc) return iK
def find_high_symmetry_monkhorst_pack(calc, density, pbc=None): """Make high symmetry Monkhorst Pack k-point grid. Searches for and returns a Monkhorst Pack grid which contains the corners of the irreducible BZ so that when the number of kpoints are reduced the full irreducible brillouion zone is spanned. Parameters ---------- calc : str The path to a calculator object. density : float The required minimum density of the Monkhorst Pack grid. pbc : Boolean list/ndarray of shape (3,) or None List indicating periodic directions. If None then pbc = [True] * 3. Returns ------- ndarray Array of shape (nk, 3) containing the kpoints. """ if pbc is None: pbc = np.array([True, True, True]) else: pbc = np.array(pbc) atoms, calc = restart(calc, txt=None) minsize, offset = kpts2sizeandoffsets(density=density, even=True, gamma=True, atoms=atoms) bzk_kc, ibzk_kc, latibzk_kc = get_bz(calc, returnlatticeibz=True) maxsize = minsize + 10 minsize[~pbc] = 1 maxsize[~pbc] = 2 if mpi.rank == 0: print('Brute force search for symmetry ' + 'complying MP-grid... please wait.') for n1 in range(minsize[0], maxsize[0]): for n2 in range(minsize[1], maxsize[1]): for n3 in range(minsize[2], maxsize[2]): size = [n1, n2, n3] size, offset = kpts2sizeandoffsets(size=size, gamma=True, atoms=atoms) ints = ((ibzk_kc + 0.5 - offset) * size - 0.5)[:, pbc] if (np.abs(ints - np.round(ints)) < 1e-5).all(): kpts_kc = monkhorst_pack(size) + offset kpts_kc = to1bz(kpts_kc, calc.wfs.gd.cell_cv) for ibzk_c in ibzk_kc: diff_kc = np.abs(kpts_kc - ibzk_c)[:, pbc].round(6) if not (np.mod(np.mod(diff_kc, 1), 1) < 1e-5).all( axis=1).any(): raise AssertionError('Did not find ' + str(ibzk_c)) if mpi.rank == 0: print('Done. Monkhorst-Pack grid:', size, offset) return kpts_kc if mpi.rank == 0: print('Did not find matching kpoints for the IBZ') print(ibzk_kc.round(5)) raise RuntimeError
import numpy as np from ase.dft.kpoints import monkhorst_pack from gpaw.kpt_descriptor import KPointDescriptor, to1bz k = 70 k_kc = monkhorst_pack((k, k, 1)) kd = KPointDescriptor(k_kc + (0.5 / k, 0.5 / k, 0)) assert (kd.N_c == (k, k, 1)).all() assert abs(kd.offset_c - (0.5 / k, 0.5 / k, 0)).sum() < 1e-9 bzk_kc = np.array([[0.5, 0.5, 0], [0.50000000001, 0.5, 0], [0.49999999999, 0.5, 0], [0.55, -0.275, 0]]) cell_cv = np.array([[1, 0, 0], [-0.5, 3**0.5 / 2, 0], [0, 0, 5]]) bz1k_kc = to1bz(bzk_kc, cell_cv) error_kc = bz1k_kc - np.array([[0.5, -0.5, 0], [0.50000000001, -0.5, 0], [0.49999999999, -0.5, 0], [0.55, -0.275, 0]]) assert abs(error_kc).max() == 0.0 assert KPointDescriptor(np.zeros((1, 3)) + 1e-14).gamma
def find_k_along_path(self, plot_BZ=True): """Finds the k-points along the bandpath present in the original calculation""" kd = self.kd acell_cv = self.acell_cv bcell_cv = self.bcell_cv kpoints = self.kpoints if plot_BZ: """Plotting the points in the Brillouin Zone""" kp_1bz = to1bz(kd.bzk_kc, acell_cv) bzk_kcv = np.dot(kd.bzk_kc, bcell_cv) kp_1bz_v = np.dot(kp_1bz, bcell_cv) import matplotlib.pyplot as plt plt.plot(bzk_kcv[:, 0], bzk_kcv[:, 1], 'xg') plt.plot(kp_1bz_v[:, 0], kp_1bz_v[:, 1], 'ob') for ik in range(1, len(kpoints)): kpoint1_v = np.dot(kpoints[ik], bcell_cv) kpoint2_v = np.dot(kpoints[ik - 1], bcell_cv) plt.plot([kpoint1_v[0], kpoint2_v[0]], [kpoint1_v[1], kpoint2_v[1]], '--vr') """Finding the points along given directions""" print('Finding the kpoints along the path') N_c = kd.N_c wpts_xc = kpoints x_x = [] k_xc = [] k_x = [] x = 0. X = [] for nwpt in range(1, len(wpts_xc)): X.append(x) to_c = wpts_xc[nwpt] from_c = wpts_xc[nwpt - 1] vec_c = to_c - from_c print('From ', from_c, ' to ', to_c) Nv_c = (vec_c * N_c).round().astype(int) Nv = abs(gcd(gcd(Nv_c[0], Nv_c[1]), Nv_c[2])) print(Nv, ' points found') dv_c = vec_c / Nv dv_v = np.dot(dv_c, bcell_cv) dx = np.linalg.norm(dv_v) if nwpt == len(wpts_xc) - 1: # X.append(Nv * dx) Nv += 1 for n in range(Nv): k_c = from_c + n * dv_c bzk_c = to1bz(np.array([k_c]), acell_cv)[0] ikpt = kd.where_is_q(bzk_c, kd.bzk_kc) x_x.append(x) k_xc.append(k_c) k_x.append(ikpt) x += dx X.append(x_x[-1]) if plot_BZ is True: for ik in range(len(k_xc)): ktemp_xcv = np.dot(k_xc[ik], bcell_cv) plt.plot(ktemp_xcv[0], ktemp_xcv[1], 'xr', markersize=10) plt.show() return x_x, k_xc, k_x, X