← Back to team overview

dolfin team mailing list archive

Re: Special functions in new PyDOLFIN functions

 

On Friday 26 December 2008 09:02:27 Harish Narayanan wrote:
> Johan Hake wrote:
> > You can always define a complex JIT-compiled function in PyDOLFIN. Using
> > this functionality, everything should just work ;)
> >
> >   >>> cppcode = '''
> >
> >   class MyFunc : public Function
> >   {
> >   public:
> >      MyFunc(FunctionSpace& V) : Function(V) {}
> >      void eval(double* values, const Data& data) const{
> >        double time = data.t;
> >        double first_normal = data.normal()[0];
> >        ...
> >      }
> >   };
> >   '''
> >
> >   >>> f = Function(V,cppcode)
>
> I did not know this, I will try to use this way of defining functions
> instead.

It's all in the docstring :)

> >> I've been told time ought to "just work," but will the Python gurus be
> >> adding support for other special functions like facet normals soon?
> >
> > Well, sadly this is not true (for now). The time, 't', is passed with the
> > Data argument to eval using the eval(double *value, const Data data)
> > function of Function. When produce the code for the JIT-compiled
> > functions using the simple c++-expressions, we overload the the simpler
> > eval(double *value, const double *x) function. The descision for this
> > was, that if a user want more complex expressions in its JIT compiled
> > functions it should use the above explained JIT compilation.
>
> Is the reasoning for this that overloading eval is a lot slower than
> JIT-compiling the function?

There are two, at least, eval function in the c++ interface of Function. Both 
take double *values as argument, together with either a Data or double *x 
argument. For convinience we have chosen to overload the simpler eval 
function for the produced and wrapped c++ code. There will be no difference 
in performance.

> > We could add access to some of the common attributes of Data in the
> > simpler c++-expression JIT compiled Functions too. By overloading
> > eval(double *value, const Data data) and then map all use of:
> >
> >   't' to 'data.t'
> >   'n' to 'data.normal()'
> >   'h' to 'data.Cell().diameter()'
> >
> > Doing this we should be able to support:
> >   >>> f = Function(V,"t*n[0]*h*sin(x[0])")
> >
> > I desided not to implement this with reason mentioned above.
>
> Your definition of 'f' above is along the lines of what I want to do,
> but if it is going to be inefficient to wrap these common variables and
> overload eval, I will use the cppcode-style definition directly.

It is only convinience aspects that's behind that descision. More special 
characters that "mean" something in the c++ expression strings will also be 
more error prone.

Johan


References