← Back to team overview

dolfin team mailing list archive

Re: Function and DofMap

 

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. :-)

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);

-- 
Anders

Attachment: signature.asc
Description: Digital signature


Follow ups

References