ufl team mailing list archive
-
ufl team
-
Mailing list archive
-
Message #00768
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