(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
DOLFIN-dev@xxxxxxxxxx
http://www.fenics.org/mailman/listinfo/dolfin-dev