Ejemplo n.º 1
0
 def update_all(self):
     """
     update all relevant attributes
     given that electron has been updated
     """
     #k is in reciprocal coord and r is in crystal coord
     #but since this is cubic you just need a factor of 2pi
     kr_up = np.matmul(self.k[:self.N], self.electron.up.transpose())
     kr_dn = np.matmul(self.k[:self.N], self.electron.dn.transpose())
     kr_up *= 2*np.pi
     kr_dn *= 2*np.pi
     self.slater_up = np.exp(1j*kr_up)
     self.slater_dn = np.exp(1j*kr_dn)
     #update inverses
     self.inverse_up = np.linalg.inv(self.slater_up)
     self.inverse_dn = np.linalg.inv(self.slater_dn)
     #update u
     kvecs = (2*np.pi/self.L)*self.k[1:]
     self.u_lr_uu = pbc.ewald_lr(self.L*self.electron.uu_table,\
             self.kappa, kvecs, self.supercell.volume)
     self.u_lr_dd = pbc.ewald_lr(self.L*self.electron.dd_table,\
             self.kappa, kvecs, self.supercell.volume)
     self.u_lr_ud = pbc.ewald_lr(self.L*self.electron.ud_table,\
             self.kappa, kvecs, self.supercell.volume)
     r_uu = np.linalg.norm(self.electron.uu_table, axis=-1)
     r_dd = np.linalg.norm(self.electron.dd_table, axis=-1)
     r_ud = np.linalg.norm(self.electron.ud_table, axis=-1)
     r_uu[np.diag_indices(self.N)] = np.inf
     r_dd[np.diag_indices(self.N)] = np.inf
     self.u_sr_uu = pbc.ewald_sr(self.kappa, r_uu*self.L)
     self.u_sr_dd = pbc.ewald_sr(self.kappa, r_dd*self.L)
     self.u_sr_ud = pbc.ewald_sr(self.kappa, r_ud*self.L)
     self.u_exp_uu = u_exp(r_uu*self.L, self.F_uu)
     self.u_exp_dd = u_exp(r_dd*self.L, self.F_uu)
     self.u_exp_ud = u_exp(r_ud*self.L, self.F_ud)
Ejemplo n.º 2
0
 def update_u_dn(self, i):
     """
     update u tables associated with down electron i
     """
     kvecs = (2*np.pi/self.L)*self.k[1:]
     vol = self.supercell.volume
     lr_dd = pbc.ewald_lr(self.electron.dd_table[i]*self.L,\
             self.kappa, kvecs, vol)
     lr_ud = pbc.ewald_lr(self.electron.ud_table[:,i]*self.L,\
             self.kappa, kvecs, vol)
     self.u_lr_dd[i,:] = np.copy(lr_dd)
     #ewald_lr is an even function of r, so no minus sign
     self.u_lr_dd[:,i] = np.copy(lr_dd)
     self.u_lr_ud[:,i] = np.copy(lr_ud)
     #first index is for up electron, not updated here
     r_dd = np.linalg.norm(self.electron.dd_table[i], axis=-1)
     r_ud = np.linalg.norm(self.electron.ud_table[:,i], axis=-1)
     r_dd[i] = np.inf
     sr_dd = pbc.ewald_sr(self.kappa, r_dd*self.L)
     sr_ud = pbc.ewald_sr(self.kappa, r_ud*self.L)
     self.u_sr_dd[i,:] = np.copy(sr_dd)
     self.u_sr_dd[:,i] = np.copy(sr_dd)
     self.u_sr_ud[:,i] = np.copy(sr_ud)
     exp_dd = u_exp(r_dd*self.L, self.F_uu)
     exp_ud = u_exp(r_ud*self.L, self.F_ud)
     self.u_exp_dd[i,:] = np.copy(exp_dd)
     self.u_exp_dd[:,i] = np.copy(exp_dd)
     self.u_exp_ud[:,i] = np.copy(exp_ud)
Ejemplo n.º 3
0
def test_laplacian_ewald_lr():
    L = 5*np.random.rand()
    v = L*np.eye(3)
    supercell = pbc.cell(v[0], v[1], v[2])
    volume = supercell.volume
    kvecs = supercell.kvecs(3)[1:,:3]
    kvecs *= 2*np.pi/L
    kappa = 5/L
    r = L*np.random.rand(3)
    #compute derivatives
    f = pbc.ewald_lr(r, kappa, kvecs, volume) #h = 0
    h = 0.00001 #finite difference step
    lap = 0
    for i in range(3):
        r[i] += h
        f_fwd = pbc.ewald_lr(r, kappa, kvecs, volume)
        r[i] -= 2*h
        f_bwd = pbc.ewald_lr(r, kappa, kvecs, volume)
        r[i] += h #restore original r
        lap += (f_fwd + f_bwd - 2*f) / h**2
    assert np.isclose(lap, pbc.laplacian_ewald_lr(r, kappa, kvecs, volume),\
            rtol=1e-2)
Ejemplo n.º 4
0
def test_grad_ewald_lr():
    L = 5*np.random.rand()
    v = L*np.eye(3)
    supercell = pbc.cell(v[0], v[1], v[2])
    volume = supercell.volume
    kvecs = supercell.kvecs(3)[1:,:3]
    kvecs *= 2*np.pi/L
    kappa = 5/L
    r = L*np.random.rand(3)
    #compute derivatives
    f = pbc.ewald_lr(r, kappa, kvecs, volume) #h = 0
    h = 0.00001 #finite difference step
    grad = np.zeros(3)
    for i in range(3):
        r[i] += h
        fwd = pbc.ewald_lr(r, kappa, kvecs, volume)
        r[i] -= 2*h
        bwd = pbc.ewald_lr(r, kappa, kvecs, volume)
        r[i] += h
        grad[i] = (fwd - bwd) / (2*h)
    assert np.isclose(grad, pbc.grad_ewald_lr(r, kappa, kvecs, volume),\
            rtol=1e-2).all()
Ejemplo n.º 5
0
def test_ewald_lr():
    """
    test ewald_lr, which performs the sum over k with matmul
    against a manual sum over k
    """
    #make supercell
    L = 5*np.random.rand()
    v = L*np.eye(3)
    supercell = pbc.cell(v[0], v[1], v[2])
    volume = supercell.volume
    kvecs = supercell.kvecs(3)[1:,:3]
    kvecs *= 2*np.pi/L
    kappa = 5/L
    r = L*np.random.rand(17, 3)
    u = np.zeros(17)
    for n in range(17):
        for k in kvecs:
            ksq = np.dot(k, k)
            kr = np.dot(k, r[n])
            u[n] += np.cos(kr)*np.exp(-ksq / (4*kappa**2)) / ksq
    u *= 4*np.pi/volume
    assert np.isclose(pbc.ewald_lr(r, kappa, kvecs, volume), u).all()