← Back to team overview

dolfin team mailing list archive

Re: Function evaluation

 



On Sat, 4 Oct 2008, Anders Logg wrote:

On Fri, Oct 03, 2008 at 11:22:49PM +0100, Garth N. Wells wrote:


Anders Logg wrote:
On Fri, Oct 03, 2008 at 11:06:46PM +0100, Garth N. Wells wrote:

Anders Logg wrote:
User-defined functions are currently defined by overloading eval().
The eval() function is available in two different versions, for vectors
(tensors) and scalars:

  void eval(double* values, const double* x) const;

  double eval(const double* x) const;

This might be ok, but functions may also depend on the current cell,
the current facet, and perhaps on the current time and other data.
These are accessible by this->cell, this->facet.

So, a function depends on x and other things and it's not obvious what
additional data a function does depend on. Are there any suggestions
for what the interface should look like for user-defined functions?

One option could be to let functions be defined by expressions
(function pointers) given to the constructor of Function. That way,
one could define a function by

  void source(const double* x) { sin(x[0]); }

  f = Function(mesh, source);

This way, there could be many different types of function pointers,
all taking a different number of arguments, and we could differentiate
between the different types.

I'm not a fan of function pointers, and I don't see how the above
solution would help if a Function depends on other data.

It would help to do things like

  double foo(const double* x) { return sin(x[0]); }
  double bar(const double* x, real t) { return t*sin(x[0]); }

  f = Function(foo);
  g = Function(bar);



I don't follow how this would work - Function will call foo, but it
doesn't know what t is? PETSc uses pointers to function in SNES, but as
far as I recall the function must have a prescribed interface.

Function could have a member _t which is initialized to zero and it
may be updated, either by user-code or by DOLFIN (if DOLFIN should
happen to know an appropriate value of t).

But replace t by cell above and we would have the same situation.

Function would know what kind of user-defined function it is because
we may overload different constructors for different types of function
pointers.

Another option if we want to avoid function pointers is to allow a number
of different eval functions (we have 2 now) and figure out an
appropriate way to decide which one to call. One of them (the main one
that gets all the arguments) would try calling each one of the others
to see which one is implemented. This is how it works now for scalar
eval().

Can the user just call the eval function directly? i.e. is it a public member function? If not, then why not just make it public, and the user calls whichever one he needs? maybe I am missing the point...

- Shawn

--
Anders



Follow ups

References