Force Expression to use eval_cell

Hey,

this question is somewhat related to my other error in Error: Problem with Expression inside an Expression: Missing eval() function (must be overloaded).
If I call an Expression inside a simple Expression I think it calls the function eval(Array& values, const Array& x). However I need it to call the function eval(Array& values, const Array& x*,const ufc::cell& cell)* (note the cell attribute in the function). My question is, how can i force the expression to call said function?

For a better understanding here is an example:

from fenics import *
import matplotlib.pyplot as plt

mesh = UnitSquareMesh(10,10)
V = FunctionSpace(mesh, 'P', 1)

cpp_code = '''#include <pybind11/pybind11.h>
#include <pybind11/eigen.h>
namespace py = pybind11;

#include <dolfin/function/Expression.h> // for expressions


class Exp1 : public dolfin::Expression
{
   public:
       Exp1() : dolfin::Expression(){} 
       void eval(Eigen::Ref<Eigen::VectorXd> values, Eigen::Ref<const Eigen::VectorXd> x,
                      const ufc::cell& cell) const override
       {
           values[0] = 10;
       }

};
PYBIND11_MODULE(SIGNATURE, m)
{
   py::class_<Exp1, std::shared_ptr<Exp1>, dolfin::Expression>(m, "Exp1")
   .def(py::init<>());
}
'''
exp_1 = CompiledExpression( compile_cpp_code(cpp_code).Exp1(), degree=2)


exp_from_exp_1 = Expression('10*exp_1', exp_1=exp_1, degree=2)



test = interpolate(exp_from_exp_1, V) 
# I assume evaluating exp_from_exp_1 calls exp_1.eval(Eigen::Ref<Eigen::VectorXd> values, 
# Eigen::Ref<const Eigen::VectorXd> x), however I need the cell attribute

As mentioned in the code, I assume that the line interpolate(exp_from_exp_1, V) in the end calls the function eval(Eigen::Ref<Eigen::VectorXd> values, Eigen::Ref<const Eigen::VectorXd> x) of my Expression exp_1. However, since I need the cell attribute I only override the eval(Eigen::RefEigen::VectorXd values, Eigen::Ref x, const ufc::cell& cell) in my custom Expression exp_1. Therefore in the code Fenics can’t find the eval function of exp_1 and I get the error mentioned in Error: Problem with Expression inside an Expression: Missing eval() function (must be overloaded). Therefore I want to know, whether there is a way to force the Expression exp_from_exp_1 to evaluate the eval function with the cell attribute?

I hope my problem is somewhat understandable.

Best Regards

Emanuel

I would strongly recommend not to try to create nested expressions.

why can’t you simply just create a single expression where you write the relations explicitly?
I.e. instead of 10*exp_x is your expression, simply add the 10 to the return value, i.e.
value[0]=10;value[0]=10 * 10.

Ok, for my understanding: Do nested expressions don’t work reliably or why shouldn’t you use them?

Unfortunately the Expressions in my system are a bit more complicated than in my minimal example, therefore making my code hard to read and maintain if I decided to avoid nested expressions. Is there a different approach to achieve something similar to nested expressions?

The problem with nested expressions is that you end up with nested interpolation, Which gets quite hard to debug when it goes wrong.
You can use them nested, But it gets very Weird to combine the Expression class with the UserExpression/compiled_cpp_code expression, as They have different signatures

2 Likes