← Back to team overview

dolfin team mailing list archive

Re: Expression class

 

On Fri, Nov 13, 2009 at 07:28:07AM +0100, Johan Hake wrote:
> On Thursday 12 November 2009 21:15:51 Anders Logg wrote:
> > I have received some complaints on the new Expression class. It works
> > reasonably well from C++ but is still confusing from Python:
> >
> > 1. Why does a function space need to be specified in the constructor?
> >
> >   f = Expression("sin(x[0])", V=V)
> >
> > Does this mean f is a function on V? (No, it doesn't.)
> >
> > 2. The keyword argument V=foo is confusing:
> >
> >   f = Expression(("sin(x[0])", "cos(x[1])"), V=V)
> >   g = Expression("1 - x[0]", V=Q)
> >
> > The reason for the function space argument V is that we need to know
> > how to approximate an expression when it appears in a form. For
> > example, when we do
> >
> >   L = dot(v, grad(f))*dx
> >
> > we need to interpolate f (locally) into a finite element space so we
> > can compute the gradient.
> >
> > Sometimes we also need to know the mesh on which the expression is defined:
> >
> >   M = f*dx
> >
> > This integral can't be computed unless we know the mesh which is why
> > one needs to do
> >
> >   assemble(M, mesh=mesh)
> >
> > My suggestion for fixing these issues is the following:
> >
> > 1. We require a mesh argument when constructing an expression.
> >
> >   f = Expression("sin(x[0])", mesh)
> >
> > 2. We allow an optional argument for specifying the finite element.
> >
> >   f = Expression("sin(x[0])", mesh, element)
> >
> > 3. When the element is not specified, we choose a simple default
> > element which is piecewise linear approximation. We can derive the
> > geometric dimension from the mesh and we can derive the value shape
> > from the expression (scalar, vector or tensor).
> >
> > This will remove the need for the V argument and the confusion about
> > whether an expression is defined on some function space (which it is
> > not). It also removes the need for an additional mesh=mesh argument
> > when assembling functionals and computing norms.
> >
> > This change will make the Constant and Expression constructors very
> > similar in that they require a value and a mesh (and some optional
> > stuff). Therefore it would be good to change the order of the
> > arguments in Constant so they are the same as in Expression:
> >
> >  f = Constant(0, mesh)
> >  f = Expression("0", mesh)
> >
> > And we should change Constant rather than Expression since Expression
> > might have an optional element argument:
> >
> >  f = Expression("0", mesh, element)
> >
> > Does this sound good?
>
> Yes, I think so. I suppose you mean
>
>   f = CompiledExpression("0", mesh)
>
> Just referring to the Blueprint about the simplification of the Expression
> class in PyDOLFIN.

I'm not so sure anymore. Calling it Expression looks simpler. What
were the reasons for splitting it into Expression and
CompiledExpression? Is it the problem with the non-standard
constructor when implementing subclasses?

It's just that the most common use of expressions in simple demos will
be stuff like

  f = Expression("sin(x([0])", mesh)

so one could argue that this should be as simple as possible (and just
be named Expression).

> Should an Expression in PyDOLFIN  then always have a mesh? This will make an
> Expression in PyDOLFIN and DOLFIN different, which is fine with me.

Yes, to avoid needing to pass the mesh to assemble() and norm() in
some cases and to automatically get the geometric dimension.

> If others agree, can you add it to the Blueprint, mentioned above, and I can
> do the change some time next week, or after a release (?).

Let's hear some more comments first.

--
Anders

Attachment: signature.asc
Description: Digital signature


Follow ups

References