# UFL Representation of Differentiation

**URL:** <https://fenicsproject.discourse.group/t/ufl-representation-of-differentiation/5507>\
**Category:** Uncategorized\
**Created:** [April 5, 2021, 10:56am UTC](https://fenicsproject.discourse.group/t/ufl-representation-of-differentiation/5507 "2021-04-05T10:56:42Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![CMA](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/cma/32/621_2.png) [@CMA](https://fenicsproject.discourse.group/u/CMA)\
**Post date:** [April 5, 2021, 10:56am UTC](https://fenicsproject.discourse.group/t/ufl-representation-of-differentiation/5507/1 "2021-04-05T10:56:42Z")

</div>

Hello,

I’m just try to understand the resultant of `diff` operator. It is a good way to get differentiation with automated way but is it possible to represent the resultant explicitly by UFL representation ?

An example from hyperelasticity:

```
F = Identity(len(u)) + grad(u)
F = variable(F)
.
.
.

```

`#Free Energy Form:`  
`psi= (mu/2)*((Ic - 3))- mu*ln(J) + (lmbda/2)*(ln(J))**2`

```
#Exact PK Sress:
S_exact = lambda F: mu * F - mu * inv(F).T + lmbda * ln(det(F)) * inv(F).T

#Alternative PK Stress:
S_alter = diff(psi, F)

```

For simple problems as above, it is simple to take difference between S\_exact and S\_alter but for complicated energy functions, I cannot be sure about the resultant of `diff` operator. Is there any way to print the result of S\_Alter explicitly as we write S\_exact ?

Regards,

---

<div class="post-metadata">

**Author:** ![kamensky](https://avatars.discourse-cdn.com/v4/letter/k/e95f7d/32.png) [@kamensky](https://fenicsproject.discourse.group/u/kamensky)\
**Post date:** [April 5, 2021, 11:48am UTC](https://fenicsproject.discourse.group/t/ufl-representation-of-differentiation/5507/2 "2021-04-05T11:48:44Z")

</div>

You can print the symbolic form of derivatives from `diff` as follows:

```python
from dolfin import *
from ufl.algorithms.ad import expand_derivatives
u = Constant(1)
u.rename("u","u")
u = variable(u)
f = exp(sin(u**2))
df_du = diff(f,u)
print(expand_derivatives(df_du))

```

In the above minimal example, it’s easy to interpret and verify the output, but the automatically-generated derivatives of more complicated expressions may not be simplified in the same way as they would be when calculated by hand, which can make them difficult to read.

---

<div class="post-metadata">

**Author:** ![CMA](https://yyz2.discourse-cdn.com/free1/user_avatar/fenicsproject.discourse.group/cma/32/621_2.png) [@CMA](https://fenicsproject.discourse.group/u/CMA)\
**Post date:** [April 5, 2021, 12:24pm UTC](https://fenicsproject.discourse.group/t/ufl-representation-of-differentiation/5507/3 "2021-04-05T12:24:30Z")

</div>

Hello kamensky,

Thanks for your answer. I tried your simple example, and it works well. However, for complicated one I got thousands of lines which is not meaningful as below:

```
{ A | A_{i_{229}, i_{230}} = (({ A | A_{i_{221}, i_{222}} = f_21[5] * (sum_{i_{47}} ({ A | A_{i_{219}, i_{220}} = ([0, 1.0, 0])[i_{47}] * ({ A | A_{i_{217}, i_{218}} = ({ A | A_{i_{38}, i_{215}, i_{216}} = (sum_{i_{39}} ({ A | A_{i_{213}, i_{214}} = ([0, 1.0, 0])[i_{39}] * ({ A | A_{i_{211}, i_{212}} = ({ A | A_{i_{35}, i_{36}, i_{209}, i_{210}} = (sum_{i_{37}} ({ A | A_{i_{207}, i_{208}} = ({ A | A_{i_{203}, i_{204}} = ({ A | A_{i_{12}, i_{13}, i_{133}, i_{134}} = (sum_{i_{14}} ({ A | A_{i_{131}, i_{132}} = ({ A | A_{i_{129}, i_{130}} = ({ A | A_{i_{51}, i_{53}, i_{52}, i_{54}} = I[i_{51}, i_{52}] * I[i_{53}, i_{54}] })[i_{12}, i_{14}, i_{129}, i_{130}] })[i_{131}, i_{132}] * ({ A | A_{i_{42}, i_{43}} = ([
  [(({ A | A_{i_{40}, i_{41}} = ([0, 0, 1.0])[i_{40}] * ([0, 0, 1.0])[i_{41}] }) + ({ A | A_{i_{10}, i_{11}} = (I + ({ A | A_{i_8, i_9} = -1 * ({ A | A_{i_{40}, i_{41}} = ([0, 0, 1.0])[i_{40}] * ([0, 0, 1.0])[i_{41}] })[i_8, i_9] }))[i_{10}, i_{11}] * (1 + f_45) }))[1, 1] * (({ A | A_{i_{40}, i_{41}} = ([0, 0, 1.0])[i_{40}] * ([0, 0, 1.0])[i_{41}] }) + ({ A | A_{i_{10}, i_{11}} = (I + ({ A | A_{i_8, i_9} = -1 * ({ A | A_{i_{40}, i_{41}} = ([0, 0, 1.0])[i_{40}] * ([0, 0, 1.0])[i_{41}] })[i_8, i_9] }))[i_{10}, i_{11}] * (1 + f_45) }))[2, 2] + -1 * (({ A | A_{i_{40}, i_{41}} = ([0, 0, 1.0])[i_{40}] * ([0, 0, 1.0])[i_{41}] }) + ........

```

Is there any other method to read it ?

---

<div class="post-metadata">

**Author:** ![kamensky](https://avatars.discourse-cdn.com/v4/letter/k/e95f7d/32.png) [@kamensky](https://fenicsproject.discourse.group/u/kamensky)\
**Post date:** [April 5, 2021, 2:05pm UTC](https://fenicsproject.discourse.group/t/ufl-representation-of-differentiation/5507/4 "2021-04-05T14:05:11Z")

</div>

The output is technically meaningful; you can still interpret simpler examples like the following:

```python
from dolfin import *
from ufl.algorithms.ad import expand_derivatives
u = Constant((1,1))
u.rename("u","u")
u = variable(u)
v = Constant((1,1))
v.rename("v","v")
print(expand_derivatives(diff(dot(u,v),u)))

```

What a human analyst might write is:

\frac{\partial (u\_i v\_i)}{\partial u\_j} = \delta\_{ij}v\_i = v\_j

The output

```auto
sum_{i_8} ({ A | A_{i_{10}} = ({ A | A_{i_9} = I[i_8, i_9] })[i_{10}] * v[i_8] })

```

corresponds roughly to the first equality (where \delta is `I`). The notation

```auto
({ A | A_{x} = y })

```

can be read "an indexed tensor with free indices `x`, defined as `y`". The definition `y` may itself be defined in terms of more such indexed tensors. In the above example, the free index j is `i_10` and the summation index i is `i_8`.

Of course, anything even slightly more complex becomes very tedious to read. However, the differentiation is already pretty well validated. Thus, it’s likely not worth the effort to try deciphering UFL’s internal representation of derivatives, which is better-suited to automation and code generation than human readability.
