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?

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


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

Reply via email to