← Back to team overview

dolfin team mailing list archive

Re: Image to Function data structure conversion

 

2009/2/16 A Navaei <axnavaei@xxxxxxxxxxxxxx>:
> 2009/2/16 Anders Logg <logg@xxxxxxxxx>:
>> On Mon, Feb 16, 2009 at 05:36:48PM +0000, Garth N. Wells wrote:
>>>
>>>
>>> A Navaei wrote:
>>> > 2009/2/16 Anders Logg <logg@xxxxxxxxx>:
>>> >> On Mon, Feb 16, 2009 at 04:36:21PM +0000, A Navaei wrote:
>>> >>> 2009/2/15 Anders Logg <logg@xxxxxxxxx>:
>>> >>>> On Sat, Feb 14, 2009 at 06:44:05PM +0000, Garth N. Wells wrote:
>>> >>>>>
>>> >>>>> A Navaei wrote:
>>> >>>>>> [snip]
>>> >>>>>>>>> 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.
>>> >>>>>>>> The same applies for FunctionSpace as its member variables are private
>>> >>>>>>>> and the public accessors are read-only which. Consider a sub-class
>>> >>>>>>>> ImageFunctionSpace:FunctionSpace, with a constructor like:
>>> >>>>>>>>
>>> >>>>>>>> ImageFunctionSpace(ImageType *imagePtr)
>>> >>>>>>>>
>>> >>>>>>>> where imagePtr is supposed to initialise FunctionSpace::_mesh using
>>> >>>>>>>> the image size, and then _dofmaps itself is initialised using _mesh.
>>> >>>>>>>> How would you do that considering the restrictions?
>>> >>>>>>>>
>>> >>>>>>> The FunctionSpace has pointers to the mesh, etc. You just need to create
>>> >>>>>>> your mesh and pass it to the FunctionSpace constructor. What else you then
>>> >>>>>>> do with the mesh, etc is up to you.
>>> >>>>>> That can be done _outside_ of a sub-class. A sub-class of
>>> >>>>>> FunctionSpace doesn't have a control over _mesh of its own parent
>>> >>>>>> FunctionSpace. The following example may make this more clear:
>>> >>>>>>
>>> >>>>>> template <typename TImage>
>>> >>>>>> class DolfinImageFunctionSpace : public dolfin::FunctionSpace
>>> >>>>>> {
>>> >>>>>> public:
>>> >>>>>>         // just some itk typedefs -- ignore
>>> >>>>>>     typedef TImage ImageType;
>>> >>>>>>     typedef typename ImageType::PixelType PixelType;
>>> >>>>>>     typedef typename ImageType::SizeType SizeType;
>>> >>>>>>
>>> >>>>>>         // .. and some dolfin typedefs -- ignore
>>> >>>>>>     typedef typename std::tr1::shared_ptr<const dolfin::Mesh> MeshConstPointerType;
>>> >>>>>>     typedef typename std::tr1::shared_ptr<const dolfin::FiniteElement>
>>> >>>>>> ElementConstPointerType;
>>> >>>>>>     typedef typename std::tr1::shared_ptr<const dolfin::DofMap>
>>> >>>>>> DofMapConstPointerType;
>>> >>>>>>
>>> >>>>>>         // the ctor
>>> >>>>>>     DolfinImageFunctionSpace(ImageType* imageData,
>>> >>>>>>                                             MeshConstPointerType mesh,
>>> >>>>>>                                             ElementConstPointerType element,
>>> >>>>>>                                             DofMapConstPointerType dofmap) :
>>> >>>>>>     dolfin::FunctionSpace(mesh, element, dofmap)
>>> >>>>>>     {
>>> >>>>>>             SizeType imageSize = imageData->GetBufferedRegion().GetSize();
>>> >>>>>>
>>> >>>>>>                 // here, we whish to call some thing like:
>>> >>>>>>                 // _mesh = UnitSquare(imageSize[0], imageSize[1]);
>>> >>>>>>                 // but it's private and the accessor is read-only.
>>> >>>>>>     };
>>> >>>>>> }
>>> >>>>>>
>>> >>>>> This breaks the concept of a function space. A function space is defined
>>> >>>>> in terms of a mesh (and other things). A function space does not define
>>> >>>>> its mesh.
>>> >>>>>
>>> >>>>> It looks to me like the class that you're creating should be called
>>> >>>>> something like
>>> >>>>>
>>> >>>>>    DolfinImageProblem,
>>> >>>>>
>>> >>>>> which can create its own Mesh, FunctionSpace and other objects.
>>> >>>>>
>>> >>>>> Garth
>>> >>>>>
>>> >>>>>> -Ali
>>> >>>> I think what you need to do is something like this:
>>> >>>>
>>> >>>> 1. Create a subclass of Function
>>> >>>>
>>> >>>> 2. In the constructor of your Function, call the empty Function()
>>> >>>> constructor
>>> >>>>
>>> >>>> 3. Then, still in the constructor of your Function (not
>>> >>>> FunctionSpace), create everything necessary like figuring out the
>>> >>>> mesh, dofmap etc and from that create a FunctionSpace
>>> >>>>
>>> >>>> 4. Then use that FunctionSpace (still in the constructor of your
>>> >>>> Function subclass) to create a new Function v which uses your special
>>> >>>> FunctionSpace in its constructor
>>> >>>>
>>> >>>> 5. Finally, assign this function to the created Function:
>>> >>>>
>>> >>>>  *this = v;
>>> >>>  error: no match for 'operator=' in
>>> >>> '*(itk::DolfinImageFunction<itk::Image<double, 2u> >*)this = v'
>>> >>>
>>> >>> Assigning Function to ImageFunction is a trouble, see the full code here:
>>> >>>
>>> >>> http://code.google.com/p/wrapitk/source/browse/trunk/ExternalProjects/ItkDolfin/src/itkDolfinImageFunction.h#87
>>> >> Do you have the latest hg version?
>>> >>
>>> >> Function assignment should work (see recent discussion on the mailing
>>> >> list on copy constructors and assignment operators for Function).
>>> >>
>>> >>> I don't understand the philosophy behind this tight security: why no
>>> >>> protected member variables? Why is everything either public or
>>> >>> private? Needless to say, the protected members were designed to allow
>>> >>> class extensions, by banning it, you're making sub classing a
>>> >>> unnecessarily complicated task. The above problem has it's own work
>>> >>> arounds, but I don't understand why the obvious way is blocked.
>>> >> The reason is simply that the constructor arguments in Function and
>>> >> FunctionSpace are const. This means no one is allowed to change the
>>> >> variables, not even the Function class (or FunctionSpace class)
>>> >> itself. For example, it's reasonable when you create a Function on a
>>> >> FunctionSpace that the Function will not change the FunctionSpace.
>>> >
>>> > Whether the member variables are read-only or not, and their
>>> > visibility are two separate concepts - you can have any combination of
>>> > these. Function and FunctionSpace do change their const variables
>>> > anyway, eg, in operator= you have:
>>> >
>>> > // Assign vector
>>> > init();
>>> > dolfin_assert(_vector);
>>> > *_vector = *v._vector;
>>> >
>>> > Which is in contradiction with what you wrote about not even the class
>>> > itself cannot change the variables.
>>> >
>>>
>>> Anders was referring to FunctionSpace. Obviously, the vector associated
>>> with a discrete Function cannot be const (and it isn't).
>>>
>>> > It would be rare that all classes have to have read-only inputs, where
>>> > the sub-classes are setences to inherit the same properties. Now, I
>>> > simply cannot have the right operator= assinging Function to
>>> > ImageFunction implemented, since I cannot assign anything to the
>>> > private member variables.
>>> >
>>> > If the visibility of the members variables is not going to change to
>>> > protected, or at least a protected read/write accessor is not
>>> > provided, then there will be no option but implementing everything in
>>> > a third-party class faking the current ImageFunction, as it's not
>>> > going to be derived from Function.
>>> >
>>>
>>> All you need to do is create a suitable FunctionSpace before creating
>>> your Function.
>>>
>>> Garth
>>
>> Yes, and you should be able to create that FunctionSpace inside the
>> constructor for your Function subclass.
>
> Yes, I can _create_ it, but I cannot _assign_ it :)
>
> Now I'm trying this work around:
>
> DolfinImageFunction(ImageType* imageData) :
>                        dolfin::Function()
> {
> ...
>        // Create a Function instance
>        FSConstPointerType V = CreateFunctionSpace();
>        DolfinImageFunction v(V);
>        *this = v;
> };
>
> which requires the repsence of this ctor:
>
> DolfinImageFunction(boost::shared_ptr<const dolfin::FunctionSpace> V):
>        dolfin::Function(V)
> {
> };
>
> This might work.
>
>
> -Ali
>

The above builds, but then I get thos runtime error:

RuntimeError: *** Error: Cannot copy Functions which do not have a
Vector (user-defined Functions).

The error originates from 'this' instance and not from v.

Just in case, here is the full code:

http://code.google.com/p/wrapitk/source/browse/trunk/ExternalProjects/ItkDolfin/src/itkDolfinImageFunction.h#47

-Ali


Follow ups

References