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

convert dolfin.cpp.Expression to ufl.Coefficient

+1 vote

The magic behind dolfin.functions.expression.Expression is essentially to convert a cpp_code string to a ufl.Coefficient that can be used to create forms. What if instead of the cpp_code string you have a dolfin.cpp.function.Expression class. How do you wrap it so it behaves like a proper ufl.Coefficient? The way I have been doing it is like this.

Let's say I have a custom class MyChildCppExpression that inherits from Expression in c++ and MyChildCppExpression is exposed in python. I can do

class MyPythonExpression(ufl.Coefficient, MyChildCppExpression):
   def __init__(self, function_space):
     MyChildCppExpression.__init__(self)
     ufl.Coefficient.__init__(self, function_space,
                             count=self.id())

This will compile in the JIT compiler but I am afraid I am missing something. For example this construct tends to compile everytime I simulate the same problem. I wonder if I should be using the function create_compiled_expression_class or if I should redefine Expression.__new__ to use MyChildCppExpression instead of a cpp_code string.

asked Oct 25, 2016 by chaffra FEniCS User (1,830 points)

Hi Chaffra,

I recently ran in the same problem.

For scalar expressions I came up with a construct of the form:

import dolfin as dl
f_cpp = MySwiggedCppExpression()
f = dl.Expression("A", A = f_cpp)

This seems to work well (at least on FEniCS 1.6.0), but it is not pretty.

Were you able to find a better solution, maybe using create_compiled_expression_class?

Thanks in advance,

Umberto

Hi Umberto,

I ended up using my approach above. It works fine and I do not notice any more slow down for the jit compiler. Note that the Fenics project has switched to dijitso for JIT compilation which is faster.

1 Answer

0 votes

Hi Chaffra,

Thank you very much for your feedback.
I will post below a self-contained example that may serve as documentation for the future.

class UserExpression(ufl.Coefficient, UserCppExpression):
    def __init__(self, element):
        UserCppExpression.__init__(self)
        ufl.Coefficient.__init__(self, element, count=self.id())

f = UserExpression(V.ufl_element())

Where:

  • UserCppExpression is a python to wrapper to a subclass of dolfin::Expression written by the user in cpp. I assumed that UserCppExpression has a default constructor. If UserCppExpression is not default constructible one can pass the needed arguments throught the__init__ method of UserExpression
  • V is a FunctionSpace (or VectorFunctionSpace, MixedFunctionSpace)
answered Mar 9, 2017 by umberto FEniCS User (6,440 points)
...