This PR builds on the dual space changes recently introduced (#21, #25) and introduces the symbolic interpolation operator (ufl.Interpolate). This PR prepares the ground for operators that can be seen as operators and as forms such as Interp or ExternalOperator. Most of the bits in this PR come from the ExternalOperator dual branch which will come in another PR.
For example, let I(u, V2) be the interpolation of the coefficient u \in V1 into the function space V2, where I refers to the interpolation operator I: V1 -> V2. I can also be seen as a form using the reflexivity of V2. That is, we have I: V1 x V2^{*} -> R where I is linear with respect to both entries, we use the notation I(u, v^*) where v^* is a Coargument in V2
Main components of this PR:
Add BaseFormOperator:
We introduce the so-called BaseFormOperator class which accounts for operators than can also be seen as forms such as Interpolate or ExternalOperator.
Add Interpolate:
Add the Interpolate class which we refer to as the symbolic interpolation operator.
Add differentiation mechanisms for BaseFormOperator objects and Interpolate differentiation:
Add a BaseFormOperatorDerivative node
Add differentiation (2 stages mechanism) for base form operators:
dF(u, I(u, v^{*}); v)/du [uhat] = \partial F/\partial u + Action(dF/dI, dI/du)
which works by:
Applying differentiation by traversing the DAG and whenever we see a BaseFormOperator, we return 0 and record the operations, i.e. instead of returning dF/du we return \partial F/\partial u.
Applying chain rule on the recorded operations, i.e. add terms like Action(dF/dI, dI/du) for all the base form operators that got recorded.
This PR builds on the dual space changes recently introduced (#21, #25) and introduces the symbolic interpolation operator (
ufl.Interpolate
). This PR prepares the ground for operators that can be seen as operators and as forms such asInterp
orExternalOperator
. Most of the bits in this PR come from theExternalOperator
dual branch which will come in another PR.For example, let
I(u, V2)
be the interpolation of the coefficientu \in V1
into the function spaceV2
, whereI
refers to the interpolation operatorI: V1 -> V2
.I
can also be seen as a form using the reflexivity ofV2
. That is, we haveI: V1 x V2^{*} -> R
whereI
is linear with respect to both entries, we use the notationI(u, v^*)
wherev^*
is aCoargument
inV2
Main components of this PR:
Add
BaseFormOperator
:We introduce the so-called
BaseFormOperator
class which accounts for operators than can also be seen as forms such asInterpolate
orExternalOperator
.Add
Interpolate
:Add the
Interpolate
class which we refer to as the symbolic interpolation operator.Add differentiation mechanisms for
BaseFormOperator
objects andInterpolate
differentiation:Add a
BaseFormOperatorDerivative
nodeAdd differentiation (2 stages mechanism) for base form operators:
dF(u, I(u, v^{*}); v)/du [uhat] = \partial F/\partial u + Action(dF/dI, dI/du)
which works by:Applying differentiation by traversing the DAG and whenever we see a BaseFormOperator, we return 0 and record the operations, i.e. instead of returning
dF/du
we return\partial F/\partial u
.Applying chain rule on the recorded operations, i.e. add terms like
Action(dF/dI, dI/du)
for all the base form operators that got recorded.Interpolate
differentiation:dI(u, v*)/du [uhat] = I(uhat, v*)
(by linearity).replace_derivative_nodes
algorithm for replacing derivative nodes.Update
analysis.py
(cf. https://github.com/firedrakeproject/ufl/pull/26)