diff --git a/pyproject.toml b/pyproject.toml index 34feb03f8cf3487250b55348ba749e47e1cb36ee..c15ef858b2d71cb0384ee75ad9b7a9372cb9f817 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,8 @@ dependencies = [ [project.optional-dependencies] test = [ - 'pytest >= 6' + 'pytest >= 6', + 'numdifftools >= 0.9', ] [tool.pytest.ini_options] diff --git a/tests/test_basic.py b/tests/test_basic.py index 0bd391e40cc79167b46d81876af45034fa5a0631..3ef1d58eb240159047061baae62e5da317f83a5b 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -5,6 +5,11 @@ import numpy as np from numpy.testing import assert_allclose from scipy.linalg import expm +try: + import numdifftools +except ImportError: + numdifftools = None + import usadelndsoc import usadelndsoc.solver @@ -157,18 +162,26 @@ def test_gauge_invariance(): div_J_y = J[1] - J[3] div_J = div_J_x + div_J_y + print("->", div_J) + # Compute source term (numdiff) - Sa = s._core.eval(Phi) + def S_s(ds): + Phi2 = Phi.copy() + dW = expm(ds * t3) + idW = np.linalg.inv(dW) + Phi2[i, j, 0] = dW[:2, :2] @ Phi[i, j, 0] @ idW[2:, 2:] + Phi2[i, j, 1] = dW[2:, 2:] @ Phi[i, j, 1] @ idW[:2, :2] + return s._core.eval(Phi2) - Phi2 = Phi.copy() ds = 1e-7 - dW = expm(ds * t3) - idW = np.linalg.inv(dW) - Phi2[i, j, 0] = dW[:2, :2] @ Phi[i, j, 0] @ idW[2:, 2:] - Phi2[i, j, 1] = dW[2:, 2:] @ Phi[i, j, 1] @ idW[:2, :2] - - Sb = s._core.eval(Phi2) - dS_ds = (Sb - Sa) / ds / 16 + dS_ds = (S_s(ds) - S_s(0)) / ds / 16 # They must match assert_allclose(div_J, dS_ds, rtol=1e-6) + + if numdifftools is not None: + # More accurate numdiff: the equality should hold to high + # numerical accuracy + D = numdifftools.Derivative(S_s) + dS_ds = D(0.0) / 16 + assert_allclose(div_J, dS_ds, rtol=1e-12)