This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

Error when computing the derivatives

0 votes

Hello All,

I am trying to compute the derivative of a function (with C++).
My code is as follows:

auto problem1 = std::make_shared<LinearVariationalProblem>(a, L, w, bcs);
...
solver.solve();  // This works fine.

// Now I need to calculate the derivative of w
auto V1     =  std::make_shared<Gradient::FunctionSpace>(mesh);
auto _a_g    =  std::make_shared<Gradient::BilinearForm>(V1,V1);
auto _L_g    =  std::make_shared<Gradient::LinearForm>(V1);
auto  gw      = std::make_shared<Function>(V1);
_L_g->u = wp;

// Solve:
auto problem2 = std::make_shared<LinearVariationalProblem>( _a_g , _L_g , gw,bcs);
LinearVariationalSolver dp_solver1(problem2);
dp_solver1.parameters["linear_solver"]="mumps";
dp_solver1.solve();

However solving problem2 works on one computer , and fails on another with this error message:

Error: Unable to define linear variational problem a(u, v) = L(v) for all v.
Reason: Expecting the boundary conditions to to live on (a subspace of) the trial space.
Where: This error was encountered inside LinearVariationalProblem.cpp.
Process: 0

DOLFIN version: 2016.2.0.dev0
Git changeset: b84974e3d89bccf46d165692b5f8c02a9f967c6f

My efl file is as follow:

vector_element = VectorElement("Lagrange", tetrahedron , 1)
element = FiniteElement("Lagrange", tetrahedron , 1)
u = Coefficient(element)
w = TrialFunction(vector_element)
v = TestFunction(vector_element)
a = inner(w, v)*dx
L = inner(grad(u), v)*dx

Can anyone point out what is wrong?
Thanks for the help.
Victor.

asked Sep 12, 2016 by wtpot FEniCS Novice (450 points)

1 Answer

0 votes

As the error message says:

Reason: Expecting the boundary conditions to to live on (a subspace of) the trial space.

You should not pass the boundary conditions bcs to the solver to compute the gradient, since bcs are boundary conditions for the scalar unknow w and not for the gradient (which is a vector)

Try

auto problem2 = std::make_shared<LinearVariationalProblem>( _a_g , _L_g , gw);

instead of

auto problem2 = std::make_shared<LinearVariationalProblem>( _a_g , _L_g , gw,bcs);

You may still have some boundary artifacts due to the Dirichlet bc, but the code should compile and execute.

answered Sep 16, 2016 by umberto FEniCS User (6,440 points)

Thank you for your comment.

I initially had it just the way you recommended (without the boundary condition), ie:

auto problem2 = std::make_shared<LinearVariationalProblem>( _a_g , _L_g , gw);

but the code would not compile, and generates the following error:

error: no matching function for call to
‘dolfin::LinearVariationalProblem::LinearVariationalProblem(std::shared_ptr&,
std::shared_ptr&,
std::shared_ptr&)’
...
...
fenics/dolfin/include/dolfin/fem/LinearVariationalProblem.h:48:5:
note: candidate expects 4 arguments, 3 provided

Ok, sorry for that.

I usually use the python interface. Generating an empty vector of bcs for the gradient may work.

std::vector<std::shared_ptr<const DirichletBC>> bcs_grad;

Yes, that fixes the issue but it worries me that it is inconsistent with the documentation (which says no boundary condition need be supplied when calculating gradients)

...