← Back to team overview

dolfin team mailing list archive

Re: PyDOLFIN interface

 

On Tuesday 04 November 2008 13:07:07 Martin Sandve Alnæs wrote:
> 2008/11/4 Johan Hake <hake@xxxxxxxxx>:
> > Hello!
> >
> > I have started the work on the PyDOLFIN. We can now define the forms in
> > the poisson demo, using the syntax previously discussed, see python
> > poisson demo.
> >
> > A FunctionSpace now inherits both dolfin::FunctionSpace and
> > ffc.FiniteElement, and it can be used to instantiate user defined
> > Functions which can be used to define forms.
> >
> > We need to discuss how to implement a discrete function. This is a bit
> > complicated using the metaclass magic that is implemented now. Now we
> > cannot do:
> >
> >  u = Function(V)
> >  x = u.vector()
> >
> > as Function is just a dummy class for creation of userdefined functions.
>
> We don't have to use metaclasses, it would be enough to implement
> Function.__new__(cls, *args). This function can return objects of
> a different type, e.g. a compiled function that doesn't inherit from
> dolfin.Function but directly from dolfin::Function.

and from ufl.Function too?

> (I didn't understand this stuff fully until last week...)

Yes I have thought about that solution, but then the created class wont be a 
Function. It can be handy to have a class that all python Function can be 
checked if isinstance of. With the __new__ function we create different 
classes.

The advantage, as I see it with your suggestion would be that we can use the 
present feature of compiling many functions at a time, but we loose the 
consistent syntax:

  class MyFunction(Function):
      def eval(v,x):
           do something
 
  class MyCompiledFunction(Function):
      cpp_code = do something

  f = MyFunction(V)
  g = MyCompiledFunction(V)

and it could be complicated to pass the right FunctionSpaces to the 
compile_function function.

> > Is it possible to define a DiscreteFunction class in c++ (or just in
> > swig?) that inherits dolfin::Function, and in its constructor calls
> > vector()?
> >
> > Then we can use this class in python to create discrete functions. We
> > then avoid the director class that is created by swig for all functions
> > that inherits the cpp_Function. The obvious syntax would then be
> >
> >  u = DiscreteFunction(V)
> >
> > in python. I think with some python magic we still can have the syntax
> >
> >  u = Function(V)
> >
> > which would imply that a discrete function is created, but I haven't
> > implemented it.
>
> That would basically be duplicating the design that has been replaced...
> I think dropping the metaclass is a much easier solution.

No, this is just for the python interface. This could come handy with the 
__new__ implementation you want too. By this we circumvent the director class 
that swig creates for dolfin::functions. We dont want to call eval on such a 
class to often do we? :)

> > We also have a problem with MixedElements. Now the FunctionSpace inherits
> > ffc.FiniteElement and a MixedElement is not a FiniteElement. I suppose we
> > could overload the __add__ operator for the FunctionSpace together with a
> > new class MixedFunctionSpace, to fix this?
> >
> > Johan
>
> We also have (in UFL at least) the classes VectorElement and TensorElement,
> so this gets complicated. I think we should just make FunctionSpace own an
> element instead.
>
> element = FiniteElement(...)
> V = FunctionSpace(mesh, element)
> f = Function(V) # calls FiniteElement.__init__(self, element)

Thats looks nice. We could also use the syntax Anders suggested, 

  V = FunctionSpace(mesh, "Lagrange", 1)

and then instantiate the FiniteElement in the __init__ function.

This wont work for the basis functions though, but we could just add a class 
that inherits the ffc.BasisFunction and which can be instantiated with both a 
FunctionSpace and a FiniteElement.

Johan


Follow ups

References