dolfin team mailing list archive
-
dolfin team
-
Mailing list archive
-
Message #10352
Re: Work on a new function.py
On Friday 24 October 2008 10:42:23 Martin Sandve Alnæs wrote:
> 2008/10/23 Johan Hake <hake@xxxxxxxxx>:
> > Hello!
> >
> > I have worked on a "new" function.py. Please have a look. It is built
> > around a metaclass for Functions. It makes it "easy" to create both a)
> > userdefined python functions and b) compiled functions.
> >
> > The work flow is the same for both cases:
> >
> > 1) Define a class
> > 2) Instantiate it with a FunctionSpace, and any user specific arguments
> >
> > With the suggested design a user can define classes a la:
> >
> > class MyCustomFunction(Function):
> > def __init__(self,V,dummy):
> > # Note no call to Function.__init__!
> > self.dummy = dummy
> >
> > def eval(self,val,x):
> > val[0] = 0.5
> > val[1] = 0.5
> >
> > def dim(self):
> > return 2
> >
> > def rank(self):
> > return 1
> >
> > # Can also declare dim and rank as int attributes, see below
> >
> > class MyCustomCompiledFunction(Function):
> > cppcode = "Jada"
> > dim = 1
> > rank = 0
> >
> > They are then instantiated by:
> >
> > mesh = UnitSquare(10,10)
> > element = FiniteElement('Lagrange','triangle',1)
> >
> > print ""
> > V = FunctionSpace(mesh,element)
> >
> > print ""
> > f0 = MyCustomFunction(V,"Dummy")
> >
> > print ""
> > f1 = MyCustomCompiledFunction(V)
> >
> > try:
> > # Cannot instantiate the Function class
> > f2 = Function(V)
> > except Exception, e:
> > print e
> >
> > With this interface only one user defined function can be compiled at a
> > time, but we will gain in similare workflow between pure python and
> > compiled functions.
> >
> > I realize that the C++ design must be in place first before we can
> > advance, but this is a proof of principle, that we can use metaclasses to
> > do nice stuff for the end user.
> >
> > Johan
>
> A possible improvement: deducting dim and rank from cppcode like
> compile_functions does today (can probably just reuse the code).
I had that in mind. But a common error for user defined functions is to not
define the dim and rank, producing nasty errors. My thought was to force the
user to define these, at least in the python interface. Then we can choose to
not force them to be set in the compiled interface, but forcing the user to
do it make the interfaces consistent.
> Also, compile_functions extracts variable names from the strings.
> Then we can do just:
>
> class MyFunc(Function):
> cppcode = ("t*sin(x[0]", "cos(x[1])", "x[0]*x[2]")
>
> f = MyFunc(V)
> f.t = 0.0
That's right. We could also extract them from the cppcode before we send them
to the code compiler, createing an __init__ function on the fly, which the
code already do, so we will get:
class MyFunc(Function):
cppcode = ("t*sin(x[0]", "cos(x[1])", "x[0]*x[2]")
f = MyFunc(V,0.0)
Maybe this would be a bit too magic? This is only possible when the cppcode is
given in the nice tuple representation you already have implemented. This
will be a bit more cumbersome when a whole code segment is handed, but
probaby doable with the right regexp? If not we could add an extra
attribute, 'args' which take a list of strings that are added to the created
__init__ function and then passed to the compiled cpp_function.
> Although the V here is a little too magic for my taste, it does save
> space and looks very nice...
I like it and I am looking forward to se how and if it all wrapps up!
Johan
Follow ups
References