← Back to team overview

ufl team mailing list archive

Re: control statements in UFL

 

2008/8/20 Anders Logg <logg@xxxxxxxxx>:
> On Wed, Aug 20, 2008 at 10:02:37AM +0200, Martin Sandve Alnæs wrote:
>> 2008/8/20 Kristian Oelgaard <k.b.oelgaard@xxxxxxxxxx>:
>> >
>> >
>> > Hi,
>> >
>> > Garth, Anders and I have discussed the possibility of defining control
>> > statements in FFC/UFL. This can be useful for many things but if we
>> > take DG advection diffusion as an example we have the following on an
>> > exterior facet:
>> >
>> > scalar = FiniteElement("Discontinuous Lagrange", "triangle", 1)
>> > vector = VectorElement("Lagrange", "triangle", 2)
>> >
>> > v = TestFunction(scalar)
>> > u = TrialFunction(scalar)
>> >
>> > b   = Function(vector)
>> > n   = FacetNormal("triangle")
>> > # outflow facet switch, computed in DOLFIN (has values 1.0 or 0.0)
>> > of  = Function(constant)
>> >
>> > a = dot(mult(v, n), mult(b, of*u))*ds
>> >
>> > This works, but means that one has to compute the value of 'of' in DOLFIN.
>> > This is currently handled by OutflowFacet in SpecialFunctions.h but to me
>> > it seems silly to add an additional argument to a form the value of which
>> > depends on the value of other arguments to the form. Wouldn't it be much
>> > nicer to let FFC/UFL produce code that can decide which values to use in
>> > tabulate_tensor()?
>> >
>> > So the question is how we can do this. I think the following could work
>> > but I don't know for sure and I definitely do not know if it's the best
>> > solution:
>> >
>> >
>> > A new FFC/UFL type with possible interface like this:
>> >
>> > Condition( left, logical_operator, right, return_value, else (optional) )
>>
>>
>> I'm not a fan of the "else (optional)". I didn't understand
>> the example below intuitively before I read this line.
>>
>> Maybe we can have named conditional operators (mirroring fortran):
>>
>>   eq(left, right) # ==
>>   ne(left, right) # !=
>>   le(left, right) # <=
>>   lt(left, right) # <
>>   ge(left, right) # >=
>>   gt(left, right) # >
>>
>> And the conditional can then be more "structured" (shorter argument
>> list, in a way):
>>
>>   c = Conditional(a, lt(left, right), b)
>>
>> mirroring "c = a if (left<right) else b" in python,
>> or:
>>
>>   c = Conditional(lt(left, right), a, b)
>
> I think this second option looks better.
>
> But wouldn't it be possible to just overload <, >, = etc for UFLObject
> so that one may do
>
>  c = Conditional(left < right, a, b)


The reason we can't do that is that those operators
(at least ==) are used for other things, like putting
expressions in sets and dicts which we cannot avoid.
If we allow it for <, >, <=, >=, but not ==, people
will be confused and make errors.


> or even
>
>  a = dot(v*n, (left < right)*u + (1 - left < right)*sin(u))*ds
>
> We could have left < right return a Conditional object which would
> return either 1 or 0 (in the generated code) depending on whether the
> comparison is true or false.

1 or 0 is a very special case, we should have the Conditional(condition, a, b).

-- 
Martin


Follow ups

References