This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

Creating a form depending on an arbitrary Python function

0 votes

Hello,

I would like to modify the example in the section "A Variable-Coefficient Poisson Problem" in the FEniCS Tutorial ( http://fenicsproject.org/documentation/tutorial/fundamentals.html ) so one could pass an arbitrary Python function (of the right type) for p without having the jit-compiler invoked for every new function p.

In Code: I basically want to do (as a minimal example)

def linear(x, y):
    return x[0] + y

def solve_my_problem(p, y):
    mesh = UnitIntervalMesh(n)
    V    = FunctionSpace(mesh, 'Lagrange', degree=1)
    ...
    a = p(SpatialCoordinate(mesh), y) * inner(nabla_grad(u), nabla_grad(v))*dx
    ...
    solver.solve()
...
solve_my_problem(linear, 10)

This would however invoke the jit-compiler for every call to solve_my_problem with any new parameter p or y. I'm afraid it is clear too me why this could not work that way.

I thought I was supposed to use a "Coefficient" here as in
http://fenicsproject.org/documentation/dolfin/dev/cpp/demo/documented/poisson/cpp/documentation.html
and I naively tried to replace the corresponding part in the above code by

...
ac = Coefficient(V.ufl_element())
A  = ac * inner(nabla_grad(u), nabla_grad(v)) * dx
A.ac = lambda x: a(x, z)
...

but this results in a compiler error

 AttributeError: 'Form' object has no attribute 'ac'

where ipython points to the line

 A.ac = lambda x: a(x, z)

Is it even intended to set a Coefficient in Python?

Thanks for reading all this already!

asked Sep 28, 2014 by Lumber FEniCS Novice (130 points)
edited Sep 28, 2014 by Lumber

1 Answer

+1 vote

Your first approach is correct. However, you should wrap the parameters which change (i.e., y and p) in Constant. Your last line should read something like

solve_my_problem(linear, Constant(10))

You can then change the parameter 10 and your form is only compiled once.

answered Sep 29, 2014 by cevito FEniCS User (5,550 points)

Thanks! This is a lot better than the 6(?) calls before already.

...