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