← Back to team overview

dolfin team mailing list archive

Re: A minimal c++ Function test and some bugs

 

On Wed, Feb 18, 2009 at 04:51:22PM +0000, A Navaei wrote:
> 2009/2/18 A Navaei <axnavaei@xxxxxxxxxxxxxx>:
> > 2009/2/18 Anders Logg <logg@xxxxxxxxx>:
> >> On Wed, Feb 18, 2009 at 02:04:35PM +0000, A Navaei wrote:
> >>> 2009/2/17 Anders Logg <logg@xxxxxxxxx>:
> >>> > On Tue, Feb 17, 2009 at 03:28:08PM +0000, Garth N. Wells wrote:
> >>> >>
> >>> >>
> >>> >> A Navaei wrote:
> >>> >> > The following minimal test for Function in c++ reveals some bugs. I
> >>> >> > guess this example can help me with dealing with the current issues of
> >>> >> > ImageFunction.
> >>> >> >
> >>> >> > (1) interpolate.py does not work when a Function is created in c++ and
> >>> >> > wrapped (see comment [2]). It seems that the bug is originated from
> >>> >> > the copy constructor (see comment [3])
> >>> >> >
> >>> >> > (2) In order to perform the interpolation, why is it necessary to
> >>> >> > create another Function and then copy it?
> >>> >> >
> >>> >> > (3) Signature checkes seem not working properly (see comment [1]). The
> >>> >> > signature-based assignments are error-prone anyway, why the
> >>> >> > object-oriented approach is not used?
> >>> >> >
> >>> >>
> >>> >> Signatures are used to permit reading/writing Functions to a file. They
> >>> >> are indeed error prone, so I believe that we reached a consensus a short
> >>> >> while ago that we would remove pre-compiled elements.
> >>> >>
> >>> >> Garth
> >>> >
> >>> > Instead of signatures, I'd recommend that you define a simple form
> >>> > file for each of the different types of FunctionSpace you need, for
> >>> > example:
> >>> >
> >>> >  element = FiniteElement("CG", "triangle", 1)
> >>> >
> >>> >  v = TestFunction(element)
> >>> >  u = TrialFunction(element)
> >>> >  a = v*u*dx
> >>> >
> >>> > If you put this in a file named My.form and compile it with FFC using
> >>> > -l dolfin, you will get a class named MyFunctionSpace that you can
> >>> > then instantiate using just a mesh:
> >>> >
> >>> >  MyFunctionSpace V(mesh);
> >>> >
> >>> > Create one form file for each of the different types of FunctionSpace
> >>> > that you need, name the files to something suitable and use the
> >>> > generated code. That way you won't need to worry about signatures,
> >>> > dofmaps and finite elements.
> >>>
> >>> Effectively, I've been using the very same method all this time, it
> >>> does not work.
> >>
> >> Yes, it does. It's used in about 20 of the demos.
> 
> Can you point me to a demo which involves initialising a Function
> inside a class and not main()?

I'm not sure we have such a demo, but we were discussing initializing
FunctionSpaces from generated code and there are plenty of such
examples (in at least 18 demos).

-- 
Anders


> >>
> >>> The copy constructor fix never worked. I've been trying to explain
> >>> this in many different ways, but the right attention was never paid to
> >>> this. Let's see if the sandbox example can convince you this time.
> >>>
> >>> A Function instance still cannot be returned by reference (or value).
> >>> Returning as shared_ptr seems to work initially, but eventually it
> >>> generates segmentation fault -- see attached.
> >>
> >> Yes, it can. There's absolutely no problem to return a Function by
> >> reference. See the updated sandbox demo.
> >
> > That's correct. There are 2 Function assignment, one inside
> > FunctionContainer ctor and the other in main(). I thought the latter
> > was the problem, which was returned by referece, but the problem was
> > initiated by the latter.
> 
> correction: ... initiated by the _former_.
> 
> 
> -Ali
> 
> >
> >>
> >> The only problem is when you want to copy a Function which is only
> >> defined in terms of an eval() operator. In those cases the Function
> >> cannot be copied.
> >>
> >> If you do the following:
> >>
> >> class MyFunction : public Function
> >> {
> >> public:
> >>
> >>  MyFunction(const FunctionSpace& V) : Function(V) {};
> >>
> >>  void eval(double* values, const double* x) const
> >>  {
> >>    values[0] = sin(x[0]);
> >>  }
> >> };
> >>
> >> MyFunction f(V);
> >> Function g = f;
> >>
> >> Do you then expect g to return sin(x)? It would be possible to
> >> implement this but it would require g to keep a pointer to f so that
> >> the eval() in g may call the eval() in f.
> >
> > In the that example, MyFunction was not of interest. I want
> > FunctionContainer to have a member function of type Function which can
> > be eventually initialised inside the class using an input
> > FunctionSpace. Forget about user defined functions, let's make the
> > problem as simple as possible. In FunctionContainer, the assignment in
> > ctor does not work, see comment [1]:
> >
> > class FunctionContainer
> > {
> > public:
> >  FunctionContainer(const FunctionSpace& V)
> >  {
> >    _f = Function(V); // [1]
> >  };
> >
> >  const Function& get_function()
> >  {
> >  message("returning");
> >    return _f;
> >  };
> > protected:
> >  Function _f;
> > };
> >
> > I hope you're not going to argue again that this is not a bug, but an
> > expected behaviour.
> >
> >
> > -Ali
> >>
> >>
> >>
> >>>
> >>> -Ali
> >>>
> >>> >
> >>> >
> >>> > -----BEGIN PGP SIGNATURE-----
> >>> > Version: GnuPG v1.4.9 (GNU/Linux)
> >>> >
> >>> > iEYEARECAAYFAkma2rQACgkQTuwUCDsYZdHp4ACfSbCXc2FAulzIdDsKvhz/6EGV
> >>> > aY4An0eyftGV3hxR3L25M9LPu3X7KFg+
> >>> > =z1cY
> >>> > -----END PGP SIGNATURE-----
> >>> >
> >>> > _______________________________________________
> >>> > DOLFIN-dev mailing list
> >>> > DOLFIN-dev@xxxxxxxxxx
> >>> > http://www.fenics.org/mailman/listinfo/dolfin-dev
> >>> >
> >>> >
> >>
> >>> // Place for random tests
> >>>
> >>> #include <dolfin.h>
> >>> #include "Poisson.h"
> >>>
> >>> using namespace dolfin;
> >>>
> >>> class MyFunction : public Function
> >>> {
> >>> public:
> >>>
> >>>   MyFunction(const FunctionSpace& V) : Function(V) {};
> >>>
> >>>   void eval(double* values, const double* x) const
> >>>   {
> >>>     message("Calling eval");
> >>>     double dx = x[0] - 0.5;
> >>>     double dy = x[1] - 0.5;
> >>>     values[0] = 500.0*exp(-(dx*dx + dy*dy) / 0.02);
> >>>   }
> >>> };
> >>>
> >>> class FunctionContainer
> >>> {
> >>> public:
> >>>   FunctionContainer(const FunctionSpace& V)
> >>>   {
> >>>     _f = Function(V);
> >>>   };
> >>>
> >>>   const Function& get_function()
> >>>   {
> >>>     return _f;
> >>>   };
> >>> protected:
> >>>   Function _f;
> >>> };
> >>>
> >>>
> >>> int main()
> >>> {
> >>>   UnitSquare mesh(2, 2);
> >>>   PoissonFunctionSpace V(mesh);
> >>>   MyFunction f(V);
> >>>   Vector x;
> >>>
> >>>   message("Interpolating to another vector");
> >>>   f.interpolate(x, f.function_space());
> >>>   x.disp();
> >>>
> >>>   message("Interpolating to the function vector");
> >>>   f.interpolate(f.vector(), f.function_space());
> >>>   f.vector().disp();
> >>>
> >>>   message("Interpolating using initialising by an external function");
> >>>   MyFunction f_(f);
> >>>   f.interpolate(f_.vector(), f.function_space());
> >>>   f.vector().disp();
> >>>
> >>>   message("Returning Function by reference");
> >>>   FunctionContainer fc(V);
> >>>   Function f2 = fc.get_function();
> >>> }
> >>>
> >>
> >>> _______________________________________________
> >>> DOLFIN-dev mailing list
> >>> DOLFIN-dev@xxxxxxxxxx
> >>> http://www.fenics.org/mailman/listinfo/dolfin-dev
> >>
> >>
> >> -----BEGIN PGP SIGNATURE-----
> >> Version: GnuPG v1.4.9 (GNU/Linux)
> >>
> >> iEYEARECAAYFAkmcOUcACgkQTuwUCDsYZdE/tACghYR+pHvXwurxKi2rKdcAPrtr
> >> XaEAnihNPT9ar+ZLx07ltK+uZM03Ntlc
> >> =8wBa
> >> -----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

Attachment: signature.asc
Description: Digital signature


References