← Back to team overview

dolfin team mailing list archive

Re: Function evaluation

 

On Fri, Oct 3, 2008 at 5:22 PM, Garth N. Wells <gnw20@xxxxxxxxx> 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.

It has a context argument for user data.

  Matt

>> 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
>
>
> _______________________________________________
> DOLFIN-dev mailing list
> DOLFIN-dev@xxxxxxxxxx
> http://www.fenics.org/mailman/listinfo/dolfin-dev
>



-- 
What most experimenters take for granted before they begin their
experiments is infinitely more interesting than any results to which
their experiments lead.
-- Norbert Wiener


Follow ups

References