← Back to team overview

dolfin team mailing list archive

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

 

On Wed, Feb 18, 2009 at 05:05:00PM +0000, A Navaei wrote:
> 2009/2/18 Anders Logg <logg@xxxxxxxxx>:
> > On Wed, Feb 18, 2009 at 04:48:00PM +0000, A Navaei wrote:
> >> 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.
> >> >
> >> >> 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.
> >>
> >> >
> >> > 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.
> >
> > Yes, this is expected behavior. What happens when you do
> >
> >  _f = Function(V);
> >
> > are the following two things:
> >
> > 1. The constructor in Function is called with V to create a
> > user-defined function with a missing eval operator (and no vector).
> >
> > 2. The assignment operator is called to assign that function to _f.
> >
> > This won't work since what you are assigning from does not have a
> > vector.
> >
> > The following will work:
> >
> >  Function g(V);
> >  g.vector();
> >  _f = g;
> 
> I didn't know that g.vector() is supposed to initialise a vector?

No, that's hard to figure out from the help text. I've updated it to
explain this better.

-- 
Anders



> I thought it would return one:
> 
> http://www.fenics.org/pub/documents/dolfin/dolfin-progr-reference/d2/d42/classdolfin_1_1Function.html#db09253826459af5460acd5e3f52ea78
> 
> Anyway, as long as it works, that's all I wanted to know.
> 
> 
> -Ali
> 
> >
> >
> >>
> >> -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
> >
> > -----BEGIN PGP SIGNATURE-----
> > Version: GnuPG v1.4.9 (GNU/Linux)
> >
> > iEYEARECAAYFAkmcPfoACgkQTuwUCDsYZdFPDwCfbkDdJK9DIIaZqiZcOtCEXp9I
> > FHIAn3NZGNVb7YMONFF19771JPrYd2Tx
> > =6fEC
> > -----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