This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

UFL: evaluate the derivative of an expression at a value

+1 vote

Hi, I'd like to have FEniCS / UFL evaluate the derivative of a function, say
f =2*t**2
at a specific argument, say t=2.

I had thought to find the derivative using diff, and then the 'replace' ufl function, but it seems in declaring 't' as a variable (in order to differentiate), replace fails with:
"This implementation can only replace Terminal objects."

MWE:

from dolfin import *
element = FiniteElement("CG", tetrahedron, 1)
t = Coefficient(element)
f1 = 2*t**2
print replace(f1,{t:2}) # works

t = variable(t)
f2 = 2*t**2
print replace(diff(f2,t),{t:2})

Thanks

asked Nov 24, 2016 by mwelland FEniCS User (8,410 points)

1 Answer

+1 vote
 
Best answer

I could only get this to work after calling apply_derivatives. I really hope there's a better way which someone will point out. I'd like to use the same functionality.

from dolfin import *
import ufl
element = FiniteElement("CG", tetrahedron, 1)
t = Coefficient(element)
f1 = 2*t**2
print replace(f1,{t:2}) # works

# t = variable(t)
f2 = 2*t**2
df2_dt = ufl.algorithms.apply_derivatives.apply_derivatives(diff(f2, t))
print replace(df2_dt, {t: 2})
answered Nov 24, 2016 by nate FEniCS Expert (17,050 points)
selected Nov 30, 2016 by mwelland

Thanks very much Nate! It works for my purposes, but I will hold off selecting 'best answer' for now in the hopes someone has a simpler way...

I explored this a little more. It seems that

diff(f2,t)

in the above works without having to define

t=variable(t)

In fact, I'd like to take derivatives with respect to a subspace of a mixed element as below. This won't work without defining

t = variable(t)

and unfortunately, the method above breaks down too...

from dolfin import *
import ufl
mesh = IntervalMesh(10, 0, 1)

P1 = FiniteElement("Lagrange",mesh.ufl_cell(),1)
PS = MixedElement([P1,P1])
VS = FunctionSpace(mesh,PS)

U = Function(VS)
t,p=split(U)

f1 = 2*t**2             # Function expression
#print replace(f1,{t:2}) # Test 'replace' works -> yes

t = variable(t)         # Make t a variable
f2 = 2*t**2             # Define a new expression with t defined as a variable (not sure if necessary)
f2dt = ufl.algorithms.apply_derivatives.apply_derivatives(diff(f2, t))

I get the error "ufl.log.UFLException: This implementation can only replace Terminal objects."

For prosperity, the following defines a function -> f1(tt), which can be evaluated at a point, differentiated and then evaluated at a point, and then either the function or its derivative applied to one element of a split mixed function:

from dolfin import *
import ufl
mesh = IntervalMesh(10, 0, 1)

P1 = FiniteElement("Lagrange",mesh.ufl_cell(),1)
PS = MixedElement([P1,P1])
V1 = FunctionSpace(mesh,P1)
VS = FunctionSpace(mesh,PS)

U = Function(VS)
t,p=split(U)
tt = Function(V1)


f1 = 2*tt**2             # Function expression
print replace(f1,{tt:1}) # Test 'replace' works -> yes
a = diff(f1,tt) # Diff works despite tt not being decalred a variable
dfdt = ufl.algorithms.apply_derivatives.apply_derivatives(diff(f1, tt))
print replace(dfdt,{tt:1}) # Test 'replace' works on derivative -> yes

print replace(f1,{tt:t})    # both look correct
print replace(dfdt,{tt:t})  # looks correct
...