@@ -645,3 +645,53 @@ def test_prism(compile_args):
645
645
ffi .cast ('double *' , coords .ctypes .data ), ffi .NULL , ffi .NULL )
646
646
647
647
assert np .isclose (sum (b ), 0.5 )
648
+
649
+
650
+ def test_complex_operations (compile_args ):
651
+ mode = "double _Complex"
652
+ cell = ufl .triangle
653
+ c_element = ufl .VectorElement ("Lagrange" , cell , 1 )
654
+ mesh = ufl .Mesh (c_element )
655
+ element = ufl .VectorElement ("DG" , cell , 0 )
656
+ V = ufl .FunctionSpace (mesh , element )
657
+ u = ufl .Coefficient (V )
658
+ J1 = ufl .real (u )[0 ] * ufl .imag (u )[1 ] * ufl .conj (u )[0 ] * ufl .dx
659
+ J2 = ufl .real (u [0 ]) * ufl .imag (u [1 ]) * ufl .conj (u [0 ]) * ufl .dx
660
+ forms = [J1 , J2 ]
661
+
662
+ compiled_forms , module , code = ffcx .codegeneration .jit .compile_forms (
663
+ forms , parameters = {'scalar_type' : mode }, cffi_extra_compile_args = compile_args )
664
+
665
+ form0 = compiled_forms [0 ].integrals (module .lib .cell )[0 ]
666
+ form1 = compiled_forms [1 ].integrals (module .lib .cell )[0 ]
667
+
668
+ ffi = module .ffi
669
+ np_type = cdtype_to_numpy (mode )
670
+ w1 = np .array ([3 + 5j , 8 - 7j ], dtype = np_type )
671
+ c = np .array ([], dtype = np_type )
672
+
673
+ coords = np .array ([[0.0 , 0.0 , 0.0 ],
674
+ [1.0 , 0.0 , 0.0 ],
675
+ [0.0 , 1.0 , 0.0 ]], dtype = np .float64 )
676
+ J_1 = np .zeros ((1 ), dtype = np_type )
677
+ kernel0 = ffi .cast (f"ufcx_tabulate_tensor_{ np_type } *" , getattr (form0 , f"tabulate_tensor_{ np_type } " ))
678
+ kernel0 (ffi .cast ('{type} *' .format (type = mode ), J_1 .ctypes .data ),
679
+ ffi .cast ('{type} *' .format (type = mode ), w1 .ctypes .data ),
680
+ ffi .cast ('{type} *' .format (type = mode ), c .ctypes .data ),
681
+ ffi .cast ('double *' , coords .ctypes .data ), ffi .NULL , ffi .NULL )
682
+
683
+ expected_result = np .array ([0.5 * np .real (w1 [0 ]) * np .imag (w1 [1 ])
684
+ * (np .real (w1 [0 ]) - 1j * np .imag (w1 [0 ]))], dtype = np_type )
685
+ assert np .allclose (J_1 , expected_result )
686
+
687
+ J_2 = np .zeros ((1 ), dtype = np_type )
688
+
689
+ kernel1 = ffi .cast (f"ufcx_tabulate_tensor_{ np_type } *" , getattr (form1 , f"tabulate_tensor_{ np_type } " ))
690
+ kernel1 (ffi .cast ('{type} *' .format (type = mode ), J_2 .ctypes .data ),
691
+ ffi .cast ('{type} *' .format (type = mode ), w1 .ctypes .data ),
692
+ ffi .cast ('{type} *' .format (type = mode ), c .ctypes .data ),
693
+ ffi .cast ('double *' , coords .ctypes .data ), ffi .NULL , ffi .NULL )
694
+
695
+ assert np .allclose (J_2 , expected_result )
696
+
697
+ assert np .allclose (J_1 , J_2 )
0 commit comments