A Navaei wrote:
> 2009/2/14 A Navaei <[email protected]>:
>> 2009/2/14 Garth N. Wells <[email protected]>:
>>>
>>> A Navaei wrote:
>>>> 2009/2/14 Johan Hake <[email protected]>:
>>>>> On Saturday 14 February 2009 17:28:18 Garth N. Wells wrote:
>>>>>> Johan Hake wrote:
>>>>>>> On Saturday 14 February 2009 13:48:05 A Navaei wrote:
>>>>>>>> It seems that the error can be re-produced even without sub-classing
>>>>>>>> and using existing dolfin classes in pure c++. Based on the itk-dolfin
>>>>>>>> interface code, the below minimal code should generate the error (note
>>>>>>>> that I use the binary distribution which uses std::tr1, replacing it
>>>>>>>> with boost shared pointer should not have any effect).
>>>>>>> Not in c++ but swig only support std::tr1::shared_ptr from version
>>>>>>> 1.3.37. But if you intend to use shared_ptr only internally there
>>>>>>> whould
>>>>>>> not be any problems.
>>>>>>>
>>>>>>>> After wrapping in python:
>>>>>>>>
>>>>>>>> (1) Calling FunctionTest.CreateFunction(), which returns by value,
>>>>>>>> results this error:
>>>>>>>>
>>>>>>>> RuntimeError: *** Error: Unable to assign to function, missing
>>>>>>>> coefficients (user-defined function).
>>>>>>> You cannot assign another user-defined function to another Function. It
>>>>>>> must be a discrete function, which has an initialized _vector. This is
>>>>>>> probably a feature that other developers should answer for.
>>>>>>>
>>>>>>> However this means that you cannot copy a userdefined function, with
>>>>>>> the
>>>>>>> side effect of not beeing able to return a user-defined Function by
>>>>>>> value.
>>>>>>>
>>>>>>>> Since dolfin::Function does come with the required copy ctors, the
>>>>>>>> problem cannot be stemmed from this.
>>>>>>> This use the assignment operator which requires the Function to be a
>>>>>>> discrete and not a user-defined Function.
>>>>>>>
>>>>>>> I consider this to be a bug in the library. Any other comments from the
>>>>>>> C++ DOLFIN developers (I am mostly dealing with the python interface)?
>>>>>> In a nutshell, are you suggesting that the Function copy constructor
>>>>>> should work for user-defined Functions?
>>>>> Yes. Why shouldn't it?
>>>>>
>>>>> I can see why the assigment operator should not work.
>>>> By 'user-defined' Function, do you mean those sub-classes which simply
>>>> override eval() in order to implement user-defined values? In this
>>>> case, perhaps there should be a difference between a 'user-defined'
>>>> Function class and a class which requires extending Function more
>>>> extensively. The latter should have access to the private member
>>>> variables.
>>>>
>>> I can't see why this is needed. Function only has two pieces of private
>>> member data, both of which can be accessed through member functions.
>> The accessors are read-only:
>>
>> const FunctionSpace& function_space() const;
>> boost::shared_ptr<const FunctionSpace> function_space_ptr() const;
>>
>> For instance, in the ImageFunction case, FunctionSpace instance needs
>> to be initialised using the image size and image data.
> 

Function should not change the FunctionSpace (that's why FunctionSpace 
is const). FunctionSpace shouldn't depend on the data and its size 
should be defined when creating the FunctionSpace.

> Well, I guess that's why you have so many friend classes in dolfin -
> that's one solution.
>

The reason for the friend classes is another one.

Garth

> 
> -Ali
> 
>>
>> -Ali
>>
>>> Garth
>>>
>>>> -Ali
>>>>
>>>>> Johan
>>>>>
>>>>>
>>>>>> Garth
>>>>>>
>>>>>>>> (2) Calling FunctionTest.CreateFunctionPtr(), which returns the shared
>>>>>>>> pointer, does not generate any errors.
>>>>>>> This should be expected, as the copy constructors is not called. When
>>>>>>> you
>>>>>>> get all this to work, eventually ;), I would suggest using shared_ptr
>>>>>>> types for the return argument, as shared_ptrs are much nicer to deal
>>>>>>> with
>>>>>>> in both c++ and python. But then you probably need the development
>>>>>>> version of DOLFIN. We do consider a release soon, which you can switch
>>>>>>> to
>>>>>>> when this is out.
>>>>>>>
>>>>>>> The support for shared_ptr in PyDOLFIN is lately added, but has more or
>>>>>>> less stabilized now, I think.
>>>>>>>
>>>>>>>> However, there are problems
>>>>>>>> with handling the shared pointer in python. I used this in my swig
>>>>>>>> interface file (or in an implicit way you can include dolfin.i
>>>>>>>> defining the right flags):
>>>>>>>>
>>>>>>>> #define SWIG_SHARED_PTR_NAMESPACE std // comment out if it's boost
>>>>>>>> #define SWIG_SHARED_PTR_SUBNAMESPACE tr1 // comment out if it's boost
>>>>>>>> %include "boost_shared_ptr.i"
>>>>>>>> # if defined(SWIG_SHARED_PTR_QNAMESPACE)
>>>>>>>> SWIG_SHARED_PTR(Function, dolfin::Function)
>>>>>>>> #endif
>>>>>>> Which version of swig do you have, refering to the comment above. You
>>>>>>> need swig version >= 1.3.35 to be able to use shared_ptr in the first
>>>>>>> place and >= 1.3.37 to be able to use std::str1::shared_ptr.
>>>>>>>
>>>>>>>> Having this, in python, FunctionTest.CreateFunctionPtr() returns a
>>>>>>>> proxy to the shared pointer object which is not useful. Are there any
>>>>>>>> steps missed in the wrapping process?
>>>>>>> Strictly speaking it does _not_ return a proxy but rather a raw pointer
>>>>>>> to the object. The proxy is the python wrapper class that swig creates
>>>>>>> for us when it have the correct type knowledge, which in this case,
>>>>>>> swig
>>>>>>> does not have.
>>>>>>>
>>>>>>>> c++ test code:
>>>>>>>> -----------------------------
>>>>>>>> class FunctionTest
>>>>>>>> {
>>>>>>>> public:
>>>>>>>>   typedef std::tr1::shared_ptr<const dolfin::Mesh>
>>>>>>>> MeshConstPointerType;
>>>>>>>>   typedef std::tr1::shared_ptr<const dolfin::FiniteElement>
>>>>>>>> ElementConstPointerType;
>>>>>>>>   typedef std::tr1::shared_ptr<const dolfin::DofMap>
>>>>>>>> DofMapConstPointerType; typedef std::tr1::shared_ptr<const
>>>>>>>> dolfin::FunctionSpace>
>>>>>>>> FSConstPointerType; typedef std::tr1::shared_ptr<dolfin::Function>
>>>>>>>> FPointerType;
>>>>>>>>
>>>>>>>>   static dolfin::Function CreateFunction()
>>>>>>>>   {
>>>>>>>>           dolfin::Mesh mesh = dolfin::UnitSquare(100, 100);
>>>>>>>>           std::string elemSig("FiniteElement('Lagrange', 'triangle',
>>>>>>>> 1)");
>>>>>>>>           std::string dofSig("FFC dof map for
>>>>>>>> FiniteElement('Lagrange',
>>>>>>>> 'triangle', 1)");
>>>>>>>>
>>>>>>>>           FSConstPointerType fs(new dolfin::FunctionSpace(
>>>>>>>>           typename IFSType::MeshConstPointerType(&mesh,
>>>>>>>> dolfin::NoDeleter<const dolfin::Mesh>()),
>>>>>>>>           typename IFSType::ElementConstPointerType(new
>>>>>>>> dolfin::FiniteElement(elemSig)), typename
>>>>>>>> IFSType::DofMapConstPointerType(new dolfin::DofMap(dofSig, mesh))) );
>>>>>>>>
>>>>>>>>           dolfin::Function func(fs);
>>>>>>>>           return func;
>>>>>>>>   };
>>>>>>>>
>>>>>>>>   static FPointerType CreateFunctionPtr()
>>>>>>>>   {
>>>>>>>>           dolfin::Mesh mesh = dolfin::UnitSquare(100, 100);
>>>>>>>>           std::string elemSig("FiniteElement('Lagrange', 'triangle',
>>>>>>>> 1)");
>>>>>>>>           std::string dofSig("FFC dof map for
>>>>>>>> FiniteElement('Lagrange',
>>>>>>>> 'triangle', 1)");
>>>>>>>>
>>>>>>>>           FSConstPointerType fs(new dolfin::FunctionSpace(
>>>>>>>>           typename IFSType::MeshConstPointerType(&mesh,
>>>>>>>> dolfin::NoDeleter<const dolfin::Mesh>()),
>>>>>>>>           typename IFSType::ElementConstPointerType(new
>>>>>>>> dolfin::FiniteElement(elemSig)), typename
>>>>>>>> IFSType::DofMapConstPointerType(new dolfin::DofMap(dofSig, mesh))) );
>>>>>>>>
>>>>>>>>           FPointerType funcp = FPointerType(new dolfin::Function(fs));
>>>>>>>>           return funcp;
>>>>>>>>   };
>>>>>>>> };
>>>>>>>> ----------------------------
>>>>>>>>
>>>>>>>>> Yes, I can call wrapped DolfinImageFunction in python with no
>>>>>>>>> problem,
>>>>>>>>> but when using it in pure c++ (itk::ImageToDolfinFunction) an then
>>>>>>>>> calling ImageToDolfinFunction after wrapped in python generated the
>>>>>>>>> error:
>>>>>>>>>
>>>>>>>>> RuntimeError: *** Error: Unable to assign to function, missing
>>>>>>>>> coefficients (user-defined function).
>>>>>>> I think we sorted out this problem above: do not return by value.
>>>>>>>
>>>>>>>>> why v._vector is not null in the first case? I also tried the shared
>>>>>>>>> pointer ctors and ended up with the same result. Moreover, I tried
>>>>>>>>> sub-classing FunctionSpace (see
>>>>>>>>>
>>>>>>>>> http://code.google.com/p/wrapitk/source/browse/trunk/ExternalProjects/I
>>>>>>>>> tk Dolfin/src/itkDolfinImageFunctionSpace.h), with and without shared
>>>>>>>>> pointer ctors, again the same error.
>>>>>>>>>
>>>>>>>>>> First I assume that you properly instantiate the templates somewhere
>>>>>>>>>> else in your build script, as itkDolfin.swg does not define any such
>>>>>>>>>> templates.
>>>>>>>>> That's correct, wrapitk instantiates the templates automatically.
>>>>>>> Ok. Is this done in some of the SMake macros? I am really not familiar
>>>>>>> to
>>>>>>> CMake
>>>>>>>
>>>>>>>>>> Second you should probably return a pointer to the created function
>>>>>>>>>> in
>>>>>>>>>> DolfinImageFunction(), and set
>>>>>>>>>>
>>>>>>>>>>  %newobject
>>>>>>>>>> itk::ImageToDolfinFunction<YourImageTypes>.DolfinImageFunction;
>>>>>>>>>>
>>>>>>>>>> or define a copy constructor to your DolfinImageFunction, as you are
>>>>>>>>>> returning by value now.
>>>>>>>>> I've tried a simple copy ctor like this:
>>>>>>>>>
>>>>>>>>>       DolfinImageFunction(const DolfinImageFunction &v)
>>>>>>>>>       {
>>>>>>>>>                *this = v;
>>>>>>>>>       }
>>>>>>>>>
>>>>>>>>> which does get called, but didn't help.
>>>>>>> Again, bug in copy constructor. You should be able to return a raw
>>>>>>> pointer to the function, but make sure you use the %newobject directive
>>>>>>> mentioned above, to till swig that it should take ownership to the
>>>>>>> returned object.
>>>>>>>
>>>>>>>>> Just to mention that one problem with c++ dolfin classes is that
>>>>>>>>> their
>>>>>>>>> member variables are mostly private, causing restrictions on the
>>>>>>>>> sub-classes.
>>>>>>> This should others answer.
>>>>>>>
>>>>>>>>> Is there a specific reason for having private variables
>>>>>>>>> instead of protected? For instance, DolfinImageFunction ctors are not
>>>>>>>>> able to initialise _function_space or _vector.
>>>>>>> This should not be any problems in the ordinary constructor as you can
>>>>>>> just pass the function_space to the super constructor, and a properly
>>>>>>> working copy constructor should also fix this for any derived copy
>>>>>>> constructors.
>>>>>>>
>>>>>>> The _vector is created by calling init(). But you do not want to do
>>>>>>> this
>>>>>>> as the Function will then change status from a user-defined to a
>>>>>>> discrete
>>>>>>> function, making it impossible to reach the eval function.
>>>>>>>
>>>>>>> Again hope this helps.
>>>>>>>
>>>>>>> Johan
>>>>>>> _______________________________________________
>>>>>>> DOLFIN-dev mailing list
>>>>>>> [email protected]
>>>>>>> http://www.fenics.org/mailman/listinfo/dolfin-dev
>>>>>
>>> --
>>> Dr Garth N Wells
>>> Department of Engineering
>>> University of Cambridge
>>> Trumpington Street
>>> Cambridge CB2 1PZ
>>> United Kingdom
>>>
>>> tel.   +44 1223 3 32743
>>> fax.   +44 1223 3 32662
>>> e-mail [email protected]
>>>
>>>

-- 
Dr Garth N Wells
Department of Engineering
University of Cambridge
Trumpington Street
Cambridge CB2 1PZ
United Kingdom

tel.   +44 1223 3 32743
fax.   +44 1223 3 32662
e-mail [email protected]

_______________________________________________
DOLFIN-dev mailing list
[email protected]
http://www.fenics.org/mailman/listinfo/dolfin-dev

Reply via email to