Class function not recognized in UserExpression

Dear fellows,
I am trying to write the C++ based expression in my FEniCS python code to gather some information regarding each cell of mesh. The python code compiles without error however when I try to call the function “my_function(mesh)” from the user expression it returns following error:

WARNING: user expression has not supplied value_shape method or an element. Assuming scalar element.
Traceback (most recent call last):
  File "mwe_for_UserExpression.py", line 41, in <module>
    my_expression.my_function(mesh)
AttributeError: 'UserExpression' object has no attribute 'my_function'

The minimal working code (simplified from my project’s bigger code) is following:

from dolfin import *

mesh = UnitCubeMesh(5,5,5)

cppcode = """
#include "dolfin.h"
#include "ufc.h"
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 boost::shared_ptr<const dolfin::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;

};""" 

my_expression = UserExpression(cppcode, degree=0)
my_expression.my_function(mesh)

While the dolfin docker version I am using is: DOLFIN version: 2019.2.0.dev0

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:

thanks a lot @conpierce8. I appreciate your concern.