← Back to team overview

dolfin team mailing list archive

Re: Image to Function data structure conversion

 

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).

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).

Since dolfin::Function does come with the required copy ctors, the
problem cannot be stemmed from this.

(2) Calling FunctionTest.CreateFunctionPtr(), which returns the shared
pointer, does not generate any errors. 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

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?


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;
	};
};
----------------------------

2009/2/13 A Navaei <axnavaei@xxxxxxxxxxxxxx>:
>>>
>>> Johan: Why the extensions in dolfin/site-packages/function.py are not
>>> implemented in c++ and then wrapped in python? It seems focusing some
>>> parts of the development in the python layer has caused some stuff to
>>> be missed in the c++ core. For reference I copy the previous
>>> communication with Kent:
>>
>> I fell that I am jumping into a discussion I do not have the beginning of, but
>> first of all:
>>
>> The thing we do in dolfin/site-packages/function.py is to be able to
>> dynamically create python function classes that inherits both cpp.Function,
>> i.e., the c++ version _and_ ffc.Function. Having this in place we are now
>> able to define a Function like:
>>
>>  V = FunctionSpace(UnitSquare(10,10),"CG",1)
>>  f = Function(V,"sin(x[0])")
>>
>> where f can be used both to define variational forms, and efficiently be used
>> in the assemble loop, where the compiled c++ version of the function is used.
>> This means that you can e.g. write
>>
>>  a = assembe(f*dx)
>>
>> What we are doing in dolfin/site-packages/function.py is however probably
>> _not_ causing your error, as it should still be possible to use pure
>> cpp.Functions or subclasses of such, in PyDOLFIN.
>>
>> To assemble a form using such function you have to instantiate a ffc.Function
>> and a DolfinImageFunction, where the former is used defining the form and the
>> latter is passed to
>>
>>   assemble(...,coefficients=[your_dolfin_image_function])
>>
>>> ----------------------------
>>> There are some issues with coding dolfin under c++, a code which works
>>> with python is difficult, if not impossible, to re-produce in c++. I
>>> tried sub-classing
>>> dolfin::Function as itk::DolfinImageFunction:
>>>
>>> http://code.google.com/p/wrapitk/source/browse/trunk/ExternalProjects/ItkDo
>>>lfin/src/itkDolfinImageFunction.h
>>>
>>> After wrapping in python, using wrapped itk::DolfinImageFunction works fine
>>> in python, but the same procedure fails when implemented in c++, as
>>> demonstrated here:
>>
>> I am not quite sure I understand this, but are you saying that you are able
>> to:
>>
>>  V = FunctionSpace(UnitSquare(10,10),"Lagrange",1)
>>  f = DolfinImageFunction(V,someimage)
>>
>> but not by calling your wrapped ImageToDolfinFunction.DolfinImageFunction()?
>
> 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).
>
> 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/ItkDolfin/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.
>
>>
>> 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.
>
> Just to mention that one problem with c++ dolfin classes is that their
> member variables are mostly private, causing restrictions on the
> sub-classes. 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.
>
>>
>> Hope this helps!
>>
>> Johan
>>
>>> http://code.google.com/p/wrapitk/source/browse/trunk/ExternalProjects/ItkDo
>>>lfin/src/itkImageToDolfinFunction.h#56
>>>
>>> which generates this error in python:
>>>
>>>  File
>>> "/usr/lib/InsightToolkit/WrapITK/lib/itkImageToDolfinFunctionPython.py",
>>> line 273, in Convert
>>>    return
>>> _itkImageToDolfinFunctionPython.itkImageToDolfinFunctionID2_Convert(*args)
>>> RuntimeError: *** Error: Unable to assign to function, missing
>>> coefficients (user-defined function).
>>>
>>> Here is the python test generating the above error:
>>>
>>> http://code.google.com/p/wrapitk/source/browse/trunk/ExternalProjects/ItkDo
>>>lfin/tests/test-01.py
>>
>>
>>
>


Follow ups

References