← Back to team overview

dolfin team mailing list archive

Re: Function and DofMap

 

On Monday 08 September 2008 21:45:27 Martin Sandve Alnæs wrote:
> 2008/9/8 Anders Logg <logg@xxxxxxxxx>:
> > On Mon, Sep 08, 2008 at 11:12:14AM +0200, Martin Sandve Alnæs wrote:
> >> 2008/9/8 Johan Hoffman <jhoffman@xxxxxxxxxx>:
> >> >> 2008/9/8 Dag Lindbo <dag@xxxxxxxxxx>:
> >> >>> Anders Logg wrote:
> >> >>>> There seems to be a problem (among many) with the current design of
> >> >>>> the Function classes (see thread "evaluating higher order mesh
> >> >>>> function").
> >> >>>>
> >> >>>> In particular, the finite element is missing in DiscreteFunction.
> >> >>>> My suggestion would be to just add it and let a DiscreteFunction
> >> >>>> consist of the following four items which are always available:
> >> >>>>
> >> >>>>   mesh, x, dof_map, finite_element
> >> >>>>
> >> >>>> Is this enough, and what other issues to we need to fix?
> >> >>>
> >> >>> I'm not sure I agree that the dof map and finite element should be
> >> >>> owned by the discrete function. There was a great suggestion from
> >> >>> Martin, in a thread "Abstraction idea" from 06/05/2008, to create a
> >> >>> class FunctionSpace where the mesh, element and dof_map(s) are
> >> >>> aggregated. Citing Martin:
> >> >>> U = FunctionSpace(mesh, dofmapset, form, 0) # or something similar
> >> >>> u = Function(U)
> >> >>> v = Function(U)
> >> >>>
> >> >>> This seems a solid approach to me since it would provide a way of
> >> >>> encapsulating the mathematical formulation of the problem, which is
> >> >>> more or less const and likely to be reused by many discrete
> >> >>> functions in a solver.
> >> >>>
> >> >>> It seems to me that there is an obvious risk that a lot of redundant
> >> >>> initialization would occur if all discrete functions should own
> >> >>> their own elements and dof maps. There seems to be consensus that
> >> >>> the mesh should be "global" for efficiency reasons, so why not treat
> >> >>> the function space the same way?
> >> >>>
> >> >>> Is there a problem with an approach where the funciton _always_ owns
> >> >>> the vector and _never_ owns the function space (and mesh)? A very
> >> >>> strict design would avoid shared/smart pointers, provide a
> >> >>> comprehensible user interface and probably help the parallellization
> >> >>> effort.
> >> >>>
> >> >>> /Dag
> >> >>
> >> >> If the Function always owns the vector, there are cases you'll have
> >> >> to make unneccessary copies of a vector, in particular such scenarios
> >> >> may occur when trying to combine dolfin with something else.
> >> >>
> >> >> If the Function never owns the function space, it must always be
> >> >> constructed explicitly by the user. This may not be a bad thing.
> >> >> However, if the Function is loaded from a file, nobody owns the
> >> >> FunctionSpace.
> >> >
> >> > Conceptually, I agree with Dag (and Martin?) that it is natural to
> >> > have global function spaces. And if the explicit construction of such
> >> > spaces can be made simple, it may not be a bad thing but a natural
> >> > part in setting up the mathematical problem. And I do not really like
> >> > that functions should be initialized from a form, which defines an
> >> > equation.
> >> >
> >> > I think one idea was to not force less mathematically oriented users
> >> > to worry about function spaces. I guess there are (at least) 2 types
> >> > of functions: (i) functions part of the form, and (ii) functions not
> >> > part of the form, but used in pre/postprocessing etc.
> >> >
> >> > For (i) it may be natural to construct the function space from the
> >> > form, and for (ii) it may be convenient in some cases, but it is not
> >> > really obvious that this is the best solution.
> >> >
> >> > Maybe an explicit construction of a function space can come with a
> >> > default, such as a nodal basis of piecewise linears?
> >> >
> >> > /Johan
> >>
> >> So:
> >>   FunctionSpace V(mesh);
> >>   Function f(V);
> >> gives a function f on piecewise linears?
> >> That's ok with me.
> >>
> >>
> >> About ownership, I think the only both robust and intuitive solution
> >> is that an object never should store a reference (or regular pointer)
> >> to another object. But as long as we are aware of the cost of doing
> >> this and state it clearly in the documentation, I'm ok with keeping
> >> e.g. the Mesh references like we do.
> >>
> >> Any time object A stores a reference to object B, the user must
> >> take care that the lifetime of B exceeds the lifetime of A. There
> >> are no exceptions to this. This puts some real limitations on the
> >> way the user must structure his program, e.g. he must sometimes
> >> (often?) keep objects around longer than they're explicitly needed.
> >>
> >> This may be a good thing, since it forces the user to think about
> >> dependencies and object lifetimes, and the objects in question
> >> use some memory.
> >
> > I think this is ok. There are many ways to create a segfault in C++.
> > If you program in C++, you will have to think about memory.
> >
> >> But if we use references instead of shared_ptr,
> >> we should never have default values:
> >> - A Function has a reference to a Mesh, which is ok since
> >>   it's always created outside.
> >> - If a DiscreteFunction is to have a reference to a Vector, or a
> >>   Function is to have a reference to a FunctionSpace, it cannot
> >>   create its own without adding memory management code.
> >>
> >> Every place we accept these limitations and requirements of how
> >> the user structures his programs, we can use references and be
> >> done with it. But don't think that the pretty syntax means the user
> >> doesn't have to think about memory management, since all the
> >> responsibility for memory management (object destruction order)
> >> is in fact placed on the user, and errors from the users side will
> >> lead to invalid references we cannot detect and segfaults.
> >
> > I want the syntax to be simple and pretty, but I don't necessarily
> > want to hide the user from problems that are part of the design of
> > C++. It isn't Python or Java. You should be expected to know what
> > you are doing. :-)
>
> It's not only about knowing what you're doing. It forces very
> hard restrictions on the design/flow of your program, which can
>
> 1) Be a major source of bugs in nontrivial apps (see Garths email), which
> are not locally visible because they depend on the global program flow.
>
> 2) Make it impossible to initialize e.g. Function in e.g a file reader,
> since the caller of the file reader would need to get the objects
> Function depends on. This is not limited to file readers, but is
> a recurring pattern in nontrivial apps.
>
> If we want to use dolfin or want dolfin to be used in apps that
> are more complicated than the traditional "read input, compute
> something, output something" app, these restrictions become
> a larger problem.
>
> > Anyway, I like the idea about having a FunctionSpace class which
> > several Functions may share. The problem we need to solve is
> > reading from file:
> >
> >  FunctionSpace V(mesh);
> >  Function u(V);
> >  file >> u;
> >
> > The last line just fills out the data in both u and V.
> >
> > This will lead to side effects as V might be changed when doing
> >
> >  FunctionSpace V(mesh);
> >  Function u(V);
> >  Function v(V);
> >  file >> u;
> >
> > V will be changed, both for u and v. In fact, the mesh will also be
> > changed.
> >
> > The best thing would be if we could do
> >
> >  file >> (mesh, V, u);
>
> This is _exactly_ the kind of issue that smart pointers solve.
>
> Btw, I tried to search the swig documentation for shared_ptr, and
> found nothing...
> I don't know what exactly they mean by "shared_ptr support".

It seems to be a set of typemaps that should kick in at the "right places". 
They are defined in

   <Lib/python/boost_shared_ptr.i> 

and used very rudimentary in

  <Examples/test_suite/li_boost_shared_ptr.i>

in the source tree of the 1.3.36 release. It seems that it is not specific for 
boost::share_ptr but should also figure out tr1::shared_ptr

I think:

  %include <boost_shared_ptr.i>

at the appropriate place should do the trick. 

Johan


Follow ups

References