← Back to team overview

dolfin team mailing list archive

Re: Patch with fixes to PyDOLFIN

 

On Sunday 02 November 2008 17:44:39 Anders Logg wrote:
> On Sun, Nov 02, 2008 at 04:28:45PM +0100, Johan Hake wrote:
> > Hello!
> >
> > I have fixed the swig interface so it compiles. I had to add SubFunction
> > in dolfin_function.h. If we do not want this we have to add
> >
> >   #include "SubFunction.h"
> >
> > to Function.h, as it is in 0.8.1.
> >
> > As function inherits ufc::function I also %imported ufc.h and added ufc-1
> > as swig dependencies in scons.cfg.
> >
> > I %renamed function.in to function._in and %extended the interface to
> > SubFunction so one can write
> >
> >   u in V
> >
> > as discussed previously.
>
> Very nice!
>
> > I am curious of how we will fix the whole PyDOLFIN interface with the
> > precompiled function spaces aso. These can all be hidden in the assemble
> > function and/or in the LinearPDE class. But what if we want to expose a
> > FunctionSpace from a compiled form? Do we want this?
> >
> > Or what if we want to create a FunctionSpace from an element and a mesh.
> > This can be done more or less in the same way as we have solved Function
> > in 0.8.1, but then we miss the whole point of reusing FunctionSpaces.
> >
> > Any good suggestions?
> >
> > Johan
>
> Here's a good suggestion... :-)
>
> We create a new Python class (in site-packages/dolfin/functionspace.py)
> which either inherits from FormCompiler.FiniteElement and
> dolfin::FunctionSpace or owns such objects as member data.

I suppose it have to inherit from FormCompiler.FiniteElement, but it only have 
to owe a cpp:FunctionSpace.

So the __init__ function in FunctionSpace would be something like:

  def __init__(self, mesh, family, order):
      FormCompiler.FiniteElement.__init__\
         (self,family,dim2shape(mesh.geometry().dim(),order))
      if self.value_dimension(0) > 1:
          form = ffc.TestFunction(self)[0]*ffc.dx
      else:
          form = ffc.TestFunction(self)*ffc.dx
      (compiled_form, module, form_data) = jit(form,mesh)
      self._V = compiled_form.function_space(0)
      
and then we can add something like

  def cpp_function_space(self):
      return self._V

to the interface, where the latter function is used in the __init__ function 
of the Function class to initialize the cpp_Function? 

Maybee we for compatability should let FunctionSpace inherit 
cpp_FunctionSpace. If we do that the __init__ function from above would look 
a bit differently.

> In PyDOLFIN, FunctionSpace will then be something that replaces both
> FormCompiler.FiniteElement and dolfin::FunctionSpace:
>
>   V = FunctionSpace(mesh, "Lagrange", 1)
>   v = TestFunction(V)
>   u = TrialFunction(V)
>   f = Function(V)
>   a = dot(grad(v), grad(u))*dx
>   L = v*f*dx
>   A = assemble(a)
>   b = assemble(L)
>
> Note that the "triangle" or "tetrahedron" argument is not needed since
> this can be deduced from the mesh.

Looks nice. Would it then be possible to reuse the cpp_FunctionSpace that is 
initialized for V when the form is compiled using jit?

I see that this is a very handy way of defining and assemble a form, but would 
it be possible with this design to define a form using only the FormCompiler 
language, and then pass this form to jit, or directly to assemble. Then 
either add the functions manually to the form a là c++ or as it is in the 
assemble function now, i.e., passing them as an optional kwarg. The latter 
could be facilitated as Martin suggested previously as 

  assemble(..., coefficients = {'f':f,'g':g},...)

> I also suggest that we don't introduce the FunctionSpace concept in
> the form compilers (FFC, SFC, UFL) since they should not know anything
> about the mesh.

Sounds reasonable.

Johan


Follow ups

References