Initial commit. Stage one work done.
This commit is contained in:
84
tests/test_api.py
Normal file
84
tests/test_api.py
Normal file
@@ -0,0 +1,84 @@
|
||||
"""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
|
||||
Reference in New Issue
Block a user