### Is it possible to compute the gradient of a Functional only at a specific point with dolfin-adjoint?

216

views

3

Hi,

I have a problem where I need the gradient of a (dolfin-adjoint) Functional but only at a specific point (and not over the whole domain, as I can solve this right now).

In my working example this would be something like

J = Functional(0.5*inner(u(eval_point) - u_exact(eval_point), u(eval_point) - u_exact(eval_point))*dx)

instead of

J = Functional(0.5*inner(u - u_exact, u - u_exact)*dx)

(which works fine)

I used conda-forge to install fenics and dolfin-adjoint

Thanks for your help!

I have a problem where I need the gradient of a (dolfin-adjoint) Functional but only at a specific point (and not over the whole domain, as I can solve this right now).

In my working example this would be something like

J = Functional(0.5*inner(u(eval_point) - u_exact(eval_point), u(eval_point) - u_exact(eval_point))*dx)

instead of

J = Functional(0.5*inner(u - u_exact, u - u_exact)*dx)

(which works fine)

```
from dolfin import *
from dolfin_adjoint import *
import numpy as np
eval_point = np.array([[0.5],[0.5]])
mesh = UnitSquareMesh(16, 16)
V = FunctionSpace(mesh, "CG", 1)
M = FunctionSpace(mesh, "DG", 0)
def G(m):
u = Function(V, name="observation")
v = TestFunction(V)
def left_boundary(x, on_boundary):
return on_boundary and near(x[0], 0.0)
def right_boundary(x, on_boundary):
return on_boundary and near(x[0], 1.0)
def top_boundary(x, on_boundary):
return on_boundary and near(x[1], 1.0)
right = AutoSubDomain(right_boundary)
top = AutoSubDomain(top_boundary)
markers = FacetFunction("size_t", mesh, 0)
markers.set_all(0)
top.mark(markers, 1)
right.mark(markers, 1)
ds = Measure('ds', domain=mesh, subdomain_data=markers)
F = inner(m*grad(u), grad(v))*dx - Constant(1.0)*v*ds(1)
bc = DirichletBC(V, 0.0, left_boundary)
solve(F == 0, u, bcs=bc)
return u
# exact thermal conductivity
m_exact_M = interpolate(Expression("exp(-((x[0] - 0.5)*(x[0] - 0.5)/2.0*10.0) - ((x[1] - 0.5)*(x[1] - 0.5)/2.0*10.0)) + 2.0", degree=2), M)
u_exact = G(m_exact_M)
'The part of major relevance__________________________________________________'
m = interpolate(Constant(3.0), M, name="parameter")
u = G(m)
J = Functional(0.5*inner(u - u_exact, u - u_exact)*dx)
m_c = Control(m)
gradient = compute_gradient(J, m_c)
```

Is there a way to avoid integration over the whole domain and evaluate this functional at a specific point (with dolfin-adjoint)?

I’ve already tried to solve this with a Dirac function, but gradient checking didn’t show the same results. Maybe there’s a way to do this with MeshFunctions?I used conda-forge to install fenics and dolfin-adjoint

Thanks for your help!

Community: FEniCS Project

### 1 Answer

0

Sure, just mark the cells adjacent to the point you want to evaluate -- you must do this as the gradient requires more than just a single point to compute -- then make your "Functional" :

where the cells around your point you care about are marked "1".

`J = Functional(0.5*inner(u - u_exact, u - u_exact)*dx(1))`

where the cells around your point you care about are marked "1".

Please login to add an answer/comment or follow this question.