On Fri, Nov 13, 2009 at 08:18:38AM +0000, Garth N. Wells wrote: > > > Anders Logg wrote: > > 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) > >>> > > We could also have > > f = Expression("sin(x[0])", mesh, k) > > where k is the order of the continuous Lagrange basis since that's the > most commonly used. > > >>> 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 is bad. If a user increases the polynomial order of the test/trial > functions and f remains P1, the convergence rate will not be optimal. > > A better solution would be to define it on a QuadratureElement by > default. This, I think, is the behaviour that most people would expect. > This would take care of higher-order cases.
Yes, I've thought about this. That would perhaps be the best solution. Does a quadrature element have a fixed degree or can the form compiler adjust it later to match the degree of for example the basis functions in the form? If one should happen to differentiate a coefficient in a form, we just need to give an informative error message and advise that one needs to specify a finite element for the approximation of the coefficient. > >>> 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). > > But it is when it's used in a form since it's interpolated in the given > space. The important point is that we only need to be able to interpolate it locally to any given cell in the mesh, so we just need a mesh and a cell. The dofmap is never used so it's different from a full function space. > >>> 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) > >>> > > Yes. Good. > >>> 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. > > Agree. Good. -- Anders > Garth > > 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. > > > > > _______________________________________________ > DOLFIN-dev mailing list > DOLFIN-dev@fenics.org > http://www.fenics.org/mailman/listinfo/dolfin-dev
signature.asc
Description: Digital signature
_______________________________________________ DOLFIN-dev mailing list DOLFIN-dev@fenics.org http://www.fenics.org/mailman/listinfo/dolfin-dev