← Back to team overview

dolfin team mailing list archive

Re: passing functions

 

I think I know what goes wrong now...

The problem is the current design of the DiscreteFunction class. It
keeps pointers to a Vector, a Mesh and a FiniteElement and gets
confused about who actually owns the data.

Here's a simple example to illustrate this:

    BilinearForm a;
    Function f(x, mesh, a.trial());
    // BilinearForm a goes out of scope somehow and deletes its element
    // Function f tries to use the FiniteElement which is deleted

We've discussed using smart pointers for the data in the class
DiscreteFunction before and that should do the trick. Does someone
have time to look into this?

/Anders
    

On Wed, Oct 04, 2006 at 04:08:31PM +0200, Dag Lindbo wrote:
> The code I attach breaks the function. Should be very simple to make, and
> understand. main() is in LSM_test.cpp
> 
> /Dag
> 
> >
> > It will take me some time to write a stand-alone code that someone else
> > can run, so hang on.
> >
> > Gdb says:
> >
> > Program received signal SIGSEGV, Segmentation fault.
> > [Switching to Thread -1208269120 (LWP 12715)]
> > 0x004776ed in dolfin::DiscreteFunction::updateVectorDimension ()
> >    from /usr/local/lib/libdolfin.so.0
> >
> >
> > Valgrind says the same (I guess):
> >
> > ==12683== Invalid read of size 4
> > ==12683==    at 0x1BA106EA:
> > dolfin::DiscreteFunction::updateVectorDimension() (in
> > /usr/local/lib/libdolfin.so.0.0.0)
> > ==12683==    by 0x1BA10966:
> > dolfin::DiscreteFunction::DiscreteFunction(dolfin::uBlasVector&,
> > dolfin::Mesh&, dolfin::FiniteElement&) (in
> > /usr/local/lib/libdolfin.so.0.0.0)
> > ==12683==    by 0x1BA13B30:
> > dolfin::Function::Function(dolfin::uBlasVector&, dolfin::Mesh&,
> > dolfin::FiniteElement&) (in /usr/local/lib/libdolfin.so.0.0.0)
> > ==12683==    by 0x804E1FB:
> > dolfin::Vec_Func_fcns::L2_Error_DF_DF(dolfin::Mesh&, dolfin::Function&,
> > dolfin::Function&) (Vec_Func_fcns.cpp:41)
> > ==12683==    by 0x808F6E6: main (LSM_test.cpp:135)
> > ==12683==  Address 0x1BD79D68 is 0 bytes inside a block of size 12 free'd
> > ==12683==    at 0x1B9098CF: operator delete(void*)
> > (vg_replace_malloc.c:155)
> > ==12683==    by 0x804F87D:
> > dolfin::Scalar_L2Error::LinearForm::FunctionElement_1::~FunctionElement_1()
> > (Scalar_L2Error.h:228)
> > ==12683==    by 0x1BA0D703: dolfin::Form::~Form() (in
> > /usr/local/lib/libdolfin.so.0.0.0)
> > ==12683==    by 0x1BA0FBCA: dolfin::LinearForm::~LinearForm() (in
> > /usr/local/lib/libdolfin.so.0.0.0)
> > ==12683==    by 0x80539FF:
> > dolfin::Scalar_L2Error::LinearForm::~LinearForm() (Scalar_L2Error.h:23)
> > ==12683==    by 0x804E52B:
> > dolfin::Vec_Func_fcns::L2_Error_Exact(dolfin::Mesh&, dolfin::Function&,
> > dolfin::Function&) (Vec_Func_fcns.cpp:29)
> > ==12683==    by 0x808F666: main (LSM_test.cpp:131)
> > pure virtual method called
> > terminate called without an active exception
> >
> >
> >
> >> On Sun, Oct 01, 2006 at 06:35:51PM +0200, Dag Lindbo wrote:
> >>> Hi all,
> >>>
> >>> I'm a bit confused about passing a Function to a function and using it
> >>> to
> >>> assemble some system. What I'm doing is passing a Function, "func", by
> >>> reference, to a function, foo, where func goes into a form and that
> >>> form
> >>> is assembled etc.
> >>>
> >>> Vector& Another_Class::foo(Mesh& mesh, Function& func)
> >>> 	{
> >>> 		AAA::BilineraForm a
> >>> 		AAA::LinearForm L(func)
> >>>
> >>> 		FEM:assemble(...)
> >>> 		lu_solver.solve(...)
> >>>
> >>> 		return x;
> >>> 	}
> >>>
> >>> This works fine, but when the context that called foo (e.g. main)
> >>> resumes
> >>> something has happended to "func". The next time it is referenced the
> >>> porgram terminates with a segmentation violation. To get around this I
> >>> can
> >>> copy the data to local Vector in foo:
> >>>
> >>> Vector& Another_Class::foo(Mesh& mesh, Function& func)
> >>> 	{
> >>> 		Vector vec = func.vector();
> >>> 		Function func2(vec,mesh,func.element());
> >>>
> >>> 		AAA::BilineraForm a
> >>> 		AAA::LinearForm L(func2)
> >>>
> >>> 		FEM:assemble(...)
> >>> 		lu_solver.solve(...)
> >>>
> >>> 		return x;
> >>> 	}
> >>>
> >>> I would dearly like to avoid this extra copy of a large vector. How
> >>> should
> >>> one do this?
> >>>
> >>> Regards,
> >>> Dag Lindbo
> >>
> >> This should not happen so it looks like a bug. Passing a function as
> >> argument to a form only has the effect that the pointer to the
> >> function is placed in a list. During assembly, all functions in the
> >> list will be interpolated to each element. The pointer is never
> >> deleted.
> >>
> >> See if you can produce a simplest possible example that breaks and
> >> maybe we can find out what goes wrong. Also check with valgrind if you
> >> have it availabe and see if you can locate the offending line.
> >>
> >> /Anders
> >> _______________________________________________
> >> DOLFIN-dev mailing list
> >> DOLFIN-dev@xxxxxxxxxx
> >> http://www.fenics.org/mailman/listinfo/dolfin-dev
> >>
> >
> >
> > _______________________________________________
> > DOLFIN-dev mailing list
> > DOLFIN-dev@xxxxxxxxxx
> > http://www.fenics.org/mailman/listinfo/dolfin-dev
> >


> _______________________________________________
> DOLFIN-dev mailing list
> DOLFIN-dev@xxxxxxxxxx
> http://www.fenics.org/mailman/listinfo/dolfin-dev



Follow ups

References