From b9ba63b98835b06364e57b96ecee6f9254dec93b Mon Sep 17 00:00:00 2001 From: Angus Gibson Date: Mon, 22 Sep 2025 23:11:14 +1000 Subject: [PATCH 1/2] Run some optimisation tests with ROL Requires pyroltrilinos in the ci dependency set --- pyproject.toml | 1 + tests/firedrake/adjoint/test_optimisation.py | 76 ++++++++++++++++++-- 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 05956ff841..29d7fe2657 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -111,6 +111,7 @@ ci = [ "pdf2image", "pygraphviz", "pylit", + "pyroltrilinos", "pytest", "pytest-split", # needed for firedrake-run-split-tests "pytest-timeout", diff --git a/tests/firedrake/adjoint/test_optimisation.py b/tests/firedrake/adjoint/test_optimisation.py index 2189a7882b..33892b534b 100644 --- a/tests/firedrake/adjoint/test_optimisation.py +++ b/tests/firedrake/adjoint/test_optimisation.py @@ -90,9 +90,35 @@ def minimize_tao_nls(rf): return solver.solve() +def minimize_rol(rf): + problem = MinimizationProblem(rf) + params = { + "General": { + "Krylov": { + "Absolute Tolerance": 1e-5, + }, + "Secant": { + "Type": "Limited-Memory BFGS", + "Maximum Storage": 10, + "Use as Hessian": True, + }, + }, + "Step": { + "Type": "Trust Region", + }, + "Status Test": { + "Relative Gradient Tolerance": 0.0, + "Gradient Tolerance": 1e-6, + }, + } + solver = ROLSolver(problem, params, inner_product="L2") + return solver.solve() + + @pytest.mark.parametrize("minimize", [minimize, minimize_tao_lmvm, - minimize_tao_nls]) + minimize_tao_nls, + minimize_rol]) @pytest.mark.skipcomplex def test_optimisation_constant_control(minimize): """This tests a list of controls in a minimisation""" @@ -152,11 +178,12 @@ def test_simple_inversion(riesz_representation): @pytest.mark.parametrize("minimize", [minimize_tao_lmvm, - minimize_tao_nls]) + minimize_tao_nls, + minimize_rol]) @pytest.mark.parametrize("riesz_representation", [None, "l2", "L2", "H1"]) @pytest.mark.skipcomplex -def test_tao_simple_inversion(minimize, riesz_representation): - """Test inversion of source term in helmholtz eqn using TAO.""" +def test_external_simple_inversion(minimize, riesz_representation): + """Test inversion of source term in helmholtz eqn using external optimisation packages.""" mesh = UnitIntervalMesh(10) V = FunctionSpace(mesh, "CG", 1) source_ref = Function(V) @@ -368,3 +395,44 @@ def test_tao_bounds(): u_ref_bound = u_ref.copy(deepcopy=True) u_ref_bound.dat.data[:] = np.maximum(u_ref_bound.dat.data_ro, lb) assert_allclose(u_opt.dat.data_ro, u_ref_bound.dat.data_ro, rtol=1.0e-2) + + +@pytest.mark.skipcomplex +def test_rol_bounds(): + mesh = UnitIntervalMesh(11) + X = SpatialCoordinate(mesh) + space = FunctionSpace(mesh, "Lagrange", 1) + u = Function(space, name="u") + u_ref = Function(space, name="u_ref").interpolate(0.5 - X[0]) + + J = assemble((u - u_ref) ** 2 * dx) + rf = ReducedFunctional(J, Control(u)) + + lb = 0.5 - 7.0 / 11.0 + ub = 10.0 # ROL doesn't support None as bounds + problem = MinimizationProblem(rf, bounds=(lb, ub)) + params = { + "General": { + "Krylov": { + "Absolute Tolerance": 1e-7, + }, + "Secant": { + "Type": "Limited-Memory BFGS", + "Maximum Storage": 10, + "Use as Hessian": True, + }, + }, + "Step": { + "Type": "Trust Region", + }, + "Status Test": { + "Relative Gradient Tolerance": 0.0, + "Gradient Tolerance": 0.0, + }, + } + solver = ROLSolver(problem, params, inner_product="L2") + u_opt = solver.solve() + + u_ref_bound = u_ref.copy(deepcopy=True) + u_ref_bound.dat.data[:] = np.maximum(u_ref_bound.dat.data_ro, lb) + assert_allclose(u_opt.dat.data_ro, u_ref_bound.dat.data_ro, rtol=1.0e-2) From 270172cd507c6c64e57618ee596e0f5a3c33b0a1 Mon Sep 17 00:00:00 2001 From: Angus Gibson Date: Fri, 10 Oct 2025 09:35:30 +1100 Subject: [PATCH 2/2] tmp! use pyadjoint master Needed until the ROL changes land in pyadjoint 2025.10.1 (presumably) --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 29d7fe2657..04794f6750 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ dependencies = [ "petsctools", "pkgconfig", "progress", - "pyadjoint-ad>=2025.10.0", + "pyadjoint-ad @ git+https://github.com/dolfin-adjoint/pyadjoint.git@master", "pycparser", "pytools[siphash]", "requests",