From 4e43d9fe212bce90d9da3ccb208e006671105abd Mon Sep 17 00:00:00 2001 From: Florian Rathgeber Date: Tue, 8 Apr 2014 18:50:45 +0100 Subject: [PATCH 1/3] Stash computed form on tensor for re-assembly When passing in a tensor to assemble, stash the form and computed kernels on the tensor such that if we reassemble the same form on the same tensor we save having to preprocess/split the form again. --- firedrake/solving.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/firedrake/solving.py b/firedrake/solving.py index 8a86ac96b1..62c32c1a7a 100644 --- a/firedrake/solving.py +++ b/firedrake/solving.py @@ -382,7 +382,17 @@ def _assemble(f, tensor=None, bcs=None): """ - kernels = compile_form(f, "form") + # We stash the form and kernels on the tensor if we reassemble for an + # existing tensor, to save having to compile the form again if identical + # Note that forms override == to construct an equation, so we have to + # explicitly test for object identity + if getattr(tensor, "_form", None) is f and hasattr(tensor, "_kernels"): + kernels = tensor._kernels + else: + kernels = compile_form(f, "form") + if tensor: + tensor._form = f + tensor._kernels = kernels fd = f.form_data() From 275671906283fa0a570b87261987adaa9541220f Mon Sep 17 00:00:00 2001 From: Florian Rathgeber Date: Tue, 8 Apr 2014 21:55:38 +0100 Subject: [PATCH 2/3] Add test assembling different forms into the same Function --- tests/regression/test_assemble.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/regression/test_assemble.py b/tests/regression/test_assemble.py index 8cac2b4e7a..192334904a 100644 --- a/tests/regression/test_assemble.py +++ b/tests/regression/test_assemble.py @@ -66,6 +66,18 @@ def test_zero_form(M, f, one): assert isinstance(zero_form, float) assert abs(zero_form - 0.5 * np.prod(f.shape())) < 1.0e-12 + +def test_assemble_with_tensor(cg1): + v = TestFunction(cg1) + L = v*dx + f = Function(cg1) + # Assemble a form into f + f = assemble(L, f) + # Assemble a different form into f + f = assemble(Constant(2)*L, f) + # Make sure we get the result of the last assembly + assert np.allclose(f.dat.data, 2*assemble(L).dat.data, rtol=1e-14) + if __name__ == '__main__': import os pytest.main(os.path.abspath(__file__)) From 856e76b211b7369d2dca5310a07807ffd4c38e1e Mon Sep 17 00:00:00 2001 From: Florian Rathgeber Date: Tue, 8 Apr 2014 21:55:49 +0100 Subject: [PATCH 3/3] Add test assembling different forms into the same Matrix --- tests/regression/test_assemble.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/regression/test_assemble.py b/tests/regression/test_assemble.py index 192334904a..0ca9e191bb 100644 --- a/tests/regression/test_assemble.py +++ b/tests/regression/test_assemble.py @@ -78,6 +78,17 @@ def test_assemble_with_tensor(cg1): # Make sure we get the result of the last assembly assert np.allclose(f.dat.data, 2*assemble(L).dat.data, rtol=1e-14) + +def test_assemble_mat_with_tensor(dg0): + u = TestFunction(dg0) + v = TrialFunction(dg0) + a = u*v*dx + M = assemble(a) + # Assemble a different form into M + M = assemble(Constant(2)*a, M) + # Make sure we get the result of the last assembly + assert np.allclose(M.M.values, 2*assemble(a).M.values, rtol=1e-14) + if __name__ == '__main__': import os pytest.main(os.path.abspath(__file__))