UserExpression instantiated inside Python function does not work if the Python function returns only DirichletBC

Issue #1070 new
Diego Hayashi Alonso created an issue

When instantiating a UserExpression inside a Python function in order to create a DirichletBC, if the Python function returns only the prepared DirichletBC, the code gives the error:

 *** Error:   Unable to evaluate expression.
 *** Reason:  Missing eval() function (must be overloaded).
 *** Where:   This error was encountered inside Expression.cpp.

If the Python function also returns the UserExpression, the code simply works. Below, follows a minimal example based on the FEniCS example for solving the Poisson equation. The code does not work if test_mode is set as 1, but works if test_mode is set as 2. Apparently, in the case it does not work, the code loses the reference count of the UserExpression.

from dolfin import *

test_mode = 1
    # 1 = Does not work
    # 2 = Works

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

print("Define boundary condition")
class BoundaryValues(UserExpression):
    def eval(self, values, x):
        values[0] = 0.0
        l = 1.0/6.0
        gbar = 100.0
        if near(x[0], 0.0) or near(x[0], 1.0):
            if 0.0 < x[1] < 0.20:
                values[0] = 1.0
            elif 0.30 < x[1] < 1.0:
                values[0] = -1.0
            else:
                values[0] = 0.0
    def value_shape(self):
        return ()

def get_bcs():
    print("get_bcs")
    bv_expression = BoundaryValues(degree = 2)
    bc = DirichletBC(V, bv_expression, "on_boundary")
    bcs = [bc]
    if test_mode == 1:
        return bcs
    else:
        return bcs, bv_expression

if test_mode == 1:
    bcs = get_bcs()
else:
    bcs, bv_expression = get_bcs()

print("Define variational problem")
u = TrialFunction(V)
v = TestFunction(V)
f = Expression("10*exp(-(pow(x[0] - 0.5, 2) + pow(x[1] - 0.5, 2)) / 0.02)", degree = 2)
a = inner(grad(u), grad(v))*dx
L = f*v*dx

print("Compute solution")
u = Function(V)
solve(a == L, u, bcs)

Comments (1)

  1. Alex

    A. Thank you, I was running into this problem.

    B. Even this only somewhat solves the issue. If you have more complicated code, save the “bv_expression” variable as a class variable to some class you are actively using otherwise the python GC will eat up you “bv_expression”. (This happened to me)

  2. Log in to comment