Subject: Re: [UFL-dev] UFL transformer

From: Martin Sandve Alnæs <[email-masked]>
Date: Fri, 20 Feb 2009 14:31:59 +0100

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

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

Are you working on quadrature or tensor code generation?
I see Anders is working on monomial representation,
so I'm guessing quadrature?

Martin

On Fri, Feb 20, 2009 at 1:25 PM, Kristian Oelgaard
<[email-masked]> wrote:
>
>
> Hi Martin,
>
> I'm afraid that I need a hint on how to go around the only big problem I have
> with Transformer.
>
> The problem is picking components or taking derivatives of BasisFunctions
> (essentially FormArguments)
>
> When I generate the code i.e. handle a BasisFunction, I need to know which
> component is asked for and the number of derivatives and in which direction.
> This is difficult in the current setup as BasisFuncion will be handled *before*
> SpatialDerivative or Indexed.
>
> I think one way of handling this would be to traverse the entire expression in a
> forward fashion first and apply indices and derivatives to the BasisFunction by
> creating a new class object which can be handled by the Transformer. Could this
> work? Or is there an obvious way around this which I just don't see?
>
> Kristian
>

---

From: Kristian Oelgaard <[email-masked]>
Date: Fri, 20 Feb 2009 14:54:24 +0100

>            tmp += self.visit(summand)

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'm currently ironing out some bugs here.)

OK, thanks for the hint.
 
> 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
 
> _______________________________________________
> UFL-dev mailing list
> [email-masked]
> http://fenics.org/mailman/listinfo/ufl-dev
>

---

From: Martin Sandve Alnæs <[email-masked]>
Date: Fri, 20 Feb 2009 14:57:58 +0100

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

> an idea of how to do things.

Good, at least you get to know the code.

Martin