55 Argument ,
66 Coefficient ,
77 Cofunction ,
8+ Adjoint ,
89 Form ,
910 FormProduct ,
1011 FormSum ,
1112 FunctionSpace ,
13+ Matrix ,
1214 Mesh ,
1315 SpatialCoordinate ,
1416 TestFunction ,
@@ -240,6 +242,16 @@ def test_form_product_constructor_and_arguments(domain):
240242 assert tuple (argument .number () for argument in nested .arguments ()) == (0 , 1 , 2 )
241243
242244
245+ def test_form_product_of_one_factor_simplifies (domain ):
246+ element = LagrangeElement (triangle , 1 )
247+ V = FunctionSpace (domain , element )
248+ v = TestFunction (V )
249+ f = Coefficient (V )
250+ L = f * v * dx
251+
252+ assert FormProduct (L ) is L
253+
254+
243255def test_form_product_rejects_invalid_inputs (domain ):
244256 element = LagrangeElement (triangle , 1 )
245257 V = FunctionSpace (domain , element )
@@ -248,7 +260,9 @@ def test_form_product_rejects_invalid_inputs(domain):
248260 L = f * v * dx
249261
250262 with pytest .raises (ValueError ):
251- FormProduct (L )
263+ FormProduct ()
264+ with pytest .raises (TypeError ):
265+ FormProduct (1 )
252266 with pytest .raises (TypeError ):
253267 FormProduct (L , 1 )
254268
@@ -266,6 +280,38 @@ def test_form_product_is_explicit_not_mul_overload(domain):
266280 Lf * Lg
267281
268282
283+ def test_adjoint_form_product_reverses_adjoint_factors (domain ):
284+ element = LagrangeElement (triangle , 1 )
285+ V = FunctionSpace (domain , element )
286+ A = Matrix (V , V )
287+ B = Matrix (V , V )
288+ C = Matrix (V , V )
289+
290+ product = FormProduct (A , B , C )
291+ adjoint_product = Adjoint (product )
292+
293+ assert isinstance (adjoint_product , FormProduct )
294+ assert tuple (factor .form () for factor in adjoint_product .factors ()) == (C , B , A )
295+ assert adjoint_product .factors () == (Adjoint (C ), Adjoint (B ), Adjoint (A ))
296+
297+
298+ def test_adjoint_form_product_leaves_rank_zero_and_one_factors_unadjointed (domain ):
299+ element = LagrangeElement (triangle , 1 )
300+ V = FunctionSpace (domain , element )
301+ v = TestFunction (V )
302+ f = Coefficient (V )
303+ functional = f * dx
304+ linear = f * v * dx
305+ A = Matrix (V , V )
306+
307+ product = FormProduct (functional , linear , A )
308+ adjoint_product = Adjoint (product )
309+
310+ assert isinstance (adjoint_product , FormProduct )
311+ assert adjoint_product .factors () == (Adjoint (A ), linear , functional )
312+ assert Adjoint (FormProduct (functional , linear )).factors () == (linear , functional )
313+
314+
269315def test_form_product_replace (domain ):
270316 element = LagrangeElement (triangle , 1 )
271317 V = FunctionSpace (domain , element )
0 commit comments