← Back to team overview

dolfin team mailing list archive

Re: Function evaluation

 



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.

I'm not saying I want to do this, just wondering if it's a good
option.


Always fun to discuss.

Constructing a class for a user-defined function is more verbose, but for complicated problems we've found it quite useful to create classes which are sub-classes of both Function and SubDomains so the boundary and the boundary condition are defined in the same class. For time-dependent problems, we let the class own a reference to the current time.

Garth

Isn't it enough to inherit also from TimeDependent?


Yes, but it's easy to just program it for each class. I added TimeDependent a long time ago before I understood C++ ;).

Garth




------------------------------------------------------------------------

_______________________________________________
DOLFIN-dev mailing list
DOLFIN-dev@xxxxxxxxxx
http://www.fenics.org/mailman/listinfo/dolfin-dev




Follow ups

References