ufl.log.UFLValueError can not be converted to any UFL type

Hi, I am trying to solve the following pde with dirichlet boundary conditions. I defined a as a scalar, which is different in different domains.

image

But I got an ufl.log.UFLValueError in the step
Fl1 = inner(nabla_grad(u) + Constant((1,0)), k*nabla_grad(v))*dx.

Is anyone know how to fix it? I also copied my code here. Thanks in Advance!

mesh = UnitSquareMesh(4, 6)

subdomains = MeshFunction("size_t", mesh, 2)
class Omega_0(SubDomain):
    def inside(self, x, on_boundary):
        return True if (x[0] + x[1]) <= 1 else False
class Omega_1(SubDomain):
    def inside(self, x, on_boundary):
        return True if (x[0] + x[1]) > 1 else False
subdomain_0 = Omega_0()
subdomain_1 = Omega_1()
subdomain_0.mark(subdomains, 0)
subdomain_1.mark(subdomains, 1)

V0 = FunctionSpace(mesh,"DG",0)
k = Function(V0)
kvalues = [1.5, 10]
for cell in range(len(subdomains.array())):
    subdomain_cell = subdomains.array()[cell]
    k.vector()[cell] = kvalues[subdomain_cell]

Ve = FiniteElement('Lagrange', mesh.ufl_cell(), 1)
Re = FiniteElement('Real', mesh.ufl_cell(), 0)
X = FunctionSpace(mesh, MixedElement([Ve, Re]))
tol = 1E-14
class topBottomBoundary(SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary and abs(x[1]) < tol or abs(x[1] - 1) < tol
class leftrightBoundary(SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary and abs(x[0]) < tol or abs(x[0] - 1) < tol
bc1 = DirichletBC(X.sub(0), Constant(0), topBottomBoundary())
bc2 = DirichletBC(X.sub(0), Constant(0), leftrightBoundary())
bc = [bc1, bc2]

u = TrialFunctions(X.sub(0).collapse())
v = TestFunctions(X.sub(0).collapse())
Fl1 = inner(nabla_grad(u) + Constant((1,0)), k*nabla_grad(v))*dx
F1 = Fl1

Fl2 = inner(nabla_grad(u) + Constant((0,1)), k*nabla_grad(v))*dx
F2 = Fl2

x = Function(X.sub(0).collapse())
a1 = lhs(F1)
L1 = rhs(F1)
solve(a1 == L1, x, bc)
plot(x)
plt.show()

y = Function(X.sub(0).collapse())
a2 = lhs(F2)
L2 = rhs(F2)
solve(a2 == L2, y, bc)  
plot(y)
plt.show()


image

There are a whole lot of issues in your code.
First of all, you are mixing up (no pun intended) the FunctionSpace with the MixedElement, and the one with the sub functions.

As far as I can tell from our code, you never use the second function space, so why define it as a mixed function space for starters?

Secondly, when you call, X.sub(0).collapse(), you create a new function space. Thus, this should only be called once for a given variational problem, i.e. you should do

X0 = X.sub(0).collapse()
u = TrialFunction(X0)
v = TestFunction(X0)
x = Function(X0)
# Define variational problem
# ...

Thirdly, you need to define Dirichlet condition in the collapsed subspace if you want to use it for a1==L1.

1 Like

Thanks for your quick reply. I wrote the MixedElement, since I might want to add lagrangian multiplier later. Actually I got the same problem when I changed the FunctionSpace like the following code.

mesh = UnitSquareMesh(4, 6)

subdomains = MeshFunction("size_t", mesh, 2)
class Omega_0(SubDomain):
    def inside(self, x, on_boundary):
        return True if (x[0] + x[1]) <= 1 else False
class Omega_1(SubDomain):
    def inside(self, x, on_boundary):
        return True if (x[0] + x[1]) > 1 else False
subdomain_0 = Omega_0()
subdomain_1 = Omega_1()
subdomain_0.mark(subdomains, 0)
subdomain_1.mark(subdomains, 1)

V0 = FunctionSpace(mesh,"DG",0)
k = Function(V0)
kvalues = [1.5, 10]
for cell in range(len(subdomains.array())):
    subdomain_cell = subdomains.array()[cell]
    k.vector()[cell] = kvalues[subdomain_cell]

V = FunctionSpace(mesh, "Lagrange", 1)
tol = 1E-14
class topBottomBoundary(SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary and abs(x[1]) < tol or abs(x[1] - 1) < tol
class leftrightBoundary(SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary and abs(x[0]) < tol or abs(x[0] - 1) < tol
bc1 = DirichletBC(V, Constant(0), topBottomBoundary())
bc2 = DirichletBC(V, Constant(0), leftrightBoundary())
bc = [bc1, bc2]

u = TrialFunctions(V)
v = TestFunctions(V)
Fl1 = inner(nabla_grad(u) + Constant((1,0)), k*nabla_grad(v))*dx
F1 = Fl1

Fl2 = inner(nabla_grad(u) + Constant((0,1)), k*nabla_grad(v))*dx
F2 = Fl2

x = Function(V)
a1 = lhs(F1)
L1 = rhs(F1)
solve(a1 == L1, x, bc)
plot(x)
plt.show()

y = Function(V)
a2 = lhs(F2)
L2 = rhs(F2)
solve(a2 == L2, y, bc)  
plot(y)
plt.show()

Could you tell me the reason for this problem?

And I indeed don’t know the FunctionSpace with the sub functions. Could you explain it a little bit?

Thanks in advance!

Replace

With

u = TrialFunction(V)
v = TestFunction(V)

I dont understand what you are asking about here.

1 Like

Never mind. I got it. Thanks!