Anders Logg wrote:
> 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?
> 

Kristian?

> 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.
> 

I think you mean element rather than cell?

Garth

>>>>> 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
>> [email protected]
>> http://www.fenics.org/mailman/listinfo/dolfin-dev

_______________________________________________
DOLFIN-dev mailing list
[email protected]
http://www.fenics.org/mailman/listinfo/dolfin-dev

Reply via email to