def get_edensityxc(self, densinfo): if isinstance(densinfo, ValGrad): rho = densinfo.value.abs() # safeguarding from nan return self.a * safepow(rho, self.p)**self.p else: return 0.5 * (self.get_edensityxc(densinfo.u * 2) + self.get_edensityxc(densinfo.d * 2))
def get_edensityxc(self, densinfo): if isinstance(densinfo, ValGrad): # unpolarized case rho = densinfo.value.abs() kf_rho = (3 * np.pi * np.pi)**(1.0 / 3) * safepow(rho, 4.0 / 3) e_unif = -3.0 / (4 * np.pi) * kf_rho return e_unif else: # polarized case eu = self.get_edensityxc(densinfo.u * 2) ed = self.get_edensityxc(densinfo.d * 2) return 0.5 * (eu + ed)
def get_edensityxc(self, densinfo): if isinstance(densinfo, ValGrad): rho = densinfo.value.abs() kf_rho = (3 * np.pi * np.pi)**(1.0 / 3) * safepow(rho, 4.0 / 3) e_unif = -3.0 / (4 * np.pi) * kf_rho norm_grad = safenorm(densinfo.grad, dim=-1) s = norm_grad / (2 * kf_rho) fx = 1 + self.kappa - self.kappa / (1 + self.mu * s * s / self.kappa) return fx * e_unif else: return 0.5 * (self.get_edensityxc(densinfo.u * 2) + self.get_edensityxc(densinfo.d * 2))
def ldac_e_true(rho, xi): # lda correlation based on PW92 rs = safepow(4 * np.pi * rho / 3.0, -1.0 / 3) sl = (slice(None, None, None),) + ((None,) * max(rs.ndim, xi.ndim)) a_pp = torch.tensor([1, 1, 1])[sl] a_a = torch.tensor([0.0310907, 0.01554535, 0.0168869])[sl] a_alpha1 = torch.tensor([0.21370, 0.20548, 0.11125])[sl] a_beta1 = torch.tensor([7.5957, 14.1189, 10.357])[sl] a_beta2 = torch.tensor([3.5876, 6.1977, 3.6231])[sl] a_beta3 = torch.tensor([1.6382, 3.3662, 0.88026])[sl] a_beta4 = torch.tensor([0.49294, 0.62517, 0.49671])[sl] a_fz20 = 1.709920934161365617563962776245 g_aux = a_beta1 * torch.sqrt(rs) + a_beta2 * rs + a_beta3 * rs ** 1.5 + a_beta4 * rs ** (a_pp + 1) # log1p(x) provides better numerical stability than log(1+x) g = -2 * a_a * (1 + a_alpha1 * rs) * torch.log1p(1. / (2 * a_a * g_aux)) f_xi = (safepow(1 + xi, 4. / 3) + safepow(1 - xi, 4. / 3) - 2) / (2 ** (4. / 3) - 2) f_pw = g[0] + xi ** 4 * f_xi * (g[1] - g[0] + g[2] / a_fz20) - f_xi * g[2] / a_fz20 return f_pw * rho
def get_edensityxc(self, densinfo): if isinstance(densinfo, ValGrad): # unpolarized case kappa = 0.804 mu = 0.21951 rho = densinfo.value.abs() kf_rho = (3 * np.pi * np.pi)**(1.0 / 3) * safepow(rho, 4.0 / 3) e_unif = -3.0 / (4 * np.pi) * kf_rho norm_grad = safenorm(densinfo.grad, dim=-1) s = norm_grad / (2 * kf_rho) fx = 1 + kappa - kappa / (1 + mu * s * s / kappa) return fx * e_unif else: # polarized case eu = self.get_edensityxc(densinfo.u * 2) ed = self.get_edensityxc(densinfo.d * 2) return 0.5 * (eu + ed)