← Back to team overview

dolfin team mailing list archive

Re: Image to Function data structure conversion

 

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.

-- 
Anders

Attachment: signature.asc
Description: Digital signature


Follow ups

References