← Back to team overview

dolfin team mailing list archive

Re: [HG DOLFIN] Work on new sub Function logic.

 



Johan Hake wrote:
On Monday 24 August 2009 10:30:52 Garth N. Wells wrote:
Johan Hake wrote:
On Monday 24 August 2009 10:11:49 Garth N. Wells wrote:
dolfin/swig/dolfin_headers.i description: Work on new sub Function
logic.
I am not sure we can completely wrap the new logic to PyDOLFIN.

To be able to have the double inheritance of cpp.Function and
ufl.Function in PyDOLFIN, new Functions have to be constructed in
the Python interface (function.py).

The operator[] is mapped to a hidden function _sub. The created
Function that is returned from this is passed to the copy
constructor in the Python version of sub (creating a new Function
object). This is basically just how we did it before the new
design, because previously operator[] returned a
SubFunctionData, which was passed to a Function constructor. The
transition to the new logic works in PyDOLFIN because the Function
copy constructor is used instead of the removed SubFunctionData
constructor.

This means that the handy operator[], which returns a Function with
a shared vector, cannot fully be used from PyDOLFIN. Would it be
possible to add a shallow copy function in some way. Would this
work with the present SubFunction design?
Would something like

     Function::sub_function(Function& sub_function, uint i)
Yes I think so. If we could make this a constructor (shallow copy
constructor) I would be most happy!
So a constructor

     Function::Function(uint i)

would be better?
Yes, but then we could not fetch the shared Vector?

I'm reluctant to add a constructor since it breaks the
paradigm that a Function constructor gives a deep copy.
Ok.

Could you create
an empty Function internally on the PyDOLFIN side and then pass it to

     Function::sub_function(Function& sub_function, uint i)

to attach the shared data to create the sub-Function 'sub_function'?
Yes, this should be fine. I guess such a function will then just
destroy any present vector and exchange it with the one shared with the
FullFunction?
Yes. We can throw an error if there is any data already attached to the
Function.
When we create a new Function in PyDOLFIN using the DiscreteFunction, we
do create a vector, so this will prevent us using this class. We use the
DiscreteFunction to circumvent some director (SWIG stuff to be able to
inherit a cpp.Function in Python) overhead wrt to call the eval function
during assemble. I guess we will not assemble the function returned from
operator[] so then we can create the Function using cpp.Function instead.
What if we add a constructor to DiscreteFunction to take care of
sub-functions? Would that work?

Yes, this should work. Then we could add a constructor taking a Function and a number as you suggested above.


This is trickier than I anticipated. The problem with

    Function::Function(const Function& v, uint i)

is that v cannot be const since v keeps track of its sub-functions and create and stores them on-demand. I could just create a sub-function and not cache it, but then it would be re-created every time. The problem with this is that creating a sub-dof map is not trivial if the dof map has been renumbered.

I'm also a bit uncomfortable with shallow copies because bad things can happen when something goes out of scope.

Could this be taken care of on the Python side by introducing something like a SubFunction? Function::operator[] returns a reference, and PyDOLFIN could take are of things through the assignment operators of the Python Function and SubFunction classes? I don't really understand how things work on the Python side for Functions, so I'm clutching at straws.

Garth


It would be neat if we could somehow make member functions 'private' to
PyDOLFIN.
We can, just rename them in dolfin_function_pre.i

  %rename (_foo) dolfin::Function::foo;

We do this for some of the functions (_sub: operator[] and _in for in)
already.
I meant C++ member functions which are intended for use through PyDOLFIN
only.

I see :) We could hide some python specific classes, like the DiscreteFunction class, by not including it in dolfin_function.h, and then manually add it to dolfin_headers.i. With this we hide it from
  #include <dolfin.h>

We then have to manually add them as #includes in dolfin.i and to dolfin_headers.i. We can automate this by adding a dolfin_pydolfin_headers.i, which lists the #includes. This file is then parsed by generate.py.

If this sounds reasonable I can look into it.

Johan

Garth



Follow ups

References