← Back to team overview

dolfin team mailing list archive

Re: Image to Function data structure conversion

 



A Navaei wrote:
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?


The actual mesh, finite element and dof_map objects are not being changed. What's changing in assigning a FunctionSpace is the mesh, finite element and dof_map to which the FunctionSpace points.

Garth

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