dolfin team mailing list archive
-
dolfin team
-
Mailing list archive
-
Message #10877
Re: Another suggestion for the Function class
On Tuesday 02 December 2008 12:06:17 Anders Logg wrote:
> On Tue, Dec 02, 2008 at 12:00:34PM +0100, Martin Sandve Alnæs wrote:
> > 2008/12/2 Anders Logg <logg@xxxxxxxxx>:
> > > Would it be difficult to add the possibility of sending in a SymPy or
> > > Swiginac expression to the Function constructor? As I understand, both
> > > can generate C++ code so it seems we could reuse what we already have
> > > for cppexpr.
> >
> > Trivial. Except that the symbols used must be named like
> > x = swiginac.symbol("x[0]") etc from the user side, we can
> > just call "swiginac_expression.printc()" to get a scalar string.
> > Eventually "swiginac_expression.evalm().evalf().printc()"
> > to be on the safe side.
We need to think of why we want this. Is it to be able to automatic
differentiate a coeffisient function in a form, which I suppose ufl.sin will
be able to, or to _even_ easier write user defined coefficient functions?
If it is the latter, and only the latter, I really do not think we need it. We
have already stated for a user that a compiled coefficient function can be
used by
f = Function(cppexpr = "sin(x[0])")
By this we have stated that we have to do something behind the seen to make it
happen, and I think this is good. It is a one liner and it cannot be
missinterpreted as something else.
If we make it too easy a la,
f = sin(x)
we can run into different namespace trubles as mentioned below. The code above
could produce different results depending of what "sin" actually is.
Introducing swiginac or sympy statements should also include a benefit of
using the symbolic character of these libraries to legitemise the use. Not
only the "to_c" functionality. And as I understand it will at least some of
the symbolic character be supported in ufl, right?
> Can't we just define
>
> x = swiginac.symbol("x[0]")
I am strongly against this. Symbols that are often used in user code should
not be predefined in a library code. I see this quite a bit in dolfin where
the namespace of ffc is included. D, i, j, n and m are all defined and have
explicit meaning. When ffc is used in form files this is obviuosly OK, but
when included in the dolfin namespace we get potential complications.
> in the __init__ file for DOLFIN so x would be available directly, just
> like dx, ds, grad, etc.
>
> > > Then, one could do things like
> > >
> > > f = Function(V, sin(x))
> > >
> > > which would be close to optimal.
> >
> > You're forgetting namespace clashes here...
> > In real code there will have to be detailed imports from different
> > modules or explicit namespace handling to separate
> > sympy.sin, numpy.sin, ufl.sin and math.sin.
>
> Ah, this can be problematic.
Yes, see below.
> > > The best of course would be if one
> > > did not need to first define f and then use it, but instead could
> > > write it directly in the form:
> > >
> > > L = v*sin(x)*dx
> >
> > We can do that easily if we add terminal symbols x,y,z or x[0], x[1],
> > ... to UFL.
> >
> > from ufl import *
> > polygon = triangle
> > element = FiniteElement("CG", polygon, 1)
> > v = TestFunction(element)
> > x = SpatialCoordinate(polygon)
> > f = sin(x[0])
> > a = f*v*dx
> >
> > Generated quadrature code can handle this directly, while tensor
> > representation would require some function extraction magic.
>
> Sounds good.
This looks good, but in a dolfin contex I think we need to hide this, e.g., in
a dolfin.ufl namespace. Then if a user want to include sin, cos, x, y, z...
from ufl in a dolfin setting he/she need to from dolfin.ufl include *, and
they should not be included in a from dolfin import * statement.
Johan
Follow ups
References