85 lines
2.6 KiB
Python
85 lines
2.6 KiB
Python
"""API surface tests: registry integrity and the pylibxc-compatible shim."""
|
|
|
|
import numpy as np
|
|
import pytest
|
|
|
|
import funxc
|
|
from funxc.libxc_compat import LibXCFunctional
|
|
|
|
|
|
def test_registry_specs_wellformed():
|
|
for fid, spec in funxc.REGISTRY.items():
|
|
assert spec.id == fid
|
|
assert spec.family in ("lda", "gga", "mgga")
|
|
assert spec.kind in ("x", "c", "xc", "k")
|
|
assert spec.libxc_id > 0
|
|
assert spec.kernel_fn is not None
|
|
assert spec.doi
|
|
|
|
|
|
def test_get_spec_is_case_insensitive():
|
|
assert funxc.get_spec("gga_x_pbe") is funxc.get_spec("GGA_X_PBE")
|
|
assert funxc.get_spec("XC_GGA_X_PBE") is funxc.get_spec("GGA_X_PBE")
|
|
with pytest.raises(KeyError):
|
|
funxc.get_spec("GGA_X_DOES_NOT_EXIST")
|
|
|
|
|
|
def test_shim_polarized_shapes():
|
|
f = LibXCFunctional("gga_x_pbe", "polarized")
|
|
n = 4
|
|
rng = np.random.default_rng(0)
|
|
inp = {
|
|
"rho": rng.uniform(0.1, 1.0, (n, 2)),
|
|
"sigma": rng.uniform(0.0, 0.5, (n, 3)),
|
|
}
|
|
out = f.compute(inp)
|
|
assert out["zk"].shape == (n, 1)
|
|
assert out["vrho"].shape == (n, 2)
|
|
assert out["vsigma"].shape == (n, 3)
|
|
|
|
|
|
def test_shim_unpolarized_shapes_and_flat_input():
|
|
f = LibXCFunctional("lda_x", 1)
|
|
rho = np.linspace(0.1, 2.0, 5)
|
|
out = f.compute({"rho": rho})
|
|
assert out["zk"].shape == (5, 1)
|
|
assert out["vrho"].shape == (5, 1)
|
|
out_exc_only = f.compute({"rho": rho}, do_vxc=False)
|
|
assert set(out_exc_only) == {"zk"}
|
|
|
|
|
|
def test_shim_mgga_shapes():
|
|
f = LibXCFunctional("mgga_x_lta", "polarized")
|
|
n = 4
|
|
rng = np.random.default_rng(1)
|
|
inp = {
|
|
"rho": rng.uniform(0.1, 1.0, (n, 2)),
|
|
"sigma": rng.uniform(0.0, 0.5, (n, 3)),
|
|
"lapl": rng.uniform(-1.0, 1.0, (n, 2)),
|
|
"tau": rng.uniform(0.1, 1.0, (n, 2)),
|
|
}
|
|
out = f.compute(inp)
|
|
assert out["zk"].shape == (n, 1)
|
|
assert out["vrho"].shape == (n, 2)
|
|
assert out["vsigma"].shape == (n, 3)
|
|
assert out["vlapl"].shape == (n, 2)
|
|
assert out["vtau"].shape == (n, 2)
|
|
# LTA has no lapl dependence: vlapl must be exactly zero
|
|
assert np.all(out["vlapl"] == 0.0)
|
|
|
|
|
|
def test_shim_metadata():
|
|
f = LibXCFunctional("gga_c_lyp", "polarized")
|
|
assert f.get_number() == 131
|
|
assert f.get_family() == "gga"
|
|
|
|
|
|
def test_composition_blyp():
|
|
"""X and C functionals compose additively (BLYP = B88 + LYP)."""
|
|
rho = np.array([[0.4, 0.3]])
|
|
sigma = np.array([[0.02, 0.01, 0.015]])
|
|
b88 = funxc.functional("GGA_X_B88").exc(rho, sigma)
|
|
lyp = funxc.functional("GGA_C_LYP").exc(rho, sigma)
|
|
total = np.asarray(b88) + np.asarray(lyp)
|
|
assert np.all(np.isfinite(total)) and total[0] < 0
|