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

Computation of the Hessian operator

0 votes

I am confused by second derivatives with fenics. I would like to compute the tensor field associated to the hessian of a vector field.

I started with the matrix field corresponding to the hessian of a scalar field and tried 2 different approaches (see code below):
- by projecting grad(grad(u)),
- by projecting u.dx(i).dx(j),
but none of them returns a good result.

Is there any way to get the proper field in the scalar case?
Thanks!

from __future__ import (division, print_function)
import dolfin as df
import sympy as sy
import sympy.printing as syp


pt = 0.5, 0.5

x, y = sy.symbols('x y')

uexpr = x ** 3 + y ** 3
jacexpr = [sy.diff(uexpr, s) for s in [x, y]]
hessexpr = [sy.diff(ex, s) for ex in jacexpr for s in [x, y]]

dfexpr = syp.ccode(uexpr).replace('x', 'x[0]').replace('y', 'x[1]')

print('Sympy expressions:')
print(uexpr)
print(jacexpr)
print(hessexpr)

print('\nDolfin expression:')
print(dfexpr)

print('\nANALYTIC SOLUTION:')
print('u(pt) =', uexpr.subs([(x, pt[0]), (y, pt[1])]))
print('jac(pt) =', [ex.subs([(x, pt[0]), (y, pt[1])]) for ex in jacexpr])
print('hess(pt) =', [ex.subs([(x, pt[0]), (y, pt[1])]) for ex in hessexpr])


expr = df.Expression(dfexpr)

n = 20
mesh = df.UnitSquareMesh(n, n)
deg = 3

Vu = df.FunctionSpace(mesh, 'Lagrange', deg)
umesh = df.project(expr, Vu)

Vg = df.VectorFunctionSpace(mesh, 'Lagrange', deg - 1)
jacmesh = df.project(df.grad(umesh), Vg)

Vh = df.TensorFunctionSpace(mesh, 'Lagrange', deg - 2)
hessmesh = df.project(df.grad(df.grad(umesh)), Vh)

print('\nPROJECTION:')
print('u(pt) =', umesh(pt))
print('jac(pt) =', jacmesh(pt))
print('hess(pt) =', hessmesh(pt))

Vgc = df.FunctionSpace(mesh, 'Lagrange', deg - 1)
Vhc = df.FunctionSpace(mesh, 'Lagrange', deg - 2)
jaccomp = [df.project(umesh.dx(i), Vgc) for i in range(2)]
hesscomp = [df.project(umesh.dx(i).dx(j), Vhc)
            for i in range(2) for j in range(2)]

print('\nCOMPONENTS:')
print('jac(pt) =', [j(pt) for j in jaccomp])
print('hess(pt) =', [h(pt) for h in hesscomp])
asked Aug 5, 2016 by Lolog FEniCS Novice (160 points)

1 Answer

0 votes

It turns out that

hessmesh = df.project(df.grad(df.grad(umesh)), Vh)

fails but

hessmesh = df.project(df.grad(jacmesh), Vh)

works.

I don't know if it is a bug or a feature.

answered Aug 7, 2016 by Lolog FEniCS Novice (160 points)
...