I am trying to initialize an expression to an expression class variable but I get an error during compilation. This same error occurs when I try to copy an expression. The problem can be reproduced by adding the following to the end of the hyperelasticity demo main.cpp.
const auto copy_expr = sigma_expression;
The error I get is:
hyperelasticity/main.cpp:237:28: error: use of deleted function ‘dolfinx::fem::Expression<double>::Expression(const dolfinx::fem::Expression<double>&)’
237 | const auto copy_expr = sigma_expression;
| ^~~~~~~~~~~~~~~~
note: ‘dolfinx::fem::Expression<double>::Expression(const dolfinx::fem::Expression<double>&)’ is implicitly declared as deleted because ‘dolfinx::fem::Expression<double>’ declares a move constructor or move assignment operator
33 | class Expression
| ^~~~~~~~~~
Is it because the Expressions class doesn’t have a copy constructor? I am using FEniCSx 0.5.2
Yes, Expression doesn’t have a copy builder.
I believe it was deliberately deleted.
What’s you use case? Maybe it could be used as an argument for adding a copy constructor.
It’s for making a QuadratureFunction class to use with the nonlinear solver. I was planning on having it look like this.
class QuadratureFunction
{
public:
QuadratureFunction(dolfinx::fem::Expression<T> expr, std::shared_ptr<dolfinx::fem::Function<T>>& u,
std::vector<int>& cells, std::shared_ptr<dolfinx::fem::FunctionSpace>& Q)
: _expr(expr), _u(u), _cells(cells), _Q(Q)
{}
/// Destructor
~QuadratureFunction();
void interpolate()
{
auto [eval_points, _shape] = _expr.X();
std::array<std::size_t, 2> shape
= {_cells.size(), _shape[0] * _expr.value_size()};
std::vector<T> values(shape[0]*shape[1]);
_expr.eval(_cells, values, shape);
// Move values into _u
dolfinx::la::petsc::Vector _u_petsc(
dolfinx::la::petsc::create_vector_wrap(*_u->x()), false);
VecSetBlockSize(_u_petsc.vec(), _Q->dofmap()->bs());
VecSetValuesBlockedLocal(
_u_petsc.vec(), _u->x()->array().size() / _Q->dofmap()->bs(),
_Q->dofmap()->list().array().data(), values.data(), INSERT_VALUES);
_u->x()->scatter_fwd();
}
private:
dolfinx::fem::Expression<T> _expr;
std::shared_ptr<dolfinx::fem::Function<T>> _u;
std::vector<int> _cells;
std::shared_ptr<dolfinx::fem::FunctionSpace> _Q;
};
I see.
What about using a shared_ptr
?
You can use std::make_shared
with the default constructor and send the shared pointer, similar to what you’re already doing for Function.
1 Like