← Back to team overview

dolfin team mailing list archive

Re: Image to Function data structure conversion

 

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

>
> --
> Anders
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.9 (GNU/Linux)
>
> iEYEARECAAYFAkmZpd4ACgkQTuwUCDsYZdFkZgCeJmNT2W6GRMM+PCFfmrwNL5kT
> Z0wAn2oqyRFPJ+aAPLxR2LiI5u9RV+rY
> =SBcR
> -----END PGP SIGNATURE-----
>
> _______________________________________________
> DOLFIN-dev mailing list
> DOLFIN-dev@xxxxxxxxxx
> http://www.fenics.org/mailman/listinfo/dolfin-dev
>
>


Follow ups

References