The problem is the automatic estimation of the quadrature degree for your integrals.
Setting:
dx = ufl.Measure(
"dx",
domain=mesh,
subdomain_data=ct,
metadata={"quadrature_degree": 8},
)
you get:
Solved for 16433 dofs. Min, max of the solved potential is -0.11544615271350633, 0.1157284028550102
Solve time without spatial transform: 1.4832050800323486
Solved for 16433 dofs. Min, max of the solved potential is -0.11654400959639583, 0.11686836195473972
Solve time with spatial transform: 1.1220996379852295
This is because the estimated quadrature degree is 62, as you can see with:
from ufl.algorithms.compute_form_data import estimate_total_polynomial_degree
print(
f"{space_transform=} , {estimate_total_polynomial_degree(a)}, {estimate_total_polynomial_degree(L)}"
)
yielding
space_transform=False , 2, 1
Solved for 16433 dofs. Min, max of the solved potential is -0.11544615271350633, 0.1157284028550102
Solve time without spatial transform: 0.6003363132476807
space_transform=True , 62, 1
Solved for 16433 dofs. Min, max of the solved potential is -0.11654400959639583, 0.11686836195473972
Solve time with spatial transform: 0.6055417060852051
You can set it up to about 15 without any huge performance hit, as there are special quadrature rules for such cases, see: basix/cpp/basix/quadrature.cpp at main · FEniCS/basix · GitHub