← Back to team overview

dolfin team mailing list archive

Re: Image to Function data structure conversion

 

2009/2/16 Garth N. Wells <gnw20@xxxxxxxxx>:
>
>
> 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).

Yes, that wasn't a good example. However, this is also applied to
FunctionSpace, here are the const inputs:

 FunctionSpace(const Mesh& mesh,
                  const FiniteElement& element,
                  const DofMap& dofmap);

But later, they are changed:

const FunctionSpace& FunctionSpace::operator= (const FunctionSpace& V)
{
  // Assign data (will be shared)
  _mesh    = V._mesh;
  _element = V._element;
  _dofmap  = V._dofmap;
...
}

or am I wrong?

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

That's right, but where? Like I mentioned, this will only work
somwhere outside of these two classes. The idea was that ImageFunction
should be of Function type and it would be nice to sub class it.


-Ali

>
> Garth
>
>>
>> -Ali
>>
>>> --
>>> Anders
>>>
>>> -----BEGIN PGP SIGNATURE-----
>>> Version: GnuPG v1.4.9 (GNU/Linux)
>>>
>>> iEYEARECAAYFAkmZmlsACgkQTuwUCDsYZdH2CQCfV+zCXddCSL0oGrSKcyDBj2Mp
>>> RSUAn3uZT4JixKq62p7BTTsHuA+qMG29
>>> =P6Ji
>>> -----END PGP SIGNATURE-----
>>>
>>> _______________________________________________
>>> DOLFIN-dev mailing list
>>> DOLFIN-dev@xxxxxxxxxx
>>> http://www.fenics.org/mailman/listinfo/dolfin-dev
>>>
>>>
>> _______________________________________________
>> DOLFIN-dev mailing list
>> DOLFIN-dev@xxxxxxxxxx
>> http://www.fenics.org/mailman/listinfo/dolfin-dev
>


Follow ups

References