From 06ba9ac8f9052625b75d1d76766162f5e458f65c Mon Sep 17 00:00:00 2001 From: "James R. Maddison" Date: Fri, 3 Jan 2025 17:46:15 +0000 Subject: [PATCH 1/5] FEniCS backend: Catch some invalid assignments --- tlm_adjoint/fenics/backend_patches.py | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/tlm_adjoint/fenics/backend_patches.py b/tlm_adjoint/fenics/backend_patches.py index 6c1276ce..e2563e1b 100644 --- a/tlm_adjoint/fenics/backend_patches.py +++ b/tlm_adjoint/fenics/backend_patches.py @@ -467,23 +467,15 @@ def Function_assign(self, orig, orig_args, rhs): annotate = annotation_enabled() tlm = tlm_enabled() if isinstance(rhs, backend_Function): - # Prevent a new vector being created + if not space_eq(rhs.function_space(), self.function_space()): + raise ValueError("Invalid assignment") - if space_eq(rhs.function_space(), self.function_space()): - if rhs is not self: - var_assign(self, rhs) - - if annotate or tlm: - eq = Assignment(self, rhs) - assert not eq._pre_process_required - eq._post_process() - else: - value = var_new(self) - orig(value, rhs) - var_assign(self, value) + if rhs is not self: + # Prevent a new vector being created + var_assign(self, rhs) if annotate or tlm: - eq = ExprInterpolation(self, rhs) + eq = Assignment(self, rhs) assert not eq._pre_process_required eq._post_process() else: From 86507d4fa95b4bee4e47a0179533a831055e9676 Mon Sep 17 00:00:00 2001 From: "James R. Maddison" Date: Fri, 3 Jan 2025 17:46:59 +0000 Subject: [PATCH 2/5] error -> error_norm --- tests/firedrake/test_patches.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/firedrake/test_patches.py b/tests/firedrake/test_patches.py index b9e1d911..4fee9e25 100644 --- a/tests/firedrake/test_patches.py +++ b/tests/firedrake/test_patches.py @@ -889,8 +889,8 @@ def forward(b): u_v.setValue(n, 1) u_v.assemblyBegin() u_v.assemblyEnd() - error = abs(assemble(y(u) - b(Function(space_1).interpolate(u)))) - assert error == 0 + error_norm = abs(assemble(y(u) - b(Function(space_1).interpolate(u)))) + assert error_norm == 0 J_val = J.value From fb1a65f839cceaaf221406ba09f034ed22af1dd0 Mon Sep 17 00:00:00 2001 From: "James R. Maddison" Date: Mon, 6 Jan 2025 18:59:12 +0000 Subject: [PATCH 3/5] FEniCS backend: Interpolation updates --- tests/fenics/test_patches.py | 28 ++++++++------------------- tlm_adjoint/fenics/backend_patches.py | 9 ++++++--- tlm_adjoint/fenics/interpolation.py | 5 +---- 3 files changed, 15 insertions(+), 27 deletions(-) diff --git a/tests/fenics/test_patches.py b/tests/fenics/test_patches.py index b3c42723..55f2e396 100644 --- a/tests/fenics/test_patches.py +++ b/tests/fenics/test_patches.py @@ -282,28 +282,16 @@ def forward(m): u.assign(-2.0) u.assign(u + 2.0 * m) - m_ = Function(space, name="m") - assign_fn(m_, m) - m = m_ - del m_ - u_ = Function(space, name="u") - assign_fn(u_, u) + assign_fn(u_, m) u = u_ del u_ - one = Function(space, name="one") - assign_fn(one, Constant(1.0)) - v = Function(space, name="v") assign_fn(v, u) - v.assign(u + one) - assign_fn(v, Constant(0.0)) - v.assign(u + v + one) - v.assign(2.5 * u + 3.6 * v + 4.7 * m) J = Functional(name="J") - J.assign(((v - 1.0) ** 4) * dx) + J.assign(((v - 0.5) ** 4) * dx) return J m = Constant(2.0, name="m") @@ -313,29 +301,29 @@ def forward(m): stop_manager() J_val = J.value - assert abs(J_val - 342974.2096) < 1.0e-9 + assert abs(J_val - 1.5 ** 4) < 1.0e-14 dJ = compute_gradient(J, m) dm = Constant(1.0) min_order = taylor_test(forward, m, J_val=J_val, dJ=dJ, dM=dm) - assert min_order > 1.99 + assert min_order > 2.00 ddJ = Hessian(forward) min_order = taylor_test(forward, m, J_val=J_val, ddJ=ddJ, dM=dm) - assert min_order > 2.99 + assert min_order > 3.00 min_order = taylor_test_tlm(forward, m, tlm_order=1, dMs=(dm,)) - assert min_order > 1.99 + assert min_order > 2.00 min_order = taylor_test_tlm_adjoint(forward, m, adjoint_order=1, dMs=(dm,)) - assert min_order > 1.99 + assert min_order > 2.00 min_order = taylor_test_tlm_adjoint(forward, m, adjoint_order=2, dMs=(dm, dm)) - assert min_order > 1.99 + assert min_order > 2.00 @pytest.mark.fenics diff --git a/tlm_adjoint/fenics/backend_patches.py b/tlm_adjoint/fenics/backend_patches.py index e2563e1b..18faa579 100644 --- a/tlm_adjoint/fenics/backend_patches.py +++ b/tlm_adjoint/fenics/backend_patches.py @@ -482,9 +482,12 @@ def Function_assign(self, orig, orig_args, rhs): orig_args() if annotate or tlm: - eq = ExprInterpolation(self, expr_new_x(rhs, self)) - assert not eq._pre_process_required - eq._post_process() + if isinstance(rhs, backend_Constant): + eq = ExprInterpolation(self, rhs) + assert not eq._pre_process_required + eq._post_process() + else: + raise NotImplementedError("Case not implemented") @manager_method(backend_Function, "copy", patch_without_manager=True) diff --git a/tlm_adjoint/fenics/interpolation.py b/tlm_adjoint/fenics/interpolation.py index 10ec130f..51afbc18 100644 --- a/tlm_adjoint/fenics/interpolation.py +++ b/tlm_adjoint/fenics/interpolation.py @@ -56,10 +56,7 @@ def value_shape(self): value, = value var_assign(x, value) elif isinstance(x, backend_Function): - try: - x.assign(expr) - except RuntimeError: - x.interpolate(Expr()) + x.interpolate(Expr()) else: raise TypeError(f"Unexpected type: {type(x)}") else: From f8912b726758759913e7f55a617cd609f870d983 Mon Sep 17 00:00:00 2001 From: "James R. Maddison" Date: Tue, 7 Jan 2025 12:30:45 +0000 Subject: [PATCH 4/5] FEniCS/Firedrake backends: Set directions in test_Storage --- tests/fenics/test_equations.py | 30 ++++++++++++++++++++--------- tests/firedrake/test_equations.py | 32 +++++++++++++++++++++---------- 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/tests/fenics/test_equations.py b/tests/fenics/test_equations.py index 690875a8..120f8866 100644 --- a/tests/fenics/test_equations.py +++ b/tests/fenics/test_equations.py @@ -490,22 +490,34 @@ def forward_J(x): dJ = compute_gradient(J, x) - min_order = taylor_test(forward_J, x, J_val=J_val, dJ=dJ, seed=1.0e-3) - assert min_order > 1.99 + dMs = tuple(var_new(x) for _ in range(2)) + for i, dm in enumerate(dMs): + if complex_mode: + interpolate_expression( + dm, cos((i + 1) * pi * X[0]) * exp(1.0j * X[0] + X[1])) + else: + interpolate_expression( + dm, cos((i + 1) * pi * X[0]) * exp(X[1])) + + min_order = taylor_test(forward_J, x, J_val=J_val, dJ=dJ, seed=1.0e-2, + dM=dMs[0]) + assert min_order > 2.00 ddJ = Hessian(forward_J) - min_order = taylor_test(forward_J, x, J_val=J_val, ddJ=ddJ, seed=1.0e-3) - assert min_order > 2.98 + min_order = taylor_test(forward_J, x, J_val=J_val, ddJ=ddJ, seed=1.0e-2, + dM=dMs[0]) + assert min_order > 3.00 - min_order = taylor_test_tlm(forward_J, x, tlm_order=1, seed=1.0e-3) - assert min_order > 1.99 + min_order = taylor_test_tlm(forward_J, x, tlm_order=1, seed=1.0e-3, + dMs=dMs[:1]) + assert min_order > 2.00 min_order = taylor_test_tlm_adjoint(forward_J, x, adjoint_order=1, - seed=1.0e-3) - assert min_order > 1.99 + seed=1.0e-3, dMs=dMs[:1]) + assert min_order > 2.00 min_order = taylor_test_tlm_adjoint(forward_J, x, adjoint_order=2, - seed=1.0e-3) + seed=1.0e-3, dMs=dMs) assert min_order > 1.99 h.close() diff --git a/tests/firedrake/test_equations.py b/tests/firedrake/test_equations.py index 811cd55e..b8df58c3 100644 --- a/tests/firedrake/test_equations.py +++ b/tests/firedrake/test_equations.py @@ -813,23 +813,35 @@ def forward_J(x): dJ = compute_gradient(J, x) - min_order = taylor_test(forward_J, x, J_val=J_val, dJ=dJ, seed=1.0e-3) - assert min_order > 1.99 + dMs = tuple(var_new(x) for _ in range(2)) + for i, dm in enumerate(dMs): + if complex_mode: + interpolate_expression( + dm, cos((i + 1) * pi * X[0]) * exp(1.0j * X[0] + X[1])) + else: + interpolate_expression( + dm, cos((i + 1) * pi * X[0]) * exp(X[1])) + + min_order = taylor_test(forward_J, x, J_val=J_val, dJ=dJ, seed=1.0e-2, + dM=dMs[0]) + assert min_order > 2.00 ddJ = Hessian(forward_J) - min_order = taylor_test(forward_J, x, J_val=J_val, ddJ=ddJ, seed=1.0e-3) - assert min_order > 2.98 + min_order = taylor_test(forward_J, x, J_val=J_val, ddJ=ddJ, seed=1.0e-2, + dM=dMs[0]) + assert min_order > 2.99 - min_order = taylor_test_tlm(forward_J, x, tlm_order=1, seed=1.0e-3) - assert min_order > 1.99 + min_order = taylor_test_tlm(forward_J, x, tlm_order=1, seed=1.0e-3, + dMs=dMs[:1]) + assert min_order > 2.00 min_order = taylor_test_tlm_adjoint(forward_J, x, adjoint_order=1, - seed=1.0e-3) - assert min_order > 1.99 + seed=1.0e-3, dMs=dMs[:1]) + assert min_order > 2.00 min_order = taylor_test_tlm_adjoint(forward_J, x, adjoint_order=2, - seed=1.0e-3) - assert min_order > 1.98 + seed=1.0e-3, dMs=dMs) + assert min_order > 2.00 h.close() From fa45fec5b66b201539736b8d16b260d1eaf5681b Mon Sep 17 00:00:00 2001 From: "James R. Maddison" Date: Tue, 7 Jan 2025 15:23:33 +0000 Subject: [PATCH 5/5] Weaken a test tolerance --- tests/firedrake/test_equations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/firedrake/test_equations.py b/tests/firedrake/test_equations.py index b8df58c3..24d9c9d4 100644 --- a/tests/firedrake/test_equations.py +++ b/tests/firedrake/test_equations.py @@ -1165,7 +1165,7 @@ def forward(m): ddJ = Hessian(forward) min_order = taylor_test(forward, m, J_val=J_val, ddJ=ddJ, seed=1.0e-3, dM=dm) - assert min_order > 2.97 + assert min_order > 2.96 min_order = taylor_test_tlm(forward, m, tlm_order=1, seed=1.0e-4, dMs=(dm,))