UserExpression breaks if __init__ is given and super().__init__() is not called
From the Expression documentation, section 3, it looks like one can pass arguments to the UserExpression
subclass through __init__
, which may then store it as class attribute so that eval
can use it. This is not the case. Attempting to do so results in an error message like AttributeError: 'P_class' object has no attribute '_ufl_shape'
.
The issue is that if one provides a __init__
, then he also needs to call super().__init__()
.
There are a bunch of fixes by @Chris Richardson on the matter (9732cf9, e6c15db), which would make calling super().__init__()
not needed, but it looks like they have never been merged. I guess we can either merge those commits, or update the documentation pointing out that calling the base constructor is needed (docs need updating after #883 anyway).
A minimal (non-)working example:
from fenics import *
test_mode = 2
# 1 does not work
# 2 works
mesh = UnitIntervalMesh(10)
V = FunctionSpace(mesh, 'Lagrange', 2)
u = TrialFunction(V)
v = TestFunction(V)
sol = Function(V)
def f(x):
return x**2
if test_mode == 1:
class P_class(UserExpression):
def __init__(self, f):
self._f = f
def eval(self, value, x):
value = self._f(x)
P = P_class(f=f)
elif test_mode == 2:
class P_class(UserExpression):
def __init__(self, f):
self._f = f
super().__init__()
def eval(self, value, x):
value = self._f(x)
P = P_class(f=f)
a = u * v * dx
L = P * v * dx
bcs = DirichletBC(V, 0, 'near(x[0], 1)')
solve(a == L, sol, bcs=bcs)
Comments (1)
-
reporter - Log in to comment