← Back to team overview

dolfin team mailing list archive

Re: Function evaluation

 

On Fri, Oct 03, 2008 at 06:46:56PM -0400, Shawn Walker wrote:
>
>
> 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

Yes, it's public. But it's used for two purposes. One is when a user
calls eval() to evaluate a function at a point (so DOLFIN must provide
this for functions in a finite element space), and the other purpose
is when a user supplies a function to DOLFIN. DOLFIN calls eval()
during assembly to interpolate user-defined functions into the finite
element space.

-- 
Anders

Attachment: signature.asc
Description: Digital signature


References