Hi community,
I have been trying to migrate a certain code I had to c++ because the call to python was very slow (very new to C++, answer might be trivial, so please explain in detail :) ). What I had, was a code like this:
class FExpression(Expression):
def __init__(self,element, u = Expression(("0.","0."), degree = 0)):
self.element = element
self.u = u
def eval(self, value, x):
p = x+self.u(x)
val = alpha*(T(p) - R(x))
value[0] = val*T(p,1,0)
value[1] = val*T(p,0,1)
My C++ proposal goes like this:
class Load : public Expression
{
public:
Function u;
Load() : Expression(2) {
u = std::make_shared<ImageReg::FunctionSpace>(mesh)
u->vector()->zero();
}
void eval(Array<double>& values, const Array<double>& x) const
{
// Constants
double beta1 = 0.7;
double beta2 = 1.3;
// Evaluation points
double dx = x[0] - 0.5;
double dy = x[1] - 0.5;
// Get reference intensity
double R = exp(-(dx*dx + dy*dy));
// Warped evaluation points
double temp [2];
u->eval(values, x);
dx += values[0];
dy += values[1];
// Target intensity
double T = exp(-beta1*dx*dx - beta2*dy*dy);
double k = -2*(R-T)*T;
values[0] = k*beta1*(-beta1*dx*dx - beta2*dy*dy);
values[1] = k*beta2*(-beta1*dx*dx - beta2*dy*dy);
}
};
The way I see it, I define a Function 'u' in the class, and calling the constructor creates the Function u and sets its coordinates to 0. The problem is that compiling this fails miserably. Below I copy the boundary and main, plus the compiling errors. This is a minimal working version, because in the future R and T will be interpolations of PNG images, but if I manage to load a Function to the expression, then it could be easier to load an array. Thanks in advance.
class DirichletBoundary : public SubDomain
{
bool inside(const Array<double>& x, bool on_boundary) const
{
return on_boundary;
}
};
int main(){
auto mesh = std::make_shared<UnitSquareMesh>(50, 50);
auto V = std::make_shared<ImageReg::FunctionSpace>(mesh);
ImageReg::BilinearForm a(V, V);
ImageReg::LinearForm L(V);
// Parameters
auto boundary_value = std::make_shared<Constant>(0.,0.);
auto mu = std::make_shared<Constant>(1.E5);
auto lamb = std::make_shared<Constant>(0.);
auto alpha = std::make_shared<Constant>(1.);
// Boundary conditions
auto boundary = std::make_shared<DirichletBoundary>();
DirichletBC bc(V, boundary_value, boundary);
// LHS construction
a.mu = mu;
a.lamb = lamb;
// RHS construction
auto f = std::make_shared<Load>();
auto u0 = std::make_shared<Function>(V);
// u0->vector()->zero();
// f.u = *u0;
L.f = f;
// Solve problem
Function u(V);
solve(a == L, u, bc);
}
[ 50%] Building CXX object CMakeFiles/ImageReg.dir/main.cpp.o
/home/nico/Dropbox/Magister/MFEM Implementation/Implementation2D/cpp/main.cpp: In constructor ‘Load::Load()’:
/home/nico/Dropbox/Magister/MFEM Implementation/Implementation2D/cpp/main.cpp:14:24: error: no matching function for call to ‘dolfin::Function::Function()’
Load() : Expression(2) {
^
In file included from /usr/include/dolfin/ale/MeshDisplacement.h:29:0,
from /usr/include/dolfin/mesh/Mesh.h:35,
from /usr/include/dolfin/mesh/dolfin_mesh.h:11,
from /usr/include/dolfin.h:15,
from /home/nico/Dropbox/Magister/MFEM Implementation/Implementation2D/cpp/main.cpp:1:
/usr/include/dolfin/function/Function.h:113:5: note: candidate: dolfin::Function::Function(const dolfin::Function&, std::size_t)
Function(const Function& v, std::size_t i);
^
/usr/include/dolfin/function/Function.h:113:5: note: candidate expects 2 arguments, 0 provided
/usr/include/dolfin/function/Function.h:102:5: note: candidate: dolfin::Function::Function(const dolfin::Function&)
Function(const Function& v);
^
/usr/include/dolfin/function/Function.h:102:5: note: candidate expects 1 argument, 0 provided
/usr/include/dolfin/function/Function.h:94:5: note: candidate: dolfin::Function::Function(std::shared_ptr, std::__cxx11::string)
Function(std::shared_ptr V,
^
/usr/include/dolfin/function/Function.h:94:5: note: candidate expects 2 arguments, 0 provided
/usr/include/dolfin/function/Function.h:84:5: note: candidate: dolfin::Function::Function(std::shared_ptr, std::shared_ptr)
Function(std::shared_ptr V,
^
/usr/include/dolfin/function/Function.h:84:5: note: candidate expects 2 arguments, 0 provided
/usr/include/dolfin/function/Function.h:72:14: note: candidate: dolfin::Function::Function(std::shared_ptr)
explicit Function(std::shared_ptr V);
^
/usr/include/dolfin/function/Function.h:72:14: note: candidate expects 1 argument, 0 provided
/home/nico/Dropbox/Magister/MFEM Implementation/Implementation2D/cpp/main.cpp:15:53: error: ‘mesh’ was not declared in this scope
u = std::make_shared(mesh)
^