Open ReubenHill opened 1 year ago
All elements on extruded meshes need to be tensor product elements (or else special). You don't realise this because UFL does some magic for P
, DQ
, etc...:
In [11]: FunctionSpace(m, "Real", 0).ufl_element()
Out[11]: FiniteElement('Real', TensorProductCell(triangle, interval), 0)
In [12]: FunctionSpace(m, "P", 1).ufl_element()
Out[12]: TensorProductElement(FiniteElement('Lagrange', triangle, 1), FiniteElement('Lagrange', interval, 1), TensorProductCell(triangle, interval)) # Not Finiteelement('P', TensorProductCell(triangle, interval), 1)
However it doesn't do the magic for Real
(see __new__
in ufl.FiniteElement
).
So what happens is that tsfc just falls through to normal fiat conversions and produces a P0
elements with a tensor product cell (ref_el.shape == 99), and things break.
You might think the workaround should be:
from firedrake import *
m = ExtrudedMesh(UnitSquareMesh(1, 1), 1)
V = FunctionSpace(m, TensorProductElement(FiniteElement("Real", triangle, 0), FiniteElement("Real", interval, 0)))
v = interpolate(Constant(1.0), V)
But this doesn't work because it defeat's Firedrake's detection of the element as a real element (so it's just treated as DG0). (This should probably be fixed, if so, then you can update the UFL magic), otherwise you'll need to handle this case in tsfc's finatinterface, perhaps like this?
diff --git a/tsfc/finatinterface.py b/tsfc/finatinterface.py
index 0c8b211..b1b072d 100644
--- a/tsfc/finatinterface.py
+++ b/tsfc/finatinterface.py
@@ -122,6 +122,12 @@ def convert_finiteelement(element, **kwargs):
if element.family() == "Real" and element.cell().cellname() in {"quadrilateral", "hexahedron"}:
lmbda = None
element = ufl.FiniteElement("DQ", element.cell(), 0)
+ elif element.family() == "Real" and isinstance(element.cell(), ufl.TensorProductCell):
+ element = ufl.TensorProductElement(
+ *(ufl.FiniteElement("Real", cell, 0) for cell in element.cell().sub_cells()),
+ cell=element.cell(),
+ )
+ return _create_element(element, **kwargs)
if lmbda is None:
if element.cell().cellname() == "quadrilateral":
# Handle quadrilateral short names like RTCF and RTCE.
MFE:
fails with traceback
In this function
For some reason
ref_el.get_shape()
reports99
but I'm not sure where that number is coming from. The number99
does not change if I change toExtrudedMesh(UnitSquareMesh(2, 3), 15)
nor if I switch toConstant(2.0, domain=m)
. It looks like the conversion of the UFL element to a FInAT one is not working as expected. I wonder if a further MFE can be found which specifically does that?