dolfin team mailing list archive
-
dolfin team
-
Mailing list archive
-
Message #09982
Re: Function evaluation
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().
--
Anders
Attachment:
signature.asc
Description: Digital signature
Follow ups
References