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

segfault of Function's assignment operator

+3 votes

Hi everyone,

I am trying to write a procedure that accepts reference to function $$ u\in V, $$ then inside some computations are made whose result is a function $$ v \in W $$ that I planned to return by assigning u = v. However I get segmentation faults if I try to work with u (plot,
calling its methods) after the function() call even if $$ V = W. $$ Can anyone point out
what the problem might be? Thanks.

#include "cG1.h" // element = FiniteElement("Lagrange", triangle, 1)
#include <dolfin.h>

using namespace dolfin;

void function(Function& u);

int main()
{
  UnitSquareMesh mesh(10, 10);
  cG1::FunctionSpace V(mesh);
  Function u(V);

  function(u);
  dolfin::info("%d", u.function_space()->dim()); 

  return 0;
}

void function(Function& u)
{
  UnitSquareMesh mesh(10, 10);
  cG1::FunctionSpace V(mesh);
  Function v(V);

  u = v;
}
asked Sep 4, 2013 by MiroK FEniCS Expert (80,920 points)
edited Sep 5, 2013 by MiroK

Please, report also version of FEniCS and used linear algebra backend.

I can reproduce it in development version. However shared_ptr version of the code works.

#include "cG1.h" // element = FiniteElement("Lagrange", triangle, 1)
#include <dolfin.h>

using namespace dolfin;

void function(boost::shared_ptr<Function> u);

int main()
{
  UnitSquareMesh mesh(10, 10);
  cG1::FunctionSpace V(mesh);
  boost::shared_ptr<Function> u(new Function(V));

  function(u);
  dolfin::info("%d", u->function_space()->dim());

  return 0;
}

void function(boost::shared_ptr<Function> u)
{
  UnitSquareMesh mesh(10, 10);
  cG1::FunctionSpace V(mesh);
  boost::shared_ptr<Function> v(new Function(V));

  u = v;
}

I am using 1.2.0+ and PETSc.

Thanks for suggestion. The code now works in a sense that it does not crash, but unfortunately does not do what I'd like to see. Consider the following example:

#include "cG1.h" // element = FiniteElement("Lagrange", triangle, 1)
#include <dolfin.h>

using namespace dolfin;

void function(boost::shared_ptr<Function> u);

int main()
{
  UnitSquareMesh mesh(10, 10);
  cG1::FunctionSpace V(mesh);
  boost::shared_ptr<Function> u( new Function(V));

  dolfin::info("%d", u->function_space()->dim()); 
  function(u);
  dolfin::info("%d", u->function_space()->dim()); 

  return 0;
}

void function(boost::shared_ptr<Function> u)
{
  UnitSquareMesh mesh(20, 20);
  cG1::FunctionSpace V(mesh);
  boost::shared_ptr<Function> v(new Function(V));
  dolfin::info("%d", v->function_space()->dim()); 

  u = v;
}

After the function() call u gives dimension of the "outside" V and not the inside one as
intended.

2 Answers

+2 votes
 
Best answer

Hi,

I think the problem is, as already pointed out, the scope and I think, as already pointed out, that it can be solved using shared pointers. However, use it for the FunctionSpace created inside the function and not for the Function itself. Perhaps you should use a shared pointer for the mesh created inside the function as well, but this seems to work:

#include "cG1.h" // element = FiniteElement("Lagrange", triangle, 1)
#include <dolfin.h>

using namespace dolfin;

void function(Function& u);

int main()
{
  UnitSquareMesh mesh(10, 10);
  cG1::FunctionSpace V(mesh);
  Function u(V);

  dolfin::info("%d", u.function_space()->dim()); 
  function(u);
  dolfin::info("%d", u.function_space()->dim()); 

  return 0;
}

void function(Function& u)
{
  UnitSquareMesh mesh(20, 20);
  //cG1::FunctionSpace V(mesh);  
  boost::shared_ptr<cG1::FunctionSpace> V( new cG1::FunctionSpace(mesh));

  Function v(V);
  dolfin::info("%d", v.function_space()->dim()); 

  u = v;
}
answered Sep 5, 2013 by mikael-mortensen FEniCS Expert (29,340 points)
selected Sep 5, 2013 by MiroK

Hi Mikael, shared_ptr to the FunctionSpace does the trick. Thanks! Just for completeness,
inside function() shared_ptr to Mesh is not needed in the above example. However, it is
probably a good idea to use since without it attempt to plot(u) after the function() call
causes crash. Here's an example:

#include "cG1.h" // element = FiniteElement("Lagrange", triangle, 1)
#include <dolfin.h>

using namespace dolfin;

void function(Function& u);

int main()
{
  UnitSquareMesh mesh(10, 10);
  cG1::FunctionSpace V(mesh);
  Function u(V);

  function(u);
  plot(u);
  interactive(true);

  return 0;
}

void function(Function& u)
{
  boost::shared_ptr<Mesh> mesh (new UnitSquareMesh(100, 100));
  //UnitSquareMesh mesh(100, 100); // crash!
  boost::shared_ptr<FunctionSpace> V(new cG1::FunctionSpace(mesh));
  Function v(V);
  u = v;
}
+4 votes

I think the issue is that of scope, you construct mesh, V, and v in the function. Once the function returns, those are no longer in scope. Since u=v, u has now been disposed. This is also why the shared pointer works.

answered Sep 5, 2013 by Charles FEniCS User (4,220 points)
...