fennol.utils.kspace
1import numpy as np 2import math 3 4def get_reciprocal_space_parameters(reciprocal_cells, cutoff, kmax=30, kthr=1.0e-6): 5 # find optimal ewald parameters (preprocessing) 6 eps = 1.0e-8 7 ratio = eps + 1 8 x = 0.5 9 i = 0 10 # approximate value 11 while ratio > eps: 12 x *= 2 13 ratio = math.erfc(x * cutoff) / cutoff 14 # refine with binary search 15 k = i + 60 16 xlo = 0.0 17 xhi = x 18 for i in range(1, k + 1): 19 x = (xlo + xhi) / 2.0 20 ratio = math.erfc(x * cutoff) / cutoff 21 if ratio > eps: 22 xlo = x 23 else: 24 xhi = x 25 bewald = x 26 27 # set k points 28 kxs = np.arange(kmax + 1) 29 kxs = np.concatenate((kxs, -kxs[1:])) 30 k = np.array(np.meshgrid(kxs, kxs, kxs)).reshape(3, -1).T[1:] 31 # set exp factor 32 m2s = [] 33 expfacs = [] 34 ks = [] 35 nks = [] 36 for i, A in enumerate(range(reciprocal_cells.shape[0])): 37 A = reciprocal_cells[i].T 38 m2 = np.sum( 39 ( 40 k[:, 0, None] * A[None, 0, :] 41 + k[:, 1, None] * A[None, 1, :] 42 + k[:, 2, None] * A[None, 2, :] 43 ) 44 ** 2, 45 axis=-1, 46 ) 47 a2 = (np.pi / bewald) ** 2 48 expfac = np.exp(-a2 * m2) / m2 49 isort = np.argsort(expfac)[::-1] 50 expfac = expfac[isort] 51 m2 = m2[isort] 52 ki = k[isort] 53 sel = (expfac > kthr).nonzero()[0] 54 nks.append(len(sel)) 55 m2s.append(m2) 56 expfacs.append(expfac) 57 ks.append(ki) 58 59 ks = np.stack(ks, axis=0) 60 m2s = np.stack(m2s, axis=0) 61 expfacs = np.stack(expfacs, axis=0) 62 nks = np.array(nks, dtype=np.int64) 63 nk = np.max(nks) 64 return ks[:, :nk, :], expfacs[:, :nk], m2s[:, :nk], bewald
def
get_reciprocal_space_parameters(reciprocal_cells, cutoff, kmax=30, kthr=1e-06):
5def get_reciprocal_space_parameters(reciprocal_cells, cutoff, kmax=30, kthr=1.0e-6): 6 # find optimal ewald parameters (preprocessing) 7 eps = 1.0e-8 8 ratio = eps + 1 9 x = 0.5 10 i = 0 11 # approximate value 12 while ratio > eps: 13 x *= 2 14 ratio = math.erfc(x * cutoff) / cutoff 15 # refine with binary search 16 k = i + 60 17 xlo = 0.0 18 xhi = x 19 for i in range(1, k + 1): 20 x = (xlo + xhi) / 2.0 21 ratio = math.erfc(x * cutoff) / cutoff 22 if ratio > eps: 23 xlo = x 24 else: 25 xhi = x 26 bewald = x 27 28 # set k points 29 kxs = np.arange(kmax + 1) 30 kxs = np.concatenate((kxs, -kxs[1:])) 31 k = np.array(np.meshgrid(kxs, kxs, kxs)).reshape(3, -1).T[1:] 32 # set exp factor 33 m2s = [] 34 expfacs = [] 35 ks = [] 36 nks = [] 37 for i, A in enumerate(range(reciprocal_cells.shape[0])): 38 A = reciprocal_cells[i].T 39 m2 = np.sum( 40 ( 41 k[:, 0, None] * A[None, 0, :] 42 + k[:, 1, None] * A[None, 1, :] 43 + k[:, 2, None] * A[None, 2, :] 44 ) 45 ** 2, 46 axis=-1, 47 ) 48 a2 = (np.pi / bewald) ** 2 49 expfac = np.exp(-a2 * m2) / m2 50 isort = np.argsort(expfac)[::-1] 51 expfac = expfac[isort] 52 m2 = m2[isort] 53 ki = k[isort] 54 sel = (expfac > kthr).nonzero()[0] 55 nks.append(len(sel)) 56 m2s.append(m2) 57 expfacs.append(expfac) 58 ks.append(ki) 59 60 ks = np.stack(ks, axis=0) 61 m2s = np.stack(m2s, axis=0) 62 expfacs = np.stack(expfacs, axis=0) 63 nks = np.array(nks, dtype=np.int64) 64 nk = np.max(nks) 65 return ks[:, :nk, :], expfacs[:, :nk], m2s[:, :nk], bewald