Coming back to an old problem I never got to solve properly… I need to pass a numpy array to a compiled expression, to no avail. Consider the following code:
import numpy
import dolfin
mesh = dolfin.UnitSquareMesh(1,1)
fe = dolfin.FiniteElement(
family="Quadrature",
cell=mesh.ufl_cell(),
degree=1,
quad_scheme="default")
cpp_code = '''\
namespace dolfin
{
class MyExpr : public Expression
{
const Array<double>* v;
public:
MyExpr(): Expression() {}
void print_v() const
{
std::cout << "v = " << v->str(1) << std::endl;
}
void init_v(
const Array<double>& v_)
{
print_v();
v = &v_;
print_v();
}
void eval(
Array<double> &expr,
const Array<double> &pos) const
{
print_v();
}
};
}'''
my_expr = dolfin.Expression(
cppcode=cpp_code,
element=fe)
my_expr.init_v(numpy.ones(2))
my_expr.print_v()
my_expr.eval(numpy.ones(1), numpy.ones(3))
This compiles and runs fine but of course, since the member pointer v
is const
, even after assigning an array to it in the init_v
function (actually I’m not even sure how/why I can do that since it is const
, but anyway), it is empty when executing the print_v
function, and equal to first parameter of the function when executing the eval
function (so weird, right?). Now, if I make the member pointer not const
:
cpp_code = '''\
namespace dolfin
{
class MyExpr : public Expression
{
Array<double>* v;
public:
MyExpr(): Expression() {}
void print_v() const
{
std::cout << "v = " << v->str(1) << std::endl;
}
void init_v(
const Array<double>& v_)
{
print_v();
v = &v_;
print_v();
}
void eval(
Array<double> &expr,
const Array<double> &pos) const
{
print_v();
}
};
}'''
my_expr = dolfin.Expression(
cppcode=cpp_code,
element=fe)
my_expr.init_v(numpy.ones(2))
my_expr.print_v()
my_expr.eval(numpy.ones(1), numpy.ones(3))
This won’t compile with the error:
error: invalid conversion from ‘const dolfin::Array<double>*’ to ‘dolfin::Array<double>*’ [-fpermissive]
v = &v_;
^
This makes sense. Now, if I remove the other const
as well:
cpp_code = '''\
namespace dolfin
{
class MyExpr : public Expression
{
Array<double>* v;
public:
MyExpr(): Expression() {}
void print_v() const
{
std::cout << "v = " << v->str(1) << std::endl;
}
void init_v(
Array<double>& v_)
{
print_v();
v = &v_;
print_v();
}
void eval(
Array<double> &expr,
const Array<double> &pos) const
{
print_v();
}
};
}'''
my_expr = dolfin.Expression(
cppcode=cpp_code,
element=fe)
my_expr.init_v(numpy.ones(2))
my_expr.print_v()
my_expr.eval(numpy.ones(1), numpy.ones(3))
This compiles fine, but at runtime I’m getting the following error:
my_expr.init_v(numpy.ones(2))
TypeError: in method 'MyExpr_init_v', argument 2 of type 'dolfin::Array< double > &'
So apparently, the compiled module recognizes a numpy array as const dolfin::Array< double > &
, but not as dolfin::Array< double > &
. Any idea on how to make this work? Thanks! Martin