← Back to team overview

ufl team mailing list archive

Re: UFL transformer

 

On Fri, Feb 20, 2009 at 2:54 PM, Kristian Oelgaard
<k.b.oelgaard@xxxxxxxxxx> wrote:
> Quoting Martin Sandve Alnæs <martinal@xxxxxxxxx>:
>
>> Hi Kristian,
>> I'm sending this to ufl-dev as well, some others may be interested.
>> (For those who don't know what the Transformer is,
>> it is partially documented in the manual now.)
>>
>> First you need to understand the difference between defining handlers
>> as pre- or post-handlers:
>>
>>    def index_sum(self, index_sum, summand, index):
>>        ... summand and index has already been visited
>> vs
>>    def index_sum(self, index_sum):
>>        #... visit summand and index yourself:
>>        summand, index = index_sum.operands()
>>        summand = self.visit(summand)
>>        ...
>>
>> Then consider that you can attach arbitrary data structures
>> to 'self' and update them during the recursion. Thus you can
>> keep a stack of the current component and indices:
>> push values before visiting subtrees, pop values when they return,
>> peek at the top of the stack to get the current value.
>> Take a look at the Stack and StackDict classes in ufl.common.
>> Something like this would evaluate an index sum
>> (probably not what you want now, just an example):
>>
>>    def index_sum(self, index_sum):
>>        #... visit summand and index yourself:
>>        summand, index = index_sum.operands()
>>        tmp = 0
>>        for i in range(index_sum.dimension()):
>>            self._index_values.push(index, i)
>>            tmp += self.visit(summand)
>>            self._index_values.pop()
>>        return tmp
>
> I think this approach will work out, I was thinking about using the replace()
> algorithm, but didn't because it has potential of becoming super slow.

I used this approach in SyFi/newsfc, but haven't got around to update it
to the latest UFL. The evaluate functions in UFL have evolved from newsfc.

>> where self._index_values is a StackDict with a "Index -> int" mapping.
>>
>> I'll dig up an example of this, but take a look at e.g.
>> IndexSum.evaluate, Indexed.evaluate, and
>> ComponentTensor.evaluate for the same concept.
>>
>> Also, you should apply expand_derivatives to the form before
>> you start working with it. This will get rid of all FunctionDerivative
>> and VariableDerivative nodes, and propagate all SpatialDerivative
>> occurences to terminals, so when you handle a SpatialDerivative
>> you know its operand is a terminal (eventually another
>> SpatialDerivative for higher order derivatives).
>> (I'm currently ironing out some bugs here.)
>
> OK, thanks for the hint.
>
>> Are you working on quadrature or tensor code generation?
>> I see Anders is working on monomial representation,
>> so I'm guessing quadrature?
>
> Yes, I'm working on quadrature. Still poking in all different directions to get
> an idea of how to do things.
>
> Kristian

Good, at least you get to know the code.

Martin


References