← Back to team overview

dolfin team mailing list archive

Re: Patch with fixes to PyDOLFIN

 

2008/11/2 Johan Hake <hake@xxxxxxxxx>:
> 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.

To clarify: The (only?) reason for owning and not inheriting is that
we want to reuse function spaces.

> 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.

To still allow reusing FunctionSpaces, it would have to be some kind
of envelope-letter design then.

>> 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?

The reuse must happen when V is constructed, so this has nothing to do
with compiling forms with 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},...)

That's not exactly what I suggested, and it won't work here, since the
names of functions are not known! We just agreed to remove "name" from
ufl.Function, but if we keep that this would be possible.

What I suggested was using the (FormCompiler.) ufl.Function instances as keys:

...
fu = ufl.Function(element)
a = ...*fu*dx
fc = compiled_function

assemble(a, ..., coefficients = {fu: fc},...)

>> 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

Ok.

-- 
Martin


Follow ups

References