예제 #1
0
def test_libxc_gga_value():
    # compare the calculated value of GGA potential
    dtype = torch.float64
    xc = get_libxc("gga_x_pbe")
    assert xc.family == 2
    assert xc.family == 2

    torch.manual_seed(123)
    n = 100
    rho_u = torch.rand((n, ), dtype=dtype)
    rho_d = torch.rand((n, ), dtype=dtype)
    rho_tot = rho_u + rho_d
    gradn_u = torch.rand((n, 3), dtype=dtype) * 0
    gradn_d = torch.rand((n, 3), dtype=dtype) * 0
    gradn_tot = gradn_u + gradn_d

    densinfo_u = ValGrad(value=rho_u, grad=gradn_u)
    densinfo_d = ValGrad(value=rho_d, grad=gradn_d)
    densinfo_tot = densinfo_u + densinfo_d
    densinfo = SpinParam(u=densinfo_u, d=densinfo_d)

    # calculate the energy and compare with analytical expression
    edens_unpol = xc.get_edensityxc(densinfo_tot)
    edens_unpol_true = pbe_e_true(rho_tot, gradn_tot)
    assert torch.allclose(edens_unpol, edens_unpol_true)

    edens_pol = xc.get_edensityxc(densinfo)
    edens_pol_true = 0.5 * (pbe_e_true(2 * rho_u, 2 * gradn_u) +
                            pbe_e_true(2 * rho_d, 2 * gradn_d))
    assert torch.allclose(edens_pol, edens_pol_true)
예제 #2
0
def test_libxc_lda_value():
    # check if the value is consistent
    xc = get_libxc("lda_x")
    assert xc.family == 1
    assert xc.family == 1

    torch.manual_seed(123)
    n = 100
    rho_u = torch.rand((n, ), dtype=torch.float64)
    rho_d = torch.rand((n, ), dtype=torch.float64)
    rho_tot = rho_u + rho_d

    densinfo_u = ValGrad(value=rho_u)
    densinfo_d = ValGrad(value=rho_d)
    densinfo = SpinParam(u=densinfo_u, d=densinfo_d)
    densinfo_tot = ValGrad(value=rho_tot)

    # calculate the energy and compare with analytic
    edens_unpol = xc.get_edensityxc(densinfo_tot)
    edens_unpol_true = lda_e_true(rho_tot)
    assert torch.allclose(edens_unpol, edens_unpol_true)

    edens_pol = xc.get_edensityxc(densinfo)
    edens_pol_true = 0.5 * (lda_e_true(2 * rho_u) + lda_e_true(2 * rho_d))
    assert torch.allclose(edens_pol, edens_pol_true)

    vxc_unpol = xc.get_vxc(densinfo_tot)
    vxc_unpol_value_true = lda_v_true(rho_tot)
    assert torch.allclose(vxc_unpol.value, vxc_unpol_value_true)

    vxc_pol = xc.get_vxc(densinfo)
    vxc_pol_u_value_true = lda_v_true(2 * rho_u)
    vxc_pol_d_value_true = lda_v_true(2 * rho_d)
    assert torch.allclose(vxc_pol.u.value, vxc_pol_u_value_true)
    assert torch.allclose(vxc_pol.d.value, vxc_pol_d_value_true)
예제 #3
0
파일: test_xc.py 프로젝트: diffqc/dqc
def test_libxc_ldac_value():
    # check if the value of lda_c_pw is consistent
    xc = get_libxc("lda_c_pw")
    assert xc.family == 1
    assert xc.family == 1

    torch.manual_seed(123)
    n = 100
    rho_1 = torch.rand((n,), dtype=torch.float64)
    rho_2 = torch.rand((n,), dtype=torch.float64)
    rho_u = torch.maximum(rho_1, rho_2)
    rho_d = torch.minimum(rho_1, rho_2)
    rho_tot = rho_u + rho_d
    xi = (rho_u - rho_d) / rho_tot

    densinfo_u = ValGrad(value=rho_u)
    densinfo_d = ValGrad(value=rho_d)
    densinfo = SpinParam(u=densinfo_u, d=densinfo_d)
    densinfo_tot = ValGrad(value=rho_tot)

    # calculate the energy and compare with analytic
    edens_unpol = xc.get_edensityxc(densinfo_tot)
    edens_unpol_true = ldac_e_true(rho_tot, rho_tot * 0)
    assert torch.allclose(edens_unpol, edens_unpol_true)

    edens_pol = xc.get_edensityxc(densinfo)
    edens_pol_true = ldac_e_true(rho_tot, xi)
    assert torch.allclose(edens_pol, edens_pol_true)
예제 #4
0
def test_xc_default_vxc(xccls, libxcname):
    # test if the default vxc implementation is correct, compared to libxc

    dtype = torch.float64
    xc = xccls()
    libxc = get_libxc(libxcname)

    torch.manual_seed(123)
    n = 100
    rho_u = torch.rand((n, ), dtype=dtype)
    rho_d = torch.rand((n, ), dtype=dtype)
    rho_tot = rho_u + rho_d
    gradn_u = torch.rand((n, 3), dtype=dtype) * 0
    gradn_d = torch.rand((n, 3), dtype=dtype) * 0
    gradn_tot = gradn_u + gradn_d

    densinfo_u = ValGrad(value=rho_u, grad=gradn_u)
    densinfo_d = ValGrad(value=rho_d, grad=gradn_d)
    densinfo_tot = densinfo_u + densinfo_d
    densinfo = SpinParam(u=densinfo_u, d=densinfo_d)

    def assert_valgrad(vg1, vg2):
        assert torch.allclose(vg1.value, vg2.value)
        assert (vg1.grad is None) == (vg2.grad is None)
        assert (vg1.lapl is None) == (vg2.lapl is None)
        if vg1.grad is not None:
            assert torch.allclose(vg1.grad, vg2.grad)
        if vg1.lapl is not None:
            assert torch.allclose(vg1.lapl, vg2.lapl)

    # check if the energy is the same (implementation check)
    xc_edens_unpol = xc.get_edensityxc(densinfo_tot)
    lxc_edens_unpol = libxc.get_edensityxc(densinfo_tot)
    assert torch.allclose(xc_edens_unpol, lxc_edens_unpol)

    xc_edens_pol = xc.get_edensityxc(densinfo)
    lxc_edens_pol = libxc.get_edensityxc(densinfo)
    assert torch.allclose(xc_edens_pol, lxc_edens_pol)

    # calculate the potential and compare with analytical expression
    xcpotinfo_unpol = xc.get_vxc(densinfo_tot)
    lxcpotinfo_unpol = libxc.get_vxc(densinfo_tot)
    assert_valgrad(xcpotinfo_unpol, lxcpotinfo_unpol)

    xcpotinfo_pol = xc.get_vxc(densinfo)
    lxcpotinfo_pol = libxc.get_vxc(densinfo)
    # print(type(xcpotinfo_pol), type(lxcpotinfo_unpol))
    assert_valgrad(xcpotinfo_pol.u, lxcpotinfo_pol.u)
    assert_valgrad(xcpotinfo_pol.d, lxcpotinfo_pol.d)
예제 #5
0
파일: test_xc.py 프로젝트: diffqc/dqc
def test_libxc_mgga_gradcheck():
    name = "mgga_x_scan"
    xc = get_libxc(name)

    torch.manual_seed(123)
    n = 2
    rho_u = torch.rand((n,), dtype=torch.float64).requires_grad_()
    rho_d = torch.rand((n,), dtype=torch.float64).requires_grad_()
    grad_u = torch.rand((3, n), dtype=torch.float64).requires_grad_()
    grad_d = torch.rand((3, n), dtype=torch.float64).requires_grad_()
    lapl_u = torch.rand((n,), dtype=torch.float64).requires_grad_()
    lapl_d = torch.rand((n,), dtype=torch.float64).requires_grad_()
    tau_w_u = (torch.norm(grad_u, dim=-2) ** 2 / (8 * rho_u)).detach()
    tau_w_d = (torch.norm(grad_d, dim=-2) ** 2 / (8 * rho_d)).detach()
    kin_u = (torch.rand((n,), dtype=torch.float64) + tau_w_u).requires_grad_()
    kin_d = (torch.rand((n,), dtype=torch.float64) + tau_w_d).requires_grad_()

    def get_edens_unpol(xc, rho, grad, lapl, kin):
        densinfo = ValGrad(value=rho, grad=grad, lapl=lapl, kin=kin)
        return xc.get_edensityxc(densinfo)

    def get_vxc_unpol(xc, rho, grad, lapl, kin):
        densinfo = ValGrad(value=rho, grad=grad, lapl=lapl, kin=kin)
        return xc.get_vxc(densinfo).value

    def get_edens_pol(xc, rho_u, rho_d, grad_u, grad_d, lapl_u, lapl_d, kin_u, kin_d):
        densinfo_u = ValGrad(value=rho_u, grad=grad_u, lapl=lapl_u, kin=kin_u)
        densinfo_d = ValGrad(value=rho_d, grad=grad_d, lapl=lapl_d, kin=kin_d)
        return xc.get_edensityxc(SpinParam(u=densinfo_u, d=densinfo_d))

    def get_vxc_pol(xc, rho_u, rho_d, grad_u, grad_d, lapl_u, lapl_d, kin_u, kin_d):
        densinfo_u = ValGrad(value=rho_u, grad=grad_u, lapl=lapl_u, kin=kin_u)
        densinfo_d = ValGrad(value=rho_d, grad=grad_d, lapl=lapl_d, kin=kin_d)
        vxc = xc.get_vxc(SpinParam(u=densinfo_u, d=densinfo_d))
        return vxc.u.value, vxc.d.value

    param_unpol = (xc, rho_u, grad_u, lapl_u, kin_u)
    param_pol   = (xc, rho_u, rho_d, grad_u, grad_d, lapl_u, lapl_d, kin_u, kin_d)

    torch.autograd.gradcheck(get_edens_unpol, param_unpol)
    torch.autograd.gradcheck(get_vxc_unpol, param_unpol)
    torch.autograd.gradgradcheck(get_edens_unpol, param_unpol)
    torch.autograd.gradgradcheck(get_vxc_unpol, param_unpol)

    torch.autograd.gradcheck(get_edens_pol, param_pol)
    torch.autograd.gradcheck(get_vxc_pol, param_pol)
    torch.autograd.gradgradcheck(get_edens_pol, param_pol)
    torch.autograd.gradgradcheck(get_vxc_pol, param_pol)
예제 #6
0
def test_libxc_gga_gradcheck():
    name = "gga_x_pbe"
    xc = get_libxc(name)

    torch.manual_seed(123)
    n = 2
    rho_u = torch.rand((n, ), dtype=torch.float64).requires_grad_()
    rho_d = torch.rand((n, ), dtype=torch.float64).requires_grad_()
    grad_u = torch.rand((n, 3), dtype=torch.float64).requires_grad_()
    grad_d = torch.rand((n, 3), dtype=torch.float64).requires_grad_()

    def get_edens_unpol(xc, rho, grad):
        densinfo = ValGrad(value=rho, grad=grad)
        return xc.get_edensityxc(densinfo)

    def get_vxc_unpol(xc, rho, grad):
        densinfo = ValGrad(value=rho, grad=grad)
        return xc.get_vxc(densinfo).value

    def get_edens_pol(xc, rho_u, rho_d, grad_u, grad_d):
        densinfo_u = ValGrad(value=rho_u, grad=grad_u)
        densinfo_d = ValGrad(value=rho_d, grad=grad_d)
        return xc.get_edensityxc(SpinParam(u=densinfo_u, d=densinfo_d))

    def get_vxc_pol(xc, rho_u, rho_d, grad_u, grad_d):
        densinfo_u = ValGrad(value=rho_u, grad=grad_u)
        densinfo_d = ValGrad(value=rho_d, grad=grad_d)
        vxc = xc.get_vxc(SpinParam(u=densinfo_u, d=densinfo_d))
        return vxc.u.value, vxc.d.value

    param_unpol = (xc, rho_u, grad_u)
    param_pol = (xc, rho_u, rho_d, grad_u, grad_d)

    torch.autograd.gradcheck(get_edens_unpol, param_unpol)
    torch.autograd.gradcheck(get_vxc_unpol, param_unpol)
    torch.autograd.gradgradcheck(get_edens_unpol, param_unpol)
    torch.autograd.gradgradcheck(get_vxc_unpol, param_unpol)

    torch.autograd.gradcheck(get_edens_pol, param_pol)
    torch.autograd.gradcheck(get_vxc_pol, param_pol)
    torch.autograd.gradgradcheck(get_edens_pol, param_pol)
    torch.autograd.gradgradcheck(get_vxc_pol, param_pol)
예제 #7
0
파일: test_xc.py 프로젝트: diffqc/dqc
def test_libxc_mgga_value():
    # compare the calculated value of MGGA potential
    dtype = torch.float64
    xc = get_libxc("mgga_x_scan")
    assert xc.family == 4

    torch.manual_seed(123)
    n = 100
    rho_u = torch.rand((n,), dtype=dtype)
    rho_d = torch.rand((n,), dtype=dtype)
    rho_tot = rho_u + rho_d
    gradn_u = torch.rand((3, n), dtype=dtype) * 0
    gradn_d = torch.rand((3, n), dtype=dtype) * 0
    gradn_tot = gradn_u + gradn_d

    lapl_u = torch.rand((n,), dtype=torch.float64)
    lapl_d = torch.rand((n,), dtype=torch.float64)
    lapl_tot = lapl_u + lapl_d
    tau_w_u = (torch.norm(gradn_u, dim=-2) ** 2 / (8 * rho_u))
    tau_w_d = (torch.norm(gradn_d, dim=-2) ** 2 / (8 * rho_d))
    kin_u = torch.rand((n,), dtype=torch.float64) + tau_w_u
    kin_d = torch.rand((n,), dtype=torch.float64) + tau_w_d
    kin_tot = kin_u + kin_d

    densinfo_u = ValGrad(value=rho_u, grad=gradn_u, lapl=lapl_u, kin=kin_u)
    densinfo_d = ValGrad(value=rho_d, grad=gradn_d, lapl=lapl_d, kin=kin_d)
    densinfo_tot = densinfo_u + densinfo_d
    densinfo = SpinParam(u=densinfo_u, d=densinfo_d)

    # calculate the energy and compare with analytical expression
    edens_unpol = xc.get_edensityxc(densinfo_tot)
    edens_unpol_true = scan_e_true(rho_tot, gradn_tot, lapl_tot, kin_tot)
    assert torch.allclose(edens_unpol, edens_unpol_true)

    edens_pol = xc.get_edensityxc(densinfo)
    edens_pol_true = 0.5 * (scan_e_true(2 * rho_u, 2 * gradn_u, 2 * lapl_u, 2 * kin_u) + \
        scan_e_true(2 * rho_d, 2 * gradn_d, 2 * lapl_d, 2 * kin_d))
    assert torch.allclose(edens_pol, edens_pol_true)