 # Taking Derivatives

Hello everyone,

I am solving a Poisson equation, and that works well, but I also want to take some partial derivatives from the variational form. I am encountering multiple errors and would really appreciate some help. I am taking two derivatives one with respect to K and one with respect to G.

1. When I use dK = TrialFunction I get

`NotImplementedError: Cannot take length of non-vector expression.`

It seems to work if I use dK = Function(V), I do not understand why? Similarly for G.

1. I can assemble the derivative with respect to K but not with respect to G. When I try to assemble with respect to G I get the following error

`ufl.algorithms.check_arities.ArityMismatch: Integrand arguments (Argument(FunctionSpace(Mesh(VectorElement(FiniteElement('Lagrange', triangle, 1), dim=2), 0), FiniteElement('Lagrange', triangle, 1)), 0, None),) differ from form arguments (Argument(FunctionSpace(Mesh(VectorElement(FiniteElement('Lagrange', triangle, 1), dim=2), 0), FiniteElement('Lagrange', triangle, 1)), 0, None), Argument(FunctionSpace(Mesh(VectorElement(FiniteElement('Lagrange', triangle, 1), dim=2), 0), FiniteElement('Lagrange', triangle, 1)), 1, None)).`

Is that because G is on the boundary (ds)?

Thank you very much for the help in advance!

``````def solve_steady_state_heat(V,mesh,boundary_markers, K, G):
bmesh = dl.BoundaryMesh(mesh, "exterior", True)
bdim  = bmesh.topology().dim()
bot_top_mesh = bot_mesh(mesh,boundary_markers,bmesh,bdim)
boundary_mesh = bmesh #for ease going from 2D to actual mesh
submesh_bottom = bot_top_mesh
submesh_top = bot_top_mesh
# boundary measure and normal vector
# ds(1) --> bottom, ds(2) --> top
ds = dl.Measure("ds", domain=mesh, subdomain_data=boundary_markers)
# define Trial and Test Functions
u_trial = dl.TrialFunction(V)
u_test = dl.TestFunction(V)
# initialize input functions
f = dl.Constant(0.0)
u0 = dl.Constant(253.0)
bmesh_markers = dl.MeshFunction('size_t', bmesh, bdim)
bmesh_markers.set_all(0)
# 1 -- bottom
# 2 -- top
for i, facet in enumerate(dl.entities(bmesh, bdim)):
p_meshentity = bmesh.entity_map(bdim)[i]
p_boundarynumber = boundary_markers.array()[p_meshentity]
bmesh_markers.array()[i] = p_boundarynumber
bottom_submesh = dl.SubMesh(bmesh, bmesh_markers, 1)
top_submesh = dl.SubMesh(bmesh, bmesh_markers, 1)
bc = dl.DirichletBC(V, u0, boundary_markers, 2)

def a(K,G,u_trial,u_test,f):
return dl.inner(ufl.exp(K) * dl.grad(u_trial), dl.grad(u_test)) * dl.dx - f * u_test * dl.dx - G*u_test*ds(1)
#    dK = dl.TestFunction(V) <-- when. I use I get the error
#   dG = dl.TestFunction(V)
dK = dl.Function(V) #<--- Question 1) Why does this work? I thought we should use            TestFunction
dG = dl.Function(V)
theta_kappa_form = dl.derivative( res_form, K,dK)
theta_kappa = dl.assemble(theta_kappa_form)
theta_G_form = dl.derivative( res_form, G,dG)
theta_G = dl.assemble(theta_G_form)

A_form = ufl.lhs(res_form)
b_form = ufl.rhs(res_form)
A, b = dl.assemble_system(A_form, b_form, bcs=bc)
theta = dl.Function(V)
dl.solve(A, theta.vector(), b)

return theta
``````

Please make sure that the code you supply is a standalone code, that when copy pasted by other can reproduce your error message.

Please also remove all unused variables from the code.

2 Likes

Thank you for your feedback Prof. Dokken,

I would directly edit the post to improve it, I cannot find an edit option. I modified one of the basic demos to give me the same errors.

``````import dolfin as dl
import matplotlib.pyplot as plt
import ufl
from dolfin import *

# Create mesh and define function space
mesh = UnitSquareMesh(32, 32)
V = FunctionSpace(mesh, "Lagrange", 1)

# Define Dirichlet boundary (x = 0 or x = 1)
def boundary(x):
return x < DOLFIN_EPS or x > 1.0 - DOLFIN_EPS

# Define boundary condition
u0 = Constant(0.0)
bc = DirichletBC(V, u0, boundary)

# Define variational problem
u = TrialFunction(V)
v = TestFunction(V)
f = Expression("10*exp(-(pow(x - 0.5, 2) + pow(x - 0.5, 2)) / 0.02)",element=V.ufl_element())
g = Expression("sin(5*x)",element=V.ufl_element())
L = f*v*dx + g*v*ds

# Compute solution
K = Function(V)
solve(a == L, K, bc)

def aa(u,v,f,g):
res_form = aa(u,v,f,g)

#dK = dl.TestFunction(V) #<--- does not work, it seems we have to use Function, but I guess K is a function as well
dK = dl.Function(V)
aa_K = dl.derivative( res_form, K,dK)
Ak = dl.assemble(aa_K)

#dg = dl.TestFunction(V) #Similar issue
dg = dl.Function(V)
aa_g = dl.derivative( res_form, g,dg)
Ag = dl.assemble(aa_g)

``````

In your variational form, you already use a `TrialFunction` (u) and a `TestFunction` (v). You cannot have two test functions multiplied by each other in the same form, and therefore the derivative command does not work.

1 Like