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

9 months ago by

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)
    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

9 months ago by
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" :

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.

Similar posts:
Search »