Implement support for new representation of spatial derivatives of functions after UFL has applied differentiation algorithm

Registered by Martin Sandve Alnæs

UFL has since before the summer had an alternative way to represent spatial derivatives of functions after the differentiation algorithm has been applied. This cannot be enabled by default in UFL because it will break existing form compilers. Supporting this in FFC will probably improve scalability for complicated forms right away, and is a prerequisite for the work-in-progress algorithms from uflacs to work properly.

The issue is the representation of spatial derivatives of functions (Coefficient/Argument) after the differentiation algorithm has
been applied. In the current vs new implementation, they are represented as e.g.

SpatialDerivative(Coefficient(V), MultiIndex((i,)))
Indexed(Grad(Coefficient(V)), MultiIndex((i,)))


ComponentTensor(SpatialDerivative(Coefficient(V), MultiIndex((i,))), MultiIndex((i,)))

So basically, the difference is that you will not encounter SpatialDerivative in an expression after expand_derivatives has been applied, but you will encounter Grad. Other derivatives like div and curl are represented in terms of Grad instead of SpatialDerivative.

The important property of the new representation is that indexing operations are distinct from operations introducing new actual values into an expression, which makes it a lot easier to identify common subexpressions involving Grad(f).

To enable this behaviour change in ufl, you need to do this before anything else:
    import ufl.algorithms.ad
    ufl.algorithms.ad.expand_derivatives = ufl.algorithms.ad.expand_derivatives2

I don't feel up to the task of implementing this without risking breaking lots of stuff, but I'll be happy to review changes and answer any further questions!

Blueprint information

Series goal:
Milestone target:
Started by
Martin Sandve Alnæs
Completed by
Martin Sandve Alnæs


This blueprint supersedes https://blueprints.launchpad.net/ffc/+spec/changed-representation-of-function-gradients-in-ufl

msa: I took the liberty to set priority to high, as this is highly important for memory and performance with complicated forms.

I have attempted to implement this change in the linked branches, without any validation, but looking at the ffc demo references the resulting code seems to get a much higher operation count. Kristian has agreed to take a look at it next week.

kbo: Did something change in the estimate_total_polynomial_degree function in UFL? Using FEniCS 1.0, the Elasticity.ufl demo in FFC estimates the polynomial degree to 0, while the dev version (and the linked repos for ufl and ffc) the degree is estimated to 2. This leads to using more quadrature points and increase in operation count. Forcing both versions to using degree 0 or 2 results in the same operation count.
Optimisations also appears to be working.

msa: the ufl degree estimation didn't have a rule for grad, so derivatives did not subtract for the degree when spatial_derivative was replaced by grad. Now it works fine. Note that ffc spends 10-15% more time in compiler stage 2 after this change, but this is a necessary change so I guess it just has to get worse before it gets better.


Work Items

This blueprint contains Public information 
Everyone can see this information.