Borrowing from this post, I think what you want is a CompiledExpression
:
from dolfin import *
mesh = UnitCubeMesh(5,5,5)
cppcode = """
#include <iostream>
#include <pybind11/pybind11.h>
#include <pybind11/eigen.h>
#include "dolfin.h"
#include "ufc.h"
namespace py = pybind11;
using namespace dolfin;
class E : public Expression
{
public:
E() : Expression() {}
void eval(Array<double>& values, const Array<double>& data, const ufc::cell& cell) const
{
values[0] = _values[cell.index];
}
void my_function(const std::shared_ptr<const Mesh> mesh)
{
std::cout << "Function is called"<<std::endl;
if (_values.size() != mesh->num_cells())
_values.resize(mesh->num_cells());
for (CellIterator cell(*mesh); !cell.end(); ++cell)
{
const uint i = cell->index();
_values[i] = i;
}
}
private:
std::vector<double> _values;
};
PYBIND11_MODULE(SIGNATURE, m)
{
py::class_<E, std::shared_ptr<E>, Expression>(m, "E")
.def(py::init<>())
.def("my_function", &E::my_function)
.def("eval", &E::eval);
}
"""
my_expression = CompiledExpression(compile_cpp_code(cppcode).E(), degree=0)
my_expression.my_function(mesh)
V = FunctionSpace(mesh, 'DG', 0)
f = project(my_expression, V)
with XDMFFile("my_expression.xdmf") as xdmf:
xdmf.write(f)
yielding: