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
>>
_______________________________________________
DOLFIN-dev mailing list
[email protected]
http://www.fenics.org/mailman/listinfo/dolfin-dev