Customized Expression class example does not work
I tried to run the customized Expression example in the dolfin documentation (last code example in https://fenicsproject.org/documentation/dolfin/dev/python/programmers-reference/functions/expression/Expression.html)
A slightly simplified version of this script is:
from fenics import *
mesh = UnitIntervalMesh(10)
class MyExpression1(Expression):
def __init__(self, mesh):
self._mesh = mesh
def eval(self, values, x):
pass
MyExpression1(degree=0, mesh=mesh)
However, when running this example on dolfin master, one gets:
git:master$ python test.py
Traceback (most recent call last):
File "test.py", line 10, in <module>
MyExpression1(degree=0, mesh=mesh)
File "/home/simon/src/fenics_master/dolfin_master/local.master/lib/python2.7/site-packages/dolfin/functions/expression.py", line 282, in __init__
user_init(self, *args, **kwargs)
TypeError: __init__() got an unexpected keyword argument 'degree'
Aborted (core dumped)
Comments (10)
-
-
reporter Yes, I was referring to the documentation. In other words, the documentation should be updated to:
from fenics import * mesh = UnitIntervalMesh(10) class MyExpression1(Expression): def __init__(self, **kwargs): self._mesh = kwargs["mesh"] def eval(self, values, x): pass MyExpression1(degree=0, mesh=mesh)
Ill make a pull request
-
Well, your proposed alternative might work, but is super misleading.
kwargs
is never used, so the parametersdegree=0
andmesh=mesh
are thrown away, never used, and the constructor of the super class is never called.self._mesh = mesh
will still work though, because it picks up the global variablemesh = UnitIntervalMesh(10)
. -
Not sure whether it changed recently, but
Expression.__init__(self, *foo, **bar)
did not use to work from Expression subclass. (I made it an error to avoid confusion.) There is (or at least was) a lot of metaclass magic and utilization of new and unused kwargs in Simon's example might be actually used there. -
That's actually not true. But there's some magic to it, and you cannot call the base class
__init__
because of this magic. See documentation ofExpression
:The user can customize initialization of derived Expressions. However, because of magic behind the scenes, a user needs to pass optional arguments to __init__ using ``**kwargs``, and _not_ calling the base class __init__:
If you check out
m=MyExpression1(degree=0, mesh=mesh)
andm.element
you will see that it'sMyExpression1.element of Coefficient(FunctionSpace(None, FiniteElement('Discontinuous Lagrange', None, 0)), 2)
. Try sending in degree=2. -
reporter Sorry, my previous implementation is clearly wrong. It is fixed now.
-
On the other hand I agree that the current state is confusing. But there does not seem to be an obvious fix.
-
Yes, @mikael_mortensen expressed it clearly.
-
The other issue is that failing MWE from the description fails with TypeError: init() got an unexpected keyword argument 'degree' rather than expression without element or degree are illega`.EDIT: Sorry, I can't read.
-
- changed status to resolved
Fixed by pull request #305.
- Log in to comment
The
__init__
method of yourMyExpression1
class clearly does not expect adegree
argument. Did you mean to writeand then
MyExpression1(mesh=mesh, degree=0)
?Edit: ah, you probably mean that the documentation is wrong...